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

Проблема в том, что когда я нажимаю клавишу, камера продолжает двигаться, а не когда я держу клавишу, она перемещается, а затем где-то останавливается. Как это исправить? Это мой код для проекта. Я импортирую модуль 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()

person e7illice    schedule 17.11.2020    source источник


Ответы (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()

person Rabbid76    schedule 17.11.2020