“别碰方块”游戏

本篇我们将探讨如何实现一个小球跳跃躲避方块的游戏。

kbhit()函数当用户有键盘输入时返回1,否则返回0。当用户按键时,执行if (kbhit())内的语句。首先获得用户输入的字符,存储在变量input中,如果用户按下的是空格键,则输出提示文字,如以下代码所示。图片

按空格键控制小球起跳

以下代码让小球初始在地面上,按下空格键后起跳,落地后小球静止。把窗口宽度、高度、小球半径等数值均用变量表示,这样代码更易阅读与调整,如下所示。图片

方块的绘制与移动

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_height = 100; // 方块高度
rect_width = 20; // 方块宽度
rect_left_x = width*3/4; // 方块左边x坐标
rect_top_y = height – rect_height; // 方块顶部y坐标


// 画方块

fillrectangle(rect_left_x, height – rect_height, rect_left_x + rect_width,height);图片

其中,rect_left_x记录方块最左边的x坐标,rect_width记录方块宽度,则方块最右边的x坐标为rect_left_x + rect_width。
由于方块最底部在窗口底部,因此其底部y坐标为窗口高度height。rect_height记录方块的高度,所以方块最顶部的y坐标rect_top_y为height-rect_height。
综上分析,函数fillrectangle(rect_left_x, height – rect_height, rect_left_x + rect_width,height)可绘制出如图所示的方块。图片

进一步,添加变量rect_vx记录方块在x方向上的速度,并初始化为-3。在while语句中,让方块从右向左移动。当方块到达窗口最左边时,再让其从最右边出现。图片

小球和方块的碰撞判断

列出小球和方块发生碰撞的3种边界情况,分析可认为小球和方块发生碰撞需同时满足以下3个条件。图片

(a)rect_left_x <= ball_x + radius(方块最左边在小球最右边的左侧或二者x坐标相同)。
(b)rect_left_x + rect_width >= ball_x – radius(方块最右边在小球最左边的右侧或二者x坐标相同)。
(c)height – rect_height <= ball_y + radius(方块最上边在小球最下边的上侧或二者y坐标相同)。

利用C语言提供的3种逻辑运算符:!(非)、&&(与)、||(或),我们可以实现多个逻辑条件的组合。

利用逻辑与运算符,在上面代码基础上添加如下代码,即可实现小球和方块的碰撞判断。当发生碰撞时,利用Sleep( )函数实现类似慢动作的效果:

// 如果小球碰到方块
   if ((rect_left_x <= ball_x + radius)

&& (rect_left_x + rect_width >= ball_x – radius)

&& (height – rect_height <= ball_y + radius) )
    {
        Sleep(100); // 慢动作效果
     }图片

随机方块的速度和高度

rand()函数可以生成随机整数,程序运行后输出一些随机数。

利用取余运算符,rand()%10可以生成0~9的一个随机整数。

RAND_MAX存储了rand( )函数所能生成的最大整数,rand( )/float(RAND_MAX)即可生成0~1的随机小数。

当方块重新出现时,添加代码设置其随机高度范围为height/4到height/2,随机速度为-3到7,添加代码如下:图片

得分的计算与显示

定义整型变量记录游戏的得分,并初始化为0:
int score = 0; // 得分
当方块跑到画面最左边时,得分增加1:
if (rect_left_x <= 0) // 如果方块跑到最左边
{
    score = score + 1; // 得分+1
}
当方块碰到小球时,得分清零:
// 如果小球碰到方块
if ((rect_left_x <= ball_x + radius) 
    && (rect_left_x + rect_width >= ball_x – radius) 
    && (height – rect_height <= ball_y + radius) )
{
    score = 0; // 得分清零
}
另外,利用EasyX的文字输出功能,可输出score:
TCHAR s[20]; // 定义字符串数组
_stprintf_s(s, _T(“%d”), score); // 将score转换为字符串
settextstyle(40, 0, _T(“宋体”)); // 设置文字大小、字体
outtextxy(50, 30, s); // 输出得分文字图片图片

避免空中起跳

我们处理一个游戏中的小bug,避免小球在空中还能继续起跳。
首先,定义变量isBallOnFloor记录小球是否在地面上,并初始化为1,表示开始小球在地面上:

int isBallOnFloor = 1; // 小球是否在地面上,避免重复起跳

当用户按下空格键时,必须同时满足isBallOnFloor为1,才让小球起跳。起跳后,设定isBallOnFloor = 0,表示目前小球不在地面上了:

if (input==’ ‘ && isBallOnFloor==1) // 当按下空格键时,并且小球在地面上时
{
    ball_vy = -17; // 给小球一个向上的速度
    isBallOnFloor = 0; // 表示小球不在地面了,不能重复起跳
}

当小球再次落到地面上后,设定isBallOnFloor = 1,表示目前小球又重新到了地面上,可以起跳了:
if (ball_y >= height-radius) // 如果小球落到地面上
{
    ball_vy = 0; // y速度为0
    ball_y = height-radius; // 规范其y坐标,避免落到地面下
    isBallOnFloor = 1; // 表示小球在地面上
}
图片图片

END

利用绘制圆、矩形的函数,分析了“别碰方块”游戏的实现方式。

 2022-08-21 19:04 发表于江苏

阅读原文

简介:冷笑话要囤到夏天慢慢讲?,欢迎关注微信公众号:小白的冬天
(0)
打赏 喜欢就点个赞支持下吧 喜欢就点个赞支持下吧

声明:本文来自“小白的冬天”,分享链接:https://www.zyxiao.com/p/324537    侵权投诉

网站客服
网站客服
内容投稿 侵权处理
分享本页
返回顶部