all repos — Legends-RPG @ fcdceff478229e97c1fc26895eeadabefefb02c5

A fantasy mini-RPG built with Python and Pygame.

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                                          True,
 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