all repos — Legends-RPG @ 90efb3275223987ac539b64b19322402ed7bfac6

A fantasy mini-RPG built with Python and Pygame.

Fixed textbox bug, added inn sign, soldier animation
Justin Armstrong justinmeister@gmail.com
Thu, 13 Mar 2014 23:09:43 -0700
commit

90efb3275223987ac539b64b19322402ed7bfac6

parent

107d1b4f334c643b35bd44f6d8865a9e9a42e3b7

M The_Stolen_Crown.pyThe_Stolen_Crown.py

@@ -6,9 +6,11 @@ quest is to recover a magic crown"""

import sys import pygame as pg +from data import setup from data.main import main if __name__ =='__main__': + setup.GAME main() pg.quit() sys.exit()
M data/collision.pydata/collision.py

@@ -18,17 +18,16 @@ blockers.extend(sprite.blockers)

return blockers - def update(self): + + def update(self, keys, current_time): """Checks for collisions between game objects""" self.update_blockers() - self.player.rect.x += self.player.x_vel - self.player.rect.y += self.player.y_vel + self.player.rect.move_ip(self.player.x_vel, self.player.y_vel) self.check_for_blockers() self.update_blockers() for sprite in self.sprites: - sprite.rect.x += sprite.x_vel - sprite.rect.y += sprite.y_vel + sprite.rect.move_ip(sprite.x_vel, sprite.y_vel) self.check_for_blockers() if self.player.rect.x % 32 == 0 and self.player.rect.y % 32 == 0:

@@ -37,6 +36,7 @@

def update_blockers(self): """Update blockers list""" + pass
M data/components/person.pydata/components/person.py

@@ -72,7 +72,8 @@

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

@@ -88,11 +89,10 @@

return vector_dict - def update(self, keys, current_time): + def update(self, current_time): """Implemented by inheriting classes""" self.blockers = self.set_blockers() self.current_time = current_time - self.check_for_input() state_function = self.state_dict[self.state] state_function() self.location = self.get_tile_location()

@@ -165,9 +165,13 @@ assert(self.rect.x % 32 == 0 or self.rect.y % 32 == 0), \

'Not centered on tile' - def animation(self): + def animated_resting(self): + self.animation(500) + + + def animation(self, freq=100): """Adjust sprite image frame based on timer""" - if (self.current_time - self.timer) > 100: + if (self.current_time - self.timer) > freq: if self.index < (len(self.image_list) - 1): self.index += 1 else:

@@ -236,7 +240,7 @@ """Soldier for the castle"""

def __init__(self, x, y): super(Soldier, self).__init__('soldier', x, y) - self.dialogue = 'Welcome to the castle, citizen.' + self.state = 'animated resting'

@@ -245,7 +249,6 @@ """Female Person for town"""

def __init__(self, x, y): super(FemaleVillager, self).__init__('femalevillager', x, y) - self.dialogue = 'Hey there, Mr. Traveller. What brings you to our town?' class MaleVillager(Person):

@@ -253,5 +256,4 @@ """Male Person for town"""

def __init__(self): super(MaleVillager, self).__init__('male villager', x, y) - self.dialogue = 'Good morrow to you, Sir.'
M data/components/textbox.pydata/components/textbox.py

@@ -1,20 +1,22 @@

__author__ = 'justinarmstrong' -import random import pygame as pg from .. import setup from .. import constants as c -class Dialogue(pg.sprite.Sprite): +class Dialogue(object): """Text box used for dialogue""" def __init__(self, x, dialogue): - super(Dialogue, self).__init__() - self.image = setup.GFX['dialoguebox'] - self.rect = self.image.get_rect(centerx=x) + self.bground = setup.GFX['dialoguebox'] + self.rect = self.bground.get_rect(centerx=x) + self.image = pg.Surface(self.rect.size) + self.image.set_colorkey(c.BLACK) + self.image.blit(self.bground, (0, 0)) self.timer = 0.0 - self.font = pg.font.Font(setup.FONTS['Fixedsys500c'], 20) - self.dialogue_image = self.font.render(dialogue, True, c.BLACK) + self.font = pg.font.Font(setup.FONTS['Fixedsys500c'], 22) + self.dialogue_image = self.font.render(dialogue, False, c.NEAR_BLACK) self.dialogue_rect = self.dialogue_image.get_rect(left=50, top=50) self.image.blit(self.dialogue_image, self.dialogue_rect) + self.done = False def update(self, current_time): """Updates scrolling text"""

@@ -36,34 +38,30 @@ """Remove textbox from sprite group after 2 seconds"""

if self.timer == 0.0: self.timer = self.current_time - elif (self.current_time - self.timer) > 2000: - self.kill() + elif (self.current_time - self.timer) > 3000: + self.done = True class DialogueHandler(object): """Handles interaction between sprites to create dialogue boxes""" - def __init__(self, player, sprites, textbox_group): + def __init__(self, player, sprites): self.player = player self.sprites = sprites - self.textbox_group = textbox_group - self.textbox_onscreen = False - self.image_list = [] + self.textbox = None def update(self, keys, current_time): """Checks for the creation of Dialogue boxes""" - if keys[pg.K_SPACE] and not self.textbox_onscreen: + if keys[pg.K_SPACE] and not self.textbox: for sprite in self.sprites: self.check_for_dialogue(sprite) - self.textbox_group.update(current_time) - - if len(self.textbox_group) < 1: - self.textbox_onscreen = False - - assert(len(self.textbox_group) < 2) + if self.textbox: + self.textbox.update(current_time) + if self.textbox.done: + self.textbox = None def check_for_dialogue(self, sprite):

@@ -73,20 +71,22 @@ tile_x, tile_y = player.location

if player.direction == 'up': if sprite.location == (tile_x, tile_y - 1): - self.textbox_group.add(Dialogue(400, sprite.dialogue)) - self.textbox_onscreen = True + self.textbox = Dialogue(400, sprite.dialogue) elif player.direction == 'down': if sprite.location == (tile_x, tile_y + 1): - self.textbox_group.add(Dialogue(400, sprite.dialogue)) - self.textbox_onscreen = True + self.textbox = Dialogue(400, sprite.dialogue) elif player.direction == 'left': if sprite.location == (tile_x - 1, tile_y): - self.textbox_group.add(Dialogue(400, sprite.dialogue)) - self.textbox_onscreen = True + self.textbox = Dialogue(400, sprite.dialogue) elif player.direction == 'right': if sprite.location == (tile_x + 1, tile_y): - self.textbox_group.add(Dialogue(400, sprite.dialogue)) - self.textbox_onscreen = True + self.textbox = Dialogue(400, sprite.dialogue) + + + def draw(self, surface): + """Draws textbox to surface""" + if self.textbox: + surface.blit(self.textbox.image, self.textbox.rect)
M data/constants.pydata/constants.py

@@ -1,5 +1,7 @@

__author__ = 'justinarmstrong' +import pygame as pg + """Constants used throughout the game""" ##GAME STATES"""

@@ -10,5 +12,9 @@

##Colors BLACK = (0, 0, 0) +NEAR_BLACK = (1, 0, 0) WHITE = (255, 255, 255) + + +
M data/setup.pydata/setup.py

@@ -10,6 +10,8 @@ import pygame as pg

from . import tools from . import constants as c +GAME = 'BEGIN GAME' + ORIGINAL_CAPTION = 'The Stolen Crown' os.environ['SDL_VIDEO_CENTERED'] = '1'

@@ -24,3 +26,5 @@ MUSIC = tools.load_all_music(os.path.join('resources', 'music'))

GFX = tools.load_all_gfx(os.path.join('resources', 'graphics')) SFX = tools.load_all_sfx(os.path.join('resources', 'sound')) +FONT = pg.font.Font(FONTS['Fixedsys500c'], 20) +
M data/states/sprite_start_pos.txtdata/states/sprite_start_pos.txt

@@ -38,8 +38,8 @@ T0T0T0000001100000000000T

0T0T0000000110000000000T0 T0T0000000011000000333T0T 0T033300000110000003330T0 -T0T3330000011000F00222T0T -0T022200000110000002220T0 +T0T3330000011000000222T0T +0T0222000001100F0002220T0 T0T2220000011000000010T0T 0T0010000001100000001T0T0 T0T0111111111111111110T0T
M data/states/town.pydata/states/town.py

@@ -3,7 +3,8 @@

import pygame as pg from .. import tools, collision from .. import tilemap as tm -from ..components import person, textbox +from .. components import person, textbox + class Town(tools._State):

@@ -24,27 +25,48 @@ self.player = person.Player('up')

self.town_sprites = pg.sprite.Group() self.start_positions = tm.set_sprite_positions(self.player, self.town_sprites) + self.set_sprite_dialogue() self.collision_handler = collision.CollisionHandler(self.player, self.blockers, self.town_sprites) - self.textbox_group = pg.sprite.Group() self.dialogue_handler = textbox.DialogueHandler(self.player, - self.town_sprites, - self.textbox_group) + self.town_sprites) + + + def set_sprite_dialogue(self): + """Sets unique dialogue for each sprite""" + for sprite in self.town_sprites: + if sprite.location == (9, 49): + sprite.dialogue = 'Welcome to our town, Mr. Traveller!' + elif sprite.location == (16, 42): + sprite.dialogue = 'You seem tired, why not rest at our Inn?' + elif sprite.location == (14, 14): + sprite.dialogue = 'Welcome to the castle, citizen.' + elif sprite.location == (11, 14): + sprite.dialogue = 'I have heard rumours that the King has lost something...' + elif sprite.location == (11, 8): + sprite.dialogue = 'Be careful. There are monsters surrounding our town.' + elif sprite.location == (14, 8): + sprite.dialogue = 'Move along, citizen.' def update(self, surface, keys, current_time): """Updates state""" - self.keys = keys - self.current_time = current_time self.player.update(keys, current_time) - self.collision_handler.update() - self.update_viewport() + self.town_sprites.update(current_time) + self.collision_handler.update(keys, current_time) self.dialogue_handler.update(keys, current_time) + self.viewport_update() self.draw_level(surface) + def viewport_update(self): + """Viewport stays centered on character, unless at edge of map""" + self.viewport.center = self.player.rect.center + self.viewport.clamp_ip(self.level_rect) + + def draw_level(self, surface): """Blits all images to screen""" self.level_surface.blit(self.town_map['surface'], self.viewport, self.viewport)

@@ -52,13 +74,10 @@ self.level_surface.blit(self.player.image, self.player.rect)

self.town_sprites.draw(self.level_surface) surface.blit(self.level_surface, (0, 0), self.viewport) - self.textbox_group.draw(surface) + self.dialogue_handler.draw(surface) + - def update_viewport(self): - """Viewport stays centered on character, unless at edge of map""" - self.viewport.center = self.player.rect.center - self.viewport.clamp_ip(self.level_rect)
M data/states/town_layer2.txtdata/states/town_layer2.txt

@@ -36,10 +36,10 @@ 0000000000011000000000000

0000000000011000000000000 0000000000011000000000000 0000000000011000000000000 -0000000000011000000333000 -0003330000011000000333000 -0003330000011000000222000 -00022200000110000002D2000 +0000000000011000033333000 +0003330000011000033333000 +0003330000011000022222000 +00022200000110000222D2000 0002D20000011000000010000 0000100000011000000010000 0000111111111111111110000
M data/states/town_layer3.txtdata/states/town_layer3.txt

@@ -36,10 +36,10 @@ 0000000000011000000000000

0000000000011000000000000 0000000000011000000000000 0000000000011000000000000 -0000000000011000000333000 -0003330000011000000333000 -0003330000011000000222000 -00022200000110000002D2000 +0000000000011000033333000 +0003330000011000033333000 +00033300000110000222I2000 +00022200000110000222D2000 0002D20000011000000010000 0000100000011000000010000 0000111111111111111110000
M data/tilemap.pydata/tilemap.py

@@ -17,6 +17,7 @@ shield = setup.GFX['shield']

potion = setup.GFX['potion'] gem = setup.GFX['gem'] castle_door = setup.GFX['castledoor'] + medieval_signs = setup.GFX['medievalsigns'] tile_dict['pavement'] = get_tile(32, 48, tileset2) tile_dict['house wall'] = get_tile(64, 48, tileset2)

@@ -49,6 +50,7 @@ tile_dict['carpet bottomright'] = get_tile(144, 144, tileset2)

tile_dict['carpet left'] = get_tile(112, 128, tileset2) tile_dict['carpet right'] = get_tile(144, 128, tileset2) tile_dict['castle window'] = get_tile(128, 59, tileset1) + tile_dict['inn sign'] = get_tile(0, 96, medieval_signs, 32, 32) return tile_dict

@@ -253,6 +255,9 @@ blit_tile_to_map(tile, row, column, map, 32)

elif letter == 'M': tile = town_map_dict['gem'] blit_tile_to_map(tile, row, column, map, 32) + elif letter == 'I': + tile = town_map_dict['inn sign'] + blit_tile_to_map(tile, row, column, map, 32) tile_map.close()

@@ -318,5 +323,3 @@

get_image = tools.get_image town_map_dict = create_town_sprite_sheet_dict() - -