diff --git a/game.py b/game.py index c9c7ef0..d07502d 100644 --- a/game.py +++ b/game.py @@ -30,15 +30,14 @@ class Game: self.player = Player(self, self.player_pos, width=self.player_width, height=self.player_height) - self.item_rect = pygame.Rect(60, 40, 10, 10) - - self.flashlight_rect = (self.player_pos, 50) + 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), @@ -51,115 +50,101 @@ class Game: def run(self) -> None: while self.running: - # Background - self.display.fill((0, 0, 0, 0)) + self.dt: float = self.clock.tick(60) / 1000.0 - # Event-Keys - for event in pygame.event.get(): - if event.type == pygame.QUIT: - self.running = False + self.update() + self.calculate_collsions() - if event.type == pygame.KEYDOWN: - if event.key == pygame.K_ESCAPE: - self.running = False + self.render() - if event.key == pygame.K_LSHIFT: - self.speed = 600 - - if event.type == pygame.KEYUP: - if event.key == pygame.K_LSHIFT: - self.speed = 300 - - # Player-Draw - # self.flashlight = pygame.draw.circle(self.display, (255, 255, 255, 0), self.flashlight_rect[0], self.flashlight_rect[1]) - - - - - - """RAYCASTING""" - ray_end = pygame.Vector2() - 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 - - - light_points.append(ray_end) - - - - - pygame.draw.polygon( - self.display, - (243, 255, 74), - light_points - ) - - pygame.draw.rect(self.display, self.color_item, self.item_rect) - - - - - for wall in self.walls: - pygame.draw.rect(self.display, "grey", wall) - - - self.player.update(walls=self.walls, dt=self.dt) - self.player.render(surface=self.display) - - # print(f"Player Pos: {self.player_pos}, Player Pos Before: {player_pos_before}") - - if self.rect_circle_collision(self.item_rect, self.flashlight_rect): - self.color_item = (0, 0, 255) - else: - self.color_item = (0, 0, 0) self.screen.blit( pygame.transform.scale(self.display, self.screen.get_size()) ) pygame.display.update() - self.dt = self.clock.tick(60) / 3000 - - 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 - '''Hausaufgabe - Player Klasse - nicht alles auf einmal kopieren''' + 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): @@ -169,7 +154,7 @@ class Player: self.player_width = width self.player_height = height - self.speed = 300 + self.speed = 150 self.rect = pygame.Rect(self.pos[0]-self.player_width/2, self.pos[1]-self.player_height/2, width, height) @@ -177,6 +162,7 @@ class Player: 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() @@ -188,9 +174,14 @@ class Player: if direction.length_squared() > 0: direction = direction.normalize() - movement = direction * self.speed * dt + movement: pygame.Vector2 = direction * self.speed * dt + + + + self.pos.x += movement.x + + # self.pos += movement - self.pos += movement # player_rect.center = round(player_pos) self.player_rect.centerx = round(self.pos.x) @@ -205,6 +196,16 @@ class Player: 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: @@ -217,20 +218,42 @@ class Player: 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 - self.pos[1] = max(self.pos[1], self.player_height/2) - - self.pos[1] = min(self.pos[1], SCREEN_HEIGHT/2-self.player_height/2) - - self.pos[0] = max(self.pos[0], self.player_width/2) - - self.pos[0] = min(self.pos[0], SCREEN_WIDTH/2-self.player_width/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 \ No newline at end of file