2026-02-06 17:51:57 +00:00
|
|
|
import pygame
|
|
|
|
|
class PhysicsEntity:
|
2026-03-04 15:50:44 +00:00
|
|
|
|
2026-02-06 17:51:57 +00:00
|
|
|
def __init__(self, game, e_type, pos:tuple, size):
|
|
|
|
|
self.game = game
|
|
|
|
|
self.e_type = e_type
|
|
|
|
|
self.pos = list(pos)
|
|
|
|
|
self.size = size
|
|
|
|
|
self.velocity = [0,0]
|
|
|
|
|
self.collisions = {"top":False, "bottom":False, "left":False, "right":False}
|
|
|
|
|
self.speed = 3
|
2026-03-04 15:50:44 +00:00
|
|
|
|
|
|
|
|
# Animationen
|
|
|
|
|
self.action = ""
|
|
|
|
|
self.flip = False
|
|
|
|
|
self.animation_offset = (-3, -3)
|
|
|
|
|
self.set_action('idle')
|
|
|
|
|
|
2026-02-06 17:51:57 +00:00
|
|
|
def update(self, tilemap, movement:tuple=(0,0)):
|
|
|
|
|
self.collisions = {"top":False, "bottom":False, "left":False, "right":False}
|
|
|
|
|
frame_movement = ((movement[0] + self.velocity[0])*self.speed, movement[1] + self.velocity[1])
|
|
|
|
|
self.pos[0] += frame_movement[0]
|
|
|
|
|
|
|
|
|
|
entity_rect = self.rect()
|
|
|
|
|
for recto in tilemap.physics_rects_around(self.pos):
|
|
|
|
|
if entity_rect.colliderect(recto):
|
|
|
|
|
if frame_movement[0] > 0:
|
|
|
|
|
entity_rect.right = recto.left
|
|
|
|
|
self.collisions["right"] = True
|
|
|
|
|
self.game.isJumping = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if frame_movement[0] < 0:
|
|
|
|
|
entity_rect.left = recto.right
|
|
|
|
|
self.collisions["left"] = True
|
|
|
|
|
self.game.isJumping = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.pos[0] = entity_rect.x
|
|
|
|
|
|
|
|
|
|
self.pos[1] += frame_movement[1]
|
|
|
|
|
entity_rect = self.rect()
|
|
|
|
|
|
|
|
|
|
for rectolino in tilemap.physics_rects_around(self.pos):
|
|
|
|
|
if entity_rect.colliderect(rectolino):
|
|
|
|
|
|
|
|
|
|
if frame_movement[1] > 0:
|
|
|
|
|
entity_rect.bottom = rectolino.top
|
|
|
|
|
self.collisions["bottom"] = True
|
|
|
|
|
self.game.isJumping = False
|
|
|
|
|
|
|
|
|
|
if frame_movement[1] < 0:
|
|
|
|
|
entity_rect.top = rectolino.bottom
|
|
|
|
|
self.collisions["top"] = True
|
|
|
|
|
|
|
|
|
|
self.pos[1] = entity_rect.y
|
|
|
|
|
|
2026-03-04 15:50:44 +00:00
|
|
|
if movement[0] > 0:
|
|
|
|
|
self.flip = False
|
|
|
|
|
if movement[0] < 0:
|
|
|
|
|
self.flip = True
|
|
|
|
|
|
2026-02-06 17:51:57 +00:00
|
|
|
if self.collisions['bottom'] or self.collisions['top']:
|
|
|
|
|
self.velocity[1] = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.velocity[1] = min(5, self.velocity[1] + 0.1)
|
|
|
|
|
|
2026-03-04 15:50:44 +00:00
|
|
|
self.animation.update()
|
2026-02-06 17:51:57 +00:00
|
|
|
def render(self, surface:pygame.Surface, offset:tuple=(0,0)):
|
2026-03-04 15:50:44 +00:00
|
|
|
surface.blit(pygame.transform.flip(self.animation.img(), self.flip, False), (self.pos[0] - offset[0] + self.animation_offset[0],self.pos[1] - offset[1] + self.animation_offset[1]))
|
|
|
|
|
|
2026-02-06 17:51:57 +00:00
|
|
|
|
|
|
|
|
def rect(self):
|
2026-03-04 15:50:44 +00:00
|
|
|
return pygame.Rect(self.pos[0], self.pos[1], self.size[0], self.size[1])
|
|
|
|
|
|
|
|
|
|
def set_action(self, action):
|
|
|
|
|
if action != self.action:
|
|
|
|
|
self.action = action
|
|
|
|
|
image = self.e_type + "/" + self.action
|
|
|
|
|
self.animation = self.game.assets[image].copy()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Player(PhysicsEntity):
|
|
|
|
|
def __init__(self, game, pos, size):
|
|
|
|
|
super().__init__(game, "player", pos, size)
|
|
|
|
|
self.air_time = 0 # Neu! Zählt, wie lange wir fallen/springe
|
|
|
|
|
|
|
|
|
|
def update(self, tilemap, movement = (0, 0)):
|
|
|
|
|
super().update(tilemap, movement)
|
|
|
|
|
|
|
|
|
|
self.air_time += 1
|
|
|
|
|
|
|
|
|
|
if self.collisions["bottom"]:
|
|
|
|
|
self.air_time = 0
|
|
|
|
|
# Wenn wir länger als 4 Frames in der Luft sind -> Springen!
|
|
|
|
|
if self.air_time > 4:
|
|
|
|
|
self.set_action('jump')
|
|
|
|
|
|
|
|
|
|
# Wenn wir nicht in der Luft sind, aber uns bewegen -> Rennen!
|
|
|
|
|
elif movement[0] != 0:
|
|
|
|
|
self.set_action('run')
|
|
|
|
|
|
|
|
|
|
# Sonst -> Rumstehen!
|
|
|
|
|
else:
|
|
|
|
|
self.set_action('idle')
|
|
|
|
|
|