woensdag 18 april 2012
Shoot to kill
The past few weeks we've been working hard on the final version of our next game. And it should go live very soon!
In the game the player is shooting on enemies, buildings and crates to destroy them. The way shooting bullets is handled in most of our games is that each bullet casts a ray (in the render engine or physics engine) to check if it hits an object. This is done each frame because the bullets are not instant but they fly through the scene over a couple of frames. Our game however is a flash 3D game and at the time of writing there was not yet a way to cast a ray inside the render engine to check if it hit an enemy. No worries, we still have a physics engine. Unfortunately the physics library we're using is implemented using ActionScript 3 code. A physics library in ActionScript 3? Isn't that slow? Indeed! It's slow, so we must be careful we don't cast too many rays per frame. This is a bit problematic for a game in which a lot of bullets can be flying around so we need some tricks to keep it down.
First of all the enemies in the game are not done with physics, they are done by just moving the visual models. So ray casting on these enemies cannot be done through the physics engine. So we do it ourselves using mathematics: given a ray and a box in space we can calculate if the ray hits the box. We can also do the same for a ray and a sphere. We then associate with each enemy a box or a sphere and in this way each bullet can cast a ray to check if it hits an enemy. Of course this is not pixel perfect but this does not ruin the gameplay as players will barely notice this.
Second, there are objects in the game that do not move such as buildings and crates. The buildings are meshes that are put in the physics engine, only just for ray casting. The bullets have a predefined path (straight forward) as soon as they are shot. This means that we only have to cast one ray at the initialization of the bullet and store the intersection point and associated object. If after a couple of frames the bullet passes the intersection point then it has hit the associated object. In this way the bullet does not have to cast rays on these static objects, only on the moving enemies. This significantly reduces the number of ray casts.
In the image above the path the bullets follow is indicated by the green ray. At the start of shooting a new bullet, the bullet checks along the green ray for intersections on buildings, crates and other static objects. After this the bullet only has to check for intersections on moving enemies along the same ray each frame.