all repos — Legends-RPG @ 6387912ba1c75cd67b42aa13d443f3b07598983d

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 = pg.sprite.Group()
 44        #self.start_positions = tm.set_sprite_positions(self.player,
 45        #                                               self.sprites,
 46        #                                               self.name,
 47        #                                               self.game_data)
 48        #self.set_sprite_dialogue()
 49        self.collision_handler = collision.CollisionHandler(self.player,
 50                                                            self.blockers,
 51                                                            self.sprites)
 52
 53        self.dialogue_handler = textbox.TextHandler(self)
 54        self.state_dict = self.make_state_dict()
 55        self.portals = self.make_level_portals()
 56        self.menu_screen = player_menu.Player_Menu(game_data, self)
 57
 58    def make_viewport(self, map_image):
 59        """Create the viewport to view the level through"""
 60        map_rect = map_image.get_rect()
 61        return setup.SCREEN.get_rect(bottom=map_rect.bottom)
 62
 63    def make_level_surface(self, map_image):
 64        """Creates the surface all images are blitted to"""
 65        map_rect = map_image.get_rect()
 66        map_width = map_rect.width
 67        if self.name == 'town':
 68            map_height = map_rect.height - 32
 69        else:
 70            map_height = map_rect.height
 71        size = map_width, map_height
 72        return pg.Surface(size).convert()
 73
 74    def make_player(self):
 75        """Makes the player and sets location"""
 76        player = person.Player(self.game_data['last direction'])
 77
 78        for object in self.renderer.tmx_data.getObjects():
 79            properties = object.__dict__
 80            if properties['name'] == 'player start':
 81                posx = properties['x'] * 2
 82                posy = (properties['y'] * 2) - 32
 83                player.rect.x = posx
 84                player.rect.y = posy
 85
 86        return player
 87
 88    def make_blockers(self):
 89        """Make the blockers for the level"""
 90        blockers = []
 91
 92        for object in self.renderer.tmx_data.getObjects():
 93            properties = object.__dict__
 94            if properties['name'] == 'blocker':
 95                left = properties['x'] * 2
 96                top = ((properties['y']) * 2) - 32
 97                blocker = pg.Rect(left, top, 32, 32)
 98                blockers.append(blocker)
 99
100        return blockers
101
102
103    def set_sprite_dialogue(self):
104        """Sets unique dialogue for each sprite"""
105        pass
106
107
108    def make_state_dict(self):
109        """Make a dictionary of states the level can be in"""
110        state_dict = {'normal': self.running_normally,
111                      'dialogue': self.handling_dialogue,
112                      'menu': self.goto_menu}
113
114        return state_dict
115
116    def make_level_portals(self):
117        """Make the portals to switch state"""
118        portal_group = pg.sprite.Group()
119
120        for object in self.renderer.tmx_data.getObjects():
121            properties = object.__dict__
122            if properties['name'] == 'portal':
123                posx = properties['x'] * 2
124                posy = (properties['y'] * 2) - 32
125                new_state = properties['new state']
126                portal_group.add(portal.Portal(posx, posy, new_state))
127
128
129        return portal_group
130
131
132    def running_normally(self, surface, keys, current_time):
133        """Update level normally"""
134        self.check_for_dialogue()
135        self.check_for_portals()
136        self.player.update(keys, current_time)
137        #self.sprites.update(current_time)
138        self.collision_handler.update(keys, current_time)
139        #self.dialogue_handler.update(keys, current_time)
140        self.check_for_menu(keys)
141        self.viewport_update()
142
143        self.draw_level(surface)
144
145
146    def check_for_portals(self):
147        """Check if the player walks into a door, requiring a level change"""
148        portal = pg.sprite.spritecollideany(self.player, self.portals)
149
150        if portal and self.player.state == 'resting':
151            self.player.location = self.player.get_tile_location()
152            self.next = portal.name
153            print self.next
154            self.update_game_data()
155            self.done = True
156
157
158    def check_for_menu(self, keys):
159        """Check if player hits enter to go to menu"""
160        if keys[pg.K_RETURN] and self.allow_input:
161            if self.player.state == 'resting':
162                self.state = 'menu'
163                self.allow_input = False
164
165        if not keys[pg.K_RETURN]:
166            self.allow_input = True
167
168
169    def update_game_data(self):
170        """Update the persistant game data dictionary"""
171        self.game_data['last location'] = self.player.location
172        self.game_data['last direction'] = self.player.direction
173        self.game_data['last state'] = self.name
174
175        self.set_new_start_pos()
176
177
178    def set_new_start_pos(self):
179        """Set new start position based on previous state"""
180        location = copy.deepcopy(self.game_data['last location'])
181        direction = self.game_data['last direction']
182        state = self.game_data['last state']
183
184        if self.next == 'player menu':
185            pass
186        elif direction == 'up':
187            location[1] += 1
188        elif direction == 'down':
189            location[1] -= 1
190        elif direction == 'left':
191            location[0] += 1
192        elif direction == 'right':
193            location[0] -= 1
194
195        self.game_data[state + ' start pos'] = location
196
197
198    def handling_dialogue(self, surface, keys, current_time):
199        """Update only dialogue boxes"""
200        #self.dialogue_handler.update(keys, current_time)
201        self.draw_level(surface)
202
203
204    def goto_menu(self, surface, keys, *args):
205        """Go to menu screen"""
206        self.menu_screen.update(surface, keys)
207        self.menu_screen.draw(surface)
208
209
210    def check_for_dialogue(self):
211        """Check if the level needs to freeze"""
212        #if self.dialogue_handler.textbox:
213        #    self.state = 'dialogue'
214        pass
215
216    def update(self, surface, keys, current_time):
217        """Updates state"""
218        state_function = self.state_dict[self.state]
219        state_function(surface, keys, current_time)
220
221    def viewport_update(self):
222        """Viewport stays centered on character, unless at edge of map"""
223        self.viewport.center = self.player.rect.center
224        self.viewport.clamp_ip(self.level_rect)
225
226    def draw_level(self, surface):
227        """Blits all images to screen"""
228        self.level_surface.blit(self.map_image, self.viewport, self.viewport)
229        self.level_surface.blit(self.player.image, self.player.rect)
230        self.sprites.draw(self.level_surface)
231
232        surface.blit(self.level_surface, (0, 0), self.viewport)
233        self.dialogue_handler.draw(surface)
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249