一、绘制小球
1、绘制一个小球
在安装EASYX图形库之后,即可创建窗口并运用fillcircle绘制圆,就是我们需要的小球了
在需要给代码注释时,可以采用:
(1)单行注释: // …
(2) 多行注释:/* … */
#include<stdio.h>
#include<conio.h>
#include<graphics.h>
int main()
{
initgraph(600, 600);//窗口信息 600宽 600高
fillcircle(300, 300, 100);//圆的信息(300,300)为圆心坐标,100为半径
_getch();//等待按键
closegraph();//关闭窗口
return 0;
}
2、绘制多个小球(利用变量修改小球位置)
同理,可以用此方法绘制更多小球
运用定义变量的方式,令小球随着指定规律(y=y+step)慢慢改变位置
#include<stdio.h>
#include<conio.h>
#include<graphics.h>
int main()
{
int y= 100;
int step = 100;//定义变量
///变量名可以由字母、下划线、数字组成,开头不能是数字 此外,大小写不同表示变量即不同 ///
initgraph(600, 600);
fillcircle(300, y, 20);
y = y + step;
fillcircle(300, y, 20);
y = y + step;
fillcircle(300, y, 20);
y = y + step;
_getch();
closegraph();
return 0;
}
ps:y+=step 与 y=y+step 效果相等
#include<stdio.h>
#include<conio.h>
#include<graphics.h>
int main()
{
int y= 100;
int step = 100;//定义变量
///变量名可以由字母、下划线、数字组成,开头不能是数字 此外,大小写不同表示变量即不同 ///
initgraph(600, 600);
fillcircle(300, y, 20);
y += step;
fillcircle(300, y, 20);
y += step;
fillcircle(300, y, 20);
y += step;
_getch();
closegraph();
return 0;
}
此时,我们获得了一个小球图像下移的过程,但是过程中所有小球都会同时显示出来
二、小球下落动画
1、小球下落
在上述基础下,每绘制完一个小球,删除,再绘制下一个,就可以实现小球从上至下出现的效果
首先,利用Sleep(1000)语句——程序暂停1000毫秒(1秒),实现小球至上而下出现,绘制完一个,再绘制下一个
然后利用cleardevice()清屏函数,在绘制新小球前清除画面上内容
#include<stdio.h>
#include<conio.h>
#include<graphics.h>
int main()
{
int y= 100;
int step = 100;//定义变量
///变量名可以由字母、下划线、数字组成,开头不能是数字 此外,大小写不同表示变量即不同 ///
initgraph(600, 600);
fillcircle(300, y, 20);
Sleep(1000);//停顿一秒
y += step;//小球y轴参数改变
cleardevice();//清除屏幕
fillcircle(300, y, 20);//小球y轴参数改变移动结果
Sleep(1000);
y += step;
cleardevice();
fillcircle(300, y, 20);
Sleep(1000);
y += step;
cleardevice();
fillcircle(300, y, 20);
Sleep(1000);
y += step;
cleardevice();
fillcircle(300, y, 20);
Sleep(1000);
y += step;
_getch();
closegraph();
return 0;
}
F5快捷运行,最后的结果如图,和我们设想的小球下落很接近
但是,每次都要输入一大段
fillcircle(300, y, 20);
Sleep(1000);//停顿一秒
y += step;//小球y轴参数改变
cleardevice();//清除屏幕
太过麻烦,于是下一步简化代码
2、利用while实现小球连续下落
while()表示当括号内为真时,重复执行之后语句。在C语言中,0为假,非0的数(比如1)为真。重复执行多条语句时,将其置于花括号{ }内。
#include<stdio.h>
#include<conio.h>
#include<graphics.h>
int main()
{
int y= 50;//定义变量
///变量名可以由字母、下划线、数字组成,开头不能是数字 此外,大小写不同表示变量即不同 ///
initgraph(600, 600);
while (1)
{
fillcircle(300, y, 20);
Sleep(10);//停顿
y +=1;//小球y轴参数改变
cleardevice();//清除屏幕
///因为要重复,所以注意几条语句的重复顺序 ///
}
_getch();
closegraph();
return 0;
}
运行结果如下:
此时小球到窗口底部就消失了,为了实现小球在现实中触地反弹的效果,我们需要进一步改进代码
3、利用if语句实现小球重复下落
if语句,也叫选择判断语句,if()表示——如果满足()内表达式的条件,则执行后面的语句,之后若执行多条语句,也用花括号{ }包含起来
关于if()内的表达式:
C语言中有6中运算判断两个数字的大小关系:
表达式 | 含义 |
x>y | x是否大于y |
x<y | x是否小于y |
x==y | x是否等于y |
x!=y | x是否不等于y |
x>=y | x是否大于或等于y |
x<=y | x是否小于或等于y |
ps:x=y是赋值语句,表示把y的值赋给x。if(x==y)表示,如果x和y相等执行之后语句
最后完整代码如下:
#include<stdio.h>
#include<conio.h>
#include<graphics.h>
int main()
{
int y= 50;//定义小球初始位置
int vy = 3;//定义小球初速度
initgraph(600, 600);
while (1)
{
fillcircle(300, y, 20);
Sleep(10);//停顿
y +=vy;//小球位置随速度改变
if (y >= 620)
y = -20;//如果小球上边缘完全离开屏幕,返回顶部下边缘触顶重新下落
cleardevice();//清除屏幕
}
_getch();
closegraph();
return 0;
}
if(y>=620)表示如果小球圆心坐标大于620,则执行后续语句y=-20重置圆心位置到-20
这里之所以是620和-20,是因为y是小球的圆心位置,还有20的半径为了保证小球上边缘完全离开屏幕,再返回顶部从小球下边沿触屏幕顶部重新下落
4、小球触底反弹
有了上述代码我们只要满足——
if(触底)
vy速度反向,小球向上运动即可
#include<stdio.h>
#include<conio.h>
#include<graphics.h>
int main()
{
int y= 50;//定义小球初始位置
int vy = 3;//定义小球初速度
initgraph(600, 600);
while (1)
{
fillcircle(300, y, 20);
Sleep(10);//停顿
y +=vy;//小球位置随速度改变
if (y >= 580)
vy = -vy;//如果小球下边缘触底,速度反向向上弹起
if (y<=20)
vy = -vy;//当然不能弹过头飞出屏幕上方
cleardevice();//清除屏幕
}
_getch();
closegraph();
return 0;
}
此时是上下边缘不能超出窗口,所以,y的判定变成了580与20
最后实际结果如图
5、玩的就是真实
在知道如何使小球反弹和下落之后,我们带入一下真实的物理情景
1、小球运动过程中是逐渐加速的,设置小球重力加速度g
2、反弹过程中受到重力和空气阻力影响反向后的小球不是相同速度
根据以上两点修改代码:
#include<stdio.h>
#include<conio.h>
#include<graphics.h>
int main()
{
int y= 100;//定义小球初始位置
int vy = 0;//定义小球初速度
float g = 0.5;//当然不是真实重力加速度,只是个实现加速效果的数值
initgraph(600, 600);
while (1)
{
y =y+vy;//小球位置随速度改变
vy = vy+g;
if (y >= 580)
vy = -0.95*vy;///如果小球下边缘触底,速度反向向上弹起并且有损失///
if (y<=20)
vy = -vy;//当然不能弹过头飞出屏幕上方
fillcircle(300, y, 20);
Sleep(10);
cleardevice();//清除屏幕
}
_getch();
closegraph();
return 0;
}
在仔细的采用浮点数float了小数变量g之后,运行结果却不是预想的g=0.5的情形,小球静止不动了
原因在于——在相加后依旧采用整型vy,y接收变量
如果你尝试将一个float
型和一个int
型相加的结果赋值给一个int
型变量,那么float
型的结果会被强制转换(或称为类型转换)成int
型。这种强制转换通常会导致小数部分被舍弃(而不是四舍五入)。请注意,这种转换的行为可能依赖于你使用的具体编程语言和环境。
所以0.5的g被舍弃变成了0,导致小球不再运动
修改代码后,采用float型接收变量
#include<stdio.h>
#include<conio.h>
#include<graphics.h>
int main()
{
float y= 100;//定义小球初始位置
float vy = 0;//定义小球初速度
float g = 0.5;//当然不是真实重力加速度,只是个实现加速效果的数值
initgraph(600, 600);
while (1)//循环运行
{
//停顿
y =y+vy;//小球速度随加速度增加
vy = vy+g;//小球位置随速度改变
if (y >= 580)
vy = -0.95*vy;///如果小球下边缘触底,速度反向向上弹起并且有损失///
fillcircle(300, y, 20);
Sleep(10);
cleardevice();//清除屏幕
}
_getch();
closegraph();
return 0;
最后完整结果如图:
综上所述,我们就完成了一个遵循物理规则的小球触底反弹的效果