[Часть 1.5] Делаем свою 3D игру на Python
Данная статья находиться в разработке и может дополняться! Пишитесвое мнение в коментариях!
Делаем редактор!
Я хочу чтобы мой редактор карт бы похож на редактор игры «Doom II» так что написал я простой класс с редактором вот так:
import tkinter as tk
from tkinter import filedialog, simpledialog
class MapEditor:
def __init__(self, root):
self.root = root
self.root.title("Map Editor")
self.root.geometry("800x600")
# Начальные настройки
self.width = 10
self.height = 8
self.cell_size = 40
self.zoom = 1.0
self.init_map()
self.create_widgets()
self.bind_events()
self.draw_map()Здесь в этом коде мы :
Импортируем необходимые модули
Создаем класс редактора карт
Инициализируем основные параметры
Вызываем методы для создания интерфейса
Дальше для того чтобы мы могли взаимодействовать с програмой мы добавим в нее холст и панель инструментов:
def create_widgets(self):
# Холст для рисования карты
self.canvas = tk.Canvas(
self.root,
bg='#202020',
cursor="crosshair"
)
self.canvas.pack(fill=tk.BOTH, expand=True)
# Панель инструментов
self.toolbar = tk.Frame(self.root)
self.toolbar.pack(fill=tk.X)
# Кнопки управления
buttons = [
('New Map', self.new_map, '#555'),
('Zoom +', lambda: self.change_zoom(0.1), '#777'),
('Zoom -', lambda: self.change_zoom(-0.1), '#777'),
('Save', self.save_map, '#388E3C'),
('Load', self.load_map, '#1976D2')
]
for text, cmd, color in buttons:
btn = tk.Button(
self.toolbar,
text=text,
command=cmd,
bg=color,
fg='white',
padx=8,
pady=4
)
btn.pack(side=tk.LEFT, padx=2, pady=2)Создаем основной холст для отображения карты
Добавляем панель инструментов с кнопками
Настраиваем визуальный стиль элементов
Ну что давайте добавим в нашу карту схему создания самих карт! Напомню вот-так выглядит наша карта в файле map.txt:
8
WWWWWWWWWW
W W
W WW WW W
W WW W
W W
W WW W
W W
WWWWWWWWWWИ теперь для официального стиля я решил переименовать этот файл в ROOM1.map!
Как вы наверное поняли я назвал егоROOM1 потому что у нас будет система нескольких комнат и мы даже сделаем целое меню !
Вот и сам код :
def init_map(self):
"""Инициализация новой карты с границами"""
self.map_data = [[' ' for _ in range(self.width)] for _ in range(self.height)]
# Создание границ
for x in range(self.width):
self.map_data[0][x] = 'W'
self.map_data[-1][x] = 'W'
for y in range(self.height):
self.map_data[y][0] = 'W'
self.map_data[y][-1] = 'W'
def draw_map(self):
"""Отрисовка карты на холсте"""
self.canvas.delete("all")
cell = self.cell_size * self.zoom
for y in range(self.height):
for x in range(self.width):
color = self.get_color(self.map_data[y][x])
x0 = x * cell
y0 = y * cell
self.canvas.create_rectangle(
x0, y0, x0 + cell, y0 + cell,
fill=color,
outline='#333',
tags=("cell", f"{x},{y}")
)
def get_color(self, cell):
"""Возвращает цвет для типа ячейки"""
return {
'W': '#4A4A4A', # Стена
'.': '#6B6B6B', # Пол
' ': '#202020' # Пустота
}.get(cell, '#202020')Ну что-же давайте посмотрим на вышедший у нас редактор! Но сначала добавим еще чуть-чуть кода и магии обработки событий!
def bind_events(self):
"""Привязка обработчиков событий"""
# Мышь
self.canvas.bind("", self.draw)
self.canvas.bind("", self.draw)
self.canvas.bind("", self.erase)
self.canvas.bind("", self.erase)
# Клавиатура
self.root.bind("", lambda e: self.change_zoom(0.1))
self.root.bind("", lambda e: self.change_zoom(-0.1))
def draw(self, event):
"""Обработчик рисования ЛКМ"""
x, y = self.get_cell_coords(event.x, event.y)
if self.is_valid_cell(x, y):
self.map_data[y][x] = 'W'
self.draw_map()
def erase(self, event):
"""Обработчик стирания ПКМ"""
x, y = self.get_cell_coords(event.x, event.y)
if self.is_valid_cell(x, y):
self.map_data[y][x] = ' '
self.draw_map() def change_zoom(self, delta):
"""Изменение масштаба"""
self.zoom = max(0.5, min(2.0, self.zoom + delta))
self.draw_map()
def new_map(self):
"""Создание новой карты"""
new_width = simpledialog.askinteger("New Map", "Width:",
minvalue=5, maxvalue=50)
new_height = simpledialog.askinteger("New Map", "Height:",
minvalue=5, maxvalue=50)
if new_width and new_height:
self.width = new_width
self.height = new_height
self.init_map()
self.draw_map()
def save_map(self):
"""Сохранение карты в файл"""
file_path = filedialog.asksaveasfilename(
defaultextension=".map",
filetypes=[("Map files", "*.map")]
)
if file_path:
with open(file_path, 'w') as f:
f.write(f"{self.height}\n")
for row in self.map_data:
f.write(''.join(row).ljust(self.width, ' ') + '\n')
def load_map(self):
"""Загрузка карты из файла"""
file_path = filedialog.askopenfilename(
filetypes=[("Map files", "*.map")]
)
if file_path:
with open(file_path, 'r') as f:
lines = [line.strip() for line in f.readlines()]
self.height = int(lines[0])
self.map_data = [list(line.ljust(self.width, ' ')[:self.width]
for line in lines[1:self.height+1]]
self.draw_map()Итог!
В этой промежуточной статье мы сделали свой редактор уровней! Ну вот и его скриншоты:




Ну что-же спасибо и пока!!!
<- ПРОШЛАЯ СТАТЬЯ
Habrahabr.ru прочитано 19628 раз
