2026-08-26 16:35:06 +00:00
|
|
|
import pygame
|
|
|
|
|
|
2026-08-07 16:20:24 +00:00
|
|
|
SCREEN_WIDTH = 1280
|
|
|
|
|
SCREEN_HEIGHT = 720
|
2026-07-17 15:45:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class Game:
|
|
|
|
|
def __init__(self):
|
|
|
|
|
pygame.init()
|
2026-07-24 16:33:42 +00:00
|
|
|
|
2026-07-17 15:45:18 +00:00
|
|
|
pygame.display.set_caption("School Game")
|
|
|
|
|
|
|
|
|
|
self.clock = pygame.Clock()
|
|
|
|
|
self.screen: pygame.Surface = pygame.display.set_mode(
|
|
|
|
|
(SCREEN_WIDTH, SCREEN_HEIGHT)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
self.display: pygame.Surface = pygame.Surface(
|
|
|
|
|
(self.screen.get_width() // 2, self.screen.get_height() // 2)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.running: bool = True
|
|
|
|
|
|
2026-07-24 15:50:34 +00:00
|
|
|
self.dt: int = 0
|
2026-07-17 15:45:18 +00:00
|
|
|
|
2026-07-24 15:50:34 +00:00
|
|
|
self.player_pos = pygame.Vector2(self.display.get_width() / 2, self.display.get_height() / 2)
|
2026-09-08 13:27:52 +00:00
|
|
|
self.player_width = 20
|
|
|
|
|
self.player_height = 20
|
|
|
|
|
|
|
|
|
|
self.player = Player(self, self.player_pos, width=self.player_width, height=self.player_height)
|
2026-07-17 15:45:18 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
self.item_rect = pygame.Rect(70, 150, 10, 10)
|
2026-08-06 09:38:54 +00:00
|
|
|
|
2026-07-24 16:33:42 +00:00
|
|
|
self.flashlight = 0
|
2026-09-18 15:29:30 +00:00
|
|
|
self.flashlight_rect = pygame.Rect(0, 0, 0, 0)
|
2026-07-24 16:33:42 +00:00
|
|
|
|
|
|
|
|
self.color_item = (0, 0, 0)
|
|
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
self.light_points: list[pygame.Vector2] = []
|
2026-08-07 16:36:14 +00:00
|
|
|
|
2026-08-19 16:27:21 +00:00
|
|
|
self.walls = [
|
2026-08-27 18:52:03 +00:00
|
|
|
pygame.Rect(100, 100, 20, 50),
|
|
|
|
|
pygame.Rect(300, 300, 200, 20),
|
|
|
|
|
pygame.Rect(550, 80, 20, 200)
|
2026-08-19 16:27:21 +00:00
|
|
|
]
|
2026-08-28 16:46:44 +00:00
|
|
|
self.light_radius = 75
|
2026-08-19 16:27:21 +00:00
|
|
|
|
|
|
|
|
# self.circle = pygame.geometry.Circle(self.player_pos[0], self.player_pos[1], 30)
|
2026-07-24 16:33:42 +00:00
|
|
|
|
2026-07-17 15:45:18 +00:00
|
|
|
def run(self) -> None:
|
|
|
|
|
while self.running:
|
2026-09-18 15:29:30 +00:00
|
|
|
self.dt: float = self.clock.tick(60) / 1000.0
|
2026-07-24 16:33:42 +00:00
|
|
|
|
|
|
|
|
|
2026-07-17 15:45:18 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
self.update()
|
|
|
|
|
self.calculate_collsions()
|
2026-08-07 16:20:24 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
self.render()
|
2026-08-07 16:20:24 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
|
|
|
|
|
self.screen.blit(
|
|
|
|
|
pygame.transform.scale(self.display, self.screen.get_size())
|
|
|
|
|
)
|
2026-08-26 16:35:06 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
pygame.display.update()
|
2026-08-26 16:35:06 +00:00
|
|
|
|
2026-08-28 16:46:44 +00:00
|
|
|
|
|
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
def update(self) -> None:
|
|
|
|
|
# Event-Keys
|
|
|
|
|
for event in pygame.event.get():
|
|
|
|
|
if event.type == pygame.QUIT:
|
|
|
|
|
self.running = False
|
2026-08-28 16:46:44 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
if event.type == pygame.KEYDOWN:
|
|
|
|
|
if event.key == pygame.K_ESCAPE:
|
|
|
|
|
self.running = False
|
2026-08-26 16:35:06 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
if event.key == pygame.K_LSHIFT:
|
|
|
|
|
self.player.speed = 300
|
2026-08-19 16:27:21 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
if event.type == pygame.KEYUP:
|
|
|
|
|
if event.key == pygame.K_LSHIFT:
|
|
|
|
|
self.player.speed = 150
|
2026-08-28 16:46:44 +00:00
|
|
|
|
2026-08-26 16:35:06 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
self.player.update(walls=self.walls, dt=self.dt)
|
2026-08-19 16:27:21 +00:00
|
|
|
|
|
|
|
|
|
2026-08-26 16:35:06 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
def render(self) -> None:
|
2026-08-26 16:35:06 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
self.display.fill((0, 0, 0, 0))
|
2026-08-26 16:35:06 +00:00
|
|
|
|
|
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
"""RAYCASTING"""
|
|
|
|
|
ray_end = pygame.Vector2()
|
|
|
|
|
self.light_points = []
|
|
|
|
|
vector = pygame.Vector2(self.light_radius, 0)
|
2026-08-26 16:35:06 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
# Lichtstrahlen berechnen
|
|
|
|
|
for i in range(360):
|
2026-08-26 16:35:06 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
rotated_vector = vector.rotate(i)
|
|
|
|
|
ray_end = self.player_pos + rotated_vector
|
2026-07-17 15:45:18 +00:00
|
|
|
|
2026-07-24 16:33:42 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
# Überschneidung mit den Wänden prüfen
|
|
|
|
|
for wall in self.walls:
|
|
|
|
|
überschneidung = wall.clipline(self.player_pos, ray_end)
|
2026-07-24 15:59:36 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
if überschneidung:
|
|
|
|
|
schnittpunkt = pygame.Vector2(überschneidung[0])
|
2026-08-19 16:27:21 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
ray_end = schnittpunkt
|
2026-08-19 16:27:21 +00:00
|
|
|
|
2026-08-28 16:46:44 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
self.light_points.append(ray_end)
|
2026-08-07 16:36:14 +00:00
|
|
|
|
2026-08-06 09:38:54 +00:00
|
|
|
|
2026-07-17 15:45:18 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
self.flashlight_rect = pygame.draw.polygon(
|
|
|
|
|
self.display,
|
|
|
|
|
(243, 255, 74),
|
|
|
|
|
self.light_points
|
|
|
|
|
)
|
2026-08-06 09:38:54 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
self.player.render(surface=self.display)
|
2026-08-06 09:38:54 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
pygame.draw.rect(self.display, self.color_item, self.item_rect)
|
2026-08-06 09:38:54 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
for wall in self.walls:
|
|
|
|
|
pygame.draw.rect(self.display, "grey", wall)
|
2026-09-18 16:06:44 +00:00
|
|
|
|
2026-07-17 15:45:18 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
def calculate_collsions(self) -> None:
|
|
|
|
|
if self.item_rect.colliderect(self.flashlight_rect):
|
|
|
|
|
self.color_item = (0, 0, 255)
|
|
|
|
|
# print("HIII")
|
|
|
|
|
else:
|
|
|
|
|
self.color_item = (0, 0, 0)
|
2026-09-08 13:27:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class Player:
|
|
|
|
|
def __init__(self, game, pos: pygame.Vector2, width, height):
|
|
|
|
|
self.game = game
|
|
|
|
|
self.pos = pos
|
|
|
|
|
|
2026-09-18 16:06:44 +00:00
|
|
|
self.width = width
|
|
|
|
|
self.height = height
|
2026-09-08 13:27:52 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
self.speed = 150
|
2026-09-08 13:27:52 +00:00
|
|
|
|
2026-09-18 16:06:44 +00:00
|
|
|
self.rect = pygame.Rect(self.pos[0]-self.width/2, self.pos[1]-self.height/2, width, height)
|
2026-09-08 13:27:52 +00:00
|
|
|
|
|
|
|
|
def update(self, walls, dt):
|
|
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
|
2026-09-08 13:27:52 +00:00
|
|
|
# Smooth Movement
|
|
|
|
|
keys = pygame.key.get_pressed()
|
|
|
|
|
|
|
|
|
|
direction = pygame.Vector2(
|
|
|
|
|
keys[pygame.K_d] - keys[pygame.K_a],
|
|
|
|
|
keys[pygame.K_s] - keys[pygame.K_w]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if direction.length_squared() > 0:
|
|
|
|
|
direction = direction.normalize()
|
|
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
movement: pygame.Vector2 = direction * self.speed * dt
|
|
|
|
|
|
|
|
|
|
|
2026-09-18 16:37:17 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
self.pos.x += movement.x
|
|
|
|
|
|
2026-09-18 16:37:17 +00:00
|
|
|
if self.pos.x - self.width/2 < 0:
|
|
|
|
|
self.pos.x = self.width/2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if self.pos.x + self.width/2 > SCREEN_WIDTH/2:
|
|
|
|
|
self.pos.x = SCREEN_WIDTH/2 - self.width/2
|
2026-09-18 15:29:30 +00:00
|
|
|
# self.pos += movement
|
2026-09-08 13:27:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
# player_rect.center = round(player_pos)
|
2026-09-18 16:06:44 +00:00
|
|
|
self.rect.centerx = round(self.pos.x)
|
2026-09-08 13:27:52 +00:00
|
|
|
|
|
|
|
|
for wall in walls:
|
2026-09-18 16:06:44 +00:00
|
|
|
if self.rect.colliderect(wall):
|
2026-09-08 13:27:52 +00:00
|
|
|
if movement.x > 0:
|
2026-09-18 16:06:44 +00:00
|
|
|
self.rect.right = wall.left
|
2026-09-08 13:27:52 +00:00
|
|
|
|
|
|
|
|
elif movement.x < 0:
|
2026-09-18 16:06:44 +00:00
|
|
|
self.rect.left = wall.right
|
2026-09-08 13:27:52 +00:00
|
|
|
|
2026-09-18 16:06:44 +00:00
|
|
|
self.pos.x = self.rect.centerx
|
2026-09-08 13:27:52 +00:00
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
self.pos.y += movement.y
|
|
|
|
|
|
2026-09-18 16:37:17 +00:00
|
|
|
if self.pos.y - self.height/2 < 0:
|
|
|
|
|
self.pos.y = self.height/2
|
|
|
|
|
|
|
|
|
|
if self.pos.y + self.height/2 > SCREEN_HEIGHT/2:
|
|
|
|
|
self.pos.y = SCREEN_HEIGHT/2 - self.height/2
|
|
|
|
|
|
2026-09-18 16:06:44 +00:00
|
|
|
self.rect.centery = round(self.pos.y)
|
2026-09-08 13:27:52 +00:00
|
|
|
|
|
|
|
|
for wall in walls:
|
2026-09-18 16:06:44 +00:00
|
|
|
if self.rect.colliderect(wall):
|
2026-09-08 13:27:52 +00:00
|
|
|
if movement.y > 0:
|
2026-09-18 16:06:44 +00:00
|
|
|
self.rect.bottom = wall.top
|
2026-09-08 13:27:52 +00:00
|
|
|
|
|
|
|
|
elif movement.y < 0:
|
2026-09-18 16:06:44 +00:00
|
|
|
self.rect.top = wall.bottom
|
2026-09-08 13:27:52 +00:00
|
|
|
|
2026-09-18 16:06:44 +00:00
|
|
|
self.pos.y = self.rect.centery
|
2026-09-08 13:27:52 +00:00
|
|
|
|
|
|
|
|
|
2026-09-18 16:37:17 +00:00
|
|
|
|
2026-09-08 13:27:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def render(self, surface):
|
|
|
|
|
|
2026-09-18 16:06:44 +00:00
|
|
|
pygame.draw.rect(surface, (255, 0, 0), self.rect)
|
2026-09-08 13:27:52 +00:00
|
|
|
|
|
|
|
|
|
2026-09-18 15:29:30 +00:00
|
|
|
|
|
|
|
|
|
2026-07-17 15:45:18 +00:00
|
|
|
game = Game()
|
2026-07-24 15:50:34 +00:00
|
|
|
game.run()
|
2026-09-18 15:29:30 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# def rect_circle_collision(self, rect, circle):
|
|
|
|
|
# rect_x, rect_y, rect_w, rect_h = rect
|
|
|
|
|
|
|
|
|
|
# circle_x = circle[0][0]
|
|
|
|
|
# circle_y = circle[0][1]
|
|
|
|
|
# circle_r = circle[1]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# # Calculate the closest point on the rectangle to the center of the circle
|
|
|
|
|
# closest_x = max(rect_x, min(circle_x, rect_x + rect_w))
|
|
|
|
|
# closest_y = max(rect_y, min(circle_y, rect_y + rect_h))
|
|
|
|
|
|
|
|
|
|
# # Calculate the distance between the center of the circle and the closest point on the rectangle
|
|
|
|
|
# dx = circle_x - closest_x
|
|
|
|
|
# dy = circle_y - closest_y
|
|
|
|
|
# distance = (dx ** 2 + dy ** 2) ** 0.5
|
|
|
|
|
|
|
|
|
|
# return distance <= circle_r
|