Данная утилита предназначена для получения координат наложения миникарты на глобальную карту в PDA (персональных цифровых помощниках, или КПК).
Следует отметить, что программа теоретически совместима с файлами всех частей трилогии. Для этого вам потребуется загрузить глобальную карту, соответствующую конкретной части игры. Убедитесь, что все необходимые файлы готовы и правильно загружены для оптимального использования утилиты.
import tkinter as tk
from tkinter import filedialog, messagebox
from PIL import Image, ImageTk
import os
class TextureEditor:
def __init__(self, master):
self.master = master
self.master.title("Game Maps Single Editor")
# Всплывающее окно с инструкцией
self.show_instructions()
# Загрузка первой текстуры
self.texture1_path = self.select_texture_file(title="Выберите первую текстуру", required_name="ui_global_map.dds", extensions=[('DDS files', '*.dds')])
if self.texture1_path:
self.texture1 = Image.open(self.texture1_path)
else:
return
# Загрузка второй текстуры
self.texture2_path = self.select_texture_file(title="Выберите вторую текстуру", extensions=[('DDS files', '*.dds')])
if self.texture2_path:
self.texture2 = Image.open(self.texture2_path).resize((250, 250), Image.LANCZOS)
else:
return
# Устанавливаем фиксированную ширину и изменяемую высоту окна
self.fixed_width = self.texture1.width
self.master.geometry(f"{self.fixed_width}x{self.texture1.height}")
self.master.resizable(False, True)
# Создаем Canvas
self.canvas = tk.Canvas(master, bg="white", height=self.texture1.height)
self.canvas.pack(fill=tk.BOTH, expand=True)
# Отображаем первую текстуру
self.tk_texture1 = ImageTk.PhotoImage(self.texture1)
self.canvas.create_image(0, 0, image=self.tk_texture1, anchor=tk.NW)
# Отображаем вторую текстуру
self.tk_texture2 = ImageTk.PhotoImage(self.texture2)
self.texture2_coords = (0, 0)
self.texture2_id = self.canvas.create_image(self.texture2_coords[0], self.texture2_coords[1],
image=self.tk_texture2, anchor=tk.NW)
# Обновляем Canvas
self.update_canvas()
# Привязываем события мыши
self.canvas.bind("<Button-1>", self.start_move_texture2)
self.canvas.bind("<B1-Motion>", self.move_texture2)
self.canvas.bind("<ButtonRelease-1>", self.release_mouse)
# Обработка перемещения мыши для скрытия или отображения курсора
self.canvas.bind("<Motion>", self.check_cursor_visibility)
# Колесико мыши для прокрутки
self.canvas.bind("<MouseWheel>", self.on_mouse_wheel)
# Создание фрейма для кнопок
self.button_frame = tk.Frame(master, bg="lightgray")
self.button_frame.place(x=0, y=0, relwidth=1)
self.save_button = tk.Button(self.button_frame, text="global_rect", command=self.save_coordinates, bg="gray", width=18)
self.save_button.pack(side=tk.LEFT, padx=5, pady=5)
self.increase_button = tk.Button(self.button_frame, text="+", command=self.increase_texture2, width=5, bg="lightgray")
self.increase_button.pack(side=tk.LEFT, padx=5, pady=5)
self.decrease_button = tk.Button(self.button_frame, text="-", command=self.decrease_texture2, width=5, bg="lightgray")
self.decrease_button.pack(side=tk.LEFT, padx=5, pady=5)
# Обновляем область прокрутки
self.update_scroll_region()
def show_instructions(self):
messagebox.showinfo("Инструкции", "Управление программой:\n\n"
"- Первой нужно выбирать текстуру глобальной карты (ui_global_map).\n"
"- Второй - локальной карты (map).\n"
"- Текстуру map.dds возможно перезаписывать на нужную.\n"
"- Левый клик для перемещения текстуры карты.\n"
"- Перетаскивайте текстуру с помочью левой кнопки мыши.\n"
"- Используйте кнопки увеличения (+) и уменьшения (-) для изменения размера текстуры.\n"
"- Используйте колесико мыши, для просмотра глобальной карты.\n"
"- Кнопка 'global_rect' сохраняет координаты текстуры в файл (coordinates.txt).\n",
icon='info')
def select_texture_file(self, title, required_name=None, extensions=None):
while True:
file_path = filedialog.askopenfilename(title=title, filetypes=extensions)
if not file_path: # Проверяем, если пользователь отменил выбор
return None
if required_name:
if os.path.basename(file_path) == required_name:
return file_path
else:
messagebox.showerror("Ошибка", f"Выберите файл с именем '{required_name}'!")
else:
if file_path.lower().endswith('.dds'):
return file_path
else:
messagebox.showerror("Ошибка", "Выберите файл в формате DDS!")
def update_canvas(self):
self.canvas.delete("all") # Удаляем все
self.canvas.create_image(0, 0, image=self.tk_texture1, anchor=tk.NW)
self.canvas.create_image(self.texture2_coords[0], self.texture2_coords[1],
image=self.tk_texture2, anchor=tk.NW)
self.update_scroll_region()
def update_scroll_region(self):
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
def start_move_texture2(self, event):
if (self.texture2_coords[0] <= event.x <= self.texture2_coords[0] + self.texture2.width and
self.texture2_coords[1] <= event.y <= self.texture2_coords[1] + self.texture2.height):
self.texture2_coords = (event.x, event.y)
self.master.config(cursor="none")
def move_texture2(self, event):
new_x = event.x
new_y = event.y
# Ограничиваем новые координаты
if new_x < 0:
new_x = 0
elif new_x + self.texture2.width > self.texture1.width:
new_x = self.texture1.width - self.texture2.width
if new_y < 0:
new_y = 0
elif new_y + self.texture2.height > self.texture1.height:
new_y = self.texture1.height - self.texture2.height
self.texture2_coords = (new_x, new_y)
self.update_canvas()
def release_mouse(self, event):
self.master.config(cursor="")
def check_cursor_visibility(self, event):
# Проверка, нужно ли скрыть курсор
if (self.texture2_coords[0] <= event.x <= self.texture2_coords[0] + self.texture2.width and
self.texture2_coords[1] <= event.y <= self.texture2_coords[1] + self.texture2.height):
self.master.config(cursor="none")
else:
self.master.config(cursor="")
def on_mouse_wheel(self, event):
# Прокрутка с помощью колесика мыши
self.canvas.yview_scroll(-1 * (event.delta // 120), "units")
def increase_texture2(self):
delta = 10 # Размер увеличения
new_width = self.texture2.width + delta
new_height = self.texture2.height + delta
self.texture2 = self.texture2.resize((new_width, new_height), Image.LANCZOS)
self.tk_texture2 = ImageTk.PhotoImage(self.texture2) # Обновляем отображаемое изображение
self.update_canvas()
def decrease_texture2(self):
delta = 10 # Размер уменьшения
new_width = max(1, self.texture2.width - delta)
new_height = max(1, self.texture2.height - delta)
self.texture2 = self.texture2.resize((new_width, new_height), Image.LANCZOS)
self.tk_texture2 = ImageTk.PhotoImage(self.texture2) # Обновляем отображаемое изображение
self.update_canvas()
def save_coordinates(self):
x1, y1 = self.texture2_coords
x2, y2 = x1 + self.texture2.width, y1 + self.texture2.height
coords = f"{x1:.1f},{y1:.1f},{x2:.1f},{y2:.1f}"
with open("coordinates.txt", "w") as file:
file.write(f"global_rect = {coords}\n")
print(f"Сохраненные координаты: global_rect = {coords}")
# Запуск приложения
if __name__ == "__main__":
root = tk.Tk()
app = TextureEditor(root)
root.mainloop()
Программка работает нормально. Объяснение: "Как работать с прожкой" - кривое. Зачет. Для пристрелки расположения локации пойдёт. Но для сборки общей карты с локациями лучше использовать "Map dragger" - программа сложная, но позволяет расположить сразу все карты локаций на общей карте, относительно друг друга и подогнать размеры. Получить координаты как расположения карты локации так и размеры самой карты локации.