Переглянути джерело

default system Font defined when no font is provided and _check_for_character_animation_files added to videogame.

Zero! Studio 1 рік тому
батько
коміт
22413c82b4
4 змінених файлів з 69 додано та 8 видалено
  1. 1 1
      data/02.yaml
  2. 39 4
      jogai/character.py
  3. 9 0
      jogai/videogame.py
  4. 20 3
      jogai/widgets.py

+ 1 - 1
data/02.yaml

@@ -3,7 +3,7 @@ gravity: 5
 scene: test_large.png
 characters:
   protagonist:
-    gravitative: False
+    gravitative: True
     chronometer: 30
     score: 10
     lives: 5

+ 39 - 4
jogai/character.py

@@ -28,12 +28,10 @@ class Character(pygame.sprite.Sprite):
     RIGHT_COLLISION = _('right')
     STATIC_COLLISION = _('static')
 
-    _predefined_key_actions_allowed = [
+    _predefined_animations_allowed = [
         _('backward'),
-        _('decrease'),
         _('down'),
         _('forward'),
-        _('increase'),
         _('jump'),
         _('up'),
     ]
@@ -51,10 +49,21 @@ class Character(pygame.sprite.Sprite):
         _('width'),
     ]
 
+    _predefined_key_actions_allowed = [
+        _('backward'),
+        _('decrease'),
+        _('down'),
+        _('forward'),
+        _('increase'),
+        _('jump'),
+        _('up'),
+    ]
+
     def __init__(
         self,
         image_filename: str,
         name: str = '',
+        animation_filenames: dict = {},
     ):
         if not isinstance(name, str):
             raise TypeError(_('The character name must be a string.'))
@@ -65,6 +74,7 @@ class Character(pygame.sprite.Sprite):
         self.predefined_keys = {}
         self.image_filename = image_filename
         self.image = None
+        self.animation_filenames = {}
         self._original_image = None
         self._original_rect = None
         self.rect = None
@@ -84,6 +94,7 @@ class Character(pygame.sprite.Sprite):
 
         super().__init__()
         self.load(image_filename)
+        self.set_animations(animation_filenames)
 
     def __repr__(self):
         return f'{_("Character")}: {self.name}'
@@ -497,6 +508,27 @@ class Character(pygame.sprite.Sprite):
             self._original_image, self.angle, self.scale_factor
         )
 
+    def set_animations(self, animations: dict):
+        """
+        Set the image animation filenames for this character.
+
+        Parameters:
+            animations: A dict with pairs {action: filename}
+
+        Examples:
+            >>> protagonist = Character('protagonist.png')
+            >>> protagonist.set_animations({'jump': 'protagonist_jump.png'})
+        """
+        if not isinstance(animations, dict):
+            raise TypeError(_('The animations must be a dict.'))
+
+        self.animation_filenames = dict(
+            filter(
+                lambda pair: pair[0] in self._predefined_animations_allowed,
+                animations.items(),
+            )
+        )
+
     def set_chronometer(self, time: int):
         """
         Set a chronometer for this character.
@@ -508,6 +540,9 @@ class Character(pygame.sprite.Sprite):
             >>> protagonist = Character('protagonist.png')
             >>> protagonist.set_chronometer(30)
         """
+        if not isinstance(time, int):
+            raise TypeError(_('Time must be a integer.'))
+
         chronometer_pos = len(_globals.vg_chronometers)
         self.chronometer = widgets.Chronometer(
             time,
@@ -831,7 +866,7 @@ class Character(pygame.sprite.Sprite):
             ):
                 offset_rect.x = settings.WINDOW_WIDTH // 2
             elif x >= _globals.vg_scene.width - settings.WINDOW_WIDTH:
-                offset_rect.x = settings.WINDOW_WIDTH*3 // 2 - (
+                offset_rect.x = settings.WINDOW_WIDTH * 3 // 2 - (
                     -x % _globals.vg_scene.width
                 )
         else:

+ 9 - 0
jogai/videogame.py

@@ -27,6 +27,15 @@ _predefined_attributes_allowed = [
 # ------------------ #
 
 
+def _check_for_character_animation_files(path: str, filenames: dict):
+    return dict(
+        filter(
+            lambda filename: os.path.isfile(os.path.join(path, filename[1])),
+            filenames,
+        )
+    )
+
+
 def _load_scene(data: dict) -> 'scene.Scene':
     """
     Load scene from data schema.

+ 20 - 3
jogai/widgets.py

@@ -13,18 +13,35 @@ class Text:
         size: int = 20,
         color: tuple = (0, 0, 0),
         position: tuple = (0, 0),
-        font: str = 'digital.ttf',
+        font: str = '',
         bold: bool = False,
         italic: bool = False,
         shadow: tuple = (),
     ):
+        # TODO: Implement shadow
+        if not isinstance(size, int):
+            raise TypeError(_('The font size must be an integer'))
+        if size < 1:
+            raise ValueError(_('The font size must be a positive integer'))
+        if not isinstance(font, str):
+            raise TypeError(_('The font must be a string'))
+        if not isinstance(bold, bool):
+            raise TypeError(_('The bold argument must be a boolean'))
+        if not isinstance(italic, bool):
+            raise TypeError(_('The italic argument must be a boolean'))
+
         if not pygame.font.get_init():
             pygame.font.init()
+        self._message = message
         self.color = color
-        self.font = pygame.font.Font(join(settings.FONTS_DIR, font), size)
+        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)
         self.font.set_bold(bold)
         self.font.set_italic(italic)
-        self._message = message
         self.render(position, message)
 
     @property