pygame raycasting纹理

在这里插入图片描述
在这里插入图片描述
插值原理
原理
在这里插入图片描述
在这里插入图片描述
color(x)=(x-x1)/(x2-x1)(color2-color1)+color1 x1<x<x2
假如说x伪3 那么color=(3-x1)/(x2-x1)
(color2-color1)+color
在这里插入图片描述

可是图片纹理 这里不需要两种颜色,只需要获得碰撞点坐标后,如果是水平位置的墙,绿色方块,获取碰撞点x就是纹理的x坐标,也就是uv坐标中的u坐标,v坐标需要计算上面提到的差值,纹理是64X64像素,高度是64,。
这里先看下绘制投影墙是怎么做到的

center = 300
				h1 = 64 / dis * 277
                gao = h1 / 2
                kai = center - gao
                en = center + h1
pygame.draw.line(screen, (55,40,140), (x + 100, kai), (x + 100, en))

在这里插入图片描述
计算每一列的高度后,定义从哪里是墙的中间点center,gao是一列的一半,加减gao计算每一列墙的起点与结束点这一列墙其实就是一条线,多条线绘制成投影墙。1起点是kai,结束点是en
碰撞点变量zx,zy
u=zx%64 这里%纹理宽度是为了不超出纹理大小

在这里插入图片描述
在这里插入图片描述
上面图片说明了我们只需要纹理的高度酒能正确映射纹理了,因为纹理横坐标就是碰撞点x坐标%纹理宽度,v需要计算差值color(x)=(x-x1)/(x2-x1)(color2-color1)+color1 x1<x<x2
先开始一个循环,遍历每一列投影墙的y坐标,oy,然后根据差值用当前点oy减去起点kai/结束点en-kai后乘上纹理高度64,原公式(x-x1)/(x2-x1)
(color2-color1)+color1是为了在两种颜色进行渐变,在这里不需要两种颜色,只要知道纹理纵坐标y或者v的起始点与结束点就能差值这一列纹理的颜色
在这里插入图片描述

                for oy in range(int(kai),int(en)):
                    v=(oy-kai)/(en-kai)*64
                    u=zx%64

                    #print(v,oy,en-kai,int(v)%64,ix)
                #print(zx, zy,cx,cy)
                #tex_x = int(test_x % 1 * tex_width)  # 使用固定纹理宽度来映射
                    
                    screen.set_at((x, oy), img.get_at((int(u), int(v)%64)))

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 = [
    [1, 1, 1,1, 1, 1, 1, 1],#0 x坐标
    [1, 0, 0, 0, 0, 0, 0, 1],#1x坐标
    [1, 0, 0, 0, 0, 0, 0, 1],#2x坐标
    [1, 0, 0, 0, 0, 0, 0, 1],#3x坐标
    [1, 0, 0, 0, 0, 0, 0, 1],#4x坐标
    [1, 0, 0, 0, 0, 1, 0, 1],#5x坐标
    [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, 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=180
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=70
img=pygame.image.load("1.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-1
        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+1
            #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+1

            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))
                screen.blit(img, (180, 0))
                #qsz.append(pz)
    #player(px, py, img)
    for x in range(190):
        dis=0
        while True:
            angle= xuanzhuanjiao - 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
            #print(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))
                #ix = int(zx % 1 * 64)0
                #iy = int(300 + gao) % 64

                cx=zx-math.floor(zx)
                cy=zy-math.floor(zy)
                ix = int(zx)%64
                iy = int(cy*64)%64
                u=zx
                #print(kai-en,en,kai)
                #print(zx,zy)
                #print(zx % 64, int(zx % 64)%255)
                #print(zx, zy, zx % 60, x, int(u * 10) % 255)
                #tex_x = int(zx % 1 * tex_width)  # 使用固定纹理宽度来映射
                #pygame.draw.line(screen, (int(zx%64)%255,40,140), (x + 100, kai), (x + 100, en))
                tex_x = int(zx % 64)  # 使用固定纹理宽度来映射
                # for y in range(int(ceiling), int(floor)):
                #     tex_y = int((y - ceiling) / (floor - ceiling) * img.get_height())
                #     if 0 <= tex_x < img.get_width() and 0 <= tex_y < img.get_height():
                #         screen.set_at((x, y*2), img.get_at((tex_x, tex_y)))
                for oy in range(int(kai),int(en)):
                    v=(oy-kai)/(en-kai)*64
                    u=cx

                    #print(v,oy,en-kai,int(v)%64,ix)
                #print(zx, zy,cx,cy)
                #tex_x = int(test_x % 1 * tex_width)  # 使用固定纹理宽度来映射
                    #pygame.draw.line(screen, (img.get_at((int(ix)%64,int(v)%64))), (x+100,kai), (x+100, en))
                    screen.set_at((x, oy), img.get_at((ix, int(v)%64)))
                    #print(ix,v)

                #print(dis)
                break

    pygame.display.flip()

相关推荐

  1. WebGL之使用纹理

    2024-05-25 19:01:19       39 阅读
  2. LearnOpenGl练习题-纹理

    2024-05-25 19:01:19       34 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-25 19:01:19       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-25 19:01:19       106 阅读
  3. 在Django里面运行非项目文件

    2024-05-25 19:01:19       87 阅读
  4. Python语言-面向对象

    2024-05-25 19:01:19       96 阅读

热门阅读

  1. 怎么通过OpenAI API调用其多模态大模型(GPT-4o)

    2024-05-25 19:01:19       34 阅读
  2. AI新时代的对决:OpenAI GPT-4o与Google Astra的较量

    2024-05-25 19:01:19       32 阅读
  3. oracle有大量的ORACLE.EXE (SHAD) 导致 process耗尽

    2024-05-25 19:01:19       35 阅读
  4. 如何让大模型更聪明?

    2024-05-25 19:01:19       33 阅读
  5. GPT-4o:人工智能的新里程碑与未来潜力

    2024-05-25 19:01:19       32 阅读
  6. 【bash】统计服务器信息脚本

    2024-05-25 19:01:19       30 阅读
  7. 繁忙的都市

    2024-05-25 19:01:19       38 阅读
  8. 【OpenCV 基础知识 7】模板匹配

    2024-05-25 19:01:19       33 阅读
  9. 鼠标滚轮使用时上下跳动的解决方法

    2024-05-25 19:01:19       34 阅读