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: 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.name = name
self.theme = theme self.theme = theme
self.abilities = abilities self.abilities = abilities
@ -11,7 +11,7 @@ class Level:
def __str__(self): def __str__(self):
return 'name: ' + self.name + ', theme: ' + self.theme + ', allowed abilities: ' + str(self.abilities) 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 = [] tiles = []
for line_number, line in enumerate(csv_grid): for line_number, line in enumerate(csv_grid):

View File

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

View File

@ -13,7 +13,7 @@ from sprite.Sprite import Sprite
from sprite.StaticSprite import StaticSprite from sprite.StaticSprite import StaticSprite
from ui_elements.TextLabel import TextLabel from ui_elements.TextLabel import TextLabel
what_to_run = 'physics' what_to_run = 'level'
def apply_frame_rate(number: float): def apply_frame_rate(number: float):
@ -30,6 +30,8 @@ if what_to_run == 'level':
csv_parse_test = LevelManager('data/levels') csv_parse_test = LevelManager('data/levels')
csv_parse_test.load_from_config('data/levels/levels.json') csv_parse_test.load_from_config('data/levels/levels.json')
print(csv_parse_test.levels[0]) print(csv_parse_test.levels[0])
for row in csv_parse_test.levels[0].tiles:
print(row)
elif what_to_run == 'physics': 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.DynamicSprite import DynamicSprite
from sprite.PositionScale import PositionScale
from sprite.Sprite import Sprite from sprite.Sprite import Sprite
from sprite.StaticSprite import StaticSprite from sprite.StaticSprite import StaticSprite
from ui_elements.UiElement import UiElement from ui_elements.UiElement import UiElement
@ -12,7 +11,13 @@ TOLERANCE = 1
class PhysicsElementsHandler: class PhysicsElementsHandler:
def __init__(self): 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]]): def tick(self, dt: float, layers: dict[str, list[UiElement]]):
sprites = [] sprites = []
@ -39,9 +44,13 @@ class PhysicsElementsHandler:
sorted_dynamic_sprites = sorted(dynamic_sprites, key=lambda spr: spr.position_scale.position[1]) sorted_dynamic_sprites = sorted(dynamic_sprites, key=lambda spr: spr.position_scale.position[1])
for sprite in sorted_dynamic_sprites: 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 total_motion = sprite.motion
motion_step = ((total_motion[0] * dt) / motion_steps, (total_motion[1] * dt) / motion_steps) 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] 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 = (
sprite.position_scale.position[0] - motion_step[0], sprite.position_scale.position[0] - motion_step[0],
sprite.position_scale.position[1] sprite.position_scale.position[1]
@ -66,14 +76,15 @@ class PhysicsElementsHandler:
sprite.set_touches_left(True) sprite.set_touches_left(True)
sprite.motion = (0, sprite.motion[1]) sprite.motion = (0, sprite.motion[1])
return False return collides_with
sprite.position_scale.position = ( sprite.position_scale.position = (
sprite.position_scale.position[0], sprite.position_scale.position[0],
sprite.position_scale.position[1] + motion_step[1] 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 = (
sprite.position_scale.position[0], sprite.position_scale.position[0],
sprite.position_scale.position[1] - motion_step[1] sprite.position_scale.position[1] - motion_step[1]
@ -86,13 +97,13 @@ class PhysicsElementsHandler:
sprite.set_touches_top(True) sprite.set_touches_top(True)
sprite.motion = (sprite.motion[0], 0) 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: for collider in colliders:
if sprite is not collider and sprite.collides_with(collider, TOLERANCE): 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: class SpriteManager:
def __init__(self): def __init__(self):
self.physics_handler = PhysicsElementsHandler() self.physics_handler = PhysicsElementsHandler()
self.physics_handler.add_collision_callback(self.collision_detected)
self.layers: dict[str, list[UiElement]] = {} self.layers: dict[str, list[UiElement]] = {}
for layer in DrawLayers.DRAW_ORDER: for layer in DrawLayers.DRAW_ORDER:
@ -39,3 +40,7 @@ class SpriteManager:
for layer in DrawLayers.DRAW_ORDER: for layer in DrawLayers.DRAW_ORDER:
for sprite in self.layers[layer]: for sprite in self.layers[layer]:
sprite.draw(screen, screen_transform) 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() image = self.render_sprite_image()
if image is not None: 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_scale = screen_transform.scale
screen_position = screen_transform.position screen_position = screen_transform.position