data/components/textbox.py (view raw)
1__author__ = 'justinarmstrong'
2import copy
3import pygame as pg
4from .. import setup
5from .. import constants as c
6
7
8
9class NextArrow(pg.sprite.Sprite):
10 """Flashing arrow indicating more dialogue"""
11 def __init__(self):
12 super(NextArrow, self).__init__()
13 self.image = setup.GFX['fancyarrow']
14 self.rect = self.image.get_rect(right=780,
15 bottom=135)
16
17
18class DialogueBox(object):
19 """Text box used for dialogue"""
20 def __init__(self, dialogue, index=0, image_key='dialoguebox', item=None):
21 self.item = item
22 self.bground = setup.GFX[image_key]
23 self.rect = self.bground.get_rect(centerx=400)
24 self.timer = 0.0
25 self.arrow_timer = 0.0
26 self.font = pg.font.Font(setup.FONTS['Fixedsys500c'], 22)
27 self.dialogue_list = dialogue
28 self.index = index
29 self.image = self.make_dialogue_box_image()
30 self.arrow = NextArrow()
31 self.check_to_draw_arrow()
32 self.done = False
33 self.name = image_key
34
35
36 def make_dialogue_box_image(self):
37 """Make the image of the dialogue box"""
38 image = pg.Surface(self.rect.size)
39 image.set_colorkey(c.BLACK)
40 image.blit(self.bground, (0, 0))
41
42 dialogue_image = self.font.render(self.dialogue_list[self.index],
43 False,
44 c.NEAR_BLACK)
45 dialogue_rect = dialogue_image.get_rect(left=50, top=50)
46 image.blit(dialogue_image, dialogue_rect)
47
48 return image
49
50
51
52 def update(self, keys, current_time):
53 """Updates scrolling text"""
54 self.current_time = current_time
55 self.draw_box(current_time)
56 self.terminate_check(keys)
57
58
59 def draw_box(self, current_time, x=400):
60 """Reveal dialogue on textbox"""
61 self.image = self.make_dialogue_box_image()
62 self.check_to_draw_arrow()
63
64
65 def terminate_check(self, keys):
66 """Remove textbox from sprite group after 2 seconds"""
67
68 if self.timer == 0.0:
69 self.timer = self.current_time
70 elif (self.current_time - self.timer) > 300:
71 if keys[pg.K_SPACE]:
72 self.done = True
73
74
75 def check_to_draw_arrow(self):
76 """Blink arrow if more text needs to be read"""
77 if self.index < len(self.dialogue_list) - 1:
78 self.image.blit(self.arrow.image, self.arrow.rect)
79 else:
80 pass
81
82
83class ItemBox(DialogueBox):
84 """Text box for information like obtaining new items"""
85 def __init__(self, dialogue, item=None):
86 super(ItemBox, self).__init__(None, 0, 'infobox', item)
87
88
89 def make_dialogue_box_image(self):
90 """Make the image of the dialogue box"""
91 image = pg.Surface(self.rect.size)
92 image.set_colorkey(c.BLACK)
93 image.blit(self.bground, (0, 0))
94
95 if self.item:
96 total = str(self.item['total'])
97 type = self.item['type']
98 dialogue = 'You received ' + total + ' ' + type + '.'
99 self.dialogue_list = [dialogue]
100 self.item = None
101
102 dialogue_image = self.font.render(self.dialogue_list[self.index],
103 False,
104 c.NEAR_BLACK)
105 dialogue_rect = dialogue_image.get_rect(left=50, top=50)
106 image.blit(dialogue_image, dialogue_rect)
107
108 return image
109
110
111
112class TextHandler(object):
113 """Handles interaction between sprites to create dialogue boxes"""
114
115 def __init__(self, level):
116 self.player = level.player
117 self.sprites = level.sprites
118 self.talking_sprite = None
119 self.textbox = None
120 self.level = level
121 self.last_textbox_timer = 0.0
122 self.game_data = level.persist
123
124
125 def update(self, keys, current_time):
126 """Checks for the creation of Dialogue boxes"""
127 if keys[pg.K_SPACE] and not self.textbox:
128 for sprite in self.sprites:
129 if (current_time - self.last_textbox_timer) > 300:
130 self.check_for_dialogue(sprite)
131
132 if self.textbox:
133 self.textbox.update(keys, current_time)
134
135 if self.textbox.done:
136
137 if self.textbox.index < (len(self.textbox.dialogue_list) - 1):
138 index = self.textbox.index + 1
139 dialogue = self.textbox.dialogue_list
140 if self.textbox.name == 'dialoguebox':
141 self.textbox = DialogueBox(dialogue, index)
142 elif self.textbox.name == 'infobox':
143 self.textbox = ItemBox(dialogue, index)
144 elif self.talking_sprite.item:
145 item = self.check_for_item()
146 self.textbox = ItemBox(None, item)
147 else:
148 self.level.state = 'normal'
149 self.textbox = None
150 self.last_textbox_timer = current_time
151 self.reset_sprite_direction()
152
153
154 def check_for_dialogue(self, sprite):
155 """Checks if a sprite is in the correct location to give dialogue"""
156 player = self.player
157 tile_x, tile_y = player.location
158
159 if player.direction == 'up':
160 if sprite.location == [tile_x, tile_y - 1]:
161 self.textbox = DialogueBox(sprite.dialogue)
162 sprite.direction = 'down'
163 self.talking_sprite = sprite
164 elif player.direction == 'down':
165 if sprite.location == [tile_x, tile_y + 1]:
166 self.textbox = DialogueBox(sprite.dialogue)
167 sprite.direction = 'up'
168 self.talking_sprite = sprite
169 elif player.direction == 'left':
170 if sprite.location == [tile_x - 1, tile_y]:
171 self.textbox = DialogueBox(sprite.dialogue)
172 sprite.direction = 'right'
173 self.talking_sprite = sprite
174 elif player.direction == 'right':
175 if sprite.location == [tile_x + 1, tile_y]:
176 self.textbox = DialogueBox(sprite.dialogue)
177 sprite.direction = 'left'
178 self.talking_sprite = sprite
179
180
181 def check_for_item(self):
182 """Checks if sprite has an item to give to the player"""
183 item = self.talking_sprite.item
184 if item:
185 self.player.item_list.append(item)
186 self.talking_sprite.item = None
187 if self.talking_sprite.name == 'king':
188 self.game_data['king item'] = None
189
190 return item
191
192
193
194 def reset_sprite_direction(self):
195 """Reset sprite to default direction"""
196 for sprite in self.sprites:
197 if sprite.state == 'resting':
198 sprite.direction = sprite.default_direction
199
200
201 def draw(self, surface):
202 """Draws textbox to surface"""
203 if self.textbox:
204 surface.blit(self.textbox.image, self.textbox.rect)
205
206
207 def make_textbox(self, name, dialogue, item=None):
208 """Make textbox on demand"""
209 if name == 'itembox':
210 textbox = ItemBox(dialogue, item)
211 elif name == 'dialoguebox':
212 textbox = DialogueBox(dialogue)
213 else:
214 textbox = None
215
216 return textbox
217
218
219 def update_for_shops(self, keys, current_time):
220 """Update text handler when player is in a shop"""
221 self.textbox.update(keys, current_time)
222 last_index = len(self.textbox.dialogue_list) - 1
223
224 if self.textbox.done and (self.textbox.index < last_index):
225 index = self.textbox.index + 1
226 dialogue = self.textbox.dialogue_list
227 self.textbox = DialogueBox(dialogue, index)
228
229
230
231
232
233
234
235