You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenGL中实现按键独立控制多个2D图形移动的技术问询

实现不同2D图形独立按键控制移动的方案

实现步骤

  • 为每个图形定义独立的全局x、y偏移变量,存储当前图形的位移值
  • 注册GLUT的按键事件回调函数,根据按下的按键修改对应图形的偏移量,修改完成后触发窗口重绘
  • 渲染每个图形前调用glPushMatrix()保存当前坐标系,使用glTranslatef()应用对应偏移后绘制图形,绘制完成后调用glPopMatrix()恢复坐标系,避免偏移互相干扰

按键控制说明

以下为默认分配的控制逻辑,可根据需求自行修改:

  • 红色矩形:W上、S下、A左、D右
  • 蓝色三角形:T上、G下、F左、H右
  • 黄色多边形:I上、K下、J左、L右
  • 绿色多边形:↑上、↓下、←左、→右(方向键)

完整修改后代码

// INCLUDE STATEMENTS FOR MS WINDOWS:
#include <windows.h>   // for MS Windows
#include <GL/glut.h>   // GLUT, include glu.h and gl.h

// 四个图形的独立偏移量定义
// 红色矩形偏移
float redOffsetX = 0.0f, redOffsetY = 0.0f;
// 蓝色三角形偏移
float blueOffsetX = 0.0f, blueOffsetY = 0.0f;
// 黄色多边形偏移
float yellowOffsetX = 0.0f, yellowOffsetY = 0.0f;
// 绿色多边形偏移
float greenOffsetX = 0.0f, greenOffsetY = 0.0f;
// 步长,控制每次移动的距离
const float MOVE_STEP = 0.02f;

/* Initialize OpenGL Graphics */
void initGL() {
    // Set "clearing" or background color
     glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Black and opaque
}

// 普通按键回调
void handleKeypress(unsigned char key, int x, int y) {
    switch(key) {
        // 红色矩形控制
        case 'w': redOffsetY += MOVE_STEP; break;
        case 's': redOffsetY -= MOVE_STEP; break;
        case 'a': redOffsetX -= MOVE_STEP; break;
        case 'd': redOffsetX += MOVE_STEP; break;
        // 蓝色三角形控制
        case 't': blueOffsetY += MOVE_STEP; break;
        case 'g': blueOffsetY -= MOVE_STEP; break;
        case 'f': blueOffsetX -= MOVE_STEP; break;
        case 'h': blueOffsetX += MOVE_STEP; break;
        // 黄色多边形控制
        case 'i': yellowOffsetY += MOVE_STEP; break;
        case 'k': yellowOffsetY -= MOVE_STEP; break;
        case 'j': yellowOffsetX -= MOVE_STEP; break;
        case 'l': yellowOffsetX += MOVE_STEP; break;
        default: return;
    }
    glutPostRedisplay();
}

// 特殊按键回调(处理方向键等)
void handleSpecialKeypress(int key, int x, int y) {
    switch(key) {
        // 绿色多边形控制(方向键)
        case GLUT_KEY_UP: greenOffsetY += MOVE_STEP; break;
        case GLUT_KEY_DOWN: greenOffsetY -= MOVE_STEP; break;
        case GLUT_KEY_LEFT: greenOffsetX -= MOVE_STEP; break;
        case GLUT_KEY_RIGHT: greenOffsetX += MOVE_STEP; break;
        default: return;
    }
    glutPostRedisplay();
}

/* Handler for window-repaint event. Call back when the window first appears and
whenever the window needs to be re-painted. */
void display() {
     glClear(GL_COLOR_BUFFER_BIT);   // Clear the color buffer with current clearing color
    
    // 绘制红色矩形
    glPushMatrix();
    glTranslatef(redOffsetX, redOffsetY, 0.0f);
    glBegin(GL_QUADS);              // Each set of 4 vertices form a quad
    glColor3f(1.0f, 0.0f, 0.0f);  // Red
    glVertex2f(-0.6f, 0.2f);
    glVertex2f(-0.2f, 0.2f);
    glVertex2f(-0.2f, 0.4f);
    glVertex2f(-0.6f, 0.4f);
    glEnd();
    glPopMatrix();
    
    // 绘制蓝色三角形
    glPushMatrix();
    glTranslatef(blueOffsetX, blueOffsetY, 0.0f);
    glBegin(GL_TRIANGLES);          // Each set of 3 vertices form a triangle
    glColor3f(0.0f, 0.0f, 1.0f);  // Blue
    glVertex2f(-0.4f, 0.5f);
    glVertex2f(0.0f, 0.5f);
    glVertex2f(-0.2f, 0.8f);
    glEnd();
    glPopMatrix();
    
    // 绘制黄色多边形
    glPushMatrix();
    glTranslatef(yellowOffsetX, yellowOffsetY, 0.0f);
    glBegin(GL_POLYGON);            // These vertices form a closed polygon
    glColor3f(1.0f, 1.0f, 0.0f);  // Yellow
    glVertex2f(0.2f, 0.0f);
    glVertex2f(0.4f, 0.0f);
    glVertex2f(0.5f, 0.2f);
    glVertex2f(0.4f, 0.4f);
    glVertex2f(0.2f, 0.4f);
    glVertex2f(0.1f, 0.2f);
    glEnd();
    glPopMatrix();
    
    // 绘制绿色多边形
    glPushMatrix();
    glTranslatef(greenOffsetX, greenOffsetY, 0.0f);
    glBegin(GL_POLYGON);            // These vertices form a closed polygon
    glColor3f(0.0f, 1.0f, 0.0f);  // Green
    glVertex2f(0.6f, 0.3f);
    glVertex2f(0.8f, 0.3f);
    glVertex2f(0.9f, 0.5f);
    glVertex2f(0.7f, 0.7f);
    glVertex2f(0.5f, 0.5f);
    glEnd();
    glPopMatrix();

    glFlush(); // 强制刷新缓冲区,立即渲染
}

int main(int argc, char** argv) {
    glutInit(&argc, argv);            // Initialize GLUT
    glutCreateWindow("Vertex, Primitive & Color");  // Create window with the given title
    glutInitWindowSize(320, 320);   // Set the window's initial width & height
    glutInitWindowPosition(50, 50); // Position the window's initial top-left corner
    glutDisplayFunc(display);       // Register callback handler for window re-paint event
    // 注册键盘回调
    glutKeyboardFunc(handleKeypress);
    glutSpecialFunc(handleSpecialKeypress);
    initGL();
    glutMainLoop();
    return 0;
}

可调整参数

  • 修改MOVE_STEP的值可以调整每次按键移动的距离,数值越大移动速度越快
  • 修改handleKeypress和handleSpecialKeypress里的按键映射,可以自定义每个图形的控制按键

内容的提问来源于stack exchange,提问作者uwu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 00:06:04