PyOpenGL Camera & pygame.key.getpressed() 连续移动

问题描述 投票:0回答:1

我对为我的项目打开 OpenGL 还很陌生。我正在尝试创建一个简单的 3D 空间,放置立方体块,并导航视图以获得基本的构建体验。

问题:

  1. 我想知道为什么我的相机默认一直沿z轴移动,而且它也一直沿我按下的方向移动。

  2. 如何限制一次输入一个?我意识到当我点击时,会创建多个立方体。

以下是完整代码。

import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import gluPerspective, gluUnProject

class Camera:
    def __init__(self):
        self.position = [0, 0, -1]
        self.move_step = 0.1

    def move(self, keys):
        if keys[K_LEFT]:
            self.position[0] -= self.move_step
        elif keys[K_RIGHT]:
            self.position[0] += self.move_step

        if keys[K_UP]:
            self.position[1] += self.move_step
        elif keys[K_DOWN]:
            self.position[1] -= self.move_step

    def apply(self):
        glTranslatef(self.position[0], self.position[1], self.position[2])

# Initialize global camera object
camera = Camera()
# List to store placed blocks
blocks = []

# Constants
BLOCK_SIZE = 1

def draw_cube(x, y, z):
    glBegin(GL_QUADS)
    glVertex3f(x - BLOCK_SIZE / 2, y - BLOCK_SIZE / 2, z + BLOCK_SIZE / 2)
    glVertex3f(x + BLOCK_SIZE / 2, y - BLOCK_SIZE / 2, z + BLOCK_SIZE / 2)
    glVertex3f(x + BLOCK_SIZE / 2, y + BLOCK_SIZE / 2, z + BLOCK_SIZE / 2)
    glVertex3f(x - BLOCK_SIZE / 2, y + BLOCK_SIZE / 2, z + BLOCK_SIZE / 2)

    glVertex3f(x - BLOCK_SIZE / 2, y - BLOCK_SIZE / 2, z - BLOCK_SIZE / 2)
    glVertex3f(x + BLOCK_SIZE / 2, y - BLOCK_SIZE / 2, z - BLOCK_SIZE / 2)
    glVertex3f(x + BLOCK_SIZE / 2, y + BLOCK_SIZE / 2, z - BLOCK_SIZE / 2)
    glVertex3f(x - BLOCK_SIZE / 2, y + BLOCK_SIZE / 2, z - BLOCK_SIZE / 2)

    glVertex3f(x - BLOCK_SIZE / 2, y + BLOCK_SIZE / 2, z + BLOCK_SIZE / 2)
    glVertex3f(x + BLOCK_SIZE / 2, y + BLOCK_SIZE / 2, z + BLOCK_SIZE / 2)
    glVertex3f(x + BLOCK_SIZE / 2, y + BLOCK_SIZE / 2, z - BLOCK_SIZE / 2)
    glVertex3f(x - BLOCK_SIZE / 2, y + BLOCK_SIZE / 2, z - BLOCK_SIZE / 2)

    glVertex3f(x - BLOCK_SIZE / 2, y - BLOCK_SIZE / 2, z + BLOCK_SIZE / 2)
    glVertex3f(x + BLOCK_SIZE / 2, y - BLOCK_SIZE / 2, z + BLOCK_SIZE / 2)
    glVertex3f(x + BLOCK_SIZE / 2, y - BLOCK_SIZE / 2, z - BLOCK_SIZE / 2)
    glVertex3f(x - BLOCK_SIZE / 2, y - BLOCK_SIZE / 2, z - BLOCK_SIZE / 2)

    glVertex3f(x - BLOCK_SIZE / 2, y - BLOCK_SIZE / 2, z + BLOCK_SIZE / 2)
    glVertex3f(x - BLOCK_SIZE / 2, y + BLOCK_SIZE / 2, z + BLOCK_SIZE / 2)
    glVertex3f(x - BLOCK_SIZE / 2, y + BLOCK_SIZE / 2, z - BLOCK_SIZE / 2)
    glVertex3f(x - BLOCK_SIZE / 2, y - BLOCK_SIZE / 2, z - BLOCK_SIZE / 2)

    glVertex3f(x + BLOCK_SIZE / 2, y - BLOCK_SIZE / 2, z + BLOCK_SIZE / 2)
    glVertex3f(x + BLOCK_SIZE / 2, y + BLOCK_SIZE / 2, z + BLOCK_SIZE / 2)
    glVertex3f(x + BLOCK_SIZE / 2, y + BLOCK_SIZE / 2, z - BLOCK_SIZE / 2)
    glVertex3f(x + BLOCK_SIZE / 2, y - BLOCK_SIZE / 2, z - BLOCK_SIZE / 2)
    glEnd()

def draw_blocks():
    for block in blocks:
        draw_cube(block[0], block[1], block[2])

def main():

    pygame.init()
    display = (800, 600)
    pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
    gluPerspective(90, (display[0] / display[1]), 0.1, 50.0)

    while True:
        
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
        
        keys = pygame.key.get_pressed()
        camera.move(keys)

        if pygame.mouse.get_pressed()[0]:
            mouse_x, mouse_y = pygame.mouse.get_pos()
            viewport = glGetIntegerv(GL_VIEWPORT)
            mouse_z = camera.position[2]

            print(blocks)

            x, y, z = gluUnProject(mouse_x, viewport[3] - mouse_y, mouse_z)
            if not any((round(x), round(y), round(z)) == block for block in blocks):
                blocks.append((round(x), round(y), round(z)))

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        camera.apply()
        draw_blocks()
        pygame.display.flip()
        pygame.time.wait(10)

if __name__ == "__main__":
    main()

我尝试过 pygame.KEYUP 来限制输入。但这不起作用。 :( 请发送帮助

python pygame pyopengl
1个回答
0
投票

glTranslatef
不设置平移矩阵,而是将当前平移矩阵乘以新平移。您必须使用位置更改来调用它,而不是使用当前位置来调用
glTranslatef

© www.soinside.com 2019 - 2024. All rights reserved.