import pygame SCREEN_WIDTH = 1280 SCREEN_HEIGHT = 720 class Game: def __init__(self): pygame.init() 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 self.dt: int = 0 self.player_pos = pygame.Vector2(self.display.get_width() / 2, self.display.get_height() / 2) self.player_width = 20 self.player_height = 20 self.player = Player(self, self.player_pos, width=self.player_width, height=self.player_height) self.item_rect = pygame.Rect(70, 150, 10, 10) self.flashlight = 0 self.flashlight_rect = pygame.Rect(0, 0, 0, 0) self.color_item = (0, 0, 0) self.light_points: list[pygame.Vector2] = [] self.walls = [ pygame.Rect(100, 100, 20, 50), pygame.Rect(300, 300, 200, 20), pygame.Rect(550, 80, 20, 200) ] self.light_radius = 75 # self.circle = pygame.geometry.Circle(self.player_pos[0], self.player_pos[1], 30) def run(self) -> None: while self.running: self.dt: float = self.clock.tick(60) / 1000.0 self.update() self.calculate_collsions() self.render() self.screen.blit( pygame.transform.scale(self.display, self.screen.get_size()) ) pygame.display.update() def update(self) -> None: # Event-Keys for event in pygame.event.get(): if event.type == pygame.QUIT: self.running = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: self.running = False if event.key == pygame.K_LSHIFT: self.player.speed = 300 if event.type == pygame.KEYUP: if event.key == pygame.K_LSHIFT: self.player.speed = 150 self.player.update(walls=self.walls, dt=self.dt) def render(self) -> None: self.display.fill((0, 0, 0, 0)) """RAYCASTING""" ray_end = pygame.Vector2() self.light_points = [] vector = pygame.Vector2(self.light_radius, 0) # Lichtstrahlen berechnen for i in range(360): rotated_vector = vector.rotate(i) ray_end = self.player_pos + rotated_vector # Überschneidung mit den Wänden prüfen for wall in self.walls: überschneidung = wall.clipline(self.player_pos, ray_end) if überschneidung: schnittpunkt = pygame.Vector2(überschneidung[0]) ray_end = schnittpunkt self.light_points.append(ray_end) self.flashlight_rect = pygame.draw.polygon( self.display, (243, 255, 74), self.light_points ) self.player.render(surface=self.display) pygame.draw.rect(self.display, self.color_item, self.item_rect) for wall in self.walls: pygame.draw.rect(self.display, "grey", wall) 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) class Player: def __init__(self, game, pos: pygame.Vector2, width, height): self.game = game self.pos = pos self.player_width = width self.player_height = height self.speed = 150 self.rect = pygame.Rect(self.pos[0]-self.player_width/2, self.pos[1]-self.player_height/2, width, height) def update(self, walls, dt): self.player_rect = pygame.Rect(self.pos[0]-10, self.pos[1]-10, self.player_width, self.player_height) # 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() movement: pygame.Vector2 = direction * self.speed * dt self.pos.x += movement.x # self.pos += movement # player_rect.center = round(player_pos) self.player_rect.centerx = round(self.pos.x) for wall in walls: if self.player_rect.colliderect(wall): if movement.x > 0: self.player_rect.right = wall.left elif movement.x < 0: self.player_rect.left = wall.right self.pos.x = self.player_rect.centerx # if self.pos.x < self.player_rect.width/2 or self.pos.x + self.player_rect.width > SCREEN_WIDTH: # self.pos.x = old_position_x if self.pos.x - self.player_rect.width/2 < 0: self.pos.x = self.player_rect.width/2 if self.pos.x + self.player_rect.width/2 > SCREEN_WIDTH: self.pos.x = SCREEN_WIDTH - self.player_rect.width/2 self.pos.y += movement.y self.player_rect.centery = round(self.pos.y) for wall in walls: if self.player_rect.colliderect(wall): if movement.y > 0: self.player_rect.bottom = wall.top elif movement.y < 0: self.player_rect.top = wall.bottom self.pos.y = self.player_rect.centery if self.pos.y - self.player_rect.height/2 < 0: self.pos.y = self.player_rect.height/2 if self.pos.y + self.player_rect.height/2 > SCREEN_HEIGHT: self.pos.y = SCREEN_HEIGHT - self.player_rect.height/2 def render(self, surface): pygame.draw.rect(surface, (255, 0, 0), self.player_rect) game = Game() game.run() # 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