Minor adjustments to physics

main
Yan Wittmann 2023-03-26 10:40:17 +02:00
parent e6d34fcbf2
commit ec550683f8
6 changed files with 34 additions and 32 deletions

View File

@ -2,7 +2,7 @@ LEVEL_SIZE = (71, 40)
class Level:
def __init__(self, name: str, theme: str, abilities: list[str], csv_grid: list[str]):
def __init__(self, name: str, theme: str, abilities: list[str], csv_grid: list[list[str]]):
self.name = name
self.theme = theme
self.abilities = abilities
@ -11,7 +11,7 @@ class Level:
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]):
def parse_csv_to_2darray(self, csv_grid: list[list[str]]):
tiles = []
for line_number, line in enumerate(csv_grid):

View File

@ -1,7 +1,3 @@
import csv
SCREEN_WIDTH = 71
SCREEN_HEIGHT = 40
STATIC = 'static'
DYNAMIC = 'dynamic'

View File

@ -13,7 +13,7 @@ from sprite.Sprite import Sprite
from sprite.StaticSprite import StaticSprite
from ui_elements.TextLabel import TextLabel
what_to_run = 'physics'
what_to_run = 'level'
def apply_frame_rate(number: float):
@ -30,6 +30,8 @@ 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])
for row in csv_parse_test.levels[0].tiles:
print(row)
elif what_to_run == 'physics':

View File

@ -1,7 +1,6 @@
from pygame.surface import Surface
from typing import Optional
from sprite.DynamicSprite import DynamicSprite
from sprite.PositionScale import PositionScale
from sprite.Sprite import Sprite
from sprite.StaticSprite import StaticSprite
from ui_elements.UiElement import UiElement
@ -12,7 +11,13 @@ TOLERANCE = 1
class PhysicsElementsHandler:
def __init__(self):
pass
self.collision_callbacks = []
def add_collision_callback(self, callback):
self.collision_callbacks.append(callback)
def remove_collision_callback(self, callback):
self.collision_callbacks.remove(callback)
def tick(self, dt: float, layers: dict[str, list[UiElement]]):
sprites = []
@ -39,9 +44,13 @@ class PhysicsElementsHandler:
sorted_dynamic_sprites = sorted(dynamic_sprites, key=lambda spr: spr.position_scale.position[1])
for sprite in sorted_dynamic_sprites:
self.attempt_move(dt, sprite, colliders, MOTION_STEPS)
collides_with = self.attempt_move(dt, sprite, colliders, MOTION_STEPS)
if collides_with is not None:
for callback in self.collision_callbacks:
callback(sprite, collides_with)
def attempt_move(self, dt: float, sprite: DynamicSprite, colliders: list[StaticSprite], motion_steps: int) -> bool:
def attempt_move(self, dt: float, sprite: DynamicSprite, colliders: list[StaticSprite],
motion_steps: int) -> Optional[StaticSprite]:
total_motion = sprite.motion
motion_step = ((total_motion[0] * dt) / motion_steps, (total_motion[1] * dt) / motion_steps)
@ -53,7 +62,8 @@ class PhysicsElementsHandler:
sprite.position_scale.position[1]
)
if self.check_collides(sprite, colliders):
collides_with = self.check_collides(sprite, colliders)
if collides_with is not None:
sprite.position_scale.position = (
sprite.position_scale.position[0] - motion_step[0],
sprite.position_scale.position[1]
@ -66,14 +76,15 @@ class PhysicsElementsHandler:
sprite.set_touches_left(True)
sprite.motion = (0, sprite.motion[1])
return False
return collides_with
sprite.position_scale.position = (
sprite.position_scale.position[0],
sprite.position_scale.position[1] + motion_step[1]
)
if self.check_collides(sprite, colliders):
collides_with = self.check_collides(sprite, colliders)
if collides_with is not None:
sprite.position_scale.position = (
sprite.position_scale.position[0],
sprite.position_scale.position[1] - motion_step[1]
@ -86,13 +97,13 @@ class PhysicsElementsHandler:
sprite.set_touches_top(True)
sprite.motion = (sprite.motion[0], 0)
return False
return collides_with
return True
return None
def check_collides(self, sprite: StaticSprite, colliders: list[StaticSprite]) -> bool:
def check_collides(self, sprite: StaticSprite, colliders: list[StaticSprite]) -> Optional[StaticSprite]:
for collider in colliders:
if sprite is not collider and sprite.collides_with(collider, TOLERANCE):
return True
return collider
return False
return None

View File

@ -19,6 +19,7 @@ class DrawLayers:
class SpriteManager:
def __init__(self):
self.physics_handler = PhysicsElementsHandler()
self.physics_handler.add_collision_callback(self.collision_detected)
self.layers: dict[str, list[UiElement]] = {}
for layer in DrawLayers.DRAW_ORDER:
@ -39,3 +40,7 @@ class SpriteManager:
for layer in DrawLayers.DRAW_ORDER:
for sprite in self.layers[layer]:
sprite.draw(screen, screen_transform)
def collision_detected(self, sprite_a: Sprite, sprite_b: Sprite):
# print(f"Collision detected between {sprite_a} and {sprite_b}")
pass

View File

@ -27,18 +27,6 @@ class UiElement:
image = self.render_sprite_image()
if image is not None:
# target_scale = (screen_transform.scale[0] * self.position_scale.scale[0],
# screen_transform.scale[1] * self.position_scale.scale[1])
# target_position = ((self.position_scale.position[0] + screen_transform.position[0]) * target_scale[0],
# (self.position_scale.position[1] + screen_transform.position[1]) * target_scale[1])
# target_size = (int(target_scale[0] * image.get_width()),
# int(target_scale[1] * image.get_height()))
# target_image = self.get_scaled_image(image, target_size)
# screen.blit(target_image, target_position)
screen_scale = screen_transform.scale
screen_position = screen_transform.position