Код: Выделить всё
import pygame
import math
import numpy as np
from pygame.locals import *
import game_map
# Define color
B_RED = (125, 22, 22)
M_RED = (107, 19, 16)
L_RED = (69, 15, 16)
BLACK = (5, 5, 10)
WHITE = (255,255,255)
GRAY = (25,25,25)
# Define the world map
world_map = game_map.world_map # World map is from another python file
def close():
""" Close the application """
pygame.display.quit()
pygame.quit()
return
clock = pygame.time.Clock()
def main():
""" Main function to run the game """
pygame.init()
# Display information
WIDTH = 1400
HEIGHT = 800
window = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Autophobia")
# Initialize player position and direction
position_x = 5 # Initial X position
position_y = 8 # Initial Y position
direction_x = 1 # Initial direction X
direction_y = 0 # Initial direction Y
plane_x = 0 # Camera plane X
plane_y = 0.66 # Camera plane Y (for FOV)
# Define movement and rotation speeds
move_speed = 0.1
rotation_speed = 0.05
## Main loop of the program
while True:
# Check the key if the player is quitting or not
for event in pygame.event.get():
if event.type == QUIT:
close()
# Key binding
keys = pygame.key.get_pressed()
if keys[K_ESCAPE]:
close()
if keys[K_UP]:
position_x += direction_x * move_speed
position_y += direction_y * move_speed
if keys[K_DOWN]:
position_x -= direction_x * move_speed
position_y -= direction_y * move_speed
if keys[K_RIGHT]:
# Rotate RIGHT
old_dir_x = direction_x
direction_x = direction_x * math.cos(rotation_speed) - direction_y * math.sin(rotation_speed)
direction_y = old_dir_x * math.sin(rotation_speed) + direction_y * math.cos(rotation_speed)
# Rotate plane
old_plane_x = plane_x
plane_x = plane_x * math.cos(rotation_speed) - plane_y * math.sin(rotation_speed)
plane_y = old_plane_x * math.sin(rotation_speed) + plane_y * math.cos(rotation_speed)
if keys[K_LEFT]:
# Rotate LEFT
old_dir_x = direction_x
direction_x = direction_x * math.cos(-rotation_speed) - direction_y * math.sin(-rotation_speed)
direction_y = old_dir_x * math.sin(-rotation_speed) + direction_y * math.cos(-rotation_speed)
# Rotate plane
old_plane_x = plane_x
plane_x = plane_x * math.cos(-rotation_speed) - plane_y * math.sin(-rotation_speed)
plane_y = old_plane_x * math.sin(-rotation_speed) + plane_y * math.cos(-rotation_speed)
# Raycasting Logic
window.fill((25, 25, 25)) # Clear the screen
pygame.draw.rect(window, (50,50,50), (0, HEIGHT/2, WIDTH, HEIGHT/2)) # Draw floor
# Calculate ray direction for each column
for columns in range(WIDTH):
camera_x = 2.0 * columns / WIDTH - 1.0
ray_pos_x = position_x
ray_pos_y = position_y
ray_dir_x = direction_x + plane_x * (2 * columns / WIDTH - 1) + 0.000001 # To avoid division by 0
ray_dir_y = direction_y + plane_y * (2 * columns / WIDTH - 1) + 0.000001
map_x = int(ray_pos_x)
map_y = int(ray_pos_y)
# Delta distance
delta_dis_x = math.sqrt(1 + (ray_dir_y / ray_dir_x) ** 2)
delta_dis_y = math.sqrt(1 + (ray_dir_x / ray_dir_y) ** 2)
# Step and initial side distance
step_x, step_y = 0, 0
side_dis_x, side_dis_y = 0.0, 0.0
# Initialize side
if ray_dir_x < 0:
step_x = -1
side_dis_x = (ray_pos_x - map_x) * delta_dis_x
else:
step_x = 1
side_dis_x = (map_x + 1.0 - ray_pos_x) * delta_dis_x
if ray_dir_y < 0:
step_y = -1
side_dis_y = (ray_pos_y - map_y) * delta_dis_y
else:
step_y = 1
side_dis_y = (map_y + 1.0 - ray_pos_y) * delta_dis_y
# Perform DDA
hit = 0
while (hit == 0):
if side_dis_x < side_dis_y:
side_dis_x += delta_dis_x
map_x += step_x
side = 0 # X-axis hit
else:
side_dis_y += delta_dis_y
map_y += step_y
side = 1 # Y-axis hit
if (world_map[map_x][map_y]) > 0:
hit = 1
# Correction of the POV
if side == 0:
perp_wall_dist = abs((map_x - ray_pos_x + (1 - step_x) / 2) / ray_dir_x)
else:
perp_wall_dist = abs((map_y - ray_pos_y + (1 - step_y) / 2) / ray_dir_y)
# Calculate the height of the wall
line_height = int(HEIGHT / (perp_wall_dist + 0.00001))
# Calculate the draw start and end
draw_start = -line_height / 2 + HEIGHT / 2
if draw_start < 0:
draw_start = 0
draw_end = line_height / 2 + HEIGHT / 2
if draw_end >= HEIGHT:
draw_end = HEIGHT - 1
# Choose the color based on the map value
if 0
Подробнее здесь: [url]https://stackoverflow.com/questions/79036888/how-do-i-fix-the-collision-mechanism-using-raycast-3d-in-pygame[/url]