8、更真实的下落与碰撞效果
现在小球的下落是匀速的,而弹起的动画效果没有增加速度衰减。加入一些物理数值进行计算,会更好地增加动画效果。
实际上有许多比较专业又开源的物理引擎,在数值计算上能够使用这些物理引擎库对游戏进行开发。比如phyX和Box2D,这两个都是开源引擎,在游戏还有其他领域使用诸多。后续会使用这些物理引擎,现在简单实现一下效果。
1)显示函数改进
写一个显示函数,其中动画显示函数中加了一个边界检测,如果超过边界就重置小球的坐标,当然不仅可以检测一个方向一个边界,这些可以自由添加。
void games_anima_display(games_obj_t circle)
{
//防止显示超过边界
if (circle->anima->y > screen_height - circle->anima->r)
circle->anima->y = screen_height - circle->anima->r;
else if (circle->anima->y < circle->anima->r)
circle->anima->y = circle->anima->r;
else if (circle->anima->x > screen_width - circle->anima->r)
circle->anima->x = screen_width - circle->anima->r;
else if (circle->anima->x < circle->anima->r)
circle->anima->x = circle->anima->r;
cleardevice();
fillcircle((int)circle->anima->x, (int)circle->anima->y, (int)circle->anima->r);
Sleep(50);
}
2)小球下落改进
小球现在是匀速下降的,我打算把它改成自由落体,加速度下落。因为本身没有给它设置质量,所以不完全按照万有引力,只是在y轴给它一个加速度。
数值计算:
速度=速度+加速度->当前的y轴位置=y轴位置+变化速度*时间(这里暂时按照1帧算,因为每次在循环调用都算是时间变化)
实现:
circle->anima->velocity += circle->anima->acceleration; //用加速度更新下降速度
circle->anima->y += circle->anima->velocity *1;
3)、小球弹起改进
给小球碰撞后,向上弹起做个减速
数值计算:
当前y轴位置=y轴位置-系数*变化速度
实现:
circle->anima->velocity = -0.95*circle->anima->velocity;
4)下落后产生碰撞弹起动画效果实现
这样就有下降的加速度,以及弹起后的减速效果了,这里去掉了传参n,在后续会放入anima的结构体中,其中K的系数也可以放到小球的动画结构体当中,这里我先用常量K表示:
void games_anima_down(games_circle_t circle)
{
//计算数值
const float K = 0.95;
circle->anima->velocity += circle->anima->acceleration; //用加速度更新下降速度
circle->anima->y += circle->anima->velocity *1;
if (circle->anima->y > screen_height - circle->anima->r)
{
circle->anima->velocity = -K*circle->anima->velocity;
}
//显示
games_anima_display(circle);
}
9、小球的抛物线反弹动画效果实现
接下来实现一点稍微复杂的动画效果,抛物线动画。
1) 抛物线的方向速度
一般而言小球是有一个初始速度的,这个初始速度可以在x轴y轴上有向量值用正弦余弦角度可以计算出来:
const float M_PI = 3.1415;
float angle_cos_sin = circle->anima->angle * (M_PI / 180.0);//计算弧度
//计算速度在x轴与y轴上的速度变化
vx = vx * cos(angle_cos_sin);
vy = vy * sin(angle_cos_sin);
但是这里为了简单起见,在结构体中添加x轴方向上的速度和y轴方向上的速度:
float vx; //x轴方向的速度
float vy; //y轴方向的速度
2)抛物线实现的逻辑:
抛物线的实现原理:
物体在运动时因为受到空气阻力和重力等的影响而发生了运动状态的改变。
这里的影响简单来讲就是x轴和y轴的速度变化了。
vy这个y轴方向上的速度方向如果开始是负数的话,小球就会往上运动。
circle->anima->x += circle->anima->vx;
circle->anima->y += circle->anima->vy;
额外的除了初始速度影响,y轴还会有一个重力,这里做的是模拟值:
// y轴上增加一个加速度,模拟受重力影响
circle->anima->vy += GRAVITY;
在发生碰撞的时候,反弹也就是减速朝着相反方向运动。
circle->anima->vx = -K*circle->anima->vx;
3)抛物线函数实现:
void games_anima_parabola(games_obj_t circle)
{
// 小球抛物线运动的计算函数
const float GRAVITY = 0.8;
const float K = 0.95;
circle->anima->x += circle->anima->vx;
circle->anima->y += circle->anima->vy;
// y轴上增加一个加速度,模拟受重力影响
circle->anima->vy += GRAVITY;
// 简单的边界检测,碰到屏幕边界反弹
if (circle->anima->x >= screen_width - circle->anima->r){
circle->anima->vx = -K*circle->anima->vx;
}
else if(circle->anima->x < circle->anima->r)
{
circle->anima->vx = -K*circle->anima->vx;
}
else if(circle->anima->y <= screen_height-circle->anima->r)
{
circle->anima->vy = -K*circle->anima->vy;
}
games_anima_display(circle);
}
4)主函数中调用和参数设置:
circle->anima->vx = 10;
circle->anima->vy = 0;
while (1)
{
//games_anima_down(circle);
games_anima_parabola(circle);
}
到此小球的基本图形其实已经完成了,下面会改进结构体,将其他图形包含进来,也会开一个定时器实现刷新(现在用了sleep,这会导致阻塞程序),以及实现简单的回调函数指针列表。
等到这一部分改完可能会上传一版本的代码,到时候可以自行取用。
2024/02/25