all repos — Legends-RPG @ 46298b7559a64ba4be11d3fb68bc23cae32b124e

A fantasy mini-RPG built with Python and Pygame.

Tweaked menu, tweaked sound effects, some other minor tweaks.
Justin Armstrong justinmeister@gmail.com
Mon, 02 Jun 2014 14:37:51 -0700
commit

46298b7559a64ba4be11d3fb68bc23cae32b124e

parent

2ded5c74f1c07582e76cc562f5d3027c49637745

M data/battlegui.pydata/battlegui.py

@@ -245,8 +245,7 @@ self.index = 0

self.rect.topleft = self.pos_list[self.index] self.allow_input = False self.enemy_pos_list = enemy_pos_list - self.sound_effect_observer = observer.SoundEffects() - self.observers = [self.sound_effect_observer] + self.observers = [observer.SoundEffects()] def notify(self, event): """
M data/components/person.pydata/components/person.py

@@ -47,7 +47,9 @@ self.death_image = pg.transform.scale2x(self.image)

self.battle = None def create_spritesheet_dict(self, sheet_key): - """Implemented by inheriting classes""" + """ + Make a dictionary of images from sprite sheet. + """ image_list = [] image_dict = {} sheet = setup.GFX[sheet_key]

@@ -68,7 +70,9 @@

return image_dict def create_animation_dict(self): - """Return a dictionary of image lists for animation""" + """ + Return a dictionary of image lists for animation. + """ image_dict = self.spritesheet_dict left_list = [image_dict['facing left 1'], image_dict['facing left 2']]

@@ -84,7 +88,9 @@

return direction_dict def create_state_dict(self): - """Return a dictionary of all state methods""" + """ + Return a dictionary of all state methods. + """ state_dict = {'resting': self.resting, 'moving': self.moving, 'animated resting': self.animated_resting,

@@ -101,8 +107,10 @@

return state_dict def create_vector_dict(self): - """Return a dictionary of x and y velocities set to - direction keys.""" + """ + Return a dictionary of x and y velocities set to + direction keys. + """ vector_dict = {'up': (0, -1), 'down': (0, 1), 'left': (-1, 0),

@@ -111,7 +119,9 @@

return vector_dict def update(self, current_time, *args): - """Implemented by inheriting classes""" + """ + Update sprite. + """ self.blockers = self.set_blockers() self.current_time = current_time self.image_list = self.animation_dict[self.direction]

@@ -120,7 +130,9 @@ state_function()

self.location = self.get_tile_location() def set_blockers(self): - """Sets blockers to prevent collision with other sprites""" + """ + Sets blockers to prevent collision with other sprites. + """ blockers = [] if self.state == 'resting' or self.state == 'autoresting':

@@ -190,7 +202,6 @@ top = box[1]*32

box_rects.append(pg.Rect(left, top, 32, 32)) return box_rects - def resting(self): """

@@ -199,10 +210,10 @@ Checks if the player is centered on a tile.

""" self.image = self.image_list[self.index] - assert(self.rect.y % 32 == 0), ('Player not centered on tile: ' - + str(self.rect.y) + " : " + str(self.name)) - assert(self.rect.x % 32 == 0), ('Player not centered on tile' - + str(self.rect.x)) + if self.rect.y % 32 != 0: + self.correct_position(self.rect.y) + if self.rect.x % 32 != 0: + self.correct_position(self.rect.x) def moving(self): """

@@ -278,7 +289,6 @@ """

Determine when to move a sprite from resting to moving in a random direction. """ - #self.image = self.image_list[self.index] self.image_list = self.animation_dict[self.direction] self.image = self.image_list[self.index]
M data/components/textbox.pydata/components/textbox.py

@@ -1,9 +1,8 @@

__author__ = 'justinarmstrong' import copy import pygame as pg -from .. import setup +from .. import setup, observer, tools from .. import constants as c - class NextArrow(pg.sprite.Sprite):

@@ -31,10 +30,14 @@ self.check_to_draw_arrow()

self.done = False self.allow_input = False self.name = image_key - + self.observers = [observer.SoundEffects()] + self.notify = tools.notify_observers + self.notify(self, c.CLICK) def make_dialogue_box_image(self): - """Make the image of the dialogue box""" + """ + Make the image of the dialogue box. + """ image = pg.Surface(self.rect.size) image.set_colorkey(c.BLACK) image.blit(self.bground, (0, 0))

@@ -67,38 +70,11 @@ if not keys[pg.K_SPACE]:

self.allow_input = True def check_to_draw_arrow(self): - """Blink arrow if more text needs to be read""" + """ + Blink arrow if more text needs to be read. + """ if self.index < len(self.dialogue_list) - 1: self.image.blit(self.arrow.image, self.arrow.rect) - else: - pass - - -class ItemBox(DialogueBox): - """Text box for information like obtaining new items""" - def __init__(self, dialogue, item=None): - super(ItemBox, self).__init__(None, 0, 'infobox', item) - - def make_dialogue_box_image(self): - """Make the image of the dialogue box""" - image = pg.Surface(self.rect.size) - image.set_colorkey(c.BLACK) - image.blit(self.bground, (0, 0)) - - if self.item: - type = 'Healing Potion' - total = str(1) - dialogue = 'You received ' + total + ' ' + type + '.' - self.dialogue_list = [dialogue] - self.item = None - - dialogue_image = self.font.render(self.dialogue_list[self.index], - False, - c.NEAR_BLACK) - dialogue_rect = dialogue_image.get_rect(left=50, top=50) - image.blit(dialogue_image, dialogue_rect) - - return image class TextHandler(object):

@@ -113,6 +89,8 @@ self.allow_input = False

self.level = level self.last_textbox_timer = 0.0 self.game_data = level.game_data + self.observers = [observer.SoundEffects()] + self.notify = tools.notify_observers def update(self, keys, current_time): """Checks for the creation of Dialogue boxes"""

@@ -204,6 +182,7 @@ self.level.state = 'normal'

self.textbox = None self.last_textbox_timer = current_time self.reset_sprite_direction() + self.notify(self, c.CLICK) def check_for_dialogue(self, sprite): """Checks if a sprite is in the correct location to give dialogue"""
M data/constants.pydata/constants.py

@@ -49,7 +49,7 @@ SWITCH_ENEMY = 'switch enemy'

PLAYER_ATTACK = 'player attack' SELECT_ITEM = 'select item' SELECT_MAGIC = 'select magic' -RUN_AWAY = 'run away' +RUN_AWAY = 'run_away' ATTACK_ANIMATION = 'attack animation' BATTLE_WON = 'battle won' ENEMY_DAMAGED = 'enemy damaged'

@@ -82,6 +82,7 @@ SWORD = 'sword'

FIRE = 'fire' PUNCH = 'punch' POWERUP = 'powerup' +TALK = 'talk' TRANSITION_SPEED = 35
M data/menugui.pydata/menugui.py

@@ -165,7 +165,7 @@ self.possible_weapons = ['Long Sword', 'Rapier']

self.possible_magic = ['Fire Blast', 'Cure'] self.quantity_items = ['Healing Potion', 'ELIXIR', 'Ether Potion'] self.slots = {} - self.state = 'stats' + self.state = 'invisible' self.state_dict = self.make_state_dict() self.print_slots = True

@@ -191,7 +191,8 @@ def make_state_dict(self):

"""Make the dictionary of state methods""" state_dict = {'stats': self.show_player_stats, 'items': self.show_items, - 'magic': self.show_magic} + 'magic': self.show_magic, + 'invisible': self.show_nothing} return state_dict

@@ -331,6 +332,13 @@

self.image = surface self.rect = rect + def show_nothing(self): + """ + Show nothing when the menu is opened from a level. + """ + self.image = pg.Surface((1, 1)) + self.rect = self.image.get_rect() + self.image.fill(c.BLACK_BLUE) def make_blank_info_box(self, title): """Make an info box with title, otherwise blank"""

@@ -365,7 +373,7 @@ self.font = pg.font.Font(setup.FONTS[c.MAIN_FONT], 22)

self.image, self.rect = self.make_image() def make_image(self): - choices = ['Stats', 'Items', 'Magic'] + choices = ['Items', 'Magic', 'Stats'] image = setup.GFX['goldbox'] rect = image.get_rect(left=10, top=425)

@@ -400,8 +408,6 @@ self.arrow = SmallArrow(self.info_box)

self.arrow_index = 0 self.allow_input = False - - def check_for_input(self, keys): """Check for input""" if self.allow_input:

@@ -437,11 +443,11 @@ elif keys[pg.K_SPACE]:

self.notify(c.CLICK2) if self.arrow.state == 'selectmenu': if self.arrow_index == 0: - self.info_box.state = 'stats' - elif self.arrow_index == 1: self.info_box.state = 'items' - elif self.arrow_index == 2: + elif self.arrow_index == 1: self.info_box.state = 'magic' + elif self.arrow_index == 2: + self.info_box.state = 'stats' elif self.arrow.state == 'itemsubmenu': self.select_item() elif self.arrow.state == 'magicsubmenu':

@@ -450,7 +456,7 @@

self.allow_input = False elif keys[pg.K_RETURN]: self.level.state = 'normal' - self.info_box.state = 'stats' + self.info_box.state = 'invisible' self.allow_input = False self.arrow_index = 0 self.arrow.state = 'selectmenu'
M data/shopgui.pydata/shopgui.py

@@ -309,9 +309,11 @@ quantity = item['quantity']

value = item['price'] power = item['power'] magic_list = ['Cure', 'Fire Blast'] + player_armor = ['Chain Mail', 'Wooden Shield'] player_items = self.level.game_data['player inventory'] player_health = self.level.game_data['player stats']['health'] player_magic = self.level.game_data['player stats']['magic'] + equipped_armor = self.level.game_data['player inventory']['equipped armor'] item_to_add = {'quantity': quantity, 'value': value,

@@ -321,7 +323,9 @@ if item_type in magic_list:

item_to_add = {'magic points': item['magic points'], 'power': item['power']} player_items[item_type] = item_to_add - elif item_type in player_items: + if item_type in player_armor: + equipped_armor.append(item_type) + if item_type in player_items: player_items[item_type]['quantity'] += quantity elif quantity > 0: player_items[item_type] = item_to_add

@@ -381,6 +385,9 @@ self.state = 'cantsellequippedarmor'

else: self.notify(c.CLOTH_BELT) self.sell_inventory_data_adjust(item_price, item_name) + else: + self.notify(c.CLOTH_BELT) + self.sell_inventory_data_adjust(item_price, item_name) def sell_inventory_data_adjust(self, item_price, item_name): """
M data/states/battle.pydata/states/battle.py

@@ -21,7 +21,9 @@ self.music = setup.MUSIC['high_action']

self.volume = 0.4 def startup(self, current_time, game_data): - """Initialize state attributes""" + """ + Initialize state attributes. + """ self.current_time = current_time self.timer = current_time self.allow_input = False

@@ -115,7 +117,9 @@

return gold def make_background(self): - """Make the blue/black background""" + """ + Make the blue/black background. + """ background = pg.sprite.Sprite() surface = pg.Surface(c.SCREEN_SIZE).convert() surface.fill(c.BLACK_BLUE)

@@ -126,7 +130,9 @@

return background_group def make_enemies(self): - """Make the enemies for the battle. Return sprite group""" + """ + Make the enemies for the battle. Return sprite group. + """ pos_list = [] for column in range(3):

@@ -158,7 +164,9 @@

return enemy_group, pos_list[0:len(enemy_group)], enemy_list def make_player(self): - """Make the sprite for the player's character""" + """ + Make the sprite for the player's character. + """ player = person.Player('left', self.game_data, 630, 220, 'battle resting', 1) player.image = pg.transform.scale2x(player.image) return player

@@ -173,7 +181,9 @@ self.enter_select_magic_state, self.try_to_run_away]

return dict(izip(pos_list, state_list)) def update(self, surface, keys, current_time): - """Update the battle state""" + """ + Update the battle state. + """ self.current_time = current_time self.check_input(keys) self.check_timed_events()

@@ -198,17 +208,21 @@ if keys[pg.K_RETURN]:

self.end_battle() elif keys[pg.K_SPACE]: + if self.state == c.SELECT_ACTION: + self.notify(c.CLICK2) enter_state_function = self.select_action_state_dict[ self.arrow.rect.topleft] enter_state_function() elif self.state == c.SELECT_ENEMY: + self.notify(c.CLICK2) self.player_actions.append(c.PLAYER_ATTACK) self.enemies_to_attack.append(self.get_enemy_to_attack()) self.action_selected = True elif self.state == c.SELECT_ITEM: + self.notify(c.CLICK2) if self.arrow.index == (len(self.arrow.pos_list) - 1): self.enter_select_action_state() elif self.info_box.item_text_list[self.arrow.index][:14] == 'Healing Potion':

@@ -218,6 +232,7 @@ elif self.info_box.item_text_list[self.arrow.index][:5] == 'Ether':

self.player_actions.append(c.DRINK_ETHER_POTION) self.action_selected = True elif self.state == c.SELECT_MAGIC: + self.notify(c.CLICK2) if self.arrow.index == (len(self.arrow.pos_list) - 1): self.enter_select_action_state() elif self.info_box.magic_text_list[self.arrow.index] == 'Cure':

@@ -661,6 +676,7 @@ self.state = self.info_box.state = c.RUN_AWAY

self.arrow.state = 'invisible' self.player.state = c.RUN_AWAY self.set_timer_to_current_time() + self.notify(c.RUN_AWAY) def enter_battle_won_state(self): """
M data/states/player_menu.pydata/states/player_menu.py

@@ -1,6 +1,7 @@

""" This is the state where the player can look at his inventory, equip items and check stats. +Most of the logic is in menugui.MenuGUI() """ import pygame as pg from .. import tools, setup, menugui

@@ -17,7 +18,9 @@ self.background = self.make_background()

self.gui = menugui.MenuGui(level, inventory, stats) def make_background(self): - """Makes the generic black/blue background""" + """ + Makes the generic black/blue background. + """ background = pg.sprite.Sprite() surface = pg.Surface(c.SCREEN_SIZE).convert() surface.fill(c.BLACK_BLUE)

@@ -31,7 +34,9 @@

return background def make_sprite(self, key, coordx, coordy, x=40, y=25): - """Get the image for the player""" + """ + Get the image for the player. + """ spritesheet = setup.GFX[key] surface = pg.Surface((32, 32)) surface.set_colorkey(c.BLACK)
M data/states/shop.pydata/states/shop.py

@@ -49,27 +49,33 @@

return state_dict def make_dialogue(self): - """Make the list of dialogue phrases""" + """ + Make the list of dialogue phrases. + """ raise NotImplementedError - def make_accept_dialogue(self): - """Make the dialogue for when the player buys an item""" + """ + Make the dialogue for when the player buys an item. + """ return ['Item purchased.'] - def make_accept_sale_dialogue(self): - """Make the dialogue for when the player sells an item""" + """ + Make the dialogue for when the player sells an item. + """ return ['Item sold.'] - def make_purchasable_items(self): - """Make the list of items to be bought at shop""" + """ + Make the list of items to be bought at shop. + """ raise NotImplementedError - def make_background(self): - """Make the level surface""" + """ + Make the level surface. + """ background = pg.sprite.Sprite() surface = pg.Surface(c.SCREEN_SIZE).convert() surface.fill(c.BLACK_BLUE)

@@ -86,9 +92,10 @@ background.image.blit(counter.image, counter.rect)

return background - def make_sprite(self, key, coordx, coordy, x, y=304): - """Get the image for the player""" + """ + Get the image for the player. + """ spritesheet = setup.GFX[key] surface = pg.Surface((32, 32)) surface.set_colorkey(c.BLACK)

@@ -103,10 +110,11 @@ sprite.image = surface

sprite.rect = rect return sprite - def make_counter(self): - """Make the counter to conduct business""" + """ + Make the counter to conduct business. + """ sprite_sheet = copy.copy(setup.GFX['house']) sprite = pg.sprite.Sprite() sprite.image = self.get_image(102, 64, 26, 82, sprite_sheet)

@@ -123,7 +131,9 @@ state_function = self.state_dict[self.state]

state_function(surface, keys, current_time) def normal_update(self, surface, keys, current_time): - """Update level normally""" + """ + Update level normally. + """ self.gui.update(keys, current_time) self.draw_level(surface)

@@ -155,29 +165,34 @@ if self.transition_alpha >= 255:

self.done = True def draw_level(self, surface): - """Blit graphics to game surface""" + """ + Blit graphics to game surface. + """ surface.blit(self.background.image, self.background.rect) self.gui.draw(surface) - class Inn(Shop): - """Where our hero gets rest""" + """ + Where our hero gets rest. + """ def __init__(self): super(Inn, self).__init__() self.name = c.INN self.key = 'innman' def make_dialogue(self): - """Make the list of dialogue phrases""" + """ + Make the list of dialogue phrases. + """ return ["Welcome to the " + self.name + "!", "Would you like a room to restore your health?"] - def make_accept_dialogue(self): - """Make the dialogue for when the player buys an item""" + """ + Make the dialogue for when the player buys an item. + """ return ['Your health has been replenished!'] - def make_purchasable_items(self): """Make list of items to be chosen"""

@@ -190,7 +205,6 @@ 'power': None,

'dialogue': dialogue} return [item] - class WeaponShop(Shop):

@@ -283,7 +297,7 @@ fire_dialogue = 'Fire Blast (150 gold)'

cure_dialogue = 'Cure (150 gold)' item1 = {'type': 'Cure', - 'price': 150, + 'price': 50, 'quantity': 1, 'magic points': 25, 'power': 50,
M data/tools.pydata/tools.py

@@ -177,6 +177,12 @@ 'rect': rect}

return tile_dict +def notify_observers(self, event): + """ + Notify all observers of events. + """ + for each_observer in self.observers: + each_observer.on_notify(event) def create_game_data_dict(): """Create a dictionary of persistant values the player
M resources/tmx/town.tmxresources/tmx/town.tmx

@@ -416,5 +416,11 @@ <object name="blocker" gid="120" x="144" y="784"/>

<object name="blocker" gid="120" x="128" y="784"/> <object name="blocker" gid="120" x="112" y="768"/> <object name="blocker" gid="120" x="112" y="752"/> + <object name="sprite" type="soldier" gid="124" x="112" y="576"> + <properties> + <property name="dialogue length" value="1"/> + <property name="dialogue0" value="Hey, there."/> + </properties> + </object> </objectgroup> </map>