参考
- 《C和C++趣味游戏编程》 童真
“别碰方块”游戏
实现一个小球跳跃躲避方块的游戏
空格键控制小球起跳
让小球初始在地面上,按下空格键后起跳,落地后小球静止
#include <graphics.h>
#include <conio.h>
#include <stdio.h>
int main()
{
float width, height, gravity; // 游戏画面宽高、重力加速度
float ball_x, ball_y, ball_vy, radius; // 小球圆心坐标、y方向速度、半径
width = 600; // 游戏画面高度
height = 400; // 游戏画面宽度
gravity = 0.6; // 重力加速度
initgraph(width, height); // 新建画布
radius = 20; // 小球半径
ball_x = width / 4; // 小球x位置
ball_y = height - radius; // 小球y位置
ball_vy = 0; // 小球初始y速度为0
while (1)
{
if (_kbhit()) // 当按键时
{
char input = _getch(); // 获得输入字符
if (input == ' ') // 当按下空格键时
{
ball_vy = -16; // 给小球一个向上的初速度
}
}
ball_vy += gravity; // 根据重力加速度更新小球y方向速度
ball_y += ball_vy; // 根据小球y方向速度更新其y坐标
if (ball_y >= height - radius) // 如果小球落到地面上
{
ball_vy = 0; // y速度为0
ball_y = height - radius; // 避免落到地面下
}
cleardevice(); // 清空画面
fillcircle(ball_x, ball_y, radius); // 绘制小球
Sleep(10);
}
closegraph();
return 0;
}
矩形的绘制
函数fillrectangle(left, top, right, bottom)可以绘制矩形,其中(left, top)为矩形左上角的(x, y)坐标,(right, bottom)为矩阵右下角的(x, y)坐标
float rect_left_x, rect_top_y, rect_width, rect_height, rect_vx; // 方块障碍物的相关参数
rect_height = 100; // 方块高度
rect_width = 20;
rect_left_x = width * 3 / 4; // 方块坐标x坐标
rect_top_y = height - rect_height; // 方块顶部y坐标
rect_vx = -3; // 方块x方向速度
fillrectangle(rect_left_x, height - rect_height, rect_left_x + rect_width, height); // 画方块
使方块左移,当跑到最左边时,从最右边重新出现
rect_left_x = rect_left_x + rect_vx; // 方块向左移
if (rect_left_x <= 0) // 如果方块跑到最左边
{
rect_left_x = width; // 在最右边重新出现
}
小球和方块的碰撞判断
小球和方块发送碰撞需同时满足以下3个条件:
- rect_left_x <= ball_x + radius(方块最左边在小球最右边的左侧或二者x坐标相同)
- rect_left_x + rect_width >= ball_x - radius(方块最右边在小球最左边的右侧或二者x坐标相同)
- height-rect_height <= ball_y + radius(方块最上边在小球最下边的上侧或二者y坐标相同)
if ((rect_left_x <= ball_x + radius)
&& (rect_left_x + rect_width >= ball_x - radius)
&& (height - rect_height <= ball_y + radius))
{
Sleep(100);
}
利用随机数增加游戏的趣味性
设置方块高度范围为height/4到height/2,随机速度为-7到-3
if (rect_left_x <= 0) // 如果方块跑到最左边
{
rect_left_x = width; // 在最右边重新出现
rect_height = rand() % int(height / 4) + height / 4; // 设置随机高度
rect_vx = rand() / float(RAND_MAX) * 4 - 7; // 设置方块随机速度
}
得分的计算显示实现方式
当方块跑到画面最左边时,得分加1:
if (rect_left_x <= 0) // 如果方块跑到最左边
{
rect_left_x = width; // 在最右边重新出现
score++; // 得分加1
rect_height = rand() % int(height / 4) + height / 4; // 设置随机高度
rect_vx = rand() / float(RAND_MAX) * 4 - 7; // 设置方块随机速度
}
当方块碰到小球时,得分清零:
if ((rect_left_x <= ball_x + radius)
&& (rect_left_x + rect_width >= ball_x - radius)
&& (height - rect_height <= ball_y + radius)) // 如果小球碰到方块
{
Sleep(100);
score = 0; // 得分清零
}
利用EasyX的文字输出功能,显示得分:
TCHAR s[20]; // 定义字符串数组
_stprintf(s, _T("%d"), score); // 将score转换为字符串
settextstyle(40, 0, _T("宋体")); // 设置文字大小、字体
outtextxy(50, 30, s); // 输出得分文字
Sleep(10);
解决小球在空中起跳的问题
定义一个变量isBallOnFloor记录小球是否在地面上,只有小球在地面上时,按下空格键,才让小球起跳
if (input == ' ' && isBallOnFloor == 1) // 当按下空格键时
{
ball_vy = -16; // 给小球一个向上的初速度
isBallOnFloor = 0; // 小球不在地面上了
}
完整代码
#include <graphics.h>
#include <conio.h>
#include <stdio.h>
int main()
{
float width, height, gravity; // 游戏画面宽高、重力加速度
float ball_x, ball_y, ball_vy, radius; // 小球圆心坐标、y方向速度、半径
float rect_left_x, rect_top_y, rect_width, rect_height, rect_vx; // 方块障碍物的相关参数
int score = 0; // 得分
width = 600; // 游戏画面高度
height = 400; // 游戏画面宽度
gravity = 0.6; // 重力加速度
initgraph(width, height); // 新建画布
radius = 20; // 小球半径
ball_x = width / 4; // 小球x位置
ball_y = height - radius; // 小球y位置
ball_vy = 0; // 小球初始y速度为0
int isBallOnFloor = 1; // 小球是否在地面上
rect_height = 100; // 方块高度
rect_width = 20;
rect_left_x = width * 3 / 4; // 方块坐标x坐标
rect_top_y = height - rect_height; // 方块顶部y坐标
rect_vx = -3; // 方块x方向速度
while (1)
{
if (_kbhit()) // 当按键时
{
char input = _getch(); // 获得输入字符
if (input == ' ' && isBallOnFloor == 1) // 当按下空格键时
{
ball_vy = -18; // 给小球一个向上的初速度
isBallOnFloor = 0; // 小球不在地面上了
}
}
ball_vy += gravity; // 根据重力加速度更新小球y方向速度
ball_y += ball_vy; // 根据小球y方向速度更新其y坐标
if (ball_y >= height - radius) // 如果小球落到地面上
{
ball_vy = 0; // y速度为0
ball_y = height - radius; // 避免落到地面下
isBallOnFloor = 1; // 小球回到地面上
}
rect_left_x = rect_left_x + rect_vx; // 方块向左移
if (rect_left_x <= 0) // 如果方块跑到最左边
{
rect_left_x = width; // 在最右边重新出现
score++; // 得分加1
rect_height = rand() % int(height / 4) + height / 4; // 设置随机高度
rect_vx = rand() / float(RAND_MAX) * 4 - 7; // 设置方块随机速度
}
if ((rect_left_x <= ball_x + radius)
&& (rect_left_x + rect_width >= ball_x - radius)
&& (height - rect_height <= ball_y + radius)) // 如果小球碰到方块
{
Sleep(100);
score = 0; // 得分清零
}
cleardevice(); // 清空画面
fillcircle(ball_x, ball_y, radius); // 绘制小球
fillrectangle(rect_left_x, height - rect_height, rect_left_x + rect_width, height); // 画方块
TCHAR s[20]; // 定义字符串数组
swprintf_s(s, _T("%d"), score); // 将score转换为字符串
settextstyle(40, 0, _T("宋体")); // 设置文字大小、字体
outtextxy(50, 30, s); // 输出得分文字
Sleep(10);
}
closegraph();
return 0;
}