Answers:
早在1990年,旧的弹球游戏就是这样制作的:
游戏场有几层(玩游戏时会看到什么):
和几层碰撞:
左图是主游戏的碰撞图,右图是特殊区域(弹球坡道)的碰撞图。
White
=球的自由区域,颜色索引为255。
Gray
=球将被“推离”该区域。颜色索引=要添加到球位置的矢量角度。浅灰色= 0度。深灰色= 360度
一些伪代码:
void do_ball_physics()
{
while(1)
{
byte color = read_pixel_under_ball(ballx, bally); //one pixel read
if(color == 255) //see remark below
break;
float vectorx = sin(color/255.0f * 2.0f * PI);
float vectory = cos(color/255.0f * 2.0f * PI);
ballx += vectorx; //push ball away from one unit
bally += vectory; //
}
}
一些特殊的颜色索引,也可以使用的东西比其他碰撞,自定义颜色范围(例如:240 - 255)可以保留用于检测之类的特殊区域spinners
,triggers
,bumpers
,holes
,...
如您所见,这非常简单。每帧只有几个像素“读取”。因此,您可以使物理模拟以真正的高帧频运行,例如:200 fps。使用高帧速率将使模拟平滑并减少“隧道效应”(当球运动太快并通过槽元素而不会发生碰撞时,会发生这种情况)。这种简单性还使过去可以386 computers
(甚至快速286
)进行流畅的弹球游戏(在其他一些技巧中,例如颜色循环,vga滚动和精灵遮罩...)。
如今,大多数弹球游戏不再像这样制作。相反,运动场是使用多边形或精灵的2d / 3d场景,并且与一些简化的线,贝塞尔曲线或代表可视化运动场的简化形状的球体发生了碰撞。
示例(来自视觉弹球):
一些游戏公司使用自己的物理引擎,而另一种更简单的方法是使用物理引擎,例如Box2D
或Bullet
。我看到的大多数iPhone弹球游戏都使用了预先存在的物理引擎+一些3D资产。
弹球的物理性质非常丰富,不仅有球洞或墙壁,而且还有反应元素(向后击打)或不平坦的表面(球变慢然后恢复速度)。
如果要创建一个好的弹球,方法是使用3D碰撞检测,或者对每个可碰撞对象使用具有距离和速度参数的方法的自定义系统,并返回变化的速度。
首先,如果您制作弹球游戏,则比包围盒更可能需要更多的边界碰撞检测:-)
考虑到成熟的弹球涉及的物理复杂性,我建议您看一下现有的2D物理引擎。Box2D在javascript方面颇有声誉,也许还有其他人,但是我没有遇到任何好的(免费)的。
Rq1:您当然可以(像我一样)在游戏的更新和平局之间使用经典分割。然后,您使用计时器(setInterval / setTimeout)和/或RequestAnimationFrame调用更新,然后以常规方式绘制。弹子球可能是您想要一次更新计时器而另一次进行平局的游戏类型,因此您可以独立调整每种比率,以在多种设备上工作。因为如果设备太慢,您不能仅仅放弃(更新+绘制):如果两次更新(dt)之间的时间太长,则物理引擎可能会错过碰撞。