Subclassed Player, added a girl sprite, added two girls to map
Justin Armstrong justinmeister@gmail.com
Mon, 10 Mar 2014 12:17:36 -0700
6 files changed,
235 insertions(+),
26 deletions(-)
M
data/collision.py
→
data/collision.py
@@ -1,11 +1,13 @@
__author__ = 'justinarmstrong' +import pygame as pg class CollisionHandler(object): """Handles collisions between the user, blockers and computer characters""" - def __init__(self, player, blockers): + def __init__(self, player, blockers, sprites): self.player = player self.blockers = blockers + self.sprites = sprites self.collided = False def update(self):@@ -26,11 +28,21 @@ if self.player.rect.colliderect(blocker):
self.collided = True if self.collided: - if self.player.x_vel != 0: - self.player.rect.x -= self.player.x_vel - else: - self.player.rect.y -= self.player.y_vel - + self.reset_after_collision() self.collided = False self.player.begin_resting() + elif pg.sprite.spritecollide(self.player, self.sprites, False): + self.reset_after_collision() + self.player.begin_resting() + + + def reset_after_collision(self): + """Put player back to original position""" + if self.player.x_vel != 0: + self.player.rect.x -= self.player.x_vel + else: + self.player.rect.y -= self.player.y_vel + + +
A
data/components/person.py
@@ -0,0 +1,193 @@
+__author__ = 'justinarmstrong' +import pygame as pg +from .. import setup + + +class Person(pg.sprite.Sprite): + """Base class for all world characters + controlled by the computer""" + + def __init__(self, sheet_key, x, y, direction='down'): + super(Person, self).__init__() + self.get_image = setup.tools.get_image + self.spritesheet_dict = self.create_spritesheet_dict(sheet_key) + self.animation_dict = self.create_animation_dict() + self.index = 0 + self.direction = direction + self.image_list = self.animation_dict[self.direction] + self.image = self.image_list[self.index] + self.rect = self.image.get_rect(left=x, top=y) + self.state_dict = self.create_state_dict() + self.vector_dict = self.create_vector_dict() + self.state = 'resting' + self.x_vel = 0 + self.y_vel = 0 + self.timer = 0.0 + + + def create_spritesheet_dict(self, sheet_key): + """Implemented by inheriting classes""" + image_list = [] + image_dict = {} + sheet = setup.GFX[sheet_key] + + image_keys = ['facing up 1', 'facing up 2', + 'facing down 1', 'facing down 2', + 'facing left 1', 'facing left 2', + 'facing right 1', 'facing right 2'] + + for row in range(2): + for column in range(4): + image_list.append( + self.get_image(self, column*32, row*32, 32, 32, sheet)) + + for key, image in zip(image_keys, image_list): + image_dict[key] = image + + return image_dict + + + def create_animation_dict(self): + """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']] + right_list = [image_dict['facing right 1'], image_dict['facing right 2']] + up_list = [image_dict['facing up 1'], image_dict['facing up 2']] + down_list = [image_dict['facing down 1'], image_dict['facing down 2']] + + direction_dict = {'left': left_list, + 'right': right_list, + 'up': up_list, + 'down': down_list} + + return direction_dict + + + def create_state_dict(self): + """Return a dictionary of all state methods""" + state_dict = {'resting': self.resting, + 'moving': self.moving} + + return state_dict + + + def create_vector_dict(self): + """Return a dictionary of x and y velocities set to + direction keys.""" + vector_dict = {'up': (0, -2), + 'down': (0, 2), + 'left': (-2, 0), + 'right': (2, 0)} + + return vector_dict + + + def update(self, *args): + """Implemented by inheriting classes""" + pass + + + def resting(self): + """ + When the Person is not moving between tiles. + 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)) + assert(self.rect.x % 32 == 0), ('Player not centered on tile' + + str(self.rect.x)) + + + def moving(self): + """Increment index and set self.image for animation.""" + if (self.current_time - self.timer) > 100: + if self.index < (len(self.image_list) - 1): + self.index += 1 + else: + self.index = 0 + self.timer = self.current_time + + self.image = self.image_list[self.index] + + assert(self.rect.x % 32 == 0 or self.rect.y % 32 == 0), \ + 'Not centered on tile' + + + def begin_moving(self, direction): + """Transition the player into the 'moving' state.""" + self.direction = direction + self.image_list = self.animation_dict[direction] + self.timer = self.current_time + self.state = 'moving' + + if self.rect.x % 32 == 0: + self.y_vel = self.vector_dict[self.direction][1] + if self.rect.y % 32 == 0: + self.x_vel = self.vector_dict[self.direction][0] + + + def begin_resting(self): + """Transition the player into the 'resting' state.""" + self.state = 'resting' + self.index = 1 + self.x_vel = self.y_vel = 0 + + +class Player(Person): + """User controlled character""" + + def __init__(self, direction): + super(Player, self).__init__('player', 0, 0, direction) + + + def update(self, keys, current_time): + """Updates player behavior""" + self.keys = keys + self.current_time = current_time + self.check_for_input() + state_function = self.state_dict[self.state] + state_function() + + + def check_for_input(self): + """Checks for player input""" + if self.state == 'resting': + if self.keys[pg.K_UP]: + self.begin_moving('up') + elif self.keys[pg.K_DOWN]: + self.begin_moving('down') + elif self.keys[pg.K_LEFT]: + self.begin_moving('left') + elif self.keys[pg.K_RIGHT]: + self.begin_moving('right') + + + + + + + + +class Soldier(Person): + """Soldier for the castle""" + + def __init__(self): + super(Soldier, self).__init__('soldier') + + +class FemaleVillager(Person): + """Female Person for town""" + + def __init__(self, x, y): + super(FemaleVillager, self).__init__('femalevillager', x, y) + + +class MaleVillager(Person): + """Male Person for town""" + + def __init__(self): + super(MaleVillager, self).__init__('male villager') +
M
data/components/player.py
→
data/components/player.py
@@ -33,16 +33,16 @@ for column in range(4):
image_list.append(self.get_image( self, column*32, row*32, 32, 32, sheet)) - dict = {'facing up 1': image_list[0], - 'facing up 2': image_list[1], - 'facing down 1': image_list[2], - 'facing down 2': image_list[3], - 'facing left 1': image_list[4], - 'facing left 2': image_list[5], - 'facing right 1': image_list[6], - 'facing right 2': image_list[7]} + image_dict = {'facing up 1': image_list[0], + 'facing up 2': image_list[1], + 'facing down 1': image_list[2], + 'facing down 2': image_list[3], + 'facing left 1': image_list[4], + 'facing left 2': image_list[5], + 'facing right 1': image_list[6], + 'facing right 2': image_list[7]} - return dict + return image_dict def create_animation_lists(self):@@ -54,12 +54,12 @@ right_list = [image_dict['facing right 1'], image_dict['facing right 2']]
up_list = [image_dict['facing up 1'], image_dict['facing up 2']] down_list = [image_dict['facing down 1'], image_dict['facing down 2']] - dict = {'left': left_list, + direction_dict = {'left': left_list, 'right': right_list, 'up': up_list, 'down': down_list} - return dict + return direction_dict def create_state_dict(self):
M
data/states/sprite_start_pos.txt
→
data/states/sprite_start_pos.txt
@@ -32,7 +32,7 @@ 0000000000000000000000000
0000000000011000000000000 0000000000011000000000000 0000000000011000000000000 -0000000000011000000000000 +0000000000011000000F00000 0000000000011000000000000 0000000000011000000000000 0000000000011000000000000@@ -46,5 +46,5 @@ 0000111111111111111110000
0000000000011000000000000 0000000000011000000000000 0000000000011000000000000 -0000000000011000000000000 +0000000F00011000000000000 00000000000P1000000000000
M
data/states/town.py
→
data/states/town.py
@@ -5,6 +5,7 @@ import pygame as pg
from .. import setup, tools, collision from .. import constants as c from .. components.player import Player +from .. components import person class Town(tools._State): def __init__(self):@@ -22,10 +23,12 @@ self.blockers = self.create_blockers()
self.viewport = self.create_viewport() self.level_surface = self.create_level_surface() self.level_rect = self.level_surface.get_rect() - self.player = Player() + self.player = person.Player('up') + self.town_sprites = pg.sprite.Group() self.start_positions = self.set_sprite_positions() self.collision_handler = collision.CollisionHandler(self.player, - self.blockers) + self.blockers, + self.town_sprites) def create_town_sprite_sheet_dict(self):@@ -287,16 +290,16 @@
def set_sprite_positions(self): """Set the start positions for all the sprites in the level""" tile_map = open(os.path.join('data', 'states', 'sprite_start_pos.txt'), 'r') - dict = {} for row, line in enumerate(tile_map): for column, letter in enumerate(line): if letter == 'P': - dict['player'] = pg.Rect(column*32, row*32, 32, 32) - - self.player.rect = dict['player'] + self.player.rect = pg.Rect(column*32, row*32, 32, 32) + elif letter == 'F': + fem_villager = person.FemaleVillager(column*32, row*32) + self.town_sprites.add(fem_villager) - return dict + tile_map.close() def update(self, surface, keys, current_time):@@ -314,6 +317,7 @@ def draw_level(self, surface):
"""Blits all images to screen""" self.level_surface.blit(self.town_map['surface'], self.viewport, self.viewport) 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)