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