Перемещать куб с помощью WASD в Pygame?

#python #opengl #pygame #pyopengl #opengl-compat

#python #opengl #pygame #pyopengl #opengl-compat

Вопрос:

Проблема в том, что когда я нажимаю клавишу, камера продолжает двигаться, а не когда я удерживаю клавишу, она перемещается, а затем где-то останавливается. Как мне это исправить? Это мой код для проекта, в который я импортирую модуль opengl и создаю ребра и поверхности вершин для куба. Я пытаюсь использовать pygame и pyopengl для создания куба, в котором я могу перемещаться по кубу с помощью движений WASD.

 import pygame
from pygame.locals import *

from OpenGL.GL import *
from OpenGL.GLU import *

verts = (
    (1, -1, -1),
    (1, 1, -1),
    (-1, 1, -1),
    (-1, -1, -1),
    (1, -1, 1),
    (1, 1, 1),
    (-1, -1, 1),
    (-1, 1, 1),
)

edges = (
    (0,1),
    (0,3),
    (0,4),
    (2,1),
    (2,3),
    (2,7),
    (6,3),
    (6,4),
    (6,7),
    (5,1),
    (5,4),
    (5,7),
)

surfaces = (
    (0, 1, 2, 3),
    (3, 2, 7, 6),
    (6, 7, 5, 4),
    (1, 5, 7, 2),
    (4, 5, 1, 0),
    (4, 0, 3, 6),
)

colors = (
    (1, 0, 0),
    (0, 1, 0),
    (0, 0, 1),
    (0,0,0),
    (1,1,1),
    (0,1,1),
    (1, 0, 0),
    (0, 1, 0),
    (0, 0, 1),
    (0,0,0),
    (1,1,1),
    (0,1,1),
)

def Cube():
    glBegin(GL_QUADS)
    x = 0
    for surface in surfaces:
        x =1
        for vertex in surface:
            glColor3fv(colors[x])
            glVertex3fv(verts[vertex])
    glEnd()
    
    
    
    
    glBegin(GL_LINES)
    for edge in edges:
        for vertex in edge:
            glVertex3fv(verts[vertex])


    glEnd()


def main():
    pygame.init()
    display = (1280, 720)
    pygame.display.set_mode(display, DOUBLEBUF|OPENGL)

    gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)

    glRotatef(0, 0, 0, 0)
    pos = 0.0
    back = 0.0
    glTranslatef(pos, 0.0, back)
    while True:

        pressed_left = False
        pressed_right = False
        pressed_up = False
        pressed_down = False
        glTranslatef(pos, 0.0, back)

        x_move = 0
        y_move = 0

        #camera
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    pressed_left = True
                elif event.key == pygame.K_RIGHT:
                    pressed_right = True
                elif event.key == pygame.K_DOWN:
                    pressed_down = True
                elif event.key == pygame.K_UP:
                    pressed_up = True
            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT:
                    pressed_left = False
                    print('off key')
                elif event.key == pygame.K_RIGHT:
                    pressed_right = False
                    print('off key')
                if event.key == pygame.K_UP:
                    pressed_up = False
                    print('off key')
                elif event.key == pygame.K_DOWN:
                    pressed_down = False
                    print('off key')

        if pressed_left == True:
            pos = -0.1
            print('key left')
        elif pressed_right == True:
            pos = 0.1
            print('key right')
        elif pressed_up == True:
            back = 0.1
            print('key up')
        elif pressed_down == True:
            back = -0.1
            print('key down')
        else:
            pos = pos
            back = back


        #glRotatef(1, 3, 1, 1)
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
        Cube()
        pygame.display.flip()
        pygame.time.wait(10)

main()
  

Ответ №1:

Устаревшие матричные преобразования OpenGL, такие как glTranslatef , не устанавливают преобразование. Матричные операции определяют новую матрицу преобразования и умножают текущую матрицу преобразования на новую матрицу.

События клавиатуры (см. Модуль pygame.event) происходят только один раз, когда изменяется состояние клавиши. KEYDOWN Событие происходит один раз при каждом нажатии клавиши. KEYUP происходит один раз при каждом отпускании ключа.
pygame.key.get_pressed() возвращает список с состоянием каждого ключа. Если клавиша удерживается нажатой, состояние ключа равно True , в противном False случае . Используется pygame.key.get_pressed() для оценки текущего состояния кнопки и получения непрерывного перемещения при удержании клавиши нажатой:

 def main():
    pygame.init()
    display = (1280, 720)
    pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
    clock = pygame.time.Clock()

    glEnable(GL_DEPTH_TEST)

    glMatrixMode(GL_PROJECTION)
    gluPerspective(90, (display[0]/display[1]), 0.1, 50.0)

    glMatrixMode(GL_MODELVIEW)
    pos, back = 0.0, -5.0
    glTranslatef(pos, 0.0, back)
    
    while True:
        clock.tick(60)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            glTranslatef(-0.1, 0.0, 0.0)
            print('key left')
        elif keys[pygame.K_RIGHT]:
            glTranslatef(0.1, 0.0, 0.0)
            print('key right')
        elif keys[pygame.K_UP]:
            glTranslatef(0.0, 0.1, 0.0)
            print('key up')
        elif keys[pygame.K_DOWN]:
            glTranslatef(0.0, -0.1, 0.0)
            print('key down')

        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
        Cube()
        pygame.display.flip()