From e103605f00c6906e0bfb43749487acd9f67c84f2 Mon Sep 17 00:00:00 2001 From: ScriptSorcerer Date: Fri, 17 Jul 2026 22:56:47 +0200 Subject: [PATCH] Added tower upgrading Issue #8 (pylint problem resolved with this change) Upgrade system not done, only simplel upgrading added --- game/screens/game_play.py | 53 +++++++++++++++++++++++++-------------- game/tower.py | 30 ++++++++++++++++------ game/upgrade_data.py | 9 +++++++ 3 files changed, 66 insertions(+), 26 deletions(-) create mode 100644 game/upgrade_data.py diff --git a/game/screens/game_play.py b/game/screens/game_play.py index 079c7e9..7f18f66 100644 --- a/game/screens/game_play.py +++ b/game/screens/game_play.py @@ -34,7 +34,6 @@ class GamePlay(BaseScreen): self.center = (self.game_surface.get_width() /2, self.game_surface.get_height() /2) self.movment = [False, False, False, False] self.selected = None - self.notunselect = True self.map = 'desert' self.path = 'assets/maps/' + str(self.map) + '.json' @@ -72,12 +71,25 @@ class GamePlay(BaseScreen): text="Cancel", manager=self.game.ui_manager ) + self.upgrade_button = pgi.elements.UIButton( + relative_rect=pg.Rect( + self.width - 200, + self.height -100, + 150, + 50 + ), + + text="Upgrade Tower", + manager=self.game.ui_manager + ) self.buy_button.hide() self.cancel_button.hide() + self.upgrade_button.hide() self.bought = False self.elements = [ self.buy_button, - self.cancel_button + self.cancel_button, + self.upgrade_button ] self.mpos = (0, 0) @@ -109,27 +121,20 @@ class GamePlay(BaseScreen): else: self.tile_pos = None - if event.type == pgi.UI_BUTTON_PRESSED: - if event.ui_element == self.buy_button: - self.bought = True - # self.tower = Tower(self.game, self.mpos, self.tile_pos, 'cannon') - if event.ui_element == self.cancel_button: - self.bought = False - self.tile_pos = (int(self.tile_pos_decimal[0]), int(self.tile_pos_decimal[1])) if event.type == pg.MOUSEBUTTONDOWN: - if self.tile_pos is not None: - if event.button == 1: - self.selected = self.select_turret(self.tile_pos) - self.clear_selection() - if self.selected is not None: - print(f'selected: {self.selected}') - self.selected.selected = True - print(f'{self.selected}') + if event.button == 1: + if self.tile_pos is not None: + if game_rect.collidepoint(self.mpos): + # only clear and reselect when clicking inside the game surface + self.clear_selection() + self.selected = self.select_tower(self.tile_pos) + if self.selected is not None: + self.selected.selected = True if self.bought: if self.game.tilemap.placeable(self.tile_pos): if not any(tw.tile_pos == self.tile_pos for tw in self.tower_group): - tower = Tower(self.game, self.mpos, self.tile_pos, 'cannon', 40) + tower = Tower(self.game, self.mpos, self.tile_pos, 'cannon') self.tower_group.add(tower) self.bought = False if event.button == 3: @@ -137,6 +142,16 @@ class GamePlay(BaseScreen): if tower.tile_pos == self.tile_pos: tower.kill() + if event.type == pgi.UI_BUTTON_PRESSED: + if event.ui_element == self.buy_button: + self.bought = True + # self.tower = Tower(self.game, self.mpos, self.tile_pos, 'cannon') + if event.ui_element == self.cancel_button: + self.bought = False + if event.ui_element == self.upgrade_button: + if self.selected: + self.selected.upgrade() + if event.type == pg.KEYDOWN: if event.key == pg.K_a: self.movment[0] = True @@ -206,7 +221,7 @@ class GamePlay(BaseScreen): surface.blit(self.game_surface, (0, self.height/6)) - def select_turret(self, tile_pos): + def select_tower(self, tile_pos): """Return the tower at tile_pos, or ``None`` if the tile is empty. Args: diff --git a/game/tower.py b/game/tower.py index 4a25092..d9f71ab 100644 --- a/game/tower.py +++ b/game/tower.py @@ -2,6 +2,7 @@ import math import pygame as pg from game.util import tile_to_pixel +from game.upgrade_data import UPGRADE_DATA class Tower(pg.sprite.Sprite): # pylint: disable=too-many-instance-attributes @@ -20,23 +21,25 @@ class Tower(pg.sprite.Sprite): pos (tuple): World-space pixel centre position. tile_pos (tuple): Grid position the tower occupies. """ - def __init__(self, game, pos, tile_pos, type, range, level=1): + def __init__(self, game, pos, tile_pos, tower_type, level=1): super().__init__() self.game = game - self.type = type - self.image = self.game.assets[type] + self.type = tower_type + self.image = self.game.assets[tower_type] self.rect = self.image.get_rect() self.rect.center = pos - self.range = range + self.level = level + + self.range = UPGRADE_DATA[self.type][self.level]["range"] + self.fire_rate = UPGRADE_DATA[self.type][self.level]["fire_rate"] + self.damage = UPGRADE_DATA[self.type][self.level]["damage"] + self.selected = False self.angle = 0 self.target = None - self.fire_rate = 180 # frames between shots — tune to taste self.fire_cooldown = 0 - self.damage = 50 - self.pos = pos self.tile_pos = tile_pos self.level = level @@ -152,6 +155,19 @@ class Tower(pg.sprite.Sprite): self.animation.play_animation() self.fire_cooldown = self.fire_rate + def upgrade(self): + """Upgrade the tower by one Level""" + print("upgrade") + next_level = self.level + 1 + data = UPGRADE_DATA[self.type] + if next_level not in data: + return + + self.level = next_level + self.damage = data[next_level]['damage'] + self.fire_rate = data[next_level]['fire_rate'] + self.range = data[next_level]['range'] + class TowerGroup(pg.sprite.Group): """Sprite group that delegates rendering and updates to each tower.""" diff --git a/game/upgrade_data.py b/game/upgrade_data.py new file mode 100644 index 0000000..73e9bcc --- /dev/null +++ b/game/upgrade_data.py @@ -0,0 +1,9 @@ +"""Upgrade Data module - Stores data for tower upgrades""" + +UPGRADE_DATA = { + 'cannon': { + 1: {'damage': 30, 'fire_rate': 180, 'range': 40}, + 2: {'damage': 50, 'fire_rate': 140, 'range': 50}, + 3: {'damage': 80, 'fire_rate': 120, 'range': 65}, + } +}