Partial collision

main
Yan Wittmann 2023-03-27 14:38:52 +02:00
parent 44d3ab01bf
commit f400b374fd
13 changed files with 156 additions and 166 deletions

View File

@ -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,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1
25 # #
26 # #
27 # #
28 # L #
29 # P P x x x x x x x x x D #
30 # # # # # # # # # # # # # # # # # # # # # # # r l # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
31 # # # # # # # # # # # # # # # # # # # # # # # r l # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
32 # # # # # # # # # # # # # # # # # # # # # # # r l # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
40 # # # # # # # # # # # # # # # # # # # # # # # r l # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
41 # # # # # # # # # # # # # # # # # # # # # # # r l # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
42
43 16 28 id=HEBEL emitter_state=false debug=1
44 10 28 id=HEBEL emitter_state=false debug=2

View File

@ -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(';')

View File

@ -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]

View File

@ -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')

View File

@ -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')

View File

@ -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):

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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