Reputation: 171
here's my code, ignore unused stuff and its overal messiness
import sys, pygame, time, math
pygame.init()
size = width, height = 640, 640
black = 0, 0, 0
screen = pygame.display.set_mode(size)
ball = pygame.image.load("ball.png")
map = pygame.image.load("map.png")
ballrect = ball.get_rect()
ballrect.x = 262
ballrect.y = 582
direction = math.pi
FOV = math.pi / 3
HALF_FOV = FOV / 2
CASTED_ARRAYS = 640
STEP_ANGLE = FOV / CASTED_ARRAYS
MAX_DEPTH = 640
def cast_rays():
start_angle = direction - HALF_FOV
for ray in range(CASTED_ARRAYS):
for depth in range(MAX_DEPTH):
target_x = (ballrect.centerx) - math.sin(start_angle) * depth
target_y = (ballrect.centery) + math.cos(start_angle) * depth
if screen.get_at((int(target_x), int(target_y))) == (223, 113, 38):
pygame.draw.line(screen, (0, 255, 255), (ballrect.centerx, ballrect.centery),
(target_x, target_y))
break
start_angle += STEP_ANGLE
while 1:
screen.blit(map, (0, 0))
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
direction -= 0.1
if keys[pygame.K_RIGHT]:
direction += 0.1
if keys[pygame.K_UP]:
ballrect.centerx += -math.sin(direction) * 5
ballrect.centery += math.cos(direction) * 5
if keys[pygame.K_DOWN]:
ballrect.centerx -= -math.sin(direction) * 5
ballrect.centery -= math.cos(direction) * 5
time.sleep(0.01)
screen.blit(ball, ballrect)
cast_rays()
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
so far, it's behaving this way:
it works, but it doesn't. i've tinkered the numbers, sometimes it gets better adding to the x, to the y, but it doesn't work completely. If you guys wanna try on your computer, here are the files needed for:
(it's tiny) so, what's going on?
Upvotes: 2
Views: 373
Reputation: 210889
You need to read the color of the map instead of the color of the screen. You draw the lines on the screen, each line "cuts a small piece of the wall:
if screen.get_at((int(target_x), int(target_y))) == (223, 113, 38):
if map.get_at((int(target_x), int(target_y))) == (223, 113, 38):
Alternatively you can draw the lines after casting the rays:
def cast_rays():
targets = []
for ray in range(CASTED_ARRAYS):
angle = direction - HALF_FOV + ray * STEP_ANGLE
s, c = math.sin(angle), math.cos(angle)
for depth in range(MAX_DEPTH):
target = (round(ballrect.centerx - s * depth), round(ballrect.centery + c * depth))
if screen.get_at(target) == (223, 113, 38):
targets.append(target)
break
start = (ballrect.centerx, ballrect.centery)
for target in targets:
pygame.draw.line(screen, (0, 255, 255), start, target)
Upvotes: 1