Как исправить механизм коллизий с помощью raycast 3D в Pygame?Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Как исправить механизм коллизий с помощью raycast 3D в Pygame?

Сообщение Anonymous »

Код: Выделить всё

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]
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • SVG рендеринг в приложении Pygame. До Pygame 2.0 Pygame не поддерживал SVG. Тогда как вы его загрузили?
    Anonymous » » в форуме Python
    0 Ответы
    4 Просмотры
    Последнее сообщение Anonymous
  • React Fiber Это механизм рендеринга или механизм согласования в рамках рендеринга?
    Anonymous » » в форуме Javascript
    0 Ответы
    28 Просмотры
    Последнее сообщение Anonymous
  • Обнаружение дубликатов двоичного дерева поиска и устранение коллизий
    Anonymous » » в форуме C++
    0 Ответы
    65 Просмотры
    Последнее сообщение Anonymous
  • Reality Kit автоматически генерирует рамку коллизий, появляющуюся под моделью.
    Anonymous » » в форуме IOS
    0 Ответы
    31 Просмотры
    Последнее сообщение Anonymous
  • Почему возникает проблема с подсчетом коллизий Unity?
    Anonymous » » в форуме C#
    0 Ответы
    15 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Python»