all repos — Legends-RPG @ 2d133e01ba83b3ec61fe15d83267616c4375ac79

A fantasy mini-RPG built with Python and Pygame.

data/components/person.py (view raw)

  1__author__ = 'justinarmstrong'
  2import pygame as pg
  3from .. import setup
  4
  5
  6class Person(pg.sprite.Sprite):
  7    """Base class for all world characters
  8    controlled by the computer"""
  9
 10    def __init__(self, sheet_key, x, y, direction='down'):
 11        super(Person, self).__init__()
 12        self.get_image = setup.tools.get_image
 13        self.spritesheet_dict = self.create_spritesheet_dict(sheet_key)
 14        self.animation_dict = self.create_animation_dict()
 15        self.index = 0
 16        self.direction = direction
 17        self.image_list = self.animation_dict[self.direction]
 18        self.image = self.image_list[self.index]
 19        self.rect = self.image.get_rect(left=x, top=y)
 20        self.state_dict = self.create_state_dict()
 21        self.vector_dict = self.create_vector_dict()
 22        self.state = 'resting'
 23        self.x_vel = 0
 24        self.y_vel = 0
 25        self.timer = 0.0
 26
 27
 28    def create_spritesheet_dict(self, sheet_key):
 29        """Implemented by inheriting classes"""
 30        image_list = []
 31        image_dict = {}
 32        sheet = setup.GFX[sheet_key]
 33
 34        image_keys = ['facing up 1', 'facing up 2',
 35                      'facing down 1', 'facing down 2',
 36                      'facing left 1', 'facing left 2',
 37                      'facing right 1', 'facing right 2']
 38
 39        for row in range(2):
 40            for column in range(4):
 41                image_list.append(
 42                    self.get_image(self, column*32, row*32, 32, 32, sheet))
 43
 44        for key, image in zip(image_keys, image_list):
 45            image_dict[key] = image
 46
 47        return image_dict
 48
 49
 50    def create_animation_dict(self):
 51        """Return a dictionary of image lists for animation"""
 52        image_dict = self.spritesheet_dict
 53
 54        left_list = [image_dict['facing left 1'], image_dict['facing left 2']]
 55        right_list = [image_dict['facing right 1'], image_dict['facing right 2']]
 56        up_list = [image_dict['facing up 1'], image_dict['facing up 2']]
 57        down_list = [image_dict['facing down 1'], image_dict['facing down 2']]
 58
 59        direction_dict = {'left': left_list,
 60                          'right': right_list,
 61                          'up': up_list,
 62                          'down': down_list}
 63
 64        return direction_dict
 65
 66
 67    def create_state_dict(self):
 68        """Return a dictionary of all state methods"""
 69        state_dict = {'resting': self.resting,
 70                      'moving': self.moving}
 71
 72        return state_dict
 73
 74
 75    def create_vector_dict(self):
 76        """Return a dictionary of x and y velocities set to
 77        direction keys."""
 78        vector_dict = {'up': (0, -2),
 79                       'down': (0, 2),
 80                       'left': (-2, 0),
 81                       'right': (2, 0)}
 82
 83        return vector_dict
 84
 85
 86    def update(self, *args):
 87        """Implemented by inheriting classes"""
 88        pass
 89
 90
 91    def resting(self):
 92        """
 93        When the Person is not moving between tiles.
 94        Checks if the player is centered on a tile.
 95        """
 96        self.image = self.image_list[self.index]
 97
 98        assert(self.rect.y % 32 == 0), ('Player not centered on tile: '
 99                                        + str(self.rect.y))
100        assert(self.rect.x % 32 == 0), ('Player not centered on tile'
101                                        + str(self.rect.x))
102
103
104    def moving(self):
105        """Increment index and set self.image for animation."""
106        if (self.current_time - self.timer) > 100:
107            if self.index < (len(self.image_list) - 1):
108                self.index += 1
109            else:
110                self.index = 0
111            self.timer = self.current_time
112
113        self.image = self.image_list[self.index]
114
115        assert(self.rect.x % 32 == 0 or self.rect.y % 32 == 0), \
116            'Not centered on tile'
117
118
119    def begin_moving(self, direction):
120        """Transition the player into the 'moving' state."""
121        self.direction = direction
122        self.image_list = self.animation_dict[direction]
123        self.timer = self.current_time
124        self.state = 'moving'
125
126        if self.rect.x % 32 == 0:
127            self.y_vel = self.vector_dict[self.direction][1]
128        if self.rect.y % 32 == 0:
129            self.x_vel = self.vector_dict[self.direction][0]
130
131
132    def begin_resting(self):
133        """Transition the player into the 'resting' state."""
134        self.state = 'resting'
135        self.index = 1
136        self.x_vel = self.y_vel = 0
137
138
139class Player(Person):
140    """User controlled character"""
141
142    def __init__(self, direction):
143        super(Player, self).__init__('player', 0, 0, direction)
144
145
146    def update(self, keys, current_time):
147        """Updates player behavior"""
148        self.keys = keys
149        self.current_time = current_time
150        self.check_for_input()
151        state_function = self.state_dict[self.state]
152        state_function()
153
154
155    def check_for_input(self):
156        """Checks for player input"""
157        if self.state == 'resting':
158            if self.keys[pg.K_UP]:
159                self.begin_moving('up')
160            elif self.keys[pg.K_DOWN]:
161                self.begin_moving('down')
162            elif self.keys[pg.K_LEFT]:
163                self.begin_moving('left')
164            elif self.keys[pg.K_RIGHT]:
165                self.begin_moving('right')
166
167
168
169
170
171
172
173
174class Soldier(Person):
175    """Soldier for the castle"""
176
177    def __init__(self):
178        super(Soldier, self).__init__('soldier')
179
180
181class FemaleVillager(Person):
182    """Female Person for town"""
183
184    def __init__(self, x, y):
185        super(FemaleVillager, self).__init__('femalevillager', x, y)
186
187
188class MaleVillager(Person):
189    """Male Person for town"""
190
191    def __init__(self):
192        super(MaleVillager, self).__init__('male villager')
193