Commit
This commit is contained in:
parent
bbac5c4fc7
commit
6c535d3073
1 changed files with 132 additions and 109 deletions
241
game.py
241
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
|
||||
Loading…
Reference in a new issue