Partial collision
parent
44d3ab01bf
commit
f400b374fd
|
@ -25,8 +25,8 @@
|
||||||
#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
||||||
#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
||||||
#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
||||||
#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
#,,,,,,,,,,,,,,,,,L,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
||||||
#,,,,,,,,,,P,,,,,,P,,,,,,,,,,,,,,,,,,,,,,,,,,x,x,x,x,x,x,x,x,x,,,,,,,,,,,,,,,,,D,,,#
|
#,,,,,,,,,,P,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,x,x,x,x,x,x,x,x,x,,,,,,,,,,,,,,,,,D,,,#
|
||||||
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,r,,,,,,,,,,,l,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
|
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,r,,,,,,,,,,,l,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
|
||||||
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,r,,,,,,,,,,,,,,l,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
|
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,r,,,,,,,,,,,,,,l,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
|
||||||
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,r,,,,,,,,,,,,,,l,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
|
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,r,,,,,,,,,,,,,,l,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
|
||||||
|
@ -40,5 +40,5 @@
|
||||||
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,r,,,,,,,,,,,,,,l,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
|
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,r,,,,,,,,,,,,,,l,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
|
||||||
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,r,,,,,,,,,,,,,,l,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
|
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,r,,,,,,,,,,,,,,l,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
|
||||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||||
16,28,id=HEBEL,emitter_state=false,debug=1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
16,28,id=HEBEL,emitter_state=false,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||||
10,28,id=HEBEL,emitter_state=false,debug=2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
10,28,id=HEBEL,emitter_state=false,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
|
|
@ -35,7 +35,7 @@ class Level:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
split_item = line[i].split('=')
|
split_item = line[i].split('=')
|
||||||
if split_item[0] in ['id', 'emitter_state', 'debug']:
|
if split_item[0] in ['id', 'emitter_state', 'debug', 'requires_and', 'requires_or', 'requires_xor']:
|
||||||
tile[split_item[0]] = split_item[1]
|
tile[split_item[0]] = split_item[1]
|
||||||
elif split_item[0] == 'requires':
|
elif split_item[0] == 'requires':
|
||||||
tile[split_item[0]] = split_item[1].split(';')
|
tile[split_item[0]] = split_item[1].split(';')
|
||||||
|
|
|
@ -1,64 +0,0 @@
|
||||||
|
|
||||||
STATIC = 'static'
|
|
||||||
DYNAMIC = 'dynamic'
|
|
||||||
|
|
||||||
|
|
||||||
class LevelElementSymbols:
|
|
||||||
SOLID_BLOCK = {
|
|
||||||
'type': STATIC,
|
|
||||||
'sprite_id': '_block_full',
|
|
||||||
'themed': True
|
|
||||||
}
|
|
||||||
SOLID_BLOCK_TOP = {
|
|
||||||
|
|
||||||
}
|
|
||||||
SOLID_BLOCK_LEFT = {
|
|
||||||
'type': STATIC,
|
|
||||||
'sprite_id': '_block_left'
|
|
||||||
}
|
|
||||||
SOLID_BLOCK_RIGHT = {
|
|
||||||
'type': STATIC,
|
|
||||||
'sprite_id': '_block_right'
|
|
||||||
}
|
|
||||||
AIR = {
|
|
||||||
'type': STATIC,
|
|
||||||
'sprite_id': 'air'
|
|
||||||
}
|
|
||||||
GATE = {
|
|
||||||
'type':STATIC,
|
|
||||||
'sprite_id': 'gate'
|
|
||||||
}
|
|
||||||
GOAL_DOOR = {
|
|
||||||
'type': STATIC,
|
|
||||||
'sprite_id': 'goal_door'
|
|
||||||
}
|
|
||||||
SMALL_SPIKE = {
|
|
||||||
'type': STATIC,
|
|
||||||
'sprite_id': 'small_spike'
|
|
||||||
}
|
|
||||||
LEVER = {
|
|
||||||
'type': STATIC,
|
|
||||||
'sprite_id': 'lever'
|
|
||||||
}
|
|
||||||
PLAYER = {
|
|
||||||
'type': DYNAMIC,
|
|
||||||
'sprite_id': 'player'
|
|
||||||
}
|
|
||||||
|
|
||||||
dict = {
|
|
||||||
'#': SOLID_BLOCK,
|
|
||||||
'+': SOLID_BLOCK_TOP,
|
|
||||||
'l': SOLID_BLOCK_RIGHT,
|
|
||||||
'r': SOLID_BLOCK_LEFT,
|
|
||||||
'': AIR,
|
|
||||||
'G': GATE,
|
|
||||||
'D': GOAL_DOOR,
|
|
||||||
'x': SMALL_SPIKE,
|
|
||||||
'L': LEVER,
|
|
||||||
'P': PLAYER
|
|
||||||
}
|
|
||||||
|
|
||||||
BLOCKS_LIST = [SOLID_BLOCK, SOLID_BLOCK_RIGHT, SOLID_BLOCK_LEFT]
|
|
||||||
|
|
||||||
INTERACTABLE_LIST = [LEVER]
|
|
||||||
|
|
|
@ -12,6 +12,9 @@ class ButtonInputLevelElement(InputLevelElement):
|
||||||
super().__init__(tile, level)
|
super().__init__(tile, level)
|
||||||
self.is_currently_stood_on = False
|
self.is_currently_stood_on = False
|
||||||
|
|
||||||
|
self.is_collider = False
|
||||||
|
self.register_collisions = True
|
||||||
|
|
||||||
def load(self, sprite_manager: SpriteManager, spritesheet_manager: SpritesheetManager, level: Level):
|
def load(self, sprite_manager: SpriteManager, spritesheet_manager: SpritesheetManager, level: Level):
|
||||||
self.spritesheet = spritesheet_manager.get_sheet('pressureplate')
|
self.spritesheet = spritesheet_manager.get_sheet('pressureplate')
|
||||||
self.set_animation_state('on' if self.emitter_state else 'off')
|
self.set_animation_state('on' if self.emitter_state else 'off')
|
||||||
|
@ -20,26 +23,16 @@ class ButtonInputLevelElement(InputLevelElement):
|
||||||
def tick(self, tick_data: TickData):
|
def tick(self, tick_data: TickData):
|
||||||
super().tick(tick_data)
|
super().tick(tick_data)
|
||||||
|
|
||||||
collisions = self.get_collides_with_direction(CollisionDirection.TOP)
|
collisions = self.get_collides_with_direction(CollisionDirection.INSIDE)
|
||||||
|
|
||||||
# debug 1: only activate when player is standing on it
|
# set active state only when player/object is standing on it
|
||||||
if self.tile['debug'] == '1':
|
if collisions and not self.is_currently_stood_on:
|
||||||
if collisions and not self.is_currently_stood_on:
|
self.is_currently_stood_on = True
|
||||||
self.is_currently_stood_on = True
|
self.set_active(True)
|
||||||
self.set_active(True)
|
elif not collisions and self.is_currently_stood_on:
|
||||||
elif not collisions and self.is_currently_stood_on:
|
self.is_currently_stood_on = False
|
||||||
self.is_currently_stood_on = False
|
self.set_active(False)
|
||||||
self.set_active(False)
|
|
||||||
|
|
||||||
# debug 2: toggle active state when player is standing on it
|
|
||||||
elif self.tile['debug'] == '2':
|
|
||||||
if collisions and not self.is_currently_stood_on:
|
|
||||||
self.is_currently_stood_on = True
|
|
||||||
self.set_active(not self.emitter_state)
|
|
||||||
elif not collisions and self.is_currently_stood_on:
|
|
||||||
self.is_currently_stood_on = False
|
|
||||||
|
|
||||||
def set_active(self, active: bool):
|
def set_active(self, active: bool):
|
||||||
self.emitter_state = active
|
self.emitter_state = active
|
||||||
self.set_animation_state('on' if self.emitter_state else 'off')
|
self.set_animation_state('on' if self.emitter_state else 'off')
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
from level.Level import Level
|
||||||
|
from level.elements.InputLevelElement import InputLevelElement
|
||||||
|
from physics.CollisionDirection import CollisionDirection
|
||||||
|
from physics.SpriteManager import SpriteManager
|
||||||
|
from physics.TickData import TickData
|
||||||
|
from sprite.SpritesheetManager import SpritesheetManager
|
||||||
|
|
||||||
|
|
||||||
|
class LeverInputLevelElement(InputLevelElement):
|
||||||
|
|
||||||
|
def __init__(self, tile: dict, level: Level):
|
||||||
|
super().__init__(tile, level)
|
||||||
|
self.is_currently_stood_on = False
|
||||||
|
|
||||||
|
self.is_collider = False
|
||||||
|
self.register_collisions = True
|
||||||
|
|
||||||
|
def load(self, sprite_manager: SpriteManager, spritesheet_manager: SpritesheetManager, level: Level):
|
||||||
|
self.spritesheet = spritesheet_manager.get_sheet('lever')
|
||||||
|
self.set_animation_state('on' if self.emitter_state else 'off')
|
||||||
|
self.position_scale.position = self.tile['position']
|
||||||
|
|
||||||
|
def tick(self, tick_data: TickData):
|
||||||
|
super().tick(tick_data)
|
||||||
|
|
||||||
|
collisions = self.get_collides_with_direction(CollisionDirection.INSIDE)
|
||||||
|
|
||||||
|
# toggle active state when player/object is standing on it
|
||||||
|
if collisions and not self.is_currently_stood_on:
|
||||||
|
self.is_currently_stood_on = True
|
||||||
|
self.set_active(not self.emitter_state)
|
||||||
|
elif not collisions and self.is_currently_stood_on:
|
||||||
|
self.is_currently_stood_on = False
|
||||||
|
|
||||||
|
def set_active(self, active: bool):
|
||||||
|
self.emitter_state = active
|
||||||
|
self.set_animation_state('on' if self.emitter_state else 'off')
|
|
@ -1,5 +1,6 @@
|
||||||
from level.Level import Level
|
from level.Level import Level
|
||||||
from level.elements.ButtonInputLevelElement import ButtonInputLevelElement
|
from level.elements.ButtonInputLevelElement import ButtonInputLevelElement
|
||||||
|
from level.elements.LeverInputLevelElement import LeverInputLevelElement
|
||||||
from level.elements.SimpleBlockLevelElement import SimpleBlockLevelElement
|
from level.elements.SimpleBlockLevelElement import SimpleBlockLevelElement
|
||||||
from level.elements.UnknownTileLevelElement import UnknownTileLevelElement
|
from level.elements.UnknownTileLevelElement import UnknownTileLevelElement
|
||||||
from physics import ConstantsParser
|
from physics import ConstantsParser
|
||||||
|
@ -16,7 +17,7 @@ TILES = {
|
||||||
'|': SimpleBlockLevelElement,
|
'|': SimpleBlockLevelElement,
|
||||||
|
|
||||||
'P': ButtonInputLevelElement,
|
'P': ButtonInputLevelElement,
|
||||||
'L': ButtonInputLevelElement, # TODO
|
'L': LeverInputLevelElement,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ class LoadedLevel:
|
||||||
if isinstance(element, SimpleBlockLevelElement):
|
if isinstance(element, SimpleBlockLevelElement):
|
||||||
if self.is_surrounded_by_blocks(world_position, level.tiles):
|
if self.is_surrounded_by_blocks(world_position, level.tiles):
|
||||||
element.is_collider = False
|
element.is_collider = False
|
||||||
# self.sprite_manager.remove_ui_element(element)
|
self.sprite_manager.remove_ui_element(element)
|
||||||
|
|
||||||
def is_surrounded_by_blocks(self, position, tiles):
|
def is_surrounded_by_blocks(self, position, tiles):
|
||||||
for i in range(-1, 2):
|
for i in range(-1, 2):
|
||||||
|
|
|
@ -4,6 +4,7 @@ import pygame
|
||||||
|
|
||||||
from level.LevelManager import LevelManager
|
from level.LevelManager import LevelManager
|
||||||
from level.elements.LoadedLevel import LoadedLevel
|
from level.elements.LoadedLevel import LoadedLevel
|
||||||
|
from physics import ConstantsParser
|
||||||
from physics.SpriteManager import SpriteManager, DrawLayers
|
from physics.SpriteManager import SpriteManager, DrawLayers
|
||||||
from physics.TickData import TickData
|
from physics.TickData import TickData
|
||||||
from physics.sprites.PlayerSprite import PlayerSprite
|
from physics.sprites.PlayerSprite import PlayerSprite
|
||||||
|
@ -32,7 +33,7 @@ if what_to_run == 'level':
|
||||||
screen_transform = PositionScale((0, 0), (1.5, 1.5))
|
screen_transform = PositionScale((0, 0), (1.5, 1.5))
|
||||||
|
|
||||||
pygame.init()
|
pygame.init()
|
||||||
screen = pygame.display.set_mode((12 * 71 * 1.5, 12 * 40 * 1.5))
|
screen = pygame.display.set_mode((12 * ConstantsParser.CONFIG.level_size[0] * screen_transform.scale[0], 12 * ConstantsParser.CONFIG.level_size[1] * screen_transform.scale[1]))
|
||||||
pygame.display.set_caption("PM GAME")
|
pygame.display.set_caption("PM GAME")
|
||||||
clock = pygame.time.Clock()
|
clock = pygame.time.Clock()
|
||||||
frame_rate = 30
|
frame_rate = 30
|
||||||
|
@ -51,13 +52,13 @@ if what_to_run == 'level':
|
||||||
ghost_character.position_scale = PositionScale((90, 50), (1, 1))
|
ghost_character.position_scale = PositionScale((90, 50), (1, 1))
|
||||||
sprite_manager.add_ui_element(DrawLayers.OBJECTS, ghost_character)
|
sprite_manager.add_ui_element(DrawLayers.OBJECTS, ghost_character)
|
||||||
|
|
||||||
calculated_frame_rate_text = TextLabel("Frame rate: 0", 2, 110, 70, alignment="left")
|
calculated_frame_rate_text = TextLabel("0 FPS", 2, 2, 70, alignment="left")
|
||||||
calculated_frame_rate_text.position_scale.scale = (0.3, 0.3)
|
calculated_frame_rate_text.position_scale.scale = (0.3, 0.3)
|
||||||
sprite_manager.add_ui_element(DrawLayers.UI, calculated_frame_rate_text)
|
sprite_manager.add_ui_element(DrawLayers.UI, calculated_frame_rate_text)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
clock.tick(frame_rate)
|
clock.tick(frame_rate)
|
||||||
calculated_frame_rate_text.text = f"Frame rate: {round(clock.get_fps())}"
|
calculated_frame_rate_text.text = f"{round(clock.get_fps())} FPS"
|
||||||
|
|
||||||
pygame_events: list[pygame.event.Event] = pygame.event.get()
|
pygame_events: list[pygame.event.Event] = pygame.event.get()
|
||||||
key_manager.update_key_events(pygame_events)
|
key_manager.update_key_events(pygame_events)
|
||||||
|
|
|
@ -3,7 +3,8 @@ class CollisionDirection:
|
||||||
RIGHT = 1
|
RIGHT = 1
|
||||||
TOP = 2
|
TOP = 2
|
||||||
BOTTOM = 3
|
BOTTOM = 3
|
||||||
DIRECTION_NAMES = ['LEFT', 'RIGHT', 'TOP', 'BOTTOM']
|
INSIDE = 4
|
||||||
|
DIRECTION_NAMES = ['LEFT', 'RIGHT', 'TOP', 'BOTTOM', 'INSIDE']
|
||||||
|
|
||||||
def __init__(self, direction: int, primary_sprite, secondary_sprite):
|
def __init__(self, direction: int, primary_sprite, secondary_sprite):
|
||||||
self.direction = direction
|
self.direction = direction
|
||||||
|
|
|
@ -40,7 +40,9 @@ class PhysicsElementsHandler:
|
||||||
# 4.2.2. If it does, move the sprite back to the previous position and stop the motion
|
# 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
|
# 4.2.3. If it doesn't, move the sprite to the new position
|
||||||
|
|
||||||
colliders = [sprite for sprite in sprites if isinstance(sprite, StaticSprite) and sprite.is_collider]
|
colliders = [sprite for sprite in sprites
|
||||||
|
if isinstance(sprite, StaticSprite) and (sprite.is_collider or sprite.register_collisions)]
|
||||||
|
|
||||||
for collider in colliders:
|
for collider in colliders:
|
||||||
collider.reset_collides_with()
|
collider.reset_collides_with()
|
||||||
|
|
||||||
|
@ -68,29 +70,45 @@ class PhysicsElementsHandler:
|
||||||
sprite.position_scale.position[1]
|
sprite.position_scale.position[1]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# print('Elements: ', list(filter(lambda spr: str(type(spr)) == "<class 'level.elements.LeverInputLevelElement.LeverInputLevelElement'>", colliders)))
|
||||||
|
|
||||||
collides_with = self.check_collides(sprite, colliders)
|
collides_with = self.check_collides(sprite, colliders)
|
||||||
if collides_with is not None:
|
for collider in collides_with:
|
||||||
sprite.position_scale.position = (
|
if collider is not None:
|
||||||
sprite.position_scale.position[0] - motion_step[0],
|
if sprite.is_collider and collider.is_collider:
|
||||||
sprite.position_scale.position[1]
|
if sprite.motion[0] > 0:
|
||||||
)
|
if sprite.register_collisions:
|
||||||
|
sprite.add_collides_with(
|
||||||
|
CollisionDirection(CollisionDirection.RIGHT, sprite, collider))
|
||||||
|
if collider.register_collisions:
|
||||||
|
collider.add_collides_with(
|
||||||
|
CollisionDirection(CollisionDirection.LEFT, collider, sprite))
|
||||||
|
|
||||||
if sprite.motion[0] > 0:
|
if sprite.motion[0] < 0:
|
||||||
sprite.add_collides_with(
|
if sprite.register_collisions:
|
||||||
CollisionDirection(CollisionDirection.RIGHT, sprite, collides_with))
|
sprite.add_collides_with(
|
||||||
collides_with.add_collides_with(
|
CollisionDirection(CollisionDirection.LEFT, sprite, collider))
|
||||||
CollisionDirection(CollisionDirection.LEFT, collides_with, sprite))
|
if collider.register_collisions:
|
||||||
|
collider.add_collides_with(
|
||||||
|
CollisionDirection(CollisionDirection.RIGHT, collider, sprite))
|
||||||
|
else:
|
||||||
|
if sprite.register_collisions:
|
||||||
|
sprite.add_collides_with(
|
||||||
|
CollisionDirection(CollisionDirection.INSIDE, sprite, collider))
|
||||||
|
if collider.register_collisions:
|
||||||
|
collider.add_collides_with(
|
||||||
|
CollisionDirection(CollisionDirection.INSIDE, collider, sprite))
|
||||||
|
|
||||||
if sprite.motion[0] < 0:
|
if collider.is_collider:
|
||||||
sprite.add_collides_with(
|
sprite.position_scale.position = (
|
||||||
CollisionDirection(CollisionDirection.LEFT, sprite, collides_with))
|
sprite.position_scale.position[0] - motion_step[0],
|
||||||
collides_with.add_collides_with(
|
sprite.position_scale.position[1]
|
||||||
CollisionDirection(CollisionDirection.RIGHT, collides_with, sprite))
|
)
|
||||||
|
|
||||||
sprite.motion = (0, sprite.motion[1])
|
sprite.motion = (0, sprite.motion[1])
|
||||||
|
|
||||||
collides_with_last = collides_with
|
collides_with_last = collider
|
||||||
collided[0] = True
|
collided[0] = True
|
||||||
|
|
||||||
if not collided[1]:
|
if not collided[1]:
|
||||||
sprite.position_scale.position = (
|
sprite.position_scale.position = (
|
||||||
|
@ -99,35 +117,51 @@ class PhysicsElementsHandler:
|
||||||
)
|
)
|
||||||
|
|
||||||
collides_with = self.check_collides(sprite, colliders)
|
collides_with = self.check_collides(sprite, colliders)
|
||||||
if collides_with is not None:
|
for collider in collides_with:
|
||||||
sprite.position_scale.position = (
|
if collider is not None:
|
||||||
sprite.position_scale.position[0],
|
if sprite.is_collider and collider.is_collider:
|
||||||
sprite.position_scale.position[1] - motion_step[1]
|
if sprite.motion[1] > 0:
|
||||||
)
|
if sprite.register_collisions:
|
||||||
|
sprite.add_collides_with(
|
||||||
|
CollisionDirection(CollisionDirection.BOTTOM, sprite, collider))
|
||||||
|
if collider.register_collisions:
|
||||||
|
collider.add_collides_with(
|
||||||
|
CollisionDirection(CollisionDirection.TOP, collider, sprite))
|
||||||
|
|
||||||
if sprite.motion[1] > 0:
|
if sprite.motion[1] < 0:
|
||||||
sprite.add_collides_with(
|
if sprite.register_collisions:
|
||||||
CollisionDirection(CollisionDirection.BOTTOM, sprite, collides_with))
|
sprite.add_collides_with(
|
||||||
collides_with.add_collides_with(
|
CollisionDirection(CollisionDirection.TOP, sprite, collider))
|
||||||
CollisionDirection(CollisionDirection.TOP, collides_with, sprite))
|
if collider.register_collisions:
|
||||||
|
collider.add_collides_with(
|
||||||
|
CollisionDirection(CollisionDirection.BOTTOM, collider, sprite))
|
||||||
|
else:
|
||||||
|
if sprite.register_collisions:
|
||||||
|
sprite.add_collides_with(
|
||||||
|
CollisionDirection(CollisionDirection.INSIDE, sprite, collider))
|
||||||
|
if collider.register_collisions:
|
||||||
|
collider.add_collides_with(
|
||||||
|
CollisionDirection(CollisionDirection.INSIDE, collider, sprite))
|
||||||
|
|
||||||
if sprite.motion[1] < 0:
|
if collider.is_collider:
|
||||||
sprite.add_collides_with(
|
sprite.position_scale.position = (
|
||||||
CollisionDirection(CollisionDirection.TOP, sprite, collides_with))
|
sprite.position_scale.position[0],
|
||||||
collides_with.add_collides_with(
|
sprite.position_scale.position[1] - motion_step[1]
|
||||||
CollisionDirection(CollisionDirection.BOTTOM, collides_with, sprite))
|
)
|
||||||
|
|
||||||
sprite.motion = (sprite.motion[0], 0)
|
sprite.motion = (sprite.motion[0], 0)
|
||||||
|
|
||||||
collides_with_last = collides_with
|
collides_with_last = collider
|
||||||
collided[1] = True
|
collided[1] = True
|
||||||
|
|
||||||
return collides_with_last
|
return collides_with_last
|
||||||
|
|
||||||
def check_collides(self, sprite: StaticSprite, colliders: list[StaticSprite]) -> Optional[StaticSprite]:
|
def check_collides(self, sprite: StaticSprite, colliders: list[StaticSprite]) -> list[StaticSprite]:
|
||||||
|
collides_with = []
|
||||||
|
|
||||||
for collider in colliders:
|
for collider in colliders:
|
||||||
if sprite is not collider:
|
if sprite is not collider:
|
||||||
if sprite.collides_with(collider, TOLERANCE):
|
if sprite.collides_with(collider, TOLERANCE):
|
||||||
return collider
|
collides_with.append(collider)
|
||||||
|
|
||||||
return None
|
return collides_with
|
||||||
|
|
|
@ -28,6 +28,7 @@ class Sprite(UiElement):
|
||||||
self.image = None
|
self.image = None
|
||||||
|
|
||||||
self.is_collider = True
|
self.is_collider = True
|
||||||
|
self.register_collisions = True
|
||||||
self.collides_with_elements: list[CollisionDirection] = []
|
self.collides_with_elements: list[CollisionDirection] = []
|
||||||
|
|
||||||
def add_collides_with(self, collision_direction: CollisionDirection):
|
def add_collides_with(self, collision_direction: CollisionDirection):
|
||||||
|
@ -84,12 +85,16 @@ class Sprite(UiElement):
|
||||||
|
|
||||||
def get_bounding_box(self) -> BoundingBox:
|
def get_bounding_box(self) -> BoundingBox:
|
||||||
if self.image is None:
|
if self.image is None:
|
||||||
print('get_bounding_box: No image for sprite: ' + str(self))
|
print('Sprite.refresh_bounding_box: No image for sprite: ' + str(self))
|
||||||
return BoundingBox(0, 0, 0, 0)
|
return self.bounding_box
|
||||||
|
|
||||||
return BoundingBox(
|
if self.bounding_box.x != self.position_scale.position[0] or \
|
||||||
self.position_scale.position[0],
|
self.bounding_box.y != self.position_scale.position[1]:
|
||||||
self.position_scale.position[1],
|
self.bounding_box = BoundingBox(
|
||||||
self.image.get_width() * self.position_scale.scale[0],
|
self.position_scale.position[0],
|
||||||
self.image.get_height() * self.position_scale.scale[1]
|
self.position_scale.position[1],
|
||||||
)
|
self.image.get_width() * self.position_scale.scale[0],
|
||||||
|
self.image.get_height() * self.position_scale.scale[1]
|
||||||
|
)
|
||||||
|
|
||||||
|
return self.bounding_box
|
||||||
|
|
|
@ -9,9 +9,6 @@ class StaticSprite(Sprite):
|
||||||
super().__init__(spritesheet)
|
super().__init__(spritesheet)
|
||||||
|
|
||||||
def collides_with(self, collider: 'StaticSprite', tolerance: float = 0.0):
|
def collides_with(self, collider: 'StaticSprite', tolerance: float = 0.0):
|
||||||
if not self.is_collider or not collider.is_collider:
|
|
||||||
return False
|
|
||||||
|
|
||||||
self_bounds = self.get_bounding_box()
|
self_bounds = self.get_bounding_box()
|
||||||
other_bounds = collider.get_bounding_box()
|
other_bounds = collider.get_bounding_box()
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import pygame
|
import pygame
|
||||||
from pygame import Surface, Rect
|
from pygame import Surface
|
||||||
from pygame.font import Font
|
from pygame.font import Font
|
||||||
|
|
||||||
from physics.TickData import TickData
|
from physics.TickData import TickData
|
||||||
|
@ -47,24 +47,6 @@ class TextLabel(UiElement):
|
||||||
def set_text(self, new_text: str):
|
def set_text(self, new_text: str):
|
||||||
self.text = new_text
|
self.text = new_text
|
||||||
|
|
||||||
def collides_point(self, position):
|
|
||||||
x, y = self.get_bounding_box().get_position()
|
|
||||||
# check for the collision on the x-axis
|
|
||||||
if position[1] < y:
|
|
||||||
return False
|
|
||||||
if position[1] > y + self.current_height:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# the y-axis check is dependent on the alignment
|
|
||||||
|
|
||||||
if position[0] < x:
|
|
||||||
return False
|
|
||||||
if position[0] > x + self.current_width:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# if the point is not outside the text, it is inside the text
|
|
||||||
return True
|
|
||||||
|
|
||||||
def get_bounding_box(self) -> BoundingBox:
|
def get_bounding_box(self) -> BoundingBox:
|
||||||
bounding_box_x = self.x_position
|
bounding_box_x = self.x_position
|
||||||
if self.alignment == "right":
|
if self.alignment == "right":
|
||||||
|
@ -72,5 +54,5 @@ class TextLabel(UiElement):
|
||||||
elif self.alignment == "center":
|
elif self.alignment == "center":
|
||||||
bounding_box_x = self.x_position - self.current_width / 2
|
bounding_box_x = self.x_position - self.current_width / 2
|
||||||
|
|
||||||
return BoundingBox(bounding_box_x, self.y_position, self.current_width, self.current_height)
|
self.bounding_box = BoundingBox(bounding_box_x, self.y_position, self.current_width, self.current_height)
|
||||||
|
return self.bounding_box
|
||||||
|
|
|
@ -17,6 +17,8 @@ class UiElement:
|
||||||
self.visible = True
|
self.visible = True
|
||||||
self.click_listeners = []
|
self.click_listeners = []
|
||||||
|
|
||||||
|
self.bounding_box = BoundingBox(0, 0, 0, 0)
|
||||||
|
|
||||||
self.uuid = uuid.uuid4()
|
self.uuid = uuid.uuid4()
|
||||||
|
|
||||||
def add_click_listener(self, listener):
|
def add_click_listener(self, listener):
|
||||||
|
@ -48,7 +50,8 @@ class UiElement:
|
||||||
image = self.render_sprite_image()
|
image = self.render_sprite_image()
|
||||||
|
|
||||||
if image is not None:
|
if image is not None:
|
||||||
target_position = CoordinateTransform.transform_world_to_screen(self.position_scale.position, screen_transform)
|
target_position = CoordinateTransform.transform_world_to_screen(self.position_scale.position,
|
||||||
|
screen_transform)
|
||||||
|
|
||||||
screen_scale = screen_transform.scale
|
screen_scale = screen_transform.scale
|
||||||
object_scale = self.position_scale.scale
|
object_scale = self.position_scale.scale
|
||||||
|
|
Loading…
Reference in New Issue