我正在使用Python、PyGame和Legacy PyOpenGL制作一个最小的Doom风格的FPS游戏引擎。我希望玩家能够通过按左右箭头键来使用glRotatef()
朝着四个方向看——向前、向后、向左和向右。你知道吗
出现了一些问题:
一把枪(一个应用了纹理的立方体,根据玩家面对的方向改变纹理坐标)应该总是出现在相机前面0.5个单位的位置,在相应的x和z位置,这取决于角度glRotatef()
将其设置为面向,移动到一个奇怪的位置,如果我在x轴上移动,然后向左看,除非我站在房间的中心。当我向左和向右移动时,立方体看起来也是静态的,尽管我提供了从glGetDoublev()
获得的x值;当我向前移动时,枪看起来是缩放的,尽管我从未实现过这样的功能。
当我打电话的时候
if event.type == pygame.KEYDOWN: # key pressed events
if event.key == pygame.K_LEFT:
glRotatef(-90,0,1,0)
if direction == 0:
direction = 3
else:
direction -= 1
往房间的左边看,我偶尔会被移到墙里面,这有时会进一步影响枪的位置。你知道吗
我尝试过添加固定的x和z变量(x_steps
和z_steps
),每次玩家移动时都会增加0.1。我不太清楚为什么这会消除“静电枪”的问题,但它确实解决了。然而,当我旋转相机时,同样的问题(枪移动到一个奇怪的位置)仍然发生。你知道吗
## pygame/opengl initialisation code
def main():
pygame.init()
display = (800,600)
global displaySurface
displaySurface = pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
pygame.display.set_caption("Wolfenstein 4D")
glEnable(GL_TEXTURE_2D)
glEnable(GL_DEPTH_TEST)
gluPerspective(45, (display[0]/display[1]),0.1,50.0)
## game loop, obtaining x,y,z positions and looking around the room
def room1():
direction = 3 ## 3 = forward, 2 = left, 1 = backward, 0 = right
while True:
pos = glGetDoublev(GL_MODELVIEW_MATRIX)
x = pos[3][0]
y = pos[3][1]
z = pos[3][2]
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN: # key pressed events
if event.key == pygame.K_LEFT:
glRotatef(-90,0,1,0)
if direction == 0:
direction = 3
else:
direction -= 1
x_steps = 0
z_steps = 0
if event.key == pygame.K_RIGHT:
glRotatef(90,0,1,0)
if direction == 3:
direction = 0
else:
direction += 1
x_steps = 0
z_steps = 0
## movement code
spd = 0.1
keys = pygame.key.get_pressed()
if direction == 3:
if keys[pygame.K_a]:
glTranslatef(spd,0,0)
x_steps -= spd
if keys[pygame.K_d]:
glTranslatef(-spd,0,0)
x_steps += spd
if keys[pygame.K_w]:
glTranslatef(0,0,spd)
z_steps -= spd
if keys[pygame.K_s]:
glTranslatef(0,0,-spd)
z_steps += spd
if direction == 2:
if keys[pygame.K_a]:
glTranslatef(0,0,-spd)
x_steps += spd
if keys[pygame.K_d]:
glTranslatef(0,0,spd)
x_steps -= spd
if keys[pygame.K_w]:
glTranslatef(spd,0,0)
z_steps -= spd
if keys[pygame.K_s]:
glTranslatef(-spd,0,0)
z_steps += spd
## gun drawing code in game loop
if direction == 3:
loadTexture("gun1.png")
drawHUDGun(x,-0.1,z-0.5,3,0.1,0.1,0.1)
if direction == 2:
loadTexture("gun.png")
drawHUDGun(z-0.5,-0.1,x+0.5,2,0.1,0.1,0.1)
## gun drawing function
def drawHUDGun(x,y,z,angle,width,height,depth=0.5,color = ((1,1,1))):
vertices = (
(width+x,-height+y,-depth+z),
(width+x,height+y,-depth+z),
(-width+x,height+y,-depth+z),
(-width+x,-height+y,-depth+z),
(width+x,-height+y,depth+z),
(width+x,height+y,depth+z),
(-width+x,-height+y,depth+z),
(-width+x,height+y,depth+z)
)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glBegin(GL_QUADS)
if angle == 3:
j = 0
if angle == 2:
j = 8
i = 0
for surface in surfaces:
i += 1
for vertex in surface:
glColor4f(1,1,1,1)
setTexCoord(0, texCoords, j)
if angle == 3:
if i >= 0 and i < 4:
if j < 4:
j += 1
if angle == 2:
if i == 2:
if j < 12:
j += 1
glVertex3fv(vertices[vertex])
glEnd()
glDisable(GL_BLEND)
glBegin(GL_LINES)
for edge in edges:
glColor3fv((0,1,0))
for vertex in edge:
glVertex3fv(vertices[vertex])
glEnd()
## implementation of the functions
main()
room1()
我预计枪在任何方向上都会出现在玩家前面0.5个单位的位置,而不管他们在房间里的什么位置,但是枪常常因为被分配了不正确的x或z坐标而不在视线范围内。
在传统的OpenGL中,存在不同的当前矩阵。受矩阵运算影响的当前矩阵可由^{} 选择。每个矩阵都组织在一个堆栈上。矩阵可以由^{}/^{} 推送和弹出。你知道吗
投影矩阵应设置为投影矩阵堆栈,视图和模型转换为modelview矩阵堆栈:
枪应该放在第一人称视角(“在你面前”)。实现这一点最简单的方法是在viewspace中绘制枪,这意味着您必须取消对modelview矩阵的所有先前转换。矩阵可以用identity matrix替换为^{} 。
将modelview矩阵保存到堆栈中,设置标识矩阵,绘制枪,最后还原modelview矩阵。例如:
相关问题 更多 >
编程相关推荐