学习C语言十天了,我实现了仿真自由落体小球『C/C++图形库EasyX』

news2025/2/28 17:15:48

文章目录

  • 💐专栏导读
  • 文章导读
  • 准备工作
  • 一、显示一个静止的小球
  • 二、显示多个小球
    • 使用#define美化代码
  • 三、小球下落动画
  • 四、利用while循环实现小球下落
  • 五、利用if语句实现小球重复下落
  • 六、实现小球落地反弹
  • 七、实现小球加速下落

💐专栏导读

🌸作者简介:花想云,在读本科生一枚,致力于 C/C++、Linux 学习。

🌸本文收录于 初学C语言必会的20个小游戏专栏,本专栏主要内容为利用C/C++与图形库EasyX实现各种有趣的小游戏。

🌸相关专栏推荐:C语言初阶系列C语言进阶系列数据结构与算法

文章导读

本文主要内容为,利用图形库与简单的C语言语法实现仿真自由落体小球。有多仿真呢?在代码中,我们引入了速度、加速度、阻力的概念,目的是尽量模仿真实的物理世界。但是真实的实现过程和物理知识没多大关系,所以小伙伴们放心食用哦~

在这里插入图片描述

准备工作

  1. vs2013/2019/2022,选择一款IDE;(并不代表其它的不能,只是我没试过而已)
  2. 下载安装easyx;
  • 进入官网easyx下载;
  • 点击安装;

在这里插入图片描述

到这就OK了,开搞!

一、显示一个静止的小球

注意

  • 文件类型为.cpp不是.c
  • 必须包含头文件graphics.hstdio.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>的代码就是最终版本了。由于某些原因,我不能在每一段代码后都附上演示动画,所以小伙伴们最好能够在敲完一段代码后,立即运行并检验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/426603.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

剪枝与重参第七课:YOLOv8剪枝

目录YOLOv8剪枝前言1.Overview2.Pretrain(option)3.Constrained Training4.Prune4.1 检查BN层的bias4.2 设置阈值和剪枝率4.3 最小剪枝Conv单元的TopConv4.4 最小剪枝Conv单元的BottomConv4.5 Seq剪枝4.6 Detect-FPN剪枝4.7 完整示例代码5.YOLOv8剪枝总结总结YOLOv8剪枝 前言 …

【三十天精通Vue 3】第八天 Vue 3 生命周期钩子详解

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: 三十天精通 Vue 3 文章目录引言一、Vue 3 生命周期钩子概述1.1 生命周期钩子的简介1.2 生命周…

mulesoft MCIA 破釜沉舟备考 2023.04.14.11

mulesoft MCIA 破釜沉舟备考 2023.04.14.111. To implement predictive maintenance on its machinery equipment, ACME Tractors has installed thousands of IoT sensors that will send data for each machinery asset as sequences of JMS messages, in near real-time, to…

惠普Probook455电脑开机突然卡住无法进入桌面

惠普Probook455电脑开机突然卡住无法进入桌面解决方法分享。最近有用户使用的惠普Probook455电脑在开机的时候&#xff0c;电脑一直卡在开机的界面上&#xff0c;无法进入到系统中。无论是重启还是安全模式都无法解决问题。那么遇到这个情况怎么去进行问题的解决&#xff0c;来…

C++---状态压缩dp---炮兵阵地(每日一道算法2023.4.16)

注意事项&#xff1a; 本题为"状态压缩dp—蒙德里安的梦想"和"状态压缩dp—小国王"和"状态压缩dp—玉米田"的近似题&#xff0c;建议先阅读这三篇文章并理解。 题目&#xff1a; 司令部的将军们打算在 NM 的网格地图上部署他们的炮兵部队。 一个…

GoogleTest+VS code编译和编写简单测试用例

目录前言一、安装gtest二、 编译gtest与运行单元测试第一种编译方式第二种编译方式前言 在B站看了非常多Gtest的教学视频&#xff0c;CSDN上gtest博客也特别多&#xff0c;但是都非常陈旧或者根本不是用vscode。本篇目的在于&#xff0c;说明如何在vscode上编写简单单元测试。…

day01_Java概述丶环境搭建

Java背景知识 Java概述 概述&#xff1a;计算机语言就是人与计算机之间进行信息交流沟通的一种特殊语言。所谓计算机编程语言&#xff0c;就是人们可以使用编程语言对计算机下达命令&#xff0c;让计算机完成人们需要的功能。 Java语言&#xff1a;是美国Sun公司&#xff08…

Siamese network

文章目录一、相似性度量1. 欧氏距离2. 马氏距离二、Siamese network1. Siamese network 基础架构2. 损失函数3. 不同的Siamese network3.1. 行人重识别3.2 其他应用场景一、相似性度量 相似性度量是机器学习中一个非常基础的概念&#xff0c;是评定两个事物之间相似程度的一种度…

E: 仓库 “http://mirrors.aliyun.com/ubuntu eoan Release” 没有 Release 文件 —— 解决方案

Ubuntu 20.04 更新的时候&#xff0c;遇到如下问题&#xff1a; 可以通过修改源&#xff0c;来进行修复&#xff1a; 1、登录如下网址&#xff1a;LUGs repo file generator 2、选择对应的 Ubuntu 版本&#xff0c;这里我是 Ubuntu 20.04 点击 Download&#xff0c;会下载一个 …

DUBBO注册中心

注册中心上保存四种类型的数据: providers: 服务提供者目录,记录着服务提供者的ip、端口等信息。 consumers: 服务消费者目录,记录服务消费者的元数据信息,服务提供者并不会用到服务消费者的信息,这里要记录消费者的信息,是给服务治理中心(dubbo-admin)使用的。 route…

五分钟排查Linux的健康状态

五分钟排查Linux的健康状态1. CPU1.1 top命令1.2 什么是负载1.3 vmstat2. 内存2.1 观测命令2.2 CPU缓存2.3 HugePage2.4 预先加载3. I/O3.1 观测命令3.2 零拷贝4. 网络参考&#xff1a;《Linux运维实战》、xjjdog 操作系统作为所有程序的载体&#xff0c;对应用的性能影响是非常…

论文阅读 | Interpolated Convolutional Networks for 3D Point Cloud Understanding

前言&#xff1a;ICCV2019点云特征提取点卷积InterpoConv Interpolated Convolutional Networks for 3D Point Cloud Understanding 引言 点云是不规则、无序、且稀疏的 处理这样的点云数据有两大类方法 第一&#xff1a;voxel化 directly rasterize irregular point clouds…

《Netty》从零开始学netty源码(三十八)之PoolSubPage

PoolSubPage 上一节中我们提到了PooledByteBufAllocator类&#xff0c;先看下netty中有关内存的类关系&#xff1a; 从图中可以看到PoolSubPage为最小单位&#xff0c;所以我们先从最小的开始分析&#xff0c;先看下它的属性值&#xff1a; 为了更好的理解这些属性的意义&…

表情包MD编辑器简单使用

&#x1f337;1 表情包 ⭐️&#xff08;1&#xff09;常规表情图标 &#x1f600; &#x1f601; &#x1f602; &#x1f603; &#x1f604; &#x1f605; &#x1f606; &#x1f609; &#x1f60a; &#x1f60b; &#x1f60e; &#x1f60d; &#x1f618; &#x1…

(Deep Learning)交叉验证(Cross Validation)

交叉验证&#xff08;Cross Validation&#xff09; 交叉验证&#xff08;Cross Validation&#xff09;是一种评估模型泛化性能的统计学方法&#xff0c;它比单次划分训练集和测试集的方法更加稳定、全面。 交叉验证不但可以解决数据集中数据量不够大的问题&#xff0c;也可以…

CSS中flex属性的的使用以及应用场景有哪些

文章目录一. flex属性?(虚假的) --- 这里主要是回顾1.1 flex-grow1.2 flex-shrink1.3 flex-basis二. flex属性 ! (真正的!!!)三. flex一些常见的值, 以及使用场景3.1 flex:initial 使用场景3.2 flex:0 和 flex:node 适用场景3.3 flex:1 和 flex:auto3.4 总结一. flex属性?(虚…

54 openEuler搭建Mariadb数据库服务器-Mariadb介绍

文章目录54 openEuler搭建Mariadb数据库服务器-Mariadb介绍54.1 MariaDB的架构54.2 MariaDB的存储引擎54 openEuler搭建Mariadb数据库服务器-Mariadb介绍 MariaDB数据库管理系统是MySQL的一个分支&#xff0c;主要由开源社区在维护&#xff0c;采用GPL授权许可。MariaDB的目的…

零售数据分析操作篇14:利用内存计算做销售筛选分析

各位数据的朋友&#xff0c;大家好&#xff0c;我是老周道数据&#xff0c;和你一起&#xff0c;用常人思维数据分析&#xff0c;通过数据讲故事。 上一讲讲了图表间联动的应用场景&#xff0c;即当我们点击某个图表时&#xff0c;会影响其他图表一起变化&#xff0c;而变化背…

Vue3 Element-plus el-menu无限级菜单组件封装

对于element中提供给我们的el-menu组件最多可以实现三层嵌套&#xff0c;如果多一层数据只能自己通过变量去加一层&#xff0c;如果加了两层、三层这种往往是行不通的&#xff0c;所以只能进行封装 效果图一、定义数据 MenuData.ts export default [{id: "1",name:…

spring boot 访问HTML

HTML整合spring boot简介默认文件路径访问自定义文件路径访问或通过Controller控制器层跳转访问简介 SpringBoot默认的页面映射路径&#xff08;即模板文件存放的位置&#xff09;为“classpath:/templates/*.html”。静态文件路径为“classpath:/static/”&#xff0c;其中可…