|
@@ -1,4 +1,5 @@
|
|
|
import os
|
|
import os
|
|
|
|
|
+from copy import deepcopy
|
|
|
from typing import Type
|
|
from typing import Type
|
|
|
|
|
|
|
|
import pygame
|
|
import pygame
|
|
@@ -43,10 +44,11 @@ class Character(pygame.sprite.Sprite):
|
|
|
self.scale_factor = 1.0
|
|
self.scale_factor = 1.0
|
|
|
self.speed = 0
|
|
self.speed = 0
|
|
|
self.predefined_keys = {}
|
|
self.predefined_keys = {}
|
|
|
- self._image = None
|
|
|
|
|
|
|
+ self.image_filename = image_filename
|
|
|
|
|
+ self.image = None
|
|
|
self._original_image = None
|
|
self._original_image = None
|
|
|
self._original_rect = None
|
|
self._original_rect = None
|
|
|
- self._rect = None
|
|
|
|
|
|
|
+ self.rect = None
|
|
|
self.name = name
|
|
self.name = name
|
|
|
self.x = 0
|
|
self.x = 0
|
|
|
self.y = 0
|
|
self.y = 0
|
|
@@ -68,6 +70,11 @@ class Character(pygame.sprite.Sprite):
|
|
|
Parameters:
|
|
Parameters:
|
|
|
data: input schema
|
|
data: input schema
|
|
|
"""
|
|
"""
|
|
|
|
|
+ if data is None:
|
|
|
|
|
+ data = {}
|
|
|
|
|
+
|
|
|
|
|
+ if not isinstance(data, dict):
|
|
|
|
|
+ raise TypeError(_('The data input must be a dict.'))
|
|
|
|
|
|
|
|
for attribute in data.keys():
|
|
for attribute in data.keys():
|
|
|
# utils._convert_function_arguments_to_string()
|
|
# utils._convert_function_arguments_to_string()
|
|
@@ -76,11 +83,11 @@ class Character(pygame.sprite.Sprite):
|
|
|
|
|
|
|
|
@property
|
|
@property
|
|
|
def height(self):
|
|
def height(self):
|
|
|
- return self._rect.height
|
|
|
|
|
|
|
+ return self.rect.height
|
|
|
|
|
|
|
|
@property
|
|
@property
|
|
|
def width(self):
|
|
def width(self):
|
|
|
- return self._rect.width
|
|
|
|
|
|
|
+ return self.rect.width
|
|
|
|
|
|
|
|
def _eval_predefined_function(
|
|
def _eval_predefined_function(
|
|
|
self, function: str, arguments: str | list | dict
|
|
self, function: str, arguments: str | list | dict
|
|
@@ -310,7 +317,7 @@ class Character(pygame.sprite.Sprite):
|
|
|
)
|
|
)
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
- self._image = pygame.transform.scale(
|
|
|
|
|
|
|
+ self.image = pygame.transform.scale(
|
|
|
self._original_image,
|
|
self._original_image,
|
|
|
(
|
|
(
|
|
|
int(self._original_rect.width * scale_factor),
|
|
int(self._original_rect.width * scale_factor),
|
|
@@ -318,7 +325,7 @@ class Character(pygame.sprite.Sprite):
|
|
|
),
|
|
),
|
|
|
)
|
|
)
|
|
|
self.scale_factor = scale_factor
|
|
self.scale_factor = scale_factor
|
|
|
- self._rect = self._image.get_rect()
|
|
|
|
|
|
|
+ self.rect = self.image.get_rect()
|
|
|
|
|
|
|
|
def set_height(self, height: int = 0):
|
|
def set_height(self, height: int = 0):
|
|
|
"""
|
|
"""
|
|
@@ -338,11 +345,11 @@ class Character(pygame.sprite.Sprite):
|
|
|
raise ValueError(_('Height must be a not negative integer.'))
|
|
raise ValueError(_('Height must be a not negative integer.'))
|
|
|
|
|
|
|
|
self.scale_factor = height / self._original_rect.height
|
|
self.scale_factor = height / self._original_rect.height
|
|
|
- self._image = pygame.transform.scale(
|
|
|
|
|
|
|
+ self.image = pygame.transform.scale(
|
|
|
self._original_image,
|
|
self._original_image,
|
|
|
(int(self._original_rect.width * self.scale_factor), height),
|
|
(int(self._original_rect.width * self.scale_factor), height),
|
|
|
)
|
|
)
|
|
|
- self._rect = self._image.get_rect()
|
|
|
|
|
|
|
+ self.rect = self.image.get_rect()
|
|
|
|
|
|
|
|
def set_keys(self, predefined_keys: dict):
|
|
def set_keys(self, predefined_keys: dict):
|
|
|
"""
|
|
"""
|
|
@@ -417,11 +424,11 @@ class Character(pygame.sprite.Sprite):
|
|
|
raise ValueError(_('Width must be a not negative integer.'))
|
|
raise ValueError(_('Width must be a not negative integer.'))
|
|
|
|
|
|
|
|
self.scale_factor = width / self._original_rect.width
|
|
self.scale_factor = width / self._original_rect.width
|
|
|
- self._image = pygame.transform.scale(
|
|
|
|
|
|
|
+ self.image = pygame.transform.scale(
|
|
|
self._original_image,
|
|
self._original_image,
|
|
|
(width, int(self._original_rect.height * self.scale_factor)),
|
|
(width, int(self._original_rect.height * self.scale_factor)),
|
|
|
)
|
|
)
|
|
|
- self._rect = self._image.get_rect()
|
|
|
|
|
|
|
+ self.rect = self.image.get_rect()
|
|
|
|
|
|
|
|
def load(self, filename: str) -> bool:
|
|
def load(self, filename: str) -> bool:
|
|
|
"""
|
|
"""
|
|
@@ -432,10 +439,25 @@ class Character(pygame.sprite.Sprite):
|
|
|
settings.CHARACTERS_DIR, filename
|
|
settings.CHARACTERS_DIR, filename
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
- self._image = self._original_image
|
|
|
|
|
|
|
+ self.image = self._original_image
|
|
|
self._original_rect = self._original_image.get_rect()
|
|
self._original_rect = self._original_image.get_rect()
|
|
|
- self._rect = self._image.get_rect()
|
|
|
|
|
|
|
+ self.rect = self.image.get_rect()
|
|
|
self.scale_factor = 1
|
|
self.scale_factor = 1
|
|
|
|
|
+ self.image_filename = filename
|
|
|
|
|
+
|
|
|
|
|
+ def copy(self):
|
|
|
|
|
+ """
|
|
|
|
|
+ Create a copy of this character keeping size and position.
|
|
|
|
|
+
|
|
|
|
|
+ Examples:
|
|
|
|
|
+ >>> ch = Character('protagonist.png')
|
|
|
|
|
+ >>> other = ch.copy()
|
|
|
|
|
+ """
|
|
|
|
|
+ new_character = Character(self.image_filename)
|
|
|
|
|
+ new_character.set_height(self.height)
|
|
|
|
|
+ new_character.set_width(self.width)
|
|
|
|
|
+ new_character.set_position((self.x, self.y))
|
|
|
|
|
+ return new_character
|
|
|
|
|
|
|
|
def paint(self):
|
|
def paint(self):
|
|
|
"""
|
|
"""
|
|
@@ -445,8 +467,8 @@ class Character(pygame.sprite.Sprite):
|
|
|
>>> ch = Character('protagonist.png')
|
|
>>> ch = Character('protagonist.png')
|
|
|
>>> ch.paint()
|
|
>>> ch.paint()
|
|
|
"""
|
|
"""
|
|
|
- if self._image:
|
|
|
|
|
- _window.blit(self._image, self._rect)
|
|
|
|
|
|
|
+ if self.image:
|
|
|
|
|
+ _window.blit(self.image, self.rect)
|
|
|
|
|
|
|
|
def _update_jump(self):
|
|
def _update_jump(self):
|
|
|
"""
|
|
"""
|
|
@@ -478,23 +500,26 @@ class Character(pygame.sprite.Sprite):
|
|
|
if not isinstance(tracking, bool):
|
|
if not isinstance(tracking, bool):
|
|
|
raise TypeError(_('The tracking parameter must be a boolean.'))
|
|
raise TypeError(_('The tracking parameter must be a boolean.'))
|
|
|
|
|
|
|
|
|
|
+ if not vg_scene:
|
|
|
|
|
+ return None
|
|
|
|
|
+
|
|
|
if tracking:
|
|
if tracking:
|
|
|
if self.x < settings.WINDOW_WIDTH // 2:
|
|
if self.x < settings.WINDOW_WIDTH // 2:
|
|
|
- self._rect.x = self.x
|
|
|
|
|
|
|
+ self.rect.x = self.x
|
|
|
elif (
|
|
elif (
|
|
|
settings.WINDOW_WIDTH // 2
|
|
settings.WINDOW_WIDTH // 2
|
|
|
< self.x
|
|
< self.x
|
|
|
< vg_scene.width - settings.WINDOW_WIDTH
|
|
< vg_scene.width - settings.WINDOW_WIDTH
|
|
|
):
|
|
):
|
|
|
- self._rect.x = settings.WINDOW_WIDTH // 2
|
|
|
|
|
|
|
+ self.rect.x = settings.WINDOW_WIDTH // 2
|
|
|
elif self.x > vg_scene.width - settings.WINDOW_WIDTH:
|
|
elif self.x > vg_scene.width - settings.WINDOW_WIDTH:
|
|
|
- self._rect.x = settings.WINDOW_WIDTH * 3 / 2 - (
|
|
|
|
|
|
|
+ self.rect.x = settings.WINDOW_WIDTH * 3 / 2 - (
|
|
|
-self.x % vg_scene.width
|
|
-self.x % vg_scene.width
|
|
|
)
|
|
)
|
|
|
- self._rect.y = self.y
|
|
|
|
|
|
|
+ self.rect.y = self.y
|
|
|
else:
|
|
else:
|
|
|
- self._rect.x = self.x + vg_scene.x
|
|
|
|
|
- self._rect.y = self.y
|
|
|
|
|
|
|
+ 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():
|