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

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

目录


准备工作

一、显示一个静止的小球

二、显示多个小球

使用#define美化代码

三、小球下落动画

四、利用while循环实现小球下落

五、利用if语句实现小球重复下落

六、实现小球落地反弹

七、实现小球加速下落


文章导读


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


正文


准备工作


  1. vs2013/2019/2022,选择一款IDE;(并不代表其它的不能,只是我没试过而已)
  2. 下载安装easyx;
  • 进入官网easyx下载
  • 点击安装;
  • 1.png
  • 到这就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;
}

2.png


二、显示多个小球


修改<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;
}


3.png


使用#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;
}

4.png


三、小球下落动画


<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>的代码就是最终版本了。由于某些原因,我不能在每一段代码后都附上演示动画,所以小伙伴们最好能够在敲完一段代码后,立即运行并检验。


目录
相关文章
|
9月前
|
API C++ Windows
Visual C++运行库、.NET Framework和DirectX运行库的作用及常见问题解决方案,涵盖MSVCP140.dll丢失、0xc000007b错误等典型故障的修复方法
本文介绍Visual C++运行库、.NET Framework和DirectX运行库的作用及常见问题解决方案,涵盖MSVCP140.dll丢失、0xc000007b错误等典型故障的修复方法,提供官方下载链接与系统修复工具使用指南。
2006 2
|
9月前
|
缓存 算法 程序员
C++STL底层原理:探秘标准模板库的内部机制
🌟蒋星熠Jaxonic带你深入STL底层:从容器内存管理到红黑树、哈希表,剖析迭代器、算法与分配器核心机制,揭秘C++标准库的高效设计哲学与性能优化实践。
C++STL底层原理:探秘标准模板库的内部机制
|
9月前
|
Ubuntu API C++
C++标准库、Windows API及Ubuntu API的综合应用
总之,C++标准库、Windows API和Ubuntu API的综合应用是一项挑战性较大的任务,需要开发者具备跨平台编程的深入知识和丰富经验。通过合理的架构设计和有效的工具选择,可以在不同的操作系统平台上高效地开发和部署应用程序。
331 11
|
9月前
|
IDE 编译器 开发工具
msvcp100.dll,msvcp120.dll,msvcp140.dll,Microsoft Visual C++ 2015 Redistributable,Visual C++ 运行库安装
MSVC是Windows下C/C++开发核心工具,集成编译器、链接器与调试器,配合Visual Studio使用。其运行时库(如msvcp140.dll)为程序提供基础函数支持,常因缺失导致软件无法运行。通过安装对应版本的Microsoft Visual C++ Redistributable可解决此类问题,广泛应用于桌面软件、游戏及系统级开发。
1122 2
|
10月前
|
并行计算 C++ Windows
|
安全 C语言 C++
比较C++的内存分配与管理方式new/delete与C语言中的malloc/realloc/calloc/free。
在实用性方面,C++的内存管理方式提供了面向对象的特性,它是处理构造和析构、需要类型安全和异常处理的首选方案。而C语言的内存管理函数适用于简单的内存分配,例如分配原始内存块或复杂性较低的数据结构,没有构造和析构的要求。当从C迁移到C++,或在C++中使用C代码时,了解两种内存管理方式的差异非常重要。
418 26
|
10月前
|
监控 网络协议 安全
基于标准C语言实现的跨平台Modbus协议库
基于标准C语言实现的跨平台Modbus协议库
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
编译器 C++ 容器
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
578 12