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 .. import tilemap as tm
13from .. components import person, textbox
14
15
16class LevelState(tools._State):
17 def __init__(self, name, width, height):
18 super(LevelState, self).__init__(name)
19 self.map_width = width
20 self.map_height = height
21
22
23 def startup(self, current_time, persist):
24 """Called when the State object is created"""
25 self.persist = persist
26 self.current_time = current_time
27 self.state = 'normal'
28 self.town_map = tm.make_level_map(self.name,
29 self.map_width,
30 self.map_height)
31 self.viewport = tm.create_viewport(self.town_map)
32 self.blockers = tm.create_blockers(self.name)
33 self.level_surface = tm.make_level_surface(self.town_map)
34 self.level_rect = self.level_surface.get_rect()
35 self.player = person.Player(persist['last direction'])
36 self.level_sprites = pg.sprite.Group()
37 self.start_positions = tm.set_sprite_positions(self.player,
38 self.level_sprites,
39 self.name,
40 self.persist)
41 self.set_sprite_dialogue()
42 self.collision_handler = collision.CollisionHandler(self.player,
43 self.blockers,
44 self.level_sprites)
45 self.dialogue_handler = textbox.DialogueHandler(self.player,
46 self.level_sprites,
47 self)
48 self.state_dict = self.make_state_dict()
49 self.portals = tm.make_level_portals(self.name)
50 self.parent_level = None
51
52
53 def set_sprite_dialogue(self):
54 """Sets unique dialogue for each sprite"""
55 raise NotImplementedError
56
57
58 def make_state_dict(self):
59 """Make a dictionary of states the level can be in"""
60 state_dict = {'normal': self.running_normally,
61 'dialogue': self.handling_dialogue}
62
63 return state_dict
64
65
66 def running_normally(self, surface, keys, current_time):
67 """Update level normally"""
68 self.check_for_dialogue()
69 self.check_for_portals()
70 self.player.update(keys, current_time)
71 self.level_sprites.update(current_time)
72 self.collision_handler.update(keys, current_time)
73 self.dialogue_handler.update(keys, current_time)
74 self.viewport_update()
75
76 self.draw_level(surface)
77
78
79 def check_for_portals(self):
80 """Check if the player walks into a door, requiring a level change"""
81 portal = pg.sprite.spritecollideany(self.player, self.portals)
82
83 if portal and self.player.state == 'resting':
84 self.player.location = self.player.get_tile_location()
85 self.next = portal.name
86 self.update_game_data()
87 self.done = True
88
89
90 def update_game_data(self):
91 """Update the persistant game data dictionary"""
92 self.persist['last location'] = self.player.location
93 self.persist['last direction'] = self.player.direction
94 self.persist['last state'] = self.name
95
96 self.set_new_start_pos()
97
98
99 def set_new_start_pos(self):
100 """Set new start position based on previous state"""
101 location = copy.deepcopy(self.persist['last location'])
102 direction = self.persist['last direction']
103 state = self.persist['last state']
104
105 if direction == 'up':
106 location[1] += 1
107 elif direction == 'down':
108 location[1] -= 1
109 elif direction == 'left':
110 location[0] += 1
111 elif direction == 'right':
112 location[0] -= 1
113
114 self.persist[state + ' start pos'] = location
115
116
117 def handling_dialogue(self, surface, keys, current_time):
118 """Update only dialogue boxes"""
119 self.dialogue_handler.update(keys, current_time)
120 self.draw_level(surface)
121
122
123 def check_for_dialogue(self):
124 """Check if the level needs to freeze"""
125 if self.dialogue_handler.textbox:
126 self.state = 'dialogue'
127
128
129 def update(self, surface, keys, current_time):
130 """Updates state"""
131 state_function = self.state_dict[self.state]
132 state_function(surface, keys, current_time)
133
134
135 def viewport_update(self):
136 """Viewport stays centered on character, unless at edge of map"""
137 self.viewport.center = self.player.rect.center
138 self.viewport.clamp_ip(self.level_rect)
139
140
141 def draw_level(self, surface):
142 """Blits all images to screen"""
143 self.level_surface.blit(self.town_map['surface'], self.viewport, self.viewport)
144 self.level_surface.blit(self.player.image, self.player.rect)
145 self.level_sprites.draw(self.level_surface)
146
147 surface.blit(self.level_surface, (0, 0), self.viewport)
148 self.dialogue_handler.draw(surface)
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163