使用 PyOpenGL 在 Python 中仅移动 2 个立方体中的一个
Posted
技术标签:
【中文标题】使用 PyOpenGL 在 Python 中仅移动 2 个立方体中的一个【英文标题】:Moving only one cube out of 2 in Python with PyOpenGL 【发布时间】:2020-03-28 12:23:32 【问题描述】:所以,我是 PyOpenGL 的新手,我想做一个简单的 3D 游戏。
我创建了一个更大的立方体(它应该代表玩家)和一个较小的立方体(它应该代表敌人)。 我需要一个能够左右移动的玩家以及从前面来的敌人。 问题是他们在同一个位置。
我正在使用glTranslatef(x, y, z)
移动玩家,但敌人移动到与玩家相同的位置。
这是我的代码:
import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import*
class display:
def __init__(self, width, height, window):
self.width = width
self.height = height
self.window = window
def update(self):
pygame.display.flip()
pygame.time.wait(10)
def clear(self):
glClearColor(0.15, 0.15, 0.15, 1)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
display = display(800, 600, pygame.display.set_mode((800, 600), DOUBLEBUF|OPENGL))
class player:
def __init__(self, vertices, edges):
self.vertices = vertices
self.edges = edges
def begin(self):
glTranslatef(0.0, -5.0, -12.0)
glRotatef(20, 1, 0.0, 0.0)
def move(self):
self.k_press = pygame.key.get_pressed()
if self.k_press[pygame.K_LEFT]:
glTranslatef(-0.2, 0, 0)
if self.k_press[pygame.K_RIGHT]:
glTranslatef(0.2, 0, 0)
def draw(self):
glBegin(GL_LINES)
for edge in player.edges:
for vertex in edge:
glVertex3fv(player.vertices[vertex])
glEnd()
player = player(
((1, -1, -1), (1, 1, -1), (-1, 1, -1), (-1, -1, -1), (1, -1, 1), (1, 1, 1), (-1, -1, 1), (-1, 1, 1)),
((0, 1), (0, 3), (0, 4), (2, 1), (2, 3), (2, 7), (6, 3), (6, 4), (6, 7), (5, 1), (5, 4), (5, 7))
)
class enemy:
def __init__(self, vertices, edges):
self.vertices = vertices
self.edges = edges
def draw(self):
glBegin(GL_LINES)
for edge in enemy.edges:
for vertex in edge:
glVertex3fv(enemy.vertices[vertex])
glEnd()
enemy = enemy(
((0.5, -0.5, -0.5), (0.5, 0.5, -0.5), (-0.5, 0.5, -0.5), (-0.5, -0.5, -0.5), (0.5, -0.5, 0.5), (0.5, 0.5, 0.5), (-0.5, -0.5, 0.5), (-0.5, 0.5, 0.5)),
((0, 1), (0, 3), (0, 4), (2, 1), (2, 3), (2, 7), (6, 3), (6, 4), (6, 7), (5, 1), (5, 4), (5, 7))
)
gluPerspective(70, (display.width/display.height), 0.1, 50.0)
player.begin()
game_over = False
while not game_over:
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
display.clear()
player.move()
player.draw()
enemy.draw()
display.update()
pygame.quit()
现在,我只想让敌人和玩家移动而不是在同一个位置。 无论如何,感谢您的帮助!
【问题讨论】:
【参考方案1】:首先用glMatrixMode
区分投影矩阵和模型矩阵。
投影矩阵应设置为当前投影矩阵,视图矩阵应设置为当前模型视图矩阵。
# set projection matrix
glMatrixMode(GL_PROJECTION)
gluPerspective(70, (display.width/display.height), 0.1, 50.0)
# set view matrix
glMatrixMode(GL_MODELVIEW)
glTranslatef(0.0, -5.0, -12.0)
glRotatef(20, 1, 0.0, 0.0)
game_over = False
while not game_over:
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
display.clear()
player.move()
player.draw()
enemy.draw()
display.update()
此设置将允许稍后更改视角。
场景中每个对象的单独运动、动画和位置可以通过每个对象的模型矩阵来实现。对象绘制前存储当前模型视图矩阵,对象绘制后恢复矩阵glPushMatrix
/glPopMatrix
。
这可以为每个对象设置单独的位置。将对象的当前位置存储在属性 (self.pos = [0, 0, 0]
) 中。操纵move
中的位置(例如self.pos[0] -= 0.2
)并在绘制对象之前将模型转换矩阵乘以当前模型视图矩阵(glTranslatef(*self.pos)
)。例如:
class player:
def __init__(self, vertices, edges):
self.vertices = vertices
self.edges = edges
self.pos = [0, 0, 0]
def move(self):
self.k_press = pygame.key.get_pressed()
if self.k_press[pygame.K_LEFT]:
self.pos[0] -= 0.2
if self.k_press[pygame.K_RIGHT]:
self.pos[0] += 0.2
def draw(self):
glPushMatrix()
glTranslatef(*self.pos)
glBegin(GL_LINES)
for edge in player.edges:
for vertex in edge:
glVertex3fv(player.vertices[vertex])
glEnd()
glPopMatrix()
class enemy:
def __init__(self, vertices, edges):
self.vertices = vertices
self.edges = edges
self.pos = [0, 0, 0]
def draw(self):
glPushMatrix()
glTranslatef(*self.pos)
glBegin(GL_LINES)
for edge in enemy.edges:
for vertex in edge:
glVertex3fv(enemy.vertices[vertex])
glEnd()
glPopMatrix()
【讨论】:
谢谢你,很抱歉打扰你,但我刚开始做这个,对此我不太了解。再次感谢!以上是关于使用 PyOpenGL 在 Python 中仅移动 2 个立方体中的一个的主要内容,如果未能解决你的问题,请参考以下文章
使用 python opengl (PyOpenGL) 创建几何着色器失败