C语言实现极简物理引擎(一):小球自由落体

目录

目标

开发环境

基本函数

        头文件

        光标定位函数 gotoxy 

        光标隐藏函数 hideCursor

绘制背景和小球

        绘制背景

        绘制小球

        效果

模拟自由落体

        边界检测

        物理模拟

主函数

完整代码

最终效果


目标

        熟悉控制台输出的基本函数

        使用控制台实现小球的自由落体模拟


开发环境

        本项目在Dev-C++环境下开发


基本函数

头文件

        在项目开始之前,我们需要引入几个必要的头文件

#include<stdio.h>
#include<stdbool.h>
#include<conio.h>
#include<Windows.h> 

光标定位函数 gotoxy

        功能:将控制台光标跳转到指定位置(不是鼠标)

void gotoxy(int x,int y){
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);  // 获取标准输出设备句柄
    COORD pos={x,y};  // 坐标位置
    SetConsoleCursorPosition(handle,pos);  // 设置控制台光标位置
}

        使用方法:调用 goto(x, y) 即可将光标移动到控制台 (x, y) 位置处

光标隐藏函数 hideCursor

        功能:隐藏控制台中的光标(防止连续输出时光标闪烁)

void hideCursor(){
    CONSOLE_CURSOR_INFO cursor_info={1,0};  // 0表示隐藏光标
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
}

        使用方法:在主函数中调用 hideCursor() 

        以上函数的实现过于高级,无需深入理解记忆,用到时直接复制粘贴即可。


绘制背景和小球

绘制背景

        为了模拟小球的自由落体,我们首先需要绘制一个25x25的方形区域作为场景

#define MAX_SIZE 25
void drawBackground(){
	for(int x=0;x<MAX_SIZE;x++){
		for(int y=0;y<MAX_SIZE;y++){
			if(x==0 || x==MAX_SIZE-1 || y==0 || y==MAX_SIZE-1)
				printf("墙");  // 可以替换为其他奇奇怪怪的符号
			else printf("  ");  // 注意这里是两个空格
		}
		printf("\n");
	}
}

绘制小球

        接下来,我们在场景中添加一个小球

void drawBall(int x,int y){
	gotoxy(2*x,y);  // 考虑字符长宽比为2:1,x坐标需乘以2
	printf("球");
}

效果

        drawBackground( ); drawBall(2, 2);


模拟自由落体

边界检测

        我们需要确保小球在运动过程中不会超出预定的边界

bool checkBoundary(double x,double y){
	if(x<=0 || x>=MAX_SIZE-1 || y<=0 || y>=MAX_SIZE-1)
		return true;
	else return false;
}

物理模拟

        我们将使用自由落体公式来更新小球的位置,并在控制台中显示其运动轨迹。

        设置刷新时间(单位:ms)

#define REFRESH_TIME 0.01;

        模拟自由落体

void simulateFreeFall(double x,double y,double vx,double vy,double g){
    // x,y: 初始位置    vx,vy:初速度    g:重力加速度
    double t = 0;  // 时间变量
	while(true){
    	drawBall((int)x,(int)y);
    	Sleep(REFRESH_TIME*1000);
    	x = x + vx*t;
    	y = y + vy*t + 0.5*g*t*t;  // 根据物理定律计算x,y
    	t += REFRESH_TIME;  // 时间递增
    	if(checkBoundary(x,y)){  // 边界检测
    		getchar();
    		break;
		};
	}
}

主函数

        最后,我们通过主函数来整合所有功能,并启动模拟过程

int main() {
    HideCursor();  // 隐藏光标
    drawBackground();  // 绘制背景
    simulateFreeFall(1,1,2,0,9.8);  // 模拟小球自由落体
    return 0;
}

完整代码

        以下是经过整合并修改的完整代码

#include<stdio.h>
#include<stdbool.h>
#include<conio.h>
#include<Windows.h> 

int MAX_SIZE = 25;
double REFRESH_TIME = 0.01;

void gotoxy(int x,int y){
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD pos = {x,y};
    SetConsoleCursorPosition(handle,pos);
}

void hideCursor(){
    CONSOLE_CURSOR_INFO cursor_info = {1,0};
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
}

bool checkBoundary(double x,double y){
	if(x<=0 || x>=MAX_SIZE-1 || y<=0 || y>=MAX_SIZE-1)
		return true;
	else return false;
}

void drawBackground(){
	gotoxy(0,0);
	for(int x=0;x<MAX_SIZE;x++){
		for(int y=0;y<MAX_SIZE;y++){
			if(checkBoundary((double)x,(double)y)) printf("墙");
			else printf("  ");
		}
		printf("\n");
	}
}

void drawBall(int x,int y){
	gotoxy(2*x,y);
	printf("球");
}

void simulateFreeFall(double x,double y,double vx,double vy,double g){
    double t = 0;
	while(true){
    	drawBall((int)x,(int)y);
    	Sleep(REFRESH_TIME*1000);
    	x = x + vx*t;
    	y = y + vy*t + 0.5*g*t*t;
    	t += REFRESH_TIME;
    	if(checkBoundary(x,y)){
    		getchar();
    		break;
		};
	}
}

int main(){
	double x,y,vx,vy,g;
	x=1; y=1; vx=1; vy=0; g=9.8;
	
	//此处可自行修改参数 
	//printf("画布大小(m):"); scanf("%d",&MAX_SIZE);
	//printf("\n刷新时间(s):"); scanf("%lf",&REFRESH_TIME);
	//printf("\n初始横坐标(m):"); scanf("%lf",&x); 
	//printf("\n初始纵坐标(m):"); scanf("%lf",&y); 
	//printf("\n初始水平速度(m/s):"); scanf("%lf",&vx);
	//printf("\n初始竖直速度(m/s):"); scanf("%lf",&vy);
	//printf("\n重力加速度(m/s^2):"); scanf("%lf",&g);
	getchar(); 
	
	hideCursor();
	drawBackground();
	simulateFreeFall(x,y,vx,vy,g);

	return 0; 
}

最终效果

相关推荐

  1. c语言实战-扫雷

    2024-02-12 19:34:01       30 阅读
  2. c语言游戏实战(9):大作战

    2024-02-12 19:34:01       52 阅读
  3. C语言游戏实战(9):大作战

    2024-02-12 19:34:01       32 阅读
  4. 《工厂模式(c++)》

    2024-02-12 19:34:01       43 阅读
  5. 《原型模式(c++)》

    2024-02-12 19:34:01       57 阅读
  6. 《过滤器模式(c++)》

    2024-02-12 19:34:01       46 阅读
  7. 《适配器模式(c++)》

    2024-02-12 19:34:01       45 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-12 19:34:01       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-12 19:34:01       106 阅读
  3. 在Django里面运行非项目文件

    2024-02-12 19:34:01       87 阅读
  4. Python语言-面向对象

    2024-02-12 19:34:01       96 阅读

热门阅读

  1. 《AI绘画从入门到精通》专栏总目录

    2024-02-12 19:34:01       67 阅读
  2. 树莓派与vnc的错误 树莓派自启vnc虚拟桌面

    2024-02-12 19:34:01       63 阅读
  3. Rust条件语句:if-else表达式详解

    2024-02-12 19:34:01       50 阅读
  4. winform 绘制无边框四周阴影

    2024-02-12 19:34:01       53 阅读
  5. MongoDB聚合:$densify

    2024-02-12 19:34:01       41 阅读
  6. 快速熟悉 MatrixOne 内核前端

    2024-02-12 19:34:01       56 阅读
  7. 什么是VPS服务器技术

    2024-02-12 19:34:01       54 阅读