目录
准备工作
一、显示一个静止的小球
二、显示多个小球
使用#define美化代码
三、小球下落动画
四、利用while循环实现小球下落
五、利用if语句实现小球重复下落
六、实现小球落地反弹
七、实现小球加速下落
文章导读
本文主要内容为,利用图形库与简单的C语言语法实现仿真自由落体小球。有多仿真呢?在代码中,我们引入了速度、加速度、阻力的概念,目的是尽量模仿真实的物理世界。但是真实的实现过程和物理知识没多大关系,所以小伙伴们放心食用哦~
正文
准备工作
- vs2013/2019/2022,选择一款IDE;(并不代表其它的不能,只是我没试过而已)
- 下载安装easyx;
- 进入官网easyx下载;
- 点击安装;
- 到这就OK了,开搞!
一、显示一个静止的小球
注意
- 文件类型为
.cpp
不是.c
; - 必须包含头文件
graphics.h
与stdio.h
; - 接下来的内容请
仔细阅读注释
的内容。
<1.1>
#include<graphics.h> #include<stdio.h> int main() { initgraph(600, 600); //初始化游戏窗口画面,宽600,高600 fillcircle(300, 300, 50); //在坐标(300,300)处画一个半径为50的圆 getchar(); //等待按键 closegraph(); //关闭窗口 return 0; }
二、显示多个小球
修改<1.1>
中的代码。添加几个小球,并控制小球的纵坐标
。
<1.2>
#include<graphics.h> #include<stdio.h> int main() { initgraph(600, 600); //初始化游戏窗口画面,宽600,高600 fillcircle(300, 100, 50); //在坐标(300,100)处画一个半径为50的圆 fillcircle(300, 250, 50); //在坐标(300,250)处画一个半径为50的圆 fillcircle(300, 400, 50); //在坐标(300,400)处画一个半径为50的圆 getchar(); //等待按键 closegraph(); //关闭窗口 return 0; }
使用#define美化代码
当我们需要频繁修改游戏窗口大小或者是小球间的间隔,那么就得每次都手动修改很多数据,未免显得有点麻烦。我们可以用#define定义一些很多地方都用到的数据,例如游戏窗口的大小、小球的间隔等,便于一次性修改。
改进<1.2>中的代码。
<1.3>
#include<graphics.h> #include<stdio.h> #define G_WIDTH 600 //游戏窗口的宽度 #define G_HEIGHT 600 //游戏窗口的高度 #define STEP 100 //两小球间的距离 int main() { int y = 100; //第一个小球的高度 initgraph(G_WIDTH, G_HEIGHT); //初始化游戏窗口画面 fillcircle(300, y, 20); //在坐标(300,y)处画一个半径为20的圆 y += STEP; fillcircle(300, y, 20); y += STEP; fillcircle(300, y, 20); y += STEP; fillcircle(300, y, 20); y += STEP; fillcircle(300, y, 20); getchar(); //等待按键 closegraph(); //关闭窗口 return 0; }
三、小球下落动画
在<1.3>
的基础上,每绘制一个小球后,加上Sleep(1000)
语句,表示程序暂停一秒
,即可实现小球从上向下一次出现的效果。
<1.4>
#include<graphics.h> #include<stdio.h> #define G_WIDTH 600 //游戏窗口的宽度 #define G_HEIGHT 600 //游戏窗口的高度 #define STEP 100 //两小球间的距离 int main() { int y = 100; //第一个小球的高度 initgraph(G_WIDTH, G_HEIGHT); //初始化游戏窗口画面 fillcircle(300, y, 20); //在坐标(300,y)处画一个半径为20的圆 Sleep(1000); //休眠1000毫秒即1秒 y += STEP; fillcircle(300, y, 20); Sleep(1000); y += STEP; fillcircle(300, y, 20); Sleep(1000); y += STEP; fillcircle(300, y, 20); Sleep(1000); y += STEP; fillcircle(300, y, 20); getchar(); //等待按键 closegraph(); //关闭窗口 return 0; }
接着,利用cleardevice()
清屏函数,在绘制新的小球前先清除画面上的内容,即可实现一个小球逐渐下落的动画效果。
<1.5>
#include<graphics.h> #include<stdio.h> #define G_WIDTH 600 //游戏窗口的宽度 #define G_HEIGHT 600 //游戏窗口的高度 #define STEP 100 //两小球间的距离 int main() { int y = 100; //第一个小球的高度 initgraph(G_WIDTH, G_HEIGHT); //初始化游戏窗口画面 cleardevice(); //清屏函数 fillcircle(300, y, 20); //在坐标(300,y)处画一个半径为20的圆 Sleep(1000); //休眠1000毫秒即1秒 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; cleardevice(); fillcircle(300, y, 20); getchar(); //等待按键 closegraph(); //关闭窗口 return 0; }
四、利用while循环实现小球下落
<1.5>
的代码中有很多重复的内容,我们可以用循环
来代替。
<1.6>
#include<graphics.h> #include<stdio.h> #define G_WIDTH 600 //游戏窗口的宽度 #define G_HEIGHT 600 //游戏窗口的高度 int main() { int y = 100; //第一个小球的高度 initgraph(G_WIDTH, G_HEIGHT); //初始化游戏窗口画面 cleardevice(); while (1) { y = y + 1; cleardevice(); //清屏函数 fillcircle(300, y, 20); //在坐标(300,y)处画一个半径为20的圆 Sleep(10); //休眠10毫秒 } getchar(); //等待按键 closegraph(); //关闭窗口 return 0; }
五、利用if语句实现小球重复下落
当小球下落到达游戏窗口的边界
处,重新为y
赋值,即y=-20
,实现重复下落。
<1.7>
//自由落体小球 Free-fall balls #include<graphics.h> #include<stdio.h> #define G_WIDTH 600 //游戏窗口的宽度 #define G_HEIGHT 600 //游戏窗口的高度 int main() { int y = 100; //第一个小球的高度 initgraph(G_WIDTH, G_HEIGHT); //初始化游戏窗口画面 cleardevice(); while (1) { y = y + 1; if (y > 620) { y = -20; } cleardevice(); //清屏函数 fillcircle(300, y, 20); //在坐标(300,y)处画一个半径为20的圆 Sleep(10); //休眠10毫秒 } getchar(); //等待按键 closegraph(); //关闭窗口 return 0; }
六、实现小球落地反弹
定义一个变量vy
表示小球在竖直方向上的速度
,并初始化为3
。在while
循环中纵坐标y
每次增加vy
。
当小球落到地面,即到达游戏窗口边界时,令vy=-vy
,使小球向上弹起。
<1.8>
#include<graphics.h> #include<stdio.h> #define G_WIDTH 600 //游戏窗口的宽度 #define G_HEIGHT 600 //游戏窗口的高度 int main() { int y = 100; //第一个小球的高度 int vy = 3; //小球竖直方向的速度 initgraph(G_WIDTH, G_HEIGHT); //初始化游戏窗口画面 cleardevice(); while (1) { y = y + vy; if (y >=580) //因为小球的底部到达边界即可 { vy = -vy; } cleardevice(); //清屏函数 fillcircle(300, y, 20); //在坐标(300,y)处画一个半径为20的圆 Sleep(10); //休眠10毫秒 } getchar(); //等待按键 closegraph(); //关闭窗口 return 0; }
七、实现小球加速下落
为了更加真实的模仿真实世界,在自由落体时,物体会有向下的重力加速度,大小为g=1.0(根据自己的喜好调节)。另外为了更加精确的表示数值,我们可以将之前的坐标和速度的类型改为float类型。
还记得物理课上讲的加速度如何影响速度吗?在while循环中,速度一直在变化,每次增加g,即vy=vy+g。
<1.9>
#include<graphics.h> #include<stdio.h> #define G_WIDTH 600 //游戏窗口的宽度 #define G_HEIGHT 600 //游戏窗口的高度 int main() { float y = 100; //第一个小球的高度 float vy = 0; //小球竖直方向的速度 float g = 1.0; //重力加速度 initgraph(G_WIDTH, G_HEIGHT); //初始化游戏窗口画面 cleardevice(); while (1) { vy = vy + g; //改变速度 y = y + vy; if (y >=580) //因为小球的底部到达边界即可 { vy = -vy; } cleardevice(); //清屏函数 fillcircle(300, y, 20); //在坐标(300,y)处画一个半径为20的圆 Sleep(10); //休眠10毫秒 } getchar(); //等待按键 closegraph(); //关闭窗口 return 0; }
另外,小球在自由落体期间会受到阻力
的影响。我们让小球在每次落地弹起的时候,速度变为之前的0.95
倍。当小球停下时,要让小球正好停止在地面上,防止小球穿过地面。
<1.10>
#include<graphics.h> #include<stdio.h> #define G_WIDTH 600 //游戏窗口的宽度 #define G_HEIGHT 600 //游戏窗口的高度 int main() { float y = 100; //第一个小球的高度 float vy = 0; //小球竖直方向的速度 float g = 0.8; //重力加速度 initgraph(G_WIDTH, G_HEIGHT); //初始化游戏窗口画面 cleardevice(); while (1) { vy = vy + g; //改变速度 y = y + vy; if (y >=580) //因为小球的底部到达边界即可 { vy = -0.95*vy; //考虑阻力的影响 } if (y > 580) //使小球静止在地面上 { y = 580; } cleardevice(); //清屏函数 fillcircle(300, y, 20); //在坐标(300,y)处画一个半径为20的圆 Sleep(10); //休眠10毫秒 } getchar(); //等待按键 closegraph(); //关闭窗口 return 0; }
<1.10>
的代码就是最终版本了。由于某些原因,我不能在每一段代码后都附上演示动画,所以小伙伴们最好能够在敲完一段代码后,立即运行并检验。