pygame raycasting

在这里插入图片描述

for x in range(140):
        dis=0
        while True:
            angle= 0 - 30 + (x / width) * 60
            dis=dis+0.1
            #self.x = dis + math.cos(math.radians(self.xuanzhuanjiao)) * 90
            #self.y = dis - math.sin(math.radians(self.xuanzhuanjiao)) * 90
            zx=px+math.cos(math.radians(angle)) * dis
            zy=py - math.sin(math.radians(angle)) * dis
            #if zx//60<13 and zy//60<7:
            if q[int(zx//60)][int(zy//60)]==1 :

140条射线 dis是射线从玩家发射 击中墙计算距离 如果q列表代表墙 在q[zx/60][zy/60]意味着在墙列表中当前射线是否击中墙,为1代表是墙,0是空
集中后计算墙的高度,然后break退出这个循环,角度加1,进行下一条射线绘制在这里插入图片描述
for x in range(400):
ray_angle = camera_direction - 30 + (x / width) * 60
distance_to_wall = 0
while True:我想问的是在这个循环中 角度有没有改过

2024/5/19 17:24:59

在这个循环中,ray_angle 在每次迭代时是根据 camera_direction、固定的偏移量 -30 和 (x / width) * 60 计算得出的。所以在每次循环中,ray_angle 的值会改变。

具体来说,对于循环中的每个 x 值,都会计算一个新的 ray_angle 值,并将其用于后续的计算和处理。这意味着随着 x 的增加,ray_angle 的值也会相应地改变。

希望解答了你的问题。如果还有其他疑问,请随时提问。

2024/5/19 17:25:32

为什么是x/width

2024/5/19 17:25:39

在这个循环中, (x / width) 是用来计算当前射线的水平位置相对于整个屏幕的比例。它的取值范围是从0到1,表示射线在屏幕上的水平位置的百分比。

这个比例值乘以60,是为了将射线的角度范围限制在-30到30之间。通过这种方式,屏幕上的每个像素都对应一个射线角度。

假设我们有一个屏幕宽度为800个像素。当 x 的取值范围从0变化到799时, (x / width) 的取值范围就从0变化到0.99875。然后,乘以60的结果就会使得 ray_angle 的范围从-30变化到29.925。

这样做的目的是根据屏幕上的每个像素位置计算出对应的射线角度,从而能够实现墙体的投影效果。

希望解答了你的问题。如果还有其他疑问,请随时提问。

2024/5/19 17:27:35

那发射了多少条射线

2024/5/19 17:27:45

在上述代码中,使用了一个 for 循环来迭代 x 值从 0 到 399,即总共迭代了 400 次。所以,在这段代码中发射了 400 条射线。

每个 x 值对应一条射线,通过计算每条射线的角度和其他参数,可以绘制出相应的投影效果,并实现伪3D效果。

希望解答了你的问题。如果还有其他疑问,请随时提问。

import pygame
from pygame.locals import *
import sys
import math

pygame.init()

width, height = 900, 600
screen = pygame.display.set_mode((width, height))
c=pygame.time.Clock()
q = [
    [0, 0, 0, 0, 0, 0, 0, 1],#0 x坐标
    [0, 0, 0, 0, 0, 0, 0, 0],#1x坐标
    [0, 0, 0, 0, 0, 0, 0, 0],#2x坐标
    [0, 0, 0, 0, 0, 0, 0, 0],#3x坐标
    [0, 0, 0, 0, 0, 0, 0, 0],#4x坐标
    [0, 0, 0, 0, 0, 1, 0, 0],#5x坐标
    [0, 0, 0, 0, 0, 0, 0, 0],
    [1, 0, 0, 0, 0, 0, 0, 0],
    [1, 0, 0, 0, 0, 0, 0, 0],
    [1, 0, 0, 0, 0, 0, 0, 1],
    [1, 0, 0, 0, 0, 0, 0, 1],#上     下
    [1, 0, 0, 0, 0, 0, 0, 1],
    [1,1, 1, 1, 1, 1, 1, 1]#右
     ]

px=170
py=270
du=0
left=False
right=False
down=False
up=False
img = pygame.image.load("4.png")  # 替换为您自己的图像文件路径
img=pygame.transform.scale(img,(30,30))

xuanzhuanjiao=0
img=pygame.image.load("4.png").convert_alpha()
def player(x,y,zhuan):

    #pygame.draw.line(screen, (40, 140, 40), (x, y), (74, 713))
    #print(du)
    screen.blit(zhuan,(x,y))
while True:
    screen.fill((255, 255, 255))
    x = 0

    #c.tick(70)
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        keys = pygame.key.get_pressed()
        if keys[pygame.K_UP]:
            #print("up")
            py=py -10
        if keys[pygame.K_LEFT]:#zuo
            px=px-10
        if keys[pygame.K_DOWN]:#xia
            #print("up")
            py = py + 10
            #print(q[int(px//60)][int(py//60)],"0控 1强 角色格子",int(px//60),int(py//60))
        if keys[pygame.K_RIGHT]:#you
            #xuanzhuanjiao=xuanzhuanjiao+1
            px=px+10
            #print(q[int(px // 60)][int(py // 60)], "0控 1强 角色格子", int(px // 60), int(py // 60))
            #print(sz)
            #在这直接写会变成子弹,写成函数qiang(ci)就能画成一次,不会移动的墙
        if keys[pygame.K_a]:
            xuanzhuanjiao=xuanzhuanjiao+10

            right=True
        if event.type == pygame.KEYUP:
            right = False
        if keys[pygame.K_l]:
            xuanzhuanjiao=xuanzhuanjiao-10
        #if keys[pygame.K_SPACE]:


    for h in range(len(q)):#画墙
        #print(q[h],"行",h)
        for g in range(len(q[h])):
            if q[h][g]==1:
                #print(q[h][g],"个",g,h)
                pz=pygame.draw.rect(screen, (140, 240, 40), (0+h*60, 0+g*60, 60, 60))
                #qsz.append(pz)
    #player(px, py, img)
    for x in range(140):
        dis=0
        while True:
            angle= 0 - 30 + (x / width) * 60
            dis=dis+0.1
            #self.x = dis + math.cos(math.radians(self.xuanzhuanjiao)) * 90
            #self.y = dis - math.sin(math.radians(self.xuanzhuanjiao)) * 90
            zx=px+math.cos(math.radians(angle)) * dis
            zy=py - math.sin(math.radians(angle)) * dis
            #if zx//60<13 and zy//60<7:
            if q[int(zx//60)][int(zy//60)]==1 :
                max_wall_height = height   # 设置墙的最大高度为屏幕高度的2/3
                # 计算墙的高度,并确保不超过最大墙高
                wall_height = min(height / dis, max_wall_height)
                ceiling = (height - wall_height) // 2
                floor = height - ceiling
                tex_width = img.get_width()  # 纹理宽度不变
                #tex_x = int(test_x % 1 * tex_width)  # 使用固定纹理宽度来映射
                #pygame.draw.line(screen, (140, 40, 40), (x, int(ceiling)*1), (x, int(floor)*1))
                center = 300
                h1 = 64 / dis * 277
                gao = h1 / 2
                kai = center - gao
                en = center + h1
                pygame.draw.line(screen, (40, 40, 40), (px, py),
                                (zx ,zy))
                pygame.draw.line(screen, (140, 40, 40), (x, kai), (x, en))
                #print(dis)
                break

    pygame.display.flip()
Raycasting算法是一种用于计算二维或三维场景中可见性和光线投射的算法。它的基本思想是从视点发射一条射线,检测它是否与场景中的物体相交,如果相交,则确定相交点的位置和法向量,并计算出光线在该点的颜色值。这个过程可以通过递归或迭代来实现,直到达到某个终止条件为止。 在二维场景中,Raycasting算法通常用于实现2D游戏中的碰撞检测和可见性计算。在三维场景中,它可以用于实现3D游戏中的光线投射和阴影计算。 Raycasting算法的基本步骤如下: 1. 确定视点和视线方向。 2. 从视点发射一条射线。 3. 检测射线是否与场景中的物体相交。 4. 如果相交,则确定相交点的位置和法向量,并计算出光线在该点的颜色值。 5. 如果没有相交,则将颜色值设置为背景色。 6. 重复步骤2-5,直到所有像素都被处理完毕。 下面是一个简单的Python实现示例: ```python import pygame from pygame.locals import * # 初始化Pygame pygame.init() # 设置窗口大小和标题 screen_width = 640 screen_height = 480 screen = pygame.display.set_mode((screen_width, screen_height)) pygame.display.set_caption("Raycasting Demo") # 定义场景中的墙壁 walls = [ ((0, 0), (0, screen_height)), ((0, 0), (screen_width, 0)), ((screen_width, 0), (screen_width, screen_height)), ((0, screen_height), (screen_width, screen_height)), ((100, 100), (200, 100)), ((200, 100), (200, 200)), ((200, 200), (100, 200)), ((100, 200), (100, 100)) ] # 定义视点和视线方向 player_pos = (150, 150) player_angle = 0 # 定义射线的数量和角度间隔 num_rays = 60 ray_angle = 60 / num_rays # 主循环 while True: # 处理事件 for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() # 清空屏幕 screen.fill((255, 255, 255)) # 绘制场景中的墙壁 for wall in walls: pygame.draw.line(screen, (0, 0, 0), wall[0], wall[1], 2) # 发射射线并绘制结果 ray_angle = player_angle - 30 for i in range(num_rays): # 计算射线的方向向量 ray_dir = (math.cos(ray_angle), math.sin(ray_angle)) # 计算射线与场景中的墙壁的交点 min_dist = float("inf") for wall in walls: intersect = get_intersect(player_pos, ray_dir, wall) if intersect: dist = distance(player_pos, intersect) if dist < min_dist: min_dist = dist closest_intersect = intersect # 绘制射线 pygame.draw.line(screen, (255, 0, 0), player_pos, closest_intersect) # 计算射线的长度和颜色 ray_length = min_dist * math.cos(math.radians(ray_angle - player_angle)) shade = int(255 - ray_length * 10) if shade < 0: shade = 0 color = (shade, shade, shade) # 绘制射线的视觉效果 pygame.draw.rect(screen, color, (i * 10, screen_height - ray_length, 10, ray_length)) # 更新射线的角度 ray_angle += ray_angle # 更新视点的位置和角度 keys = pygame.key.get_pressed() if keys[K_LEFT]: player_angle -= 5 if keys[K_RIGHT]: player_angle += 5 if keys[K_UP]: player_pos = (player_pos[0] + math.cos(math.radians(player_angle)) * 5, player_pos[1] + math.sin(math.radians(player_angle)) * 5) if keys[K_DOWN]: player_pos = (player_pos[0] - math.cos(math.radians(player_angle)) * 5, player_pos[1] - math.sin(math.radians(player_angle)) * 5) # 绘制视点 pygame.draw.circle(screen, (0, 255, 0), player_pos, 5) # 更新屏幕 pygame.display.update() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值