Raylib下载详见:https://blog.csdn.net/lijiale20150909/article/details/166683223?spm1001.2014.3001.5501/******************************************************************************* bouncing_ball.c —— raylib 弹球物理演示** 编译Linux / apt 安装 raylib 后* gcc bouncing_ball.c -o bouncing_ball -lraylib -lGL -lm -lpthread -ldl -lrt -lX11** 运行* ./bouncing_ball** 操作* 空格 暂停 / 继续* R 重置球的位置与速度* 鼠标左键 在点击处重新放置球* ESC / 关闭窗口 退出******************************************************************************/#include raylib.h#include math.h#define GRAVITY 100.0f /* 重力加速度像素/秒² */#define RESTITUTION 1.06f /* 弹性系数每次反弹保留的速度比例 */#define SLEEP_SPEED 20.0f /* 静止阈值垂直速度低于此值时认为已停止像素/秒 */#define AIR_DRAG 1.06f /* 空气阻力每秒衰减系数接近 1 表示几乎无阻力 */int main(void){/* ---------- 窗口初始化 ---------- */const int screenWidth 800;const int screenHeight 600;InitWindow(screenWidth, screenHeight, raylib - 弹球物理);SetTargetFPS(60);/* ---------- 小球初始状态 ---------- *//* 注意speed 的单位是「像素/秒」不再是「像素/帧」 */Vector2 position { 100.0f, 100.0f };Vector2 speed { 220.0f, 0.0f };float radius 24.0f;bool pause false;bool sleeping false; /* 球是否已经静止在地面上 *//* ---------- 主循环 ---------- */while (!WindowShouldClose()){/* 输入 */if (IsKeyPressed(KEY_SPACE)) pause !pause;if (IsKeyPressed(KEY_R)){position (Vector2){ 100.0f, 100.0f };speed (Vector2){ 220.0f, 0.0f };sleeping false;}if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){Vector2 m GetMousePosition();position m;speed (Vector2){ 0.0f, 0.0f };sleeping false;}/* 物理更新 */if (!pause !sleeping){float dt GetFrameTime();float dtScale dt ; /* 兼容「按帧书写」的习惯数值 *//* 1) 位移与重力 */position.x speed.x * dtScale;position.y speed.y * dtScale;speed.y GRAVITY * dtScale;/* 2) 空气阻力可选让水平速度缓慢衰减 */speed.x * powf(AIR_DRAG, dtScale);speed.y * powf(AIR_DRAG, dtScale);/* 3) 左右墙壁翻转 把球拉回边界内 */if (position.x radius){position.x radius;speed.x fabsf(speed.x); /* 强制向右 */}else if (position.x GetScreenWidth() - radius){position.x GetScreenWidth() - radius;speed.x -fabsf(speed.x); /* 强制向左 */}/* 4) 上下边界翻转 拉回边界内 能量损耗 */if (position.y radius){position.y radius;speed.y fabsf(speed.y); /* 强制向下 */}else if (position.y GetScreenHeight() - radius){position.y GetScreenHeight() - radius;speed.y * -RESTITUTION;/* 5) 静止判定弹得太小就直接停下避免永久微弹 */if (fabsf(speed.y) SLEEP_SPEED){speed.y 0.0f;position.y GetScreenHeight() - radius;sleeping true;}}}/* 绘制暂停时依然绘制画面不会黑屏 */BeginDrawing();ClearBackground(RAYWHITE);DrawCircleV(position, radius, MAROON);DrawCircleLines((int)position.x, (int)position.y, radius, DARKBROWN);DrawText(SPACE: 暂停/继续 R: 重置 鼠标左键: 放置球, 10, 10, 18, DARKGRAY);DrawFPS(10, GetScreenHeight() - 28);if (pause) DrawText([ PAUSED ], 10, 36, 20, RED);if (sleeping) DrawText([ 已静止 ], 10, 36, 20, BLUE);EndDrawing();}CloseWindow();return 0;}
