Return to repo list

heart-of-gold

Tactical RPG written in python, using pygame.
Return to HMagellan.com

commit 9674b9145b1082e35bdb2acb57e30a2c9586c6a2
parent 515ce6391a849e50b6dda8bb5c76ce78e989a2b2
Author: Erik Letson <hmagellan@hmagellan.com>
Date:   Sun, 25 Apr 2021 18:11:09 -0500

complete overhaul of how action buttons are defined

Diffstat:
Msrc/turn.py | 220++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 180 insertions(+), 40 deletions(-)

diff --git a/src/turn.py b/src/turn.py @@ -22,6 +22,7 @@ from .constants import * # This file contains the following: # 1. The TurnManager class, which handles turn order and displaying turn info in the GUI # 2. Several entity subclasses used by TurnManager to make up the battle UI +# 3. The ActionButton generic class and its associated subclasses that represent the actually-displayed action buttons ################################# # Section 1 - TurnManager class # @@ -88,10 +89,16 @@ class TurnManager(manager.Manager): self.turn_projection = [] self.former_candidates = [] self.current_turn = 1 - for b in range(0, 7): - nab = ActionButton(sheets["action_buttons_1"], (0, b), None, False, self) - nab.set_position(((SCREEN_WIDTH // 8), (SCREEN_HEIGHT // 10) + (((SCREEN_HEIGHT // 14) - 4)) * b)) - self.action_buttons.append(nab) + + # Create action buttons + self.action_buttons.append(MoveActionButton(sheets["action_buttons_1"], (0, 0), None, False, self, 0)) + self.action_buttons.append(AttackActionButton(sheets["action_buttons_1"], (0, 1), None, False, self, 1)) + self.action_buttons.append(SkillActionButton(sheets["action_buttons_1"], (0, 2), None, False, self, 2)) + self.action_buttons.append(ItemActionButton(sheets["action_buttons_1"], (0, 3), None, False, self, 3)) + self.action_buttons.append(GuardActionButton(sheets["action_buttons_1"], (0, 4), None, False, self, 5)) + self.action_buttons.append(PushActionButton(sheets["action_buttons_1"], (0, 5), None, False, self, 4)) + self.action_buttons.append(EndTurnActionButton(sheets["action_buttons_1"], (0, 6), None, False, self, 6)) + self.shift_turns() # NOTE: This happens here to properly snap after the snap involved in a turn shift. This is, again, not pretty self.camera.snap_to_position(tuple(self.board_events["init_camera_pos"])) @@ -268,40 +275,9 @@ class TurnManager(manager.Manager): self.game.control_mode = CTRL_MODES.Turn_Display_Stats break - # Do action buttons. They are ordered so we know which is which by index - # TODO: Nothing else is index-accessed this way. This should be changed. - # Truly, calling to the bus should be performed by the button object itself. - # This object should have an associated bus method that it is passed when created, - # and it should call this when clicked. This whole structure here should be replaced - # with a call to a 'am i collided-with' function for every button in action buttons. - # The buttons could also have a 'result_ctrl_mode' attribute that represents what - # CTRL_MODE should be switched to when it is clicked. It is possible that the - # easiest way to do this would be to make an abstract action button class that - # works like the current one along with having a generic, overwritable 'be_clicked' - # method and taking a 'result_ctrl_mode' argument in addition to the current ones, - # and then subclassing this into the resultant actual action buttons. - if self.action_buttons[0].rect.collidepoint(pos) and self.action_buttons[0].clickable: - self.bus.perform_display_move_range_of_piece(self.current_active_piece) - self.camera.snap_to_position(self.current_active_piece.rect.center) - self.game.control_mode = CTRL_MODES.Turn_Select_Move - elif self.action_buttons[1].rect.collidepoint(pos) and self.action_buttons[1].clickable: - self.bus.perform_display_attack_range_of_piece(self.current_active_piece) - self.camera.snap_to_position(self.current_active_piece.rect.center) - self.game.control_mode = CTRL_MODES.Turn_Select_Attack - elif self.action_buttons[2].rect.collidepoint(pos) and self.action_buttons[2].clickable: - self.camera.snap_to_position(self.current_active_piece.rect.center) - self.game.control_mode = CTRL_MODES.Turn_Choose_Skill - elif self.action_buttons[3].rect.collidepoint(pos) and self.action_buttons[3].clickable: - self.camera.snap_to_position(self.current_active_piece.rect.center) - self.game.control_mode = CTRL_MODES.Turn_Choose_Item - elif self.action_buttons[4].rect.collidepoint(pos) and self.action_buttons[4].clickable: - self.bus.perform_execute_guard(self.current_active_piece) - self.game.control_mode = CTRL_MODES.Turn_Watch_Guard - elif self.action_buttons[5].rect.collidepoint(pos) and self.action_buttons[5].clickable: - self.camera.snap_to_position(self.current_active_piece.rect.center) - self.game.control_mode = CTRL_MODES.Turn_Select_Push - elif self.action_buttons[6].rect.collidepoint(pos) and self.action_buttons[6].clickable: - self.shift_turns() + # ActionButton objects are easier + for a in self.action_buttons: + a.be_clicked(pos) def kill_piece(self, piece): """ @@ -550,6 +526,10 @@ class TurnTrayMoreButton(entity.Entity): self.more = not self.more self.set_sprite((0, int(self.more))) +################################################# +# Section 3 - ActionButton class and subclasses # +################################################# + class ActionButton(entity.Entity): """ Class representing the buttons that can be @@ -557,12 +537,14 @@ class ActionButton(entity.Entity): during their turn. """ - def __init__(self, sheet, sprite = (0, 0), animation = None, animated = None, - manager = None): + def __init__(self, sheet, sprite = (0, 0), animation = None, animated = None, manager = None, screen_pos_y_offset = 0): # Parent initialization super().__init__(sheet, sprite, animation, animated) + # Setup + self.set_position(((SCREEN_WIDTH // 8), (SCREEN_HEIGHT // 10) + ((SCREEN_HEIGHT // 14) - 4) * screen_pos_y_offset)) + # Other values self.manager = manager self.clickable = False @@ -574,3 +556,161 @@ class ActionButton(entity.Entity): """ self.clickable = not self.clickable self.set_sprite((int(not self.clickable), self.sprite[1])) + + def be_clicked(self, click_pos): + """ + Check if this button has been clicked, and if so, + activate. + """ + if self.rect.collidepoint(click_pos) and self.clickable: + self.activate() + if self.result_ctrl_mode != None: + self.manager.game.control_mode = self.result_ctrl_mode + + def activate(self): + """ + Generic activation function overwritten in children. + """ + pass + +# Subclasses +class MoveActionButton(ActionButton): + """ + Class representing the button that lets the player move + the current active piece. + """ + + def __init__(self, sheet, sprite = (0, 0), animation = None, animated = None, manager = None, screen_pos_y_offset = 0): + + # Parent initialization + super().__init__(sheet, sprite, animation, animated, manager, screen_pos_y_offset) + + # Other + self.result_ctrl_mode = CTRL_MODES.Turn_Select_Move + + def activate(self): + """ + Move-button-specific activation effects. + """ + self.manager.bus.perform_display_move_range_of_piece(self.manager.current_active_piece) + self.manager.camera.snap_to_position(self.manager.current_active_piece.rect.center) + +class AttackActionButton(ActionButton): + """ + Class representing the button that lets the player choose + an attack target for the current active piece. + """ + def __init__(self, sheet, sprite = (0, 0), animation = None, animated = None, manager = None, screen_pos_y_offset = 0): + + # Parent initialization + super().__init__(sheet, sprite, animation, animated, manager, screen_pos_y_offset) + + # Other + self.result_ctrl_mode = CTRL_MODES.Turn_Select_Attack + + def activate(self): + """ + AttackButton-specific activation effects. + """ + self.manager.bus.perform_display_attack_range_of_piece(self.manager.current_active_piece) + self.manager.camera.snap_to_position(self.manager.current_active_piece.rect.center) + +class SkillActionButton(ActionButton): + """ + Class representing the button that lets the player select + a skill for the current active piece to use. + """ + + def __init__(self, sheet, sprite = (0, 0), animation = None, animated = None, manager = None, screen_pos_y_offset = 0): + + # Parent initialization + super().__init__(sheet, sprite, animation, animated, manager, screen_pos_y_offset) + + # Other + self.result_ctrl_mode = CTRL_MODES.Turn_Choose_Skill + + def activate(self): + """ + SkillButton-specific activation effects. + """ + self.manager.camera.snap_to_position(self.manager.current_active_piece.rect.center) + +class ItemActionButton(ActionButton): + """ + Class representing the button that lets the player select + an item for the current active piece to use. + """ + + def __init__(self, sheet, sprite = (0, 0), animation = None, animated = None, manager = None, screen_pos_y_offset = 0): + + # Parent initialization + super().__init__(sheet, sprite, animation, animated, manager, screen_pos_y_offset) + + # Other + self.result_ctrl_mode = CTRL_MODES.Turn_Choose_Item + + def activate(self): + """ + ItemButton-specific activation effects. + """ + self.manager.camera.snap_to_position(self.manager.current_active_piece.rect.center) + +class GuardActionButton(ActionButton): + """ + Class representing the button that lets the player make + the current active piece guard. + """ + + def __init__(self, sheet, sprite = (0, 0), animation = None, animated = None, manager = None, screen_pos_y_offset = 0): + + # Parent initialization + super().__init__(sheet, sprite, animation, animated, manager, screen_pos_y_offset) + + # Other + self.result_ctrl_mode = CTRL_MODES.Turn_Watch_Guard + + def activate(self): + """ + GuardButton-specific activation effects. + """ + self.manager.bus.perform_execute_guard(self.manager.current_active_piece) + +class PushActionButton(ActionButton): + """ + Class representing the button that lets the player select + a push target for the current active piece. + """ + + def __init__(self, sheet, sprite = (0, 0), animation = None, animated = None, manager = None, screen_pos_y_offset = 0): + + # Parent initialization + super().__init__(sheet, sprite, animation, animated, manager, screen_pos_y_offset) + + # Other + self.result_ctrl_mode = CTRL_MODES.Turn_Select_Push + + def activate(self): + """ + PushButton-specific activation effects. + """ + self.manager.camera.snap_to_position(self.manager.current_active_piece.rect.center) + +class EndTurnActionButton(ActionButton): + """ + Class representing the button that lets the player end + the current turn. + """ + + def __init__(self, sheet, sprite = (0, 0), animation = None, animated = None, manager = None, screen_pos_y_offset = 0): + + # Parent initialization + super().__init__(sheet, sprite, animation, animated, manager, screen_pos_y_offset) + + # Other + self.result_ctrl_mode = None + + def activate(self): + """ + EndTurnButton-specific activation effects. + """ + self.manager.shift_turns()