all repos — Legends-RPG @ a55164ece8c0aeea2d6fcc25cf11f80345134f11

A fantasy mini-RPG built with Python and Pygame.

data/states/level_state.py (view raw)

  1__author__ = 'justinarmstrong'
  2"""
  3This is the base class all level states (i.e. states
  4where the player can move around the screen) inherit
  5from.  This class inherits from the generic state class
  6found in the tools.py module.
  7"""
  8
  9import copy
 10import pygame as pg
 11from .. import tools, collision
 12from .. components import person, textbox, portal
 13from . import player_menu
 14from .. import tilerender
 15from .. import setup
 16
 17
 18class LevelState(tools._State):
 19    def __init__(self):
 20        super(LevelState, self).__init__()
 21        self.name = None
 22        self.tmx_map = None
 23        self.map_width = None
 24        self.map_height = None
 25
 26    def startup(self, current_time, game_data):
 27        """Called when the State object is created"""
 28        self.game_data = game_data
 29        self.current_time = current_time
 30        self.state = 'normal'
 31        self.allow_input = False
 32        self.renderer = tilerender.Renderer(self.tmx_map)
 33        self.map_image = self.renderer.make_2x_map()
 34
 35        self.viewport = self.make_viewport(self.map_image)
 36        self.level_surface = self.make_level_surface(self.map_image)
 37        self.level_rect = self.level_surface.get_rect()
 38        self.player = None
 39        self.portals = None
 40        self.player = person.Player(game_data['last direction'])
 41        self.player = self.make_player()
 42        self.blockers = self.make_blockers()
 43        self.sprites = self.make_sprites()
 44
 45        self.collision_handler = collision.CollisionHandler(self.player,
 46                                                            self.blockers,
 47                                                            self.sprites)
 48
 49        self.dialogue_handler = textbox.TextHandler(self)
 50        self.state_dict = self.make_state_dict()
 51        self.portals = self.make_level_portals()
 52        self.menu_screen = player_menu.Player_Menu(game_data, self)
 53
 54    def make_viewport(self, map_image):
 55        """Create the viewport to view the level through"""
 56        map_rect = map_image.get_rect()
 57        return setup.SCREEN.get_rect(bottom=map_rect.bottom)
 58
 59    def make_level_surface(self, map_image):
 60        """Creates the surface all images are blitted to"""
 61        map_rect = map_image.get_rect()
 62        map_width = map_rect.width
 63        if self.name == 'town':
 64            map_height = map_rect.height - 32
 65        else:
 66            map_height = map_rect.height
 67        size = map_width, map_height
 68        return pg.Surface(size).convert()
 69
 70    def make_player(self):
 71        """Makes the player and sets location"""
 72        player = person.Player(self.game_data['last direction'])
 73        last_state = self.game_data['last state']
 74
 75        for object in self.renderer.tmx_data.getObjects():
 76            properties = object.__dict__
 77            if properties['name'] == 'start point':
 78                if last_state == properties['state']:
 79                    posx = properties['x'] * 2
 80                    posy = (properties['y'] * 2) - 32
 81                    player.rect.x = posx
 82                    player.rect.y = posy
 83
 84        return player
 85
 86    def make_blockers(self):
 87        """Make the blockers for the level"""
 88        blockers = []
 89
 90        for object in self.renderer.tmx_data.getObjects():
 91            properties = object.__dict__
 92            if properties['name'] == 'blocker':
 93                left = properties['x'] * 2
 94                top = ((properties['y']) * 2) - 32
 95                blocker = pg.Rect(left, top, 32, 32)
 96                blockers.append(blocker)
 97
 98        return blockers
 99
100    def make_sprites(self):
101        """Make any sprites for the level as needed"""
102        sprites = pg.sprite.Group()
103
104        for object in self.renderer.tmx_data.getObjects():
105            properties = object.__dict__
106            if properties['name'] == 'sprite':
107                left = properties['x'] * 2
108                top = ((properties['y']) * 2) - 32
109
110                if properties['type'] == 'oldman':
111                    sprites.add(person.OldMan(left, top))
112                elif properties['type'] == 'bluedressgirl':
113                    sprites.add(person.FemaleVillager(left, top))
114                elif properties['type'] == 'femalewarrior':
115                    sprites.add(person.FemaleVillager2(left, top))
116                elif properties['type'] == 'devil':
117                    print 'hi'
118                    sprites.add(person.Devil(left, top))
119
120
121        return sprites
122
123
124    def set_sprite_dialogue(self):
125        """Sets unique dialogue for each sprite"""
126        pass
127
128
129    def make_state_dict(self):
130        """Make a dictionary of states the level can be in"""
131        state_dict = {'normal': self.running_normally,
132                      'dialogue': self.handling_dialogue,
133                      'menu': self.goto_menu}
134
135        return state_dict
136
137    def make_level_portals(self):
138        """Make the portals to switch state"""
139        portal_group = pg.sprite.Group()
140
141        for object in self.renderer.tmx_data.getObjects():
142            properties = object.__dict__
143            if properties['name'] == 'portal':
144                posx = properties['x'] * 2
145                posy = (properties['y'] * 2) - 32
146                new_state = properties['type']
147                portal_group.add(portal.Portal(posx, posy, new_state))
148
149
150        return portal_group
151
152
153    def running_normally(self, surface, keys, current_time):
154        """Update level normally"""
155        self.check_for_dialogue()
156        self.check_for_portals()
157        self.player.update(keys, current_time)
158        self.sprites.update(current_time)
159        self.collision_handler.update(keys, current_time)
160        self.dialogue_handler.update(keys, current_time)
161        self.check_for_menu(keys)
162        self.viewport_update()
163
164        self.draw_level(surface)
165
166
167    def check_for_portals(self):
168        """Check if the player walks into a door, requiring a level change"""
169        portal = pg.sprite.spritecollideany(self.player, self.portals)
170
171        if portal and self.player.state == 'resting':
172            self.player.location = self.player.get_tile_location()
173            self.next = portal.name
174            self.update_game_data()
175            self.done = True
176
177
178    def check_for_menu(self, keys):
179        """Check if player hits enter to go to menu"""
180        if keys[pg.K_RETURN] and self.allow_input:
181            if self.player.state == 'resting':
182                self.state = 'menu'
183                self.allow_input = False
184
185        if not keys[pg.K_RETURN]:
186            self.allow_input = True
187
188
189    def update_game_data(self):
190        """Update the persistant game data dictionary"""
191        self.game_data['last location'] = self.player.location
192        self.game_data['last direction'] = self.player.direction
193        self.game_data['last state'] = self.name
194        self.set_new_start_pos()
195
196
197    def set_new_start_pos(self):
198        """Set new start position based on previous state"""
199        location = copy.deepcopy(self.game_data['last location'])
200        direction = self.game_data['last direction']
201
202        if self.next == 'player menu':
203            pass
204        elif direction == 'up':
205            location[1] += 1
206        elif direction == 'down':
207            location[1] -= 1
208        elif direction == 'left':
209            location[0] += 1
210        elif direction == 'right':
211            location[0] -= 1
212
213
214
215    def handling_dialogue(self, surface, keys, current_time):
216        """Update only dialogue boxes"""
217        self.dialogue_handler.update(keys, current_time)
218        self.draw_level(surface)
219
220
221    def goto_menu(self, surface, keys, *args):
222        """Go to menu screen"""
223        self.menu_screen.update(surface, keys)
224        self.menu_screen.draw(surface)
225
226
227    def check_for_dialogue(self):
228        """Check if the level needs to freeze"""
229        if self.dialogue_handler.textbox:
230            self.state = 'dialogue'
231
232    def update(self, surface, keys, current_time):
233        """Updates state"""
234        state_function = self.state_dict[self.state]
235        state_function(surface, keys, current_time)
236
237    def viewport_update(self):
238        """Viewport stays centered on character, unless at edge of map"""
239        self.viewport.center = self.player.rect.center
240        self.viewport.clamp_ip(self.level_rect)
241
242    def draw_level(self, surface):
243        """Blits all images to screen"""
244        self.level_surface.blit(self.map_image, self.viewport, self.viewport)
245        self.level_surface.blit(self.player.image, self.player.rect)
246        self.sprites.draw(self.level_surface)
247
248        surface.blit(self.level_surface, (0, 0), self.viewport)
249        self.dialogue_handler.draw(surface)
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265