Files
pixel_tower_defense/editor.py
T
ScriptSorcerer f3a5647e5b To much gap between last commit
Im now working next on shoorting for turret

Added new sand map and new cannon tower images aswell as function to play animations, showing range, placing turrets on allowed tiles for towers

Buy and cancel button to buy towers
2026-07-04 23:50:07 +02:00

281 lines
9.9 KiB
Python

import pygame as pg
import pygame_gui as pgi
from game.util import *
from game.tilemap import Tilemap
RENDER_SCALE = 2.0
WINDOW_SIZE=(640, 480)
class Editor():
def __init__(self):
pg.font.init()
self.screen = pg.display.set_mode(WINDOW_SIZE)
self.clock = pg.time.Clock()
self.width, self.height = pg.display.get_surface().get_size()
self.tilemap = Tilemap(self, 16)
self.display = pg.Surface((WINDOW_SIZE[0] / RENDER_SCALE, WINDOW_SIZE[1] / RENDER_SCALE))
self.manager = pgi.UIManager(self.screen.get_size(), "assets/theme/editor_theme.json")
self.map = 'desert'
self.path = 'assets/maps/' + str(self.map) + '.json'
try:
self.tilemap.load(self.path)
except FileNotFoundError:
print('File not Found')
self.scroll = [0, 0]
self.assets = {
"base": load_images("/tiles/test"),
"jungle": load_images("/tiles/jungle"),
"desert": load_images('/tiles/desert')
}
self.tile_list = list(self.assets)
self.tile_group = 0
self.tile_variant = 0
self.movment = [False, False, False, False]
self.clicking = False
self.right_clicking = False
self.shift = False
self.ongrid = True
self.edit_mode = "tile"
self.drop_down_controls = pgi.elements.UIDropDownMenu(
options_list=["Mode: Tile", "Mode: Path"],
starting_option="Mode: Tile",
relative_rect=pg.Rect((self.screen.get_width() -200, 0), (200, 30)),
manager=self.manager
)
def run(self):
self.running = True
while self.running:
self.clock.tick(60)
self.update()
self.draw()
return self.running
def update(self):
#for pygame_gui
time_delta = self.clock.tick(60) / 1000.0
self.mpos = pg.mouse.get_pos()
# print(self.mpos)
self.mpos = (self.mpos[0] / RENDER_SCALE, self.mpos[1] / RENDER_SCALE)
self.tile_pos = (int((self.mpos[0] + self.scroll[0]) // self.tilemap.tile_size), int((self.mpos[1] + self.scroll[1]) // self.tilemap.tile_size))
# print(self.tile_pos)
self.scroll[0] += (self.movment[1] - self.movment[0]) * 2
self.scroll[1] += (self.movment[3] - self.movment[2]) * 2
self.process_clicks()
self.current_tile_img = self.assets[self.tile_list[self.tile_group]][self.tile_variant].copy()
for event in pg.event.get():
if event.type == pg.QUIT:
self.running = False
self.process_event(event)
self.manager.update(time_delta)
def process_event(self, event):
#pygame_gui
self.manager.process_events(event)
if event.type == pgi.UI_DROP_DOWN_MENU_CHANGED:
self.edit_mode = event.text.split(" ")[1].lower()
if event.type == pg.MOUSEBUTTONDOWN:
if event.button == 1:
self.clicking = True
if event.button == 3:
self.right_clicking = True
if self.shift:
if event.button == 4:
self.tile_variant = (self.tile_variant - 1) % len(self.assets[self.tile_list[self.tile_group]])
if event.button == 5:
self.tile_variant = (self.tile_variant + 1) % len(self.assets[self.tile_list[self.tile_group]])
else:
if event.button == 4:
self.tile_group = (self.tile_group - 1) % len(self.tile_list)
self.tile_variant = 0
if event.button == 5:
self.tile_group = (self.tile_group + 1) % len(self.tile_list)
self.tile_variant = 0
if event.type == pg.MOUSEBUTTONUP:
if event.button == 1:
self.clicking = False
if event.button == 3:
self.right_clicking = False
if event.type == pg.KEYDOWN:
if event.key == pg.K_a:
self.movment[0] = True
if event.key == pg.K_d:
self.movment[1] = True
if event.key == pg.K_w:
self.movment[2] = True
if event.key == pg.K_s:
self.movment[3] = True
if event.key == pg.K_LSHIFT:
self.shift = True
if event.key == pg.K_o:
self.tilemap.save(self.path)
if event.key == pg.K_BACKSPACE:
if self.edit_mode == "path":
self.remove_last_waypoint()
if event.key == pg.K_c:
if self.edit_mode == "path":
self.clear_waypoints()
if event.type == pg.KEYUP:
if event.key == pg.K_a:
self.movment[0] = False
if event.key == pg.K_d:
self.movment[1] = False
if event.key == pg.K_w:
self.movment[2] = False
if event.key == pg.K_s:
self.movment[3] = False
if event.key == pg.K_LSHIFT:
self.shift = False
def process_clicks(self):
if self.manager.get_hovering_any_element():
return
if self.clicking and self.ongrid and self.edit_mode == "tile":
self.tilemap.tilemap[str(self.tile_pos[0]) + ';' + str(self.tile_pos[1])] = {'type': self.tile_list[self.tile_group], 'variant': self.tile_variant, 'pos': self.tile_pos}
if self.clicking and self.ongrid and self.edit_mode == "path":
self.add_waypoint(self.tile_pos)
if self.right_clicking and self.edit_mode == "tile":
tile_loc = str(self.tile_pos[0]) + ';' + str(self.tile_pos[1])
if tile_loc in self.tilemap.tilemap:
del self.tilemap.tilemap[tile_loc]
if self.right_clicking and self.edit_mode == "path":
self.remove_waypoint_at(self.tile_pos)
def draw(self):
self.display.fill((0, 0, 0))
render_scroll = (int(self.scroll[0]), int(self.scroll[1]))
self.draw_grid(self.display, 60, render_scroll)
self.tilemap.render(self.display, offset=render_scroll)
if self.edit_mode == "path":
self.draw_path(self.display, self.tilemap.waypoints, self.scroll)
if self.ongrid and self.edit_mode == "tile":
self.display.blit(self.current_tile_img, (self.tile_pos[0] * self.tilemap.tile_size - self.scroll[0], self.tile_pos[1] * self.tilemap.tile_size - self.scroll[1]))
elif self.ongrid and self.edit_mode == "path":
pg.draw.circle(self.display, (255, 0, 0), (self.tile_pos[0] * self.tilemap.tile_size - self.scroll[0] + self.tilemap.tile_size//2, self.tile_pos[1] * self.tilemap.tile_size - self.scroll[1] + self.tilemap.tile_size//2), 5)
else:
if self.edit_mode == "tile":
self.display.blit(self.current_tile_img, self.mpos)
self.display.blit(self.current_tile_img, (10, 10))
self.screen.blit(pg.transform.scale(self.display, self.screen.get_size()))
self.manager.draw_ui(self.screen)
pg.display.update()
def draw_grid(self, surf, alpha, offset=(0, 0)):
tile_size = self.tilemap.tile_size
temp_surf = pg.Surface((self.width, self.height), pg.SRCALPHA)
offset_x, offset_y = offset
start_x = (offset_x // tile_size) * tile_size # normalize
start_y = (offset_y // tile_size) * tile_size
for x in range(start_x, offset_x + self.width, tile_size):
screen_x = x - offset_x
pg.draw.line(
temp_surf,
(255, 255, 255, alpha),
(screen_x, 0),
(screen_x, self.height)
)
for y in range(start_y, offset_y + self.height + tile_size, tile_size):
screen_y = y - offset_y
pg.draw.line(
temp_surf,
(255, 255, 255, alpha),
(0, screen_y),
(self.width, screen_y)
)
surf.blit(temp_surf, (0, 0))
def draw_path(self, surf, waypoints, offset):
if len(waypoints) == 0:
return
# draw first point even if there is no line yet
if len(waypoints) == 1:
pixel_point = tile_to_pixel(
waypoints[0],
self.tilemap.tile_size,
True
)
pixel_point_off = (
pixel_point[0] - offset[0],
pixel_point[1] - offset[1]
)
pg.draw.circle(surf, (255, 0, 0), pixel_point_off, 3)
return
for i in range(len(waypoints) -1):
tile_point1 = waypoints[i]
tile_point2 = waypoints[i+1]
pixel_point1 = tile_to_pixel(tile_point1, self.tilemap.tile_size, True)
pixel_point2 = tile_to_pixel(tile_point2, self.tilemap.tile_size, True)
pixel_point1_off = (pixel_point1[0] - offset[0], pixel_point1[1] - offset[1])
pixel_point2_off = (pixel_point2[0] - offset[0], pixel_point2[1] - offset[1])
pg.draw.circle(surf, (255, 0, 0), pixel_point1_off, 3)
pg.draw.line(
surf,
(255, 0, 0),
pixel_point1_off,
pixel_point2_off
)
pg.draw.circle(surf, (255, 0, 0), pixel_point2_off, 3)
def add_waypoint(self, tile_pos):
waypoint = [tile_pos[0], tile_pos[1]]
if waypoint in self.tilemap.waypoints:
return
self.tilemap.waypoints.append(waypoint)
def remove_waypoint_at(self, tile_pos):
waypoint = [tile_pos[0], tile_pos[1]]
if waypoint in self.tilemap.waypoints:
self.tilemap.waypoints.remove(waypoint)
def remove_last_waypoint(self):
if self.tilemap.waypoints:
self.tilemap.waypoints.pop()
def clear_waypoints(self):
self.tilemap.waypoints.clear()