all repos — Legends-RPG @ 9ee373a472b1ac434cf268cdcf3875ada4c57b29

A fantasy mini-RPG built with Python and Pygame.

data/shopgui.py (view raw)

  1"""
  2This class controls the textbox GUI for any shop state.
  3A Gui object is created and updated by the shop state.
  4"""
  5
  6import pygame as pg
  7from . import setup
  8from . components import textbox
  9from . import constants as c
 10
 11
 12class Gui(object):
 13    """Class that controls the GUI of the shop state"""
 14    def __init__(self, level):
 15        self.level = level
 16        self.player_inventory = level.game_data['player inventory']
 17        self.name = level.name
 18        self.state = 'dialogue'
 19        self.font = pg.font.Font(setup.FONTS['Fixedsys500c'], 22)
 20        self.index = 0
 21        self.timer = 0.0
 22        self.item = level.item
 23        self.dialogue = level.dialogue
 24        self.accept_dialogue = level.accept_dialogue
 25        self.arrow = textbox.NextArrow()
 26        self.selection_arrow = textbox.NextArrow()
 27        self.arrow_pos1 = (50, 485)
 28        self.arrow_pos2 = (50, 535)
 29        self.selection_arrow.rect.topleft = self.arrow_pos1
 30        self.dialogue_box = self.make_dialogue_box(self.dialogue, self.index)
 31        self.gold_box = self.make_gold_box()
 32        self.selection_box = self.make_selection_box()
 33        self.state_dict = self.make_state_dict()
 34
 35
 36    def make_dialogue_box(self, dialogue_list, index):
 37        """Make the sprite that controls the dialogue"""
 38        image = setup.GFX['dialoguebox']
 39        rect = image.get_rect()
 40        surface = pg.Surface(rect.size)
 41        surface.set_colorkey(c.BLACK)
 42        surface.blit(image, rect)
 43        dialogue = self.font.render(dialogue_list[index],
 44                                    True,
 45                                    c.NEAR_BLACK)
 46        dialogue_rect = dialogue.get_rect(left=50, top=50)
 47        surface.blit(dialogue, dialogue_rect)
 48        sprite = pg.sprite.Sprite()
 49        sprite.image = surface
 50        sprite.rect = rect
 51        self.check_to_draw_arrow(sprite)
 52
 53        return sprite
 54
 55
 56    def make_selection_box(self):
 57        """Make the box for the player to select options"""
 58        image = setup.GFX['shopbox']
 59        rect = image.get_rect(bottom=608)
 60
 61        surface = pg.Surface(rect.size)
 62        surface.set_colorkey(c.BLACK)
 63        surface.blit(image, (0, 0))
 64
 65        if self.state == 'select':
 66            choices = self.item['dialogue']
 67        elif self.state == 'confirm':
 68            choices = ['Yes',
 69                       'No']
 70        else:
 71            choices = ['Not',
 72                       'assigned']
 73        choice1 = self.font.render(choices[0], True, c.NEAR_BLACK)
 74        choice1_rect = choice1.get_rect(x=200, y=25)
 75        choice2 = self.font.render(choices[1], True, c.NEAR_BLACK)
 76        choice2_rect = choice2.get_rect(x=200, y=75)
 77        surface.blit(choice1, choice1_rect)
 78        surface.blit(choice2, choice2_rect)
 79        sprite = pg.sprite.Sprite()
 80        sprite.image = surface
 81        sprite.rect = rect
 82
 83        return sprite
 84
 85
 86
 87    def check_to_draw_arrow(self, sprite):
 88        """Blink arrow if more text needs to be read"""
 89        if self.index < len(self.dialogue) - 1:
 90            sprite.image.blit(self.arrow.image, self.arrow.rect)
 91
 92
 93    def make_gold_box(self):
 94        """Make the box to display total gold"""
 95        image = setup.GFX['goldbox']
 96        rect = image.get_rect(bottom=608, right=800)
 97
 98        surface = pg.Surface(rect.size)
 99        surface.set_colorkey(c.BLACK)
100        surface.blit(image, (0, 0))
101        gold = self.player_inventory['gold']
102        text = 'Gold: ' + str(gold)
103        text_render = self.font.render(text, True, c.NEAR_BLACK)
104        text_rect = text_render.get_rect(x=80, y=60)
105
106        surface.blit(text_render, text_rect)
107
108        sprite = pg.sprite.Sprite()
109        sprite.image = surface
110        sprite.rect = rect
111
112        return sprite
113
114
115
116    def make_state_dict(self):
117        """Make the state dictionary for the GUI behavior"""
118        state_dict = {'dialogue': self.control_dialogue,
119                      'select': self.make_selection,
120                      'confirm': self.confirm_selection,
121                      'reject': self.reject_insufficient_gold,
122                      'accept': self.accept_purchase,
123                      'hasitem': self.has_item}
124
125        return state_dict
126
127
128    def control_dialogue(self, keys, current_time):
129        """Control the dialogue boxes"""
130        self.dialogue_box = self.make_dialogue_box(self.dialogue, self.index)
131
132        if self.index < (len(self.dialogue) - 1):
133            if keys[pg.K_SPACE]:
134                self.index += 1
135
136        elif self.index == (len(self.dialogue) - 1):
137            self.state = 'select'
138            self.timer = current_time
139
140
141    def make_selection(self, keys, current_time):
142        """Control the selection"""
143        self.dialogue_box = self.make_dialogue_box(self.dialogue, self.index)
144        self.selection_box = self.make_selection_box()
145        self.gold_box = self.make_gold_box()
146
147        if keys[pg.K_DOWN]:
148            self.selection_arrow.rect.topleft = self.arrow_pos2
149        elif keys[pg.K_UP]:
150            self.selection_arrow.rect.topleft = self.arrow_pos1
151        elif keys[pg.K_SPACE] and (current_time - self.timer) > 200:
152            if self.selection_arrow.rect.topleft == self.arrow_pos2:
153                self.level.done = True
154                self.level.game_data['last direction'] = 'down'
155            elif self.selection_arrow.rect.topleft == self.arrow_pos1:
156                self.state = 'confirm'
157                self.timer = current_time
158
159
160
161    def confirm_selection(self, keys, current_time):
162        """Confirm selection state for GUI"""
163        dialogue = ['Are you sure?']
164        self.selection_box = self.make_selection_box()
165        self.gold_box = self.make_gold_box()
166        self.dialogue_box = self.make_dialogue_box(dialogue, 0)
167
168        if keys[pg.K_DOWN]:
169            self.selection_arrow.rect.topleft = self.arrow_pos2
170        elif keys[pg.K_UP]:
171            self.selection_arrow.rect.topleft = self.arrow_pos1
172        elif keys[pg.K_SPACE] and (current_time - self.timer) > 200:
173            if self.selection_arrow.rect.topleft == self.arrow_pos1:
174                self.buy_item()
175            else:
176                self.state = 'select'
177            self.timer = current_time
178            self.selection_arrow.rect.topleft = self.arrow_pos1
179    
180    
181    def buy_item(self):
182        """Attempt to allow player to purchase item"""
183        self.player_inventory['gold'] -= self.item['price']
184        
185        if self.player_inventory['gold'] < 0:
186            self.player_inventory['gold'] += self.item['price']
187            self.state = 'reject'
188        else:
189            if (self.item['type'] == 'Fire Spell' and
190                        'Fire Spell' in self.player_inventory):
191                    self.state = 'hasitem'
192                    self.player_inventory['gold'] += self.item['price']
193            else:
194                self.state = 'accept'
195                self.add_player_item(self.item)
196
197
198    def reject_insufficient_gold(self, keys, current_time):
199        """Reject player selection if they do not have enough gold"""
200        dialogue = ["You don't have enough gold!"]
201        self.dialogue_box = self.make_dialogue_box(dialogue, 0)
202
203        if keys[pg.K_SPACE] and (current_time - self.timer) > 200:
204            self.state = 'select'
205            self.timer = current_time
206            self.selection_arrow.rect.topleft = self.arrow_pos1
207
208
209    def accept_purchase(self, keys, current_time):
210        """Accept purchase and confirm with message"""
211        self.dialogue_box = self.make_dialogue_box(self.accept_dialogue, 0)
212        self.gold_box = self.make_gold_box()
213
214        if keys[pg.K_SPACE] and (current_time - self.timer) > 200:
215            self.state = 'select'
216            self.timer = current_time
217            self.selection_arrow.rect.topleft = self.arrow_pos1
218
219
220    def has_item(self, keys, current_time):
221        """Tell player he has item already"""
222        dialogue = ["You have that item already."]
223        self.dialogue_box = self.make_dialogue_box(dialogue, 0)
224
225        if keys[pg.K_SPACE] and (current_time - self.timer) > 200:
226            self.state = 'select'
227            self.timer = current_time
228            self.selection_arrow.rect.topleft = self.arrow_pos1
229
230
231    def add_player_item(self, item):
232        """Add item to player's inventory"""
233        item_type = item['type']
234        quantity = item['quantity']
235        player_item = self.level.game_data['player inventory']
236
237        if item_type in player_item:
238            player_item[item_type] += quantity
239        elif quantity > 0:
240            player_item[item_type] = quantity
241
242
243
244    def update(self, keys, current_time):
245        """Updates the shop GUI"""
246        state_function = self.state_dict[self.state]
247        state_function(keys, current_time)
248
249
250    def draw(self, surface):
251        """Draw GUI to level surface"""
252        state_list1 = ['dialogue', 'reject', 'accept', 'hasitem']
253        state_list2 = ['select', 'confirm']
254
255        if self.state in state_list1:
256            surface.blit(self.dialogue_box.image, self.dialogue_box.rect)
257            surface.blit(self.gold_box.image, self.gold_box.rect)
258        elif self.state in state_list2:
259            surface.blit(self.dialogue_box.image, self.dialogue_box.rect)
260            surface.blit(self.selection_box.image, self.selection_box.rect)
261            surface.blit(self.selection_arrow.image, self.selection_arrow.rect)
262            surface.blit(self.gold_box.image, self.gold_box.rect)