|
@@ -20,6 +20,7 @@ class Character(pygame.sprite.Sprite):
|
|
|
_('down'),
|
|
_('down'),
|
|
|
_('forward'),
|
|
_('forward'),
|
|
|
_('increase'),
|
|
_('increase'),
|
|
|
|
|
+ _('jump'),
|
|
|
_('up'),
|
|
_('up'),
|
|
|
]
|
|
]
|
|
|
|
|
|
|
@@ -49,6 +50,9 @@ class Character(pygame.sprite.Sprite):
|
|
|
self.name = name
|
|
self.name = name
|
|
|
self.x = 0
|
|
self.x = 0
|
|
|
self.y = 0
|
|
self.y = 0
|
|
|
|
|
+ self.is_jumping = False
|
|
|
|
|
+ self.jump_force = settings.DEFAULT_JUMP_FORCE
|
|
|
|
|
+ self._jump_counter = self.jump_force
|
|
|
|
|
|
|
|
super().__init__()
|
|
super().__init__()
|
|
|
self.load(image_filename)
|
|
self.load(image_filename)
|
|
@@ -90,39 +94,6 @@ class Character(pygame.sprite.Sprite):
|
|
|
|
|
|
|
|
eval(f'self.{function}({processed_arguments})')
|
|
eval(f'self.{function}({processed_arguments})')
|
|
|
|
|
|
|
|
- def _update_rect_position(
|
|
|
|
|
- self, vg_scene: Type['scene.Scene'], tracking: bool = False
|
|
|
|
|
- ) -> int:
|
|
|
|
|
- """
|
|
|
|
|
- Calculate and update the position where the character must be painted.
|
|
|
|
|
- Only one character can be tracked.
|
|
|
|
|
-
|
|
|
|
|
- Parameters:
|
|
|
|
|
- vg_scene: The scene information.
|
|
|
|
|
- tracking: True if the character must be followed, False otherwise.
|
|
|
|
|
- """
|
|
|
|
|
- # TODO: check vg_scene type
|
|
|
|
|
- if not isinstance(tracking, bool):
|
|
|
|
|
- raise TypeError(_('The tracking parameter must be a boolean.'))
|
|
|
|
|
-
|
|
|
|
|
- if tracking:
|
|
|
|
|
- if self.x < settings.WINDOW_WIDTH // 2:
|
|
|
|
|
- self._rect.x = self.x
|
|
|
|
|
- elif (
|
|
|
|
|
- settings.WINDOW_WIDTH // 2
|
|
|
|
|
- < self.x
|
|
|
|
|
- < vg_scene.width - settings.WINDOW_WIDTH
|
|
|
|
|
- ):
|
|
|
|
|
- self._rect.x = settings.WINDOW_WIDTH // 2
|
|
|
|
|
- elif self.x > vg_scene.width - settings.WINDOW_WIDTH:
|
|
|
|
|
- self._rect.x = settings.WINDOW_WIDTH * 3 / 2 - (
|
|
|
|
|
- -self.x % vg_scene.width
|
|
|
|
|
- )
|
|
|
|
|
- self._rect.y = self.y
|
|
|
|
|
- else:
|
|
|
|
|
- self._rect.x = self.x + vg_scene.x
|
|
|
|
|
- self._rect.y = self.y
|
|
|
|
|
-
|
|
|
|
|
def move(
|
|
def move(
|
|
|
self,
|
|
self,
|
|
|
x: int | None = None,
|
|
x: int | None = None,
|
|
@@ -210,7 +181,9 @@ class Character(pygame.sprite.Sprite):
|
|
|
"""
|
|
"""
|
|
|
if amount is None:
|
|
if amount is None:
|
|
|
amount = self.speed
|
|
amount = self.speed
|
|
|
- self.move(0, amount, key)
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if not self.is_jumping:
|
|
|
|
|
+ self.move(0, amount, key)
|
|
|
|
|
|
|
|
def forward(self, amount: int | None = None, key: str = ''):
|
|
def forward(self, amount: int | None = None, key: str = ''):
|
|
|
"""
|
|
"""
|
|
@@ -244,7 +217,30 @@ class Character(pygame.sprite.Sprite):
|
|
|
"""
|
|
"""
|
|
|
if amount is None:
|
|
if amount is None:
|
|
|
amount = self.speed
|
|
amount = self.speed
|
|
|
- self.move(0, -amount, key)
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if not self.is_jumping:
|
|
|
|
|
+ self.move(0, -amount, key)
|
|
|
|
|
+
|
|
|
|
|
+ def jump(self, force: float | None = None, key: str = ''):
|
|
|
|
|
+ if force is None:
|
|
|
|
|
+ force = settings.DEFAULT_JUMP_FORCE
|
|
|
|
|
+
|
|
|
|
|
+ if isinstance(force, int):
|
|
|
|
|
+ force = float(force)
|
|
|
|
|
+
|
|
|
|
|
+ if not isinstance(force, float):
|
|
|
|
|
+ raise TypeError(_('The jump force must be a float number.'))
|
|
|
|
|
+
|
|
|
|
|
+ if force < 0:
|
|
|
|
|
+ raise ValueError(_('The jump force must be a non-negative float.'))
|
|
|
|
|
+
|
|
|
|
|
+ self.jump_force = force
|
|
|
|
|
+ self.jump_counter = force
|
|
|
|
|
+
|
|
|
|
|
+ if not self.is_jumping and (
|
|
|
|
|
+ not key or _get_keys()[utils.eval_key(key)]
|
|
|
|
|
+ ):
|
|
|
|
|
+ self.is_jumping = True
|
|
|
|
|
|
|
|
def decrease(self, decrement: float | int = 0.001, key: str = ''):
|
|
def decrease(self, decrement: float | int = 0.001, key: str = ''):
|
|
|
"""
|
|
"""
|
|
@@ -452,6 +448,56 @@ class Character(pygame.sprite.Sprite):
|
|
|
if self._image:
|
|
if self._image:
|
|
|
_window.blit(self._image, self._rect)
|
|
_window.blit(self._image, self._rect)
|
|
|
|
|
|
|
|
|
|
+ def _update_jump(self):
|
|
|
|
|
+ """
|
|
|
|
|
+ Calculate and update the character position during the jump.
|
|
|
|
|
+ """
|
|
|
|
|
+ if self.is_jumping:
|
|
|
|
|
+ if self._jump_counter >= -self.jump_force:
|
|
|
|
|
+ self.move(
|
|
|
|
|
+ 0,
|
|
|
|
|
+ -int((self._jump_counter * abs(self._jump_counter)) * 0.5),
|
|
|
|
|
+ )
|
|
|
|
|
+ self._jump_counter -= 1
|
|
|
|
|
+ else:
|
|
|
|
|
+ self._jump_counter = settings.DEFAULT_JUMP_FORCE
|
|
|
|
|
+ self.is_jumping = False
|
|
|
|
|
+
|
|
|
|
|
+ def _update_rect_position(
|
|
|
|
|
+ self, vg_scene: Type['scene.Scene'], tracking: bool = False
|
|
|
|
|
+ ):
|
|
|
|
|
+ """
|
|
|
|
|
+ Calculate and update the position where the character must be painted.
|
|
|
|
|
+ Only one character can be tracked.
|
|
|
|
|
+
|
|
|
|
|
+ Parameters:
|
|
|
|
|
+ vg_scene: The scene information.
|
|
|
|
|
+ tracking: True if the character must be followed, False otherwise.
|
|
|
|
|
+ """
|
|
|
|
|
+ # TODO: check vg_scene type
|
|
|
|
|
+ if not isinstance(tracking, bool):
|
|
|
|
|
+ raise TypeError(_('The tracking parameter must be a boolean.'))
|
|
|
|
|
+
|
|
|
|
|
+ if tracking:
|
|
|
|
|
+ if self.x < settings.WINDOW_WIDTH // 2:
|
|
|
|
|
+ self._rect.x = self.x
|
|
|
|
|
+ elif (
|
|
|
|
|
+ settings.WINDOW_WIDTH // 2
|
|
|
|
|
+ < self.x
|
|
|
|
|
+ < vg_scene.width - settings.WINDOW_WIDTH
|
|
|
|
|
+ ):
|
|
|
|
|
+ self._rect.x = settings.WINDOW_WIDTH // 2
|
|
|
|
|
+ elif self.x > vg_scene.width - settings.WINDOW_WIDTH:
|
|
|
|
|
+ self._rect.x = settings.WINDOW_WIDTH * 3 / 2 - (
|
|
|
|
|
+ -self.x % vg_scene.width
|
|
|
|
|
+ )
|
|
|
|
|
+ self._rect.y = self.y
|
|
|
|
|
+ else:
|
|
|
|
|
+ self._rect.x = self.x + vg_scene.x
|
|
|
|
|
+ self._rect.y = self.y
|
|
|
|
|
+
|
|
|
def update(self):
|
|
def update(self):
|
|
|
for action, key in self.predefined_keys.items():
|
|
for action, key in self.predefined_keys.items():
|
|
|
eval(f'self.{action}(key="{key}")')
|
|
eval(f'self.{action}(key="{key}")')
|
|
|
|
|
+
|
|
|
|
|
+ self._update_jump()
|