First cut at a replica of the python raycaster. Left side almost works the same but have to sort out math differences.
This commit is contained in:
parent
6b181382bd
commit
ca80736d7c
21 changed files with 2165 additions and 90 deletions
126
pycaster.py
Normal file
126
pycaster.py
Normal file
|
@ -0,0 +1,126 @@
|
|||
import pygame
|
||||
import sys
|
||||
import math
|
||||
|
||||
SCREEN_HEIGHT=480
|
||||
SCREEN_WIDTH=SCREEN_HEIGHT * 2
|
||||
MAP_SIZE=8
|
||||
TILE_SIZE=int((SCREEN_WIDTH / 2) / MAP_SIZE)
|
||||
FOV=math.pi / 3
|
||||
HALF_FOV = FOV / 2
|
||||
CASTED_RAYS=30
|
||||
STEP_ANGLE = FOV / CASTED_RAYS
|
||||
MAX_DEPTH = int(MAP_SIZE * TILE_SIZE)
|
||||
SCALE = (SCREEN_WIDTH / 2) / CASTED_RAYS
|
||||
|
||||
|
||||
player_x = (SCREEN_WIDTH/2)/2
|
||||
player_y = (SCREEN_WIDTH/2)/2
|
||||
player_angle = math.pi
|
||||
|
||||
MAP = ('########'
|
||||
'# # #'
|
||||
'# # ###'
|
||||
'# #'
|
||||
'## #'
|
||||
'# ### #'
|
||||
'# # #'
|
||||
'########')
|
||||
|
||||
pygame.init()
|
||||
win = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
|
||||
pygame.display.set_caption("Ray-Casting")
|
||||
clock = pygame.time.Clock()
|
||||
|
||||
def draw_map():
|
||||
light_grey = (191, 191, 191)
|
||||
dark_grey = (65,65,65)
|
||||
|
||||
for i in range(MAP_SIZE):
|
||||
for j in range(MAP_SIZE):
|
||||
square = i * MAP_SIZE + j
|
||||
|
||||
pygame.draw.rect(win,
|
||||
light_grey if MAP[square] == '#' else dark_grey,
|
||||
(j * TILE_SIZE, i * TILE_SIZE, TILE_SIZE -1, TILE_SIZE - 1))
|
||||
|
||||
def ray_casting():
|
||||
# left angle of FOV
|
||||
start_angle = player_angle - HALF_FOV
|
||||
|
||||
for ray in range(CASTED_RAYS):
|
||||
for depth in range(1,MAX_DEPTH):
|
||||
target_x = player_x - math.sin(start_angle) * depth
|
||||
target_y = player_y + math.cos(start_angle) * depth
|
||||
col = int(target_x / TILE_SIZE)
|
||||
row = int(target_y / TILE_SIZE)
|
||||
square = row * MAP_SIZE + col
|
||||
|
||||
if MAP[square] == '#':
|
||||
pygame.draw.rect(win,
|
||||
(195, 137, 38),
|
||||
(col * TILE_SIZE,
|
||||
row * TILE_SIZE,
|
||||
TILE_SIZE -1, TILE_SIZE-1))
|
||||
|
||||
pygame.draw.line(win, (233, 166, 49),
|
||||
(player_x, player_y),
|
||||
(target_x, target_y))
|
||||
|
||||
# wall shading
|
||||
color = 255 / (1 + depth * depth * 0.0001)
|
||||
|
||||
# fix fish eye effect
|
||||
depth *= math.cos(player_angle - start_angle)
|
||||
|
||||
# calculate wall height
|
||||
wall_height = 21000 / (depth)
|
||||
|
||||
if wall_height > SCREEN_HEIGHT:
|
||||
wall_height = SCREEN_HEIGHT
|
||||
|
||||
pygame.draw.rect(win,
|
||||
(color, color, color),
|
||||
(SCREEN_HEIGHT + ray * SCALE,
|
||||
(SCREEN_HEIGHT / 2) - wall_height/2,
|
||||
SCALE, wall_height))
|
||||
|
||||
break
|
||||
|
||||
start_angle += STEP_ANGLE
|
||||
|
||||
while True:
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
pygame.quit()
|
||||
sys.exit(0)
|
||||
|
||||
# update 2d background
|
||||
pygame.draw.rect(win, (0,0,0), (0, 0, SCREEN_HEIGHT, SCREEN_HEIGHT))
|
||||
|
||||
# update 3d background
|
||||
pygame.draw.rect(win, (100, 100, 100), (480, SCREEN_HEIGHT / 2, SCREEN_HEIGHT, SCREEN_HEIGHT))
|
||||
pygame.draw.rect(win, (200, 200, 200), (480, -SCREEN_HEIGHT / 2, SCREEN_HEIGHT, SCREEN_HEIGHT))
|
||||
|
||||
draw_map()
|
||||
ray_casting()
|
||||
|
||||
keys = pygame.key.get_pressed()
|
||||
if keys[pygame.K_LEFT]:
|
||||
# working with radians, not degrees
|
||||
player_angle -= 0.1
|
||||
elif keys[pygame.K_RIGHT]:
|
||||
player_angle += 0.1
|
||||
elif keys[pygame.K_UP]:
|
||||
forward = True
|
||||
player_x += -1 * math.sin(player_angle) * 5
|
||||
player_y += math.cos(player_angle) * 5
|
||||
elif keys[pygame.K_DOWN]:
|
||||
forward = False
|
||||
player_x -= -1 * math.sin(player_angle) * 5
|
||||
player_y -= math.cos(player_angle) * 5
|
||||
|
||||
# update the display
|
||||
pygame.display.flip()
|
||||
|
||||
clock.tick(30)
|
Loading…
Add table
Add a link
Reference in a new issue