Ninja-Jump-and-run/scripts/entities.py

114 lines
3.6 KiB
Python
Raw Normal View History

2026-02-06 17:51:57 +00:00
import pygame
2026-04-24 16:45:31 +00:00
from scripts.tilemap import Tilemap
2026-03-04 15:50:44 +00:00
2026-04-24 16:45:31 +00:00
class PhysicsEntity:
def __init__(self, game, e_type, pos: tuple, size):
2026-02-06 17:51:57 +00:00
self.game = game
self.e_type = e_type
self.pos = list(pos)
self.size = size
2026-04-24 16:45:31 +00:00
self.velocity = [0, 0]
self.collisions = {"top": False, "bottom": False, "left": False, "right": False}
2026-02-06 17:51:57 +00:00
self.speed = 3
2026-03-04 15:50:44 +00:00
# Animationen
self.action = ""
self.flip = False
self.animation_offset = (-3, -3)
2026-04-24 16:45:31 +00:00
self.set_action("idle")
def update(self, tilemap: 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],
)
2026-02-06 17:51:57 +00:00
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
2026-04-24 16:45:31 +00:00
2026-02-06 17:51:57 +00:00
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-04-24 16:45:31 +00:00
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
2026-04-24 16:45:31 +00:00
if self.collisions["bottom"] or self.collisions["top"]:
self.velocity[1] = 0
2026-02-06 17:51:57 +00:00
self.velocity[1] = min(5, self.velocity[1] + 0.1)
2026-03-04 15:50:44 +00:00
self.animation.update()
2026-04-24 16:45:31 +00:00
def render(self, surface: pygame.Surface, offset: tuple = (0, 0)):
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])
2026-04-24 16:45:31 +00:00
2026-03-04 15:50:44 +00:00
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
2026-04-24 16:45:31 +00:00
def update(self, tilemap, movement=(0, 0)):
2026-03-04 15:50:44 +00:00
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:
2026-04-24 16:45:31 +00:00
self.set_action("jump")
2026-03-04 15:50:44 +00:00
# Wenn wir nicht in der Luft sind, aber uns bewegen -> Rennen!
elif movement[0] != 0:
2026-04-24 16:45:31 +00:00
self.set_action("run")
2026-03-04 15:50:44 +00:00
# Sonst -> Rumstehen!
else:
2026-04-24 16:45:31 +00:00
self.set_action("idle")