厌倦了枯燥的算法题?不妨换个思路,用编程创造一点小乐趣。今天,我们结合图形库和物理模拟,带你亲手用 C++ 编写一个简化版的“跳一跳”小游戏。这不仅是一次编程实践,更是一次理解游戏物理逻辑的好机会。
如何用代码模拟跳跃的物理效果?关键在于一个简单的物理模型:重力加速度。下面,我们将通过完整的代码,一步步实现小球跳跃、移动障碍物以及得分逻辑。
核心代码实现
以下是游戏的核心 C++ 代码,它使用了 EasyX 图形库进行画面绘制和交互。
#include <graphics.h>
#include <conio.h>
#include <string>
#include <stdio.h>
#include <windows.h>
#include <mmsystem.h>
#pragma comment(lib, "Winmm.lib")
//Jump Game
using namespace std;
char s[20];
void startup(){ //打开背景音乐
mciSendString("open ice_bk.mp3 alias bkmusic", NULL, 0, NULL);
mciSendString(_T("play bkmusic repeat"), NULL, 0, NULL);
}
void PlayMusicOnce(const char * fileName){
char cmdString1[50];
sprintf(cmdString1, "open %s alias tmpmusic", fileName);
mciSendString(_T("close tmpmusic"), NULL, 0, NULL);
mciSendString(cmdString1, NULL, 0, NULL);//打开音乐
mciSendString(_T("play tmpmusic"), NULL, 0, NULL);//播放一次
}
void display(int h,int v){
sprintf(s,"%d",h);//转换为字符串
settextstyle(40,0,_T("微软雅黑"));
settextcolor(YELLOW);
outtextxy(500,30,s);
sprintf(s,"%d",v);
settextstyle(40,0,_T("微软雅黑"));
settextcolor(YELLOW);
outtextxy(500,110,s);//output
}
int main(){
bool isBallOnFloor = 1;
double width, height, gravity; //游戏画布尺寸、加速度
double ball_x, ball_y, ball_vy, radius; // 小球圆心坐标、y方向速度、半径
double rect_left_x,rect_top_y,rect_width,rect_height,rect_vx;//长方形木块相关参数
int score = 0;//得分
width = 600; // 游戏画面宽度
height = 600; // 游戏画面高度
gravity = 0.5;// 加速度
initgraph(width, height,EW_SHOWCONSOLE); //新建一个画布
setbkcolor(CYAN);
cleardevice();
startup();
radius = 20; //小球半径
ball_x = width / 4;//小球x位置
ball_y = height - radius;//小球y位置
ball_vy = 0;//小球初始速度为0
rect_height = 100;//方块高
rect_width = 20;//方块宽
rect_left_x = width * 3 / 4;
rect_top_y = height - rect_height;
rect_vx = -4;//方块x方向速度
while (-1) {
if (_kbhit()) { //当按键时
char c = _getch(); //获得输入字符
if ( (c == 32) && isBallOnFloor ) { //当按下空格键时
ball_vy = -20; //给小球一个向上的速度
isBallOnFloor = false;//离开地板
}
}
ball_vy = ball_vy + gravity; //根据重力加速度更新小球y方向速度
ball_y = ball_y + ball_vy; //根据小球y方向速度更新其y坐标
if (ball_y >= height - radius) { //如果小球落到地面上
ball_vy = 0; //y速度重置为零
ball_y = height - radius;
isBallOnFloor = true;//落地
}
//move block to left
rect_left_x = rect_left_x + rect_vx;//move to left
if(rect_left_x <= 0) {
score ++;//得一分
rect_left_x = width;//右边重新进入画布
rect_height = rand() % int(height/4) + height / 4;//随机方块高度
rect_vx = rand() / float(RAND_MAX) * 3 - 7;//随机设置速度
}
//如果小球碰到方块,得分清零
if((rect_left_x <= ball_x +radius) && (rect_left_x + rect_width >= ball_x - radius )
&& height-rect_height <= ball_y + radius ) {
Sleep(100);//慢动作
PlayMusicOnce("woodhit.wav");
score = 0;
}
cleardevice();//清空画面
display(rect_height,rect_vx);//打印矩形当前状态
setfillcolor(GREEN);
fillrectangle(rect_left_x,height - rect_height,rect_left_x + rect_width,height);
if(ball_vy <= 0)setfillcolor(RED);
else setfillcolor(GREEN);
fillcircle(ball_x, ball_y, radius);//绘制小球
//显示分数
sprintf(s,"%d",score);//转换为字符串
settextstyle(60,0,_T("微软雅黑"));
settextcolor(BROWN);
outtextxy(50,30,s);
Sleep(10);
}
closegraph();
return 0;
}
你可以直接运行这段代码。游戏规则是:按空格键控制小球跳跃,避开从右侧向左移动的绿色方块。每成功避开一个方块(即方块移出画面左边界),得一分。如果小球撞上方块,则得分清零。游戏界面左上角显示当前得分。
代码解析与自定义
如果你理解了上面的代码,完全可以动手调整参数,创造出不同难度的版本。例如:
- 增加难度:调高重力
gravity 的值,或让方块的移动速度 rect_vx 更快(即更负)。
- 降低难度:减小重力,或增大小球的初始跳跃速度(即
ball_vy = -20 中的绝对值)。
- 改变游戏体验:调整方块的宽度
rect_width、高度随机范围,甚至修改小球和方块的颜色。
这个项目的核心知识点涵盖了基础的 循环与分支语句、字符串与数字的转换(sprintf),以及利用 EasyX图形库 进行图形绘制和键盘交互。其中,利用 rand() 函数为障碍物生成随机高度和速度,是增加游戏可玩性的关键 算法 技巧。
环境配置指南
要成功编译并运行上述代码,你需要配置一个支持 EasyX 图形库的开发环境。
-
下载并安装 EasyX:
访问 EasyX 官网 https://easyx.cn/easyx-20230723,下载适用于 MinGW 编译器的版本(例如 EasyX_20230723.exe)并进行安装。
-
配置编译器选项(关键步骤):
如果你使用的是 Dev-C++、Code::Blocks 等集成开发环境,需要在项目的编译选项中加入特定的链接库参数。如下图所示,在“连接器命令行”选项中添加:
-static-libgcc -leasyx -lwinmm

同时,为了使用现代C++特性,建议在“编译时加入以下命令”中填写 `-std=c++17`。
完成以上配置后,你就能顺利编译并运行这个“跳一跳”游戏了。自己动手实现一个小游戏,是不是比单纯刷题更有成就感?如果在实现过程中有任何想法或问题,都欢迎在云栈社区与大家一起交流探讨。