소스 검색

Inventory() added to widgets and generate_thumbnail() added to Character()

Zero! Studio 1 년 전
부모
커밋
96a082ed64
4개의 변경된 파일91개의 추가작업 그리고 7개의 파일을 삭제
  1. 2 1
      jogai/_globals.py
  2. 17 4
      jogai/character.py
  3. 10 2
      jogai/settings.py
  4. 62 0
      jogai/widgets.py

+ 2 - 1
jogai/_globals.py

@@ -20,8 +20,9 @@ marks = None
 mark_font = None
 vg_scene = None
 vg_characters = []
+vg_chronometers = []
 vg_groups = []
 vg_levelbars = []
 vg_scoreboards = []
 vg_texts = []
-vg_chronometers = []
+visible_inventory = None

+ 17 - 4
jogai/character.py

@@ -33,8 +33,8 @@ class Character(pygame.sprite.Sprite):
         _('backward'),
         _('down'),
         _('forward'),
-        _('jump'),
         _('stop'),
+        _('jump'),
         _('up'),
     ]
 
@@ -76,6 +76,8 @@ class Character(pygame.sprite.Sprite):
         self.predefined_keys = {}
         self.image_filename = image_filename
         self.image = None
+        self.thumbnail = None
+        self.thumbnail_rect = None
         self.animation_filenames = {}
         self._original_image = None
         self._original_rect = None
@@ -85,7 +87,7 @@ class Character(pygame.sprite.Sprite):
         self.y = 0
         self.gravitative = False
         self.is_jumping = False
-        self.jump_force = settings.DEFAULT_JUMP_FORCE
+        self.jump_force = settings.CHARACTER_DEFAULT_JUMP_FORCE
         self._jump_counter = self.jump_force
         self.angle = 0
         self.collidable = True
@@ -352,7 +354,7 @@ class Character(pygame.sprite.Sprite):
             >>> protagonist.jump()
         """
         if force is None:
-            force = settings.DEFAULT_JUMP_FORCE
+            force = settings.CHARACTER_DEFAULT_JUMP_FORCE
 
         if isinstance(force, int):
             force = float(force)
@@ -804,6 +806,16 @@ class Character(pygame.sprite.Sprite):
                     return self.STATIC_COLLISION
         return ''
 
+    def generate_thumbnail(
+        self, height: int = settings.CHARACTER_DEFAULT_THUMBNAIL_SIZE
+    ):
+        self.scale_factor = height / self._original_rect.height
+        self.thumbnail = pygame.transform.scale(
+            self._original_image,
+            (int(self._original_rect.width * self.scale_factor), height),
+        )
+        self.thumbnail_rect = self.thumbnail.get_rect()
+
     def load(self, filename: str, preserve_size: bool = False):
         """
         >>> protagonist = Character('protagonist.png')
@@ -815,6 +827,7 @@ class Character(pygame.sprite.Sprite):
         if preserve_size:
             height = self.height
         self.image = self._original_image
+        self.generate_thumbnail()
         self._original_rect = self._original_image.get_rect()
         self.rect = self.image.get_rect()
         self.scale_factor = 1
@@ -850,7 +863,7 @@ class Character(pygame.sprite.Sprite):
                 )
                 self._jump_counter -= 1
             else:
-                self._jump_counter = settings.DEFAULT_JUMP_FORCE
+                self._jump_counter = settings.CHARACTER_DEFAULT_JUMP_FORCE
                 self.is_jumping = False
                 self.load(
                     self.animation_filenames[_('stop')], preserve_size=True

+ 10 - 2
jogai/settings.py

@@ -25,8 +25,10 @@ FONTS_DIR = _('fonts')
 DEFAULT_DATA_FILENAME = 'default_data.yaml'
 DATA_DIR = _('data')
 
-# DEFAULT CHARACTER FEATURES
-DEFAULT_JUMP_FORCE = 10.0
+# CHARACTER FEATURES
+CHARACTER_DEFAULT_JUMP_FORCE = 10.0
+CHARACTER_DEFAULT_THUMBNAIL_SIZE = 40
+
 
 # ------- #
 # WIDGETS #
@@ -51,3 +53,9 @@ LEVELBARS_DEFAULT_THICK = 3
 LEVELBARS_DEFAULT_BORDER_COLOR = (200, 0, 0)
 LEVELBARS_DEFAULT_FILL_COLOR = (241, 74, 6)
 LEVELBARS_DEFAULT_POSITION = (WINDOW_WIDTH - LEVELBARS_DEFAULT_WIDTH - 20, 25)
+
+# INVENTORY
+INVENTORY_DEFAULT_BACKGROUND_COLOR = (0, 0, 0, 180)
+INVENTORY_DEFAULT_TEXT_COLOR = (255, 255, 255)
+INVENTORY_DEFAULT_ITEMS_BY_ROW = 6
+INVENTORY_MARGIN = 50

+ 62 - 0
jogai/widgets.py

@@ -259,6 +259,68 @@ class Chronometer(Text):
         self.render()
 
 
+class Inventory:
+    def __init__(
+        self,
+        background_color: tuple = settings.INVENTORY_DEFAULT_BACKGROUND_COLOR,
+        text_color: tuple = settings.INVENTORY_DEFAULT_TEXT_COLOR,
+        font: str = '',
+        size: int = 30,
+    ):
+        self.background_color = background_color
+        self.text_color = text_color
+        self._items = {}
+        self.rect = pygame.Rect(
+            0, 0, settings.WINDOW_WIDTH, settings.WINDOW_HEIGHT
+        )
+        try:
+            if not font:
+                raise FileNotFoundError
+            self.font = pygame.font.Font(join(settings.FONTS_DIR, font), size)
+        except FileNotFoundError:
+            self.font = pygame.font.Font(None, size)
+
+    def add(self, item):
+        if item in self._items.keys():
+            self._items[item] += 1
+        else:
+            self._items.update({item: 1})
+
+    def show(self, key: str = ''):
+        if not isinstance(key, str):
+            raise TypeError(_('Key pressed must be a string.'))
+        if not key or _get_keys()[utils.eval_key(key)]:
+            _globals.visible_inventory = self
+
+    def hide(self, key: str = ''):
+        if not isinstance(key, str):
+            raise TypeError(_('Key pressed must be a string.'))
+        if not key or _get_keys()[utils.eval_key(key)]:
+            _globals.visible_inventory = None
+
+    def draw(self):
+        shape = pygame.Surface(self.rect.size, pygame.SRCALPHA)
+        pygame.draw.rect(shape, self.background_color, self.rect)
+        _globals._window.blit(shape, self.rect)
+        for pos, item in enumerate(self._items.keys()):
+            width = item.thumbnail.get_width()
+            height = item.thumbnail.get_height()
+            x = (
+                settings.INVENTORY_MARGIN
+                + (pos // settings.INVENTORY_DEFAULT_ITEMS_BY_ROW)
+                * settings.CHARACTER_DEFAULT_THUMBNAIL_SIZE
+                * 4
+            )
+            y = settings.INVENTORY_MARGIN + (pos % 7) * (
+                height + settings.CHARACTER_DEFAULT_THUMBNAIL_SIZE // 2
+            )
+            _globals._window.blit(item.thumbnail, (x, y))
+            _globals._window.blit(
+                self.font.render(f'x{self._items[item]}', 1, self.text_color),
+                (x + width + 10, y + 5),
+            )
+
+
 class LevelBar(pygame.Surface):
     def __init__(
         self,