C/C++ 趣味编程——小球自由落体

本文详细介绍了如何使用C语言和EASYX图形库绘制小球,并通过循环、Sleep和cleardevice等技术实现小球的下落动画,最终实现小球触底反弹的物理模拟。
摘要由CSDN通过智能技术生成

       

一、绘制小球

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>yx是否大于y
x<yx是否小于y
x==yx是否等于y
x!=yx是否不等于y
x>=yx是否大于等于y
x<=yx是否小于等于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;

最后完整结果如图: 

        综上所述,我们就完成了一个遵循物理规则的小球触底反弹的效果

  • 19
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值