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