Started implementing framework

main
Yan Wittmann 2023-03-25 15:41:32 +01:00
parent 2554fd94f0
commit 73b22dca7d
18 changed files with 460 additions and 37 deletions

Binary file not shown.

View File

@ -0,0 +1,43 @@
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,X,X,X,X,X,X,X,X,X,,,,,,,,,,,,,,,,,D,,,
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
3,3,id=HEBEL,requires=HEBEL;HEBEL-2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 X X X X X X X X X D
30 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
31 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
32 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
33 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
34 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
35 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
36 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
37 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
38 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
39 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
40 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
41 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
42
43 3 3 id=HEBEL requires=HEBEL;HEBEL-2

View File

@ -0,0 +1,10 @@
[
{
"name": "1-1",
"theme": "ghost",
"abilities": [
"dash"
],
"file": "1-1.csv"
}
]

View File

Before

Width:  |  Height:  |  Size: 714 B

After

Width:  |  Height:  |  Size: 714 B

View File

@ -0,0 +1,44 @@
LEVEL_SIZE = (71, 40)
class Level:
def __init__(self, name: str, theme: str, abilities: list[str], csv_grid: list[str]):
self.name = name
self.theme = theme
self.abilities = abilities
self.tiles = self.parse_csv_to_2darray(csv_grid)
def __str__(self):
return 'name: ' + self.name + ', theme: ' + self.theme + ', allowed abilities: ' + str(self.abilities)
def parse_csv_to_2darray(self, csv_grid: list[str]):
tiles = []
for line_number, line in enumerate(csv_grid):
if line_number <= LEVEL_SIZE[1]:
tiles.append([])
for item_number, item in enumerate(line):
if item_number <= LEVEL_SIZE[0]:
tiles[line_number].append({'tile': item})
else:
print('Level is too wide:', item_number, '>', LEVEL_SIZE[0])
break
elif line[0] != '':
x = int(line[0])
y = int(line[1])
tile = tiles[x][y]
for i in range(2, len(line)):
if line[i] == '':
break
split_item = line[i].split('=')
if split_item[0] == 'id':
tile[split_item[0]] = split_item[1]
elif split_item[0] == 'requires':
tile[split_item[0]] = split_item[1].split(';')
else:
raise ValueError('Incorrect attribute name: ' + split_item[0])
tiles[x][y] = tile
return tiles

View File

@ -0,0 +1,18 @@
import csv
SCREEN_WIDTH = 71
SCREEN_HEIGHT = 40
STATIC = 'static'
DYNAMIC = 'dynamic'
class LevelElementSymbols:
SOLID_BLOCK = {
'symbol': '#',
'type': STATIC
}
AIR = {
'symbol': '',
'type': STATIC
}

View File

@ -0,0 +1,29 @@
import sys
import os
import json
from level.Level import Level
class LevelManager:
def __init__(self, level_dir: str):
self.level_dir = level_dir
self.levels = []
def load_from_config(self, config_file: str):
print('Loading levels from sprite sheet config file', config_file)
config = json.load(open(config_file))
for level_data in config:
csv = self.parse_csv(self.level_dir + '/' + level_data['file'])
level = Level(level_data['name'], level_data['theme'], level_data['abilities'], csv)
self.levels.append(level)
def parse_csv(self, file: str):
csv_array = []
with open(file) as csvfile:
for row in csvfile:
split_row = row.split(',')
filtered_row = list(map(lambda x: x.replace('\n', ''), split_row))
csv_array.append(filtered_row)
return csv_array

View File

@ -1,21 +1,101 @@
import random import random
import pygame import pygame
from pygame.font import Font
from PositionScale import PositionScale from level.LevelManager import LevelManager
from SpritesheetManager import SpritesheetManager from sprite.DynamicSprite import DynamicSprite
from Sprite import Sprite from sprite.PositionScale import PositionScale
from sprite.SpritesheetManager import SpritesheetManager
from physics.PhysicsElementsHandler import PhysicsElementsHandler
from sprite.Sprite import Sprite
from sprite.StaticSprite import StaticSprite
from ui_elements.TextLabel import TextLabel
what_to_run = 'physics'
if what_to_run == 'level':
csv_parse_test = LevelManager('data/levels')
csv_parse_test.load_from_config('data/levels/levels.json')
print(csv_parse_test.levels[0])
elif what_to_run == 'physics':
screen_transform = PositionScale((0, 0), (4, 4))
pygame.init()
screen = pygame.display.set_mode((600, 500))
pygame.display.set_caption("PE GAME")
clock = pygame.time.Clock()
spritesheet_manager = SpritesheetManager("data/sprites", "data/sprites/sprites.json")
test_1_sprite = DynamicSprite(spritesheet_manager.get_sheet("test_1"))
test_2_sprite = StaticSprite(spritesheet_manager.get_sheet("test_1"))
test_1_sprite.position_scale = PositionScale((10, 10), (1, 1))
test_2_sprite.position_scale = PositionScale((100, 100), (1, 1))
physics_handler = PhysicsElementsHandler()
physics_handler.add_sprite(test_1_sprite)
physics_handler.add_sprite(test_2_sprite)
while True:
clock.tick(10)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit(0)
screen.fill((0, 0, 0))
physics_handler.tick(1)
physics_handler.draw(screen, screen_transform)
pygame.display.update()
elif what_to_run == 'textlabel':
screen_transform = PositionScale((0, 0), (4, 4))
pygame.init()
screen = pygame.display.set_mode((300, 300))
pygame.display.set_caption("PM GAME")
clock = pygame.time.Clock()
test = TextLabel("Hallo", 100, 100, 50, Font('data/font/MilkyNice.otf'))
while True:
clock.tick(5)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
screen.fill((0, 0, 0))
test.draw(screen, screen_transform)
pygame.display.update()
elif what_to_run == 'sprite':
screen_transform = PositionScale((0, 0), (4, 4))
pygame.init() pygame.init()
screen = pygame.display.set_mode((300, 300)) screen = pygame.display.set_mode((300, 300))
pygame.display.set_caption("PE GAME") pygame.display.set_caption("PE GAME")
clock = pygame.time.Clock() clock = pygame.time.Clock()
spritesheet_manager = SpritesheetManager("sprites", "sprites/sprites.json") spritesheet_manager = SpritesheetManager("data/sprites", "data/sprites/sprites.json")
test_1_sprite = Sprite(spritesheet_manager.get_sheet("test_1")) test_1_sprite = Sprite(spritesheet_manager.get_sheet("test_1"))
test_2_sprite = Sprite(spritesheet_manager.get_sheet("test_1"))
test_1_sprite.dump("debug.png") test_1_sprite.position_scale = PositionScale((10, 10), (1, 1))
test_2_sprite.position_scale = PositionScale((60, 60), (1, 1))
# test_1_sprite.dump("debug.png")
while True: while True:
clock.tick(5) clock.tick(5)
@ -27,7 +107,9 @@ while True:
screen.fill((0, 0, 0)) screen.fill((0, 0, 0))
test_1_sprite.tick(1) test_1_sprite.tick(1)
test_1_sprite.draw(screen, PositionScale((40, 40), (3, 3))) test_1_sprite.draw(screen, screen_transform)
test_2_sprite.tick(1)
test_2_sprite.draw(screen, screen_transform)
pygame.display.update() pygame.display.update()
if random.randint(1, 10) == 1: if random.randint(1, 10) == 1:

View File

@ -0,0 +1,62 @@
from pygame.surface import Surface
from sprite.DynamicSprite import DynamicSprite
from sprite.PositionScale import PositionScale
from sprite.Sprite import Sprite
from sprite.StaticSprite import StaticSprite
MOTION_STEPS = 10
class PhysicsElementsHandler:
def __init__(self):
self.sprites: list[Sprite] = []
def add_sprite(self, sprite: Sprite):
self.sprites.append(sprite)
def remove_sprite(self, sprite: Sprite):
self.sprites.remove(sprite)
def tick(self, dt: float):
for sprite in self.sprites:
sprite.tick(dt)
# handle motion and collisions. To do this:
# 1. Find all sprites that have collision enabled and store them in a list
# 2. Create a list of all sprites that are dynamic sprites
# 3. Sort the sprites by their y position
# 4. For each sprite:
# 4.1. Divide the motion into MOTION_STEPS steps
# 4.2. For each step:
# 4.2.1. Check if the sprite collides with any other sprite
# 4.2.2. If it does, move the sprite back to the previous position and stop the motion
# 4.2.3. If it doesn't, move the sprite to the new position
colliders = [sprite for sprite in self.sprites if sprite.is_collider and isinstance(sprite, StaticSprite)]
dynamic_sprites = [sprite for sprite in self.sprites if isinstance(sprite, DynamicSprite)]
sorted_dynamic_sprites = sorted(dynamic_sprites, key=lambda spr: spr.position_scale.position[1])
for sprite in sorted_dynamic_sprites:
total_motion = sprite.motion
motion_step = (total_motion[0] / MOTION_STEPS, total_motion[1] / MOTION_STEPS)
for i in range(MOTION_STEPS):
sprite.position_scale.position = (
sprite.position_scale.position[0] + motion_step[0],
sprite.position_scale.position[1] + motion_step[1]
)
for collider in colliders:
if sprite is not collider and sprite.collides_with(collider):
sprite.position_scale.position = (
sprite.position_scale.position[0] - motion_step[0],
sprite.position_scale.position[1] - motion_step[1]
)
sprite.motion = (0, 0)
break
def draw(self, screen: Surface, screen_transform: PositionScale):
for sprite in self.sprites:
sprite.draw(screen, screen_transform)

View File

@ -0,0 +1,13 @@
class BoundingBox:
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
def get_dimensions(self):
return self.width, self.height
def get_position(self):
return self.x, self.y

View File

@ -0,0 +1,25 @@
import pygame
import sys
from sprite.Sprite import Sprite
from sprite.Spritesheet import Spritesheet
from sprite.StaticSprite import StaticSprite
sys.path.append('./sprite')
class DynamicSprite(StaticSprite):
def __init__(self, spritesheet: Spritesheet):
super().__init__(spritesheet)
self.motion = (0, 0)
self.deceleration_horizontal = 0
self.gravity = 0
def tick(self, dt: float):
super().tick(dt)
self.motion = (
self.motion[0] - self.deceleration_horizontal * dt,
self.motion[1] + self.gravity * dt
)

View File

@ -1,5 +1,5 @@
class PositionScale: class PositionScale:
def __init__(self, position=(0, 0), scale=(1, 1)): def __init__(self, position: tuple[int, int] = (0, 0), scale: tuple[int, int] = (1, 1)):
self.position = position self.position = position
self.scale = scale self.scale = scale

View File

@ -1,10 +1,15 @@
import pygame import pygame
import sys
from PositionScale import PositionScale from sprite.BoundingBox import BoundingBox
from sprite.PositionScale import PositionScale
from sprite.Spritesheet import Spritesheet
sys.path.append('./sprite')
class Sprite: class Sprite:
def __init__(self, spritesheet): def __init__(self, spritesheet: Spritesheet):
self.spritesheet = spritesheet self.spritesheet = spritesheet
self.animation_state = list(self.spritesheet.animations.keys())[0] self.animation_state = list(self.spritesheet.animations.keys())[0]
@ -18,34 +23,40 @@ class Sprite:
self.image = None self.image = None
def tick(self, dt): self.is_collider = True
def tick(self, dt: float):
animation = self.spritesheet.animations[self.animation_state] animation = self.spritesheet.animations[self.animation_state]
if self.animated: if self.animated:
self.animation_delay += dt self.animation_delay += dt
while self.animation_delay >= animation["delays"][self.animation_frame % len(animation["delays"])]: while self.animation_delay >= animation['delays'][self.animation_frame % len(animation['delays'])]:
self.animation_delay -= animation["delays"][self.animation_frame % len(animation["delays"])] self.animation_delay -= animation['delays'][self.animation_frame % len(animation['delays'])]
self.animation_frame = (self.animation_frame + 1) % len(animation["images"]) self.animation_frame = (self.animation_frame + 1) % len(animation['images'])
self.image = animation["images"][self.animation_frame % len(animation["images"])] self.image = animation['images'][self.animation_frame % len(animation['images'])]
def set_animation_state(self, state): def set_animation_state(self, state: str):
if state in self.spritesheet.animations: if state in self.spritesheet.animations:
self.animation_state = state self.animation_state = state
self.animation_delay = 0 self.animation_delay = 0
self.tick(0) self.tick(0)
def set_animation_frame(self, frame): def set_animation_frame(self, frame: int):
self.animation_frame = frame self.animation_frame = frame
self.tick(0) self.tick(0)
def draw(self, screen, screen_transform): def draw(self, screen: pygame.Surface, screen_transform: PositionScale):
if not self.visible: if not self.visible:
return return
if self.image is not None: if self.image is not None:
target_position = screen_transform.apply_scale_to_position() target_position = screen_transform.apply_scale_to_position()
target_position = (
target_position[0] + self.position_scale.position[0],
target_position[1] + self.position_scale.position[1]
)
target_scale = ( target_scale = (
screen_transform.scale[0] * self.position_scale.scale[0], screen_transform.scale[0] * self.position_scale.scale[0],
@ -60,6 +71,14 @@ class Sprite:
screen.blit(target_image, target_position) screen.blit(target_image, target_position)
def get_bounding_box(self) -> BoundingBox:
return BoundingBox(
self.position_scale.position[0],
self.position_scale.position[1],
self.image.get_width(),
self.image.get_height()
)
def get_scaled_image(self, image, resize): def get_scaled_image(self, image, resize):
return pygame.transform.scale(image, resize) return pygame.transform.scale(image, resize)
@ -71,7 +90,7 @@ class Sprite:
for animation in self.spritesheet.animations.values(): for animation in self.spritesheet.animations.values():
max_height = 0 max_height = 0
total_width = 0 total_width = 0
for image in animation["images"]: for image in animation['images']:
total_width += image.get_width() total_width += image.get_width()
max_height = max(max_height, image.get_height()) max_height = max(max_height, image.get_height())
width = max(width, total_width) width = max(width, total_width)
@ -83,7 +102,7 @@ class Sprite:
y = 0 y = 0
for animation in self.spritesheet.animations.values(): for animation in self.spritesheet.animations.values():
max_height = 0 max_height = 0
for image in animation["images"]: for image in animation['images']:
sheet.blit(image, (x, y)) sheet.blit(image, (x, y))
x += image.get_width() x += image.get_width()
max_height = max(max_height, image.get_height()) max_height = max(max_height, image.get_height())

View File

@ -1,7 +1,9 @@
import pygame
import json import json
import sys
from Spritesheet import Spritesheet from sprite.Spritesheet import Spritesheet
sys.path.append('./sprite')
# This class is used to load named sprite sheets from the img folder. # This class is used to load named sprite sheets from the img folder.

View File

@ -0,0 +1,41 @@
import pygame
import sys
from sprite.Sprite import Sprite
from sprite.Spritesheet import Spritesheet
sys.path.append('./sprite')
class StaticSprite(Sprite):
def __init__(self, spritesheet: Spritesheet):
super().__init__(spritesheet)
self.position = (0, 0)
def collides_with(self, collider: 'StaticSprite'):
if not self.is_collider or not collider.is_collider:
return False
self_bounds = self.get_bounding_box()
other_bounds = collider.get_bounding_box()
self_dimensions = self_bounds.get_dimensions()
other_dimensions = other_bounds.get_dimensions()
self_position = self_bounds.get_position()
other_position = other_bounds.get_position()
if self_position[0] + self_dimensions[0] < other_position[0]:
return False
if self_position[0] > other_position[0] + other_dimensions[0]:
return False
if self_position[1] + self_dimensions[1] < other_position[1]:
return False
if self_position[1] > other_position[1] + other_dimensions[1]:
return False
return True

View File

@ -0,0 +1,35 @@
import pygame
from pygame.examples.textinput import Screen
from pygame.font import Font
from sprite.PositionScale import PositionScale
class TextLabel:
# pygame.font.Font('data/font/arcade.TTF')
def __init__(self, text: str, x_position: float, y_position: float, font_size: float, font: Font,
alignment: str = "left"):
self.text = text
self.x_position = x_position
self.y_position = y_position
self.alignment = alignment
self.current_width = 0
self.current_height = 0
self.font_size = font_size
self.font = font
self.position_scale = PositionScale()
def draw(self, screen: Screen, screen_transform: PositionScale):
rendered_font = self.font.render(str(self.text), True, (255, 255, 255))
self.current_width = rendered_font.get_width()
self.current_height = rendered_font.get_height()
if self.alignment == "right":
screen.blit(rendered_font, (self.x_position - self.current_width / 2, self.y_position))
elif self.alignment == "right":
screen.blit(rendered_font, (self.x_position, self.y_position))
elif self.alignment == "center":
screen.blit(rendered_font, (self.x_position - self.current_width, self.y_position))
def set_text(self, new_text: str):
self.text = new_text