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

基于GLUT库的打砖块游戏优化:实现小球固定速度持续移动

打砖块游戏持续运动优化方案

当前游戏只能按键逐帧运行的核心原因是:原代码仅在键盘按键触发时才发起重绘,且动画逻辑耦合在myDisplay的单次for循环内,没有定时自动重绘的机制。具体优化方案如下:

修改步骤

  • 新增定时器回调函数,设置固定刷新间隔(16ms对应约60帧刷新率),定时触发重绘,摆脱对按键事件的依赖
  • 移除myDisplay函数内的外层for循环,单次重绘仅执行一帧的坐标更新、绘制、碰撞检测逻辑
  • 主函数中注册定时器回调,启动自动刷新循环
  • 修复原代码绘制挡板后颜色未复位的问题,避免小球变成黑色
  • 原有挡板操作、碰撞检测、得分逻辑无需改动,可直接兼容

完整优化后代码

#include<stdio.h>
#include<GL/glut.h>
#include<math.h>
#define pi 3.142857

// 全局声明
// c和d分别统计按键'b'和'n'的按下次数
// left和right为可移动挡板的左右边界坐标
int c = 0, d = 0, left = 0, right = 0;
int m = 0, j = 1, flag1 = 0, l = 1, flag2 = 0, n = 0, score = 0, count = 1;

// 定时器回调函数,实现定时重绘
void timer(int value) {
    glutPostRedisplay();
    glutTimerFunc(16, timer, 0); // 16ms刷新一次,约60帧
}

// 初始化函数
void myInit (void)
{
    // 将背景色重置为白色(RGB三个通道值均为1.0)
    glClearColor(1.0, 1.0, 1.0, 0.0);

    // 设置绘制颜色为红色(RGB模型中仅R通道值为1.0)
    glColor3f(1.0f, 0.0f, 0.0f);

    // 设置点的宽度为1单位
    glPointSize(1.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    // 设置X、Y方向的窗口坐标范围
    gluOrtho2D(-620.0, 620.0, -340.0, 340.0);
}

// 键盘事件响应函数,按键按下时触发
void keyboard(unsigned char key, int x, int y)
{
    left = -200 + 200 * (d - c);
    right = 200 + 200 * (d - c);

    // 当挡板触碰窗口左边界时,后续按b键不会再左移,仅可按n键右移
    if (left == -600)
    {
        // 110为字符'n'的ASCII值,按下n键时d自增
        if (key == 110)
            d++;
    }
    // 当挡板触碰窗口右边界时,后续按n键不会再右移,仅可按b键左移
    else if (right == 600)
    {
        // 98为字符'b'的ASCII值,按下b键时c自增
        if (key == 98)
            c++;
    }
    // 挡板处于窗口中间区域时,可按对应按键左右移动
    else
    {
        if (key == 98)
            c++;
        if (key == 110)
            d++;
    }
    glutPostRedisplay();
}

void myDisplay(void)
{
    // x、y存储圆周上的点坐标
    int x, y;
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_LINE_STRIP);
    // i记录角度值
    float i = 0;
    // m的变化对应垂直方向移动,n的变化对应水平方向移动
    m = m + 6;
    n = n + 4;
    // 绘制圆心在(0, 12)的圆,遍历角度到2π即360度
    while (i <= 2 * pi)
    {
        y = 12 + 20 * cos(i);
        x = 20 * sin(i);
        i = i + 0.1;
        // flag1为0表示小球向上移动,为1表示向下移动
        if (m == 288 && flag1 == 0)
        {
            j = -1;
            m = -288;
            flag1 = 1;
            score++;
        }
        if (m == 288 && flag1 == 1)
        {
            j = 1;
            m = -288;
            flag1 = 0;
        }
        // flag2为0表示小球向右移动,为1表示向左移动
        if (n == 580 && flag2 == 0)
        {
            l = -1;
            n = -580;
            flag2 = 1;
        }
        if (n == 580 && flag2 == 1)
        {
            l = 1;
            n = -580;
            flag2 = 0;
        }
        // 小球运动坐标计算
        glVertex2i((x - l * n), (y - j * m));
    }
    glEnd();

    // 绘制游戏窗口外框矩形
    glBegin(GL_LINE_LOOP);
        glVertex2i(-600, -320);
        glVertex2i(-600, 320);
        glVertex2i(600, 320);
        glVertex2i(600, -320);
    glEnd();

    // 绘制接球用的底部矩形挡板
    glColor3f(0,0,0);
    glBegin(GL_LINE_LOOP);
    left = -200 + 200 * (d - c);
    right = 200 + 200 * (d - c);
        glVertex2i(left, -315);
        glVertex2i(left, -295);
        glVertex2i(right, -295);
        glVertex2i(right, -315);
    glEnd();
    // 恢复小球颜色为红色,避免下一帧绘制小球变成黑色
    glColor3f(1.0f, 0.0f, 0.0f);

    // 检测下落的小球是否被挡板接住
    if ((j * m) == 276)
    {
        if ((left > ((-1 * l * n) + 20)) || (right < (-1 * l * n) - 20))
        {
            printf("Game Over !!!\nYour Score is :\t%d\n", score);
            exit(0);
        }
    }
    glutSwapBuffers();
}

// 主函数
int main (int argc, char** argv)
{
    glutInit(&argc, argv);

    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
    // 声明窗口尺寸
    glutInitWindowSize(1100, 600);

    // 声明窗口位置为(0,0),即左下角对应坐标(0,0)
    glutInitWindowPosition(0, 0);

    // 设置窗口名称
    glutCreateWindow("Game");

    // 注册键盘事件回调函数
    glutKeyboardFunc(keyboard);
    // 注册定时器回调
    glutTimerFunc(0, timer, 0);
    // 调用初始化函数
    myInit();
    glutDisplayFunc(myDisplay);
    glutMainLoop();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 04:36:04