插值原理
原理
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()