all repos — Legends-RPG @ 00a3f968654ae3c3bde4de50fa7c18bbe4190801

A fantasy mini-RPG built with Python and Pygame.

data/menugui.py (view raw)

  1# -*- coding: utf-8 -*-
  2"""
  3This class controls all the GUI for the player
  4menu screen.
  5"""
  6import pygame as pg
  7from . import setup
  8from . import constants as c
  9from . import tilemap
 10
 11
 12class SmallArrow(pg.sprite.Sprite):
 13    """Small arrow for menu"""
 14    def __init__(self):
 15        super(SmallArrow, self).__init__()
 16        self.image = setup.GFX['smallarrow']
 17        self.rect = self.image.get_rect()
 18        self.pos_list = self.make_pos_list()
 19
 20
 21    def make_pos_list(self):
 22        """Make the list of possible arrow positions"""
 23        pos_list = []
 24
 25        for i in range(4):
 26            pos = (35, 356 + (i * 50))
 27            pos_list.append(pos)
 28
 29        return pos_list
 30
 31
 32    def update(self, pos_index):
 33        """Update arrow position"""
 34        self.rect.topleft = self.pos_list[pos_index]
 35
 36
 37    def draw(self, surface):
 38        """Draw to surface"""
 39        surface.blit(self.image, self.rect)
 40
 41
 42
 43class GoldBox(pg.sprite.Sprite):
 44    def __init__(self, inventory):
 45        self.inventory = inventory
 46        self.font = pg.font.Font(setup.FONTS[c.MAIN_FONT], 22)
 47        self.image, self.rect = self.make_image()
 48
 49    def make_image(self):
 50        """Make the surface for the gold box"""
 51        image = setup.GFX['goldbox2']
 52        rect = image.get_rect(left=10, top=234)
 53
 54        surface = pg.Surface(rect.size)
 55        surface.set_colorkey(c.BLACK)
 56        surface.blit(image, (0, 0))
 57
 58        text = "Gold: " + str(self.inventory['gold'])
 59        text_render = self.font.render(text, True, c.NEAR_BLACK)
 60        text_rect = text_render.get_rect(centerx=130,
 61                                         centery=35)
 62        surface.blit(text_render, text_rect)
 63
 64        return surface, rect
 65
 66
 67    def draw(self, surface):
 68        """Draw to surface"""
 69        surface.blit(self.image, self.rect)
 70
 71
 72
 73class InfoBox(pg.sprite.Sprite):
 74    def __init__(self, inventory, player_stats):
 75        super(InfoBox, self).__init__()
 76        self.inventory = inventory
 77        self.player_stats = player_stats
 78        self.font = pg.font.Font(setup.FONTS[c.MAIN_FONT], 22)
 79        self.big_font = pg.font.Font(setup.FONTS[c.MAIN_FONT], 24)
 80        self.title_font = pg.font.Font(setup.FONTS[c.MAIN_FONT], 28)
 81        self.title_font.set_underline(True)
 82        self.get_tile = tilemap.get_tile
 83        self.sword = self.get_tile(96, 0, setup.GFX['shopsigns'], 32, 32)
 84        self.shield = self.get_tile(64, 0, setup.GFX['shopsigns'], 32, 32)
 85        self.potion = self.get_tile(32, 0, setup.GFX['shopsigns'], 32, 32)
 86        self.possible_potions = ['Healing Potion']
 87        self.possible_armor = ['Wooden Shield', 'Chain Mail']
 88        self.possible_weapons = ['Long Sword', 'Rapier']
 89        self.possible_magic = ['Fire Blast', 'Cure']
 90        self.quantity_items = ['Healing Potion']
 91        self.state_dict = self.make_state_dict()
 92
 93
 94    def make_state_dict(self):
 95        """Make the dictionary of state methods"""
 96        state_dict = {'stats': self.show_player_stats,
 97                      'items': self.show_items,
 98                      'magic': self.show_magic}
 99
100        return state_dict
101
102
103    def show_player_stats(self):
104        """Show the player's main stats"""
105        title = 'STATS'
106        stat_list = ['Level', 'Health',
107                     'Magic Points', 'Experience to next level']
108        surface, rect = self.make_blank_info_box(title)
109
110        for i, stat in enumerate(stat_list):
111            if stat == 'Health' or stat == 'Magic Points':
112                text = (stat + ": " + str(self.player_stats[stat]['current']) +
113                        " / " + str(self.player_stats[stat]['maximum']))
114            else:
115                text = stat + ": " + str(self.player_stats[stat])
116            text_image = self.font.render(text, True, c.NEAR_BLACK)
117            text_rect = text_image.get_rect(x=50, y=80+(i*50))
118            surface.blit(text_image, text_rect)
119
120        self.image = surface
121        self.rect = rect
122
123
124    def show_items(self):
125        """Show list of items the player has"""
126        title = 'ITEMS'
127        potions = ['POTIONS']
128        weapons = ['WEAPONS']
129        armor = ['ARMOR']
130        for item in self.inventory:
131            if item in self.possible_potions:
132                potions.append(item)
133            elif item in self.possible_weapons:
134                weapons.append(item)
135            elif item in self.possible_armor:
136                armor.append(item)
137
138        surface, rect = self.make_blank_info_box(title)
139
140        surface = self.blit_item_list(surface, weapons, 85)
141        surface = self.blit_item_list(surface, armor, 235)
142        surface = self.blit_item_list(surface, potions, 390)
143
144        self.sword['rect'].topleft = 50, 80
145        self.shield['rect'].topleft = 50, 230
146        self.potion['rect'].topleft = 50, 385
147        surface.blit(self.sword['surface'], self.sword['rect'])
148        surface.blit(self.shield['surface'], self.shield['rect'])
149        surface.blit(self.potion['surface'], self.potion['rect'])
150
151
152        self.image = surface
153        self.rect = rect
154
155
156    def blit_item_list(self, surface, item_list, starty):
157        """Blit item list to info box surface"""
158        for i, item in enumerate(item_list):
159            if item in self.quantity_items:
160                text = item + ": " + str(self.inventory[item]['quantity'])
161                text_image = self.font.render(text, True, c.NEAR_BLACK)
162                text_rect = text_image.get_rect(x=90, y=starty+(i*50))
163                surface.blit(text_image, text_rect)
164            elif i == 0:
165                text = item
166                text_image = self.big_font.render(text, True, c.NEAR_BLACK)
167                text_rect = text_image.get_rect(x=90, y=starty)
168                surface.blit(text_image, text_rect)
169            else:
170                text = item
171                text_image = self.font.render(text, True, c.NEAR_BLACK)
172                text_rect = text_image.get_rect(x=90, y=starty+(i*50))
173                surface.blit(text_image, text_rect)
174
175        return surface
176
177
178    def show_magic(self):
179        """Show list of magic spells the player knows"""
180        title = 'MAGIC'
181        item_list = []
182        for item in self.inventory:
183            if item in self.possible_magic:
184                item_list.append(item)
185                item_list = sorted(item_list)
186
187        surface, rect = self.make_blank_info_box(title)
188
189        for i, item in enumerate(item_list):
190            text_image = self.font.render(item, True, c.NEAR_BLACK)
191            text_rect = text_image.get_rect(x=50, y=80+(i*50))
192            surface.blit(text_image, text_rect)
193
194        self.image = surface
195        self.rect = rect
196
197
198    def make_blank_info_box(self, title):
199        """Make an info box with title, otherwise blank"""
200        image = setup.GFX['playerstatsbox']
201        rect = image.get_rect(left=285, top=35)
202        centerx = rect.width / 2
203
204        surface = pg.Surface(rect.size)
205        surface.set_colorkey(c.BLACK)
206        surface.blit(image, (0,0))
207
208        title_image = self.title_font.render(title, True, c.NEAR_BLACK)
209        title_rect = title_image.get_rect(centerx=centerx, y=30)
210        surface.blit(title_image, title_rect)
211
212        return surface, rect
213
214
215    def update(self, state):
216        state_function = self.state_dict[state]
217        state_function()
218
219
220    def draw(self, surface):
221        """Draw to surface"""
222        surface.blit(self.image, self.rect)
223
224
225
226
227class SelectionBox(pg.sprite.Sprite):
228    def __init__(self):
229        self.font = pg.font.Font(setup.FONTS[c.MAIN_FONT], 22)
230        self.image, self.rect = self.make_image()
231
232
233    def make_image(self):
234        choices = ['Stats', 'Items', 'Magic', 'Exit']
235        image = setup.GFX['selectionbox']
236        rect = image.get_rect(left=10, top=330)
237
238        surface = pg.Surface(rect.size)
239        surface.set_colorkey(c.BLACK)
240        surface.blit(image, (0, 0))
241
242        for i, choice in enumerate(choices):
243            choice_image = self.font.render(choice, True, c.NEAR_BLACK)
244            choice_rect = choice_image.get_rect(x=100, y=(25 + (i * 50)))
245            surface.blit(choice_image, choice_rect)
246
247        return surface, rect
248
249
250    def draw(self, surface):
251        """Draw to surface"""
252        surface.blit(self.image, self.rect)
253
254
255
256
257class MenuGui(object):
258    def __init__(self, level, inventory, stats):
259        self.level = level
260        self.inventory = inventory
261        self.stats = stats
262        self.info_box = InfoBox(inventory, stats)
263        self.gold_box = GoldBox(inventory)
264        self.selection_box = SelectionBox()
265        self.arrow = SmallArrow()
266        self.state_dict = self.make_state_dict()
267        self.arrow_index = 0
268        self.allow_input = False
269        self.state = 'stats'
270
271
272    def make_arrow_pos_list(self):
273        """Make the list of possible arrow positions"""
274        pos_list = []
275
276        for i in range(4):
277            pos = (35, 356 + (i * 50))
278            pos_list.append(pos)
279
280        return pos_list
281
282
283
284    def make_state_dict(self):
285        """Make the dictionary of all menu states"""
286        state_dict = {'stats': self.select_main_options,
287                      'items': self.select_item,
288                      'magic': self.select_item}
289
290        return state_dict
291
292
293    def select_main_options(self, keys):
294        """Allow player to select items, magic, weapons and armor"""
295        self.info_box.update(self.state)
296        self.arrow.update(self.arrow_index)
297        self.check_for_input(keys)
298
299
300    def check_for_input(self, keys):
301        """Check for input"""
302        if self.allow_input:
303            if keys[pg.K_DOWN]:
304                if self.arrow_index < 3:
305                    self.arrow_index += 1
306                    self.allow_input = False
307            elif keys[pg.K_UP]:
308                if self.arrow_index > 0:
309                    self.arrow_index -= 1
310                    self.allow_input = False
311            elif keys[pg.K_SPACE]:
312                if self.arrow_index == 0:
313                    self.state = 'stats'
314
315                elif self.arrow_index == 1:
316                    self.state = 'items'
317
318                elif self.arrow_index == 2:
319                    self.state = 'magic'
320
321                elif self.arrow_index == 3:
322                    self.level.state = 'normal'
323                    self.arrow_index = 0
324                    self.state = 'stats'
325
326
327                self.allow_input = False
328            elif keys[pg.K_RETURN]:
329                self.level.state = 'normal'
330                self.state = 'stats'
331                self.allow_input = False
332                self.arrow_index = 0
333
334        if (not keys[pg.K_DOWN]
335                and not keys[pg.K_UP]
336                and not keys[pg.K_RETURN]
337                and not keys[pg.K_SPACE]):
338            self.allow_input = True
339
340
341    def select_item(self, keys):
342        """Select item from list"""
343        self.info_box.update(self.state)
344        self.arrow.update(self.arrow_index)
345        self.check_for_input(keys)
346
347
348    def update(self, keys):
349        state_function = self.state_dict[self.state]
350        state_function(keys)
351
352
353    def draw(self, surface):
354        self.gold_box.draw(surface)
355        self.info_box.draw(surface)
356        self.selection_box.draw(surface)
357        self.arrow.draw(surface)