From: Neil Date: Tue, 13 May 2014 16:53:41 +0000 (+0200) Subject: Hack in multi-modal behaviour X-Git-Tag: 0.1~337 X-Git-Url: https://git.ctpug.org.za/?a=commitdiff_plain;h=42e40dc4e5a5ae8a11934b5f718c9bd4e91f06ce;p=naja.git Hack in multi-modal behaviour --- diff --git a/naja/constants.py b/naja/constants.py index 8506db0..b6fce4e 100644 --- a/naja/constants.py +++ b/naja/constants.py @@ -52,3 +52,7 @@ BOARD_SIZE = (5 * TILE_SIZE[0], 5 * TILE_SIZE[1]) BIT_SIZE = (5 * TILE_SIZE[0], (SCREEN[1] - 5 * TILE_SIZE[1]) // 2) INFO_SIZE = (SCREEN[0] - 5 * TILE_SIZE[0], SCREEN[1]) PLAYER_SIZE = (64, 96) + +# Player States +MOVE = 1 +ACT = 2 diff --git a/naja/gameboard.py b/naja/gameboard.py index de0bc1e..33afc5d 100644 --- a/naja/gameboard.py +++ b/naja/gameboard.py @@ -1,7 +1,8 @@ from random import choice from naja.constants import( - BITS, DIRECTION_BITS, CONDITION_BITS, PLAYER_DEFAULTS) + BITS, DIRECTION_BITS, CONDITION_BITS, PLAYER_DEFAULTS, + MOVE, ACT) from naja.player import Player from naja import actions @@ -19,6 +20,7 @@ class GameBoard(object): self.locations = [item.copy() for item in state['locations']] self.player = player self.board_locations = board_locations + self.player_mode = MOVE @classmethod def new_game(cls, locations_definition, @@ -88,6 +90,15 @@ class GameBoard(object): self.health -= 1 # TODO: Check win/lose + def change_mode(self): + """Advance to the next mode""" + if self.player_mode == MOVE: + self.player_mode = ACT + elif self.player_mode == ACT: + self.player_mode = MOVE + else: + raise RuntimeError("Illegal player mode %s" % self.player_mode) + class LocationCard(object): """ diff --git a/naja/widgets/info_area.py b/naja/widgets/info_area.py index 906e9d5..2a4d06b 100644 --- a/naja/widgets/info_area.py +++ b/naja/widgets/info_area.py @@ -2,14 +2,28 @@ Widget for the game board information area. """ import pygame +import pygame.locals as pgl -from naja.constants import INFO_SIZE, EIGHT_BIT_SCALE +from naja.constants import INFO_SIZE, EIGHT_BIT_SCALE, MOVE, ACT +from naja.events import InvalidateTheWorld from naja.resources import resources from naja.resources.mutators import EIGHT_BIT from naja.widgets.base import Widget from naja.widgets.tile import BIT_MAP -from naja.widgets.text import TextBoxWidget +from naja.widgets.text import TextBoxWidget, TextWidget + + +HINTS = { + MOVE: "Move using the arrow keys.\nPress SPACE to stay in place", + ACT: "Choose an action using the Up/Down keys.\n" + "Press Return to execute the action.", + } + +TITLES = { + MOVE: "Move the Robot", + ACT: "Choose an Action", + } class InfoAreaWidget(Widget): @@ -20,6 +34,7 @@ class InfoAreaWidget(Widget): super(InfoAreaWidget, self).__init__(pos, INFO_SIZE) self.card = None self.state = state + self.chosen = 0 def prepare(self): self.surface = pygame.surface.Surface(INFO_SIZE) @@ -27,8 +42,11 @@ class InfoAreaWidget(Widget): # Quick hack for testing self.card = self.state.board_locations[self.state.player.position] # Extract actions and such from the card - y_offset = 0 - for action in self.card.actions: + title = TextWidget((0, 0), TITLES[self.state.gameboard.player_mode], + colour=(255, 255, 255)) + title.render(self.surface) + y_offset = title.surface.get_rect().height + 8 + for choice, action in enumerate(self.card.actions): if action.required_bits: img_name = BIT_MAP[action.required_bits].replace('.png', '_small.png') img = resources.get_image(img_name, @@ -36,14 +54,48 @@ class InfoAreaWidget(Widget): self.surface.blit(img, (0, y_offset)) y_offset += 8 text = TextBoxWidget((12, y_offset), action.TEXT, - box_width= (INFO_SIZE[0] - 12) // EIGHT_BIT_SCALE, - fontsize = 28, padding = 4) + box_width=(INFO_SIZE[0] - 12) // EIGHT_BIT_SCALE, + fontsize=28) text.render(self.surface) + if choice == self.chosen: + colour = (255, 255, 0, 128) + bottom = y_offset + text.surface.get_rect().height + right = text.surface.get_rect().width + 12 + pygame.draw.lines(self.surface, colour, True, + [(12, y_offset), (right, y_offset), + (right, bottom), (12, bottom)], 4) y_offset += text.surface.get_rect().height + 16 - + # We cheat horribly for layout reasons + hint = TextBoxWidget((0, 0), HINTS[self.state.gameboard.player_mode], + box_width = INFO_SIZE[0] // EIGHT_BIT_SCALE) + hint.prepare() + y_offset = INFO_SIZE[1] - hint.surface.get_rect().height + self.surface.blit(hint.surface, (0, y_offset)) def set_card(self, card): self.card = card def draw(self, surface): surface.blit(self.surface, self.pos) + + def handle_event(self, ev): + if self.state.gameboard.player_mode == MOVE: + return super(InfoAreaWidget, self).handle_event(ev) + if ev.type == pgl.KEYDOWN: + if ev.key in (pgl.K_RETURN, pgl.K_KP_ENTER): + self.state.gameboard.change_mode() + # FIXME: also need to signal the correct action + # here + InvalidateTheWorld.post() + return True + if ev.key in (pgl.K_UP, pgl.K_w): + if self.chosen > 0: + self.chosen -= 1 + InvalidateTheWorld.post() + return True + if ev.key in (pgl.K_DOWN, pgl.K_s): + if self.chosen + 1 < len(self.card.actions): + self.chosen += 1 + InvalidateTheWorld.post() + return True + return super(InfoAreaWidget, self).handle_event(ev) diff --git a/naja/widgets/robot.py b/naja/widgets/robot.py index b6e219b..3518cb0 100644 --- a/naja/widgets/robot.py +++ b/naja/widgets/robot.py @@ -2,7 +2,7 @@ import pygame.locals as pgl -from naja.constants import PLAYER_SIZE, BIT_SIZE, TILE_SIZE, BITS +from naja.constants import PLAYER_SIZE, BIT_SIZE, TILE_SIZE, BITS, ACT from naja.events import InvalidateTheWorld from naja.resources import resources from naja.resources.mutators import EIGHT_BIT @@ -39,21 +39,31 @@ class RobotWidget(Widget): surface.blit(self.surface, self.rect) def handle_event(self, ev): + if self.state.gameboard.player_mode == ACT: + return super(RobotWidget, self).handle_event(ev) if ev.type == pgl.KEYDOWN: if ev.key in (pgl.K_UP, pgl.K_w): if self.state.player.move(BITS.NORTH): + self.state.gameboard.change_mode() InvalidateTheWorld.post() return True if ev.key in (pgl.K_DOWN, pgl.K_s): if self.state.player.move(BITS.SOUTH): + self.state.gameboard.change_mode() InvalidateTheWorld.post() return True if ev.key in (pgl.K_LEFT, pgl.K_a): if self.state.player.move(BITS.WEST): + self.state.gameboard.change_mode() InvalidateTheWorld.post() return True if ev.key in (pgl.K_RIGHT, pgl.K_d): if self.state.player.move(BITS.EAST): + self.state.gameboard.change_mode() InvalidateTheWorld.post() return True - super(RobotWidget, self).handle_event(ev) + if ev.key in (pgl.K_SPACE,): + self.state.gameboard.change_mode() + InvalidateTheWorld.post() + return True + return super(RobotWidget, self).handle_event(ev)