
Tile Engine: The Other Collisions
things that go boom
This is another class that should be familiar to you if you followed the H.E.R.O tutorial. This class will loop through all sprites and run collision checks. In this case there will be no collision with platforms, the Maze takes care of that. But instead we check on Bullet-Tank collision and Tank-Tank collision.
Note:As I mentioned in the H.E.R.O tutorial, tile engines are possibly the best engines to use in platform games. The amount of looping I did in the H.E.R.O game could be cut down drastically. The block method I used in that game is useful however when used with a line collision engine, which I will explain how to do in a future tutorial. But to build a Platform game with a Tile engine, you do basically the same as I am doing here, only you add the constant Y speed, so the sprite is always either falling through the air or touching at least one solid cell.
The ScreenManager Class
package tiletank {
import flash.events.Event;
import flash.events.EventDispatcher;
import tiletank.tank.*;
import tiletank.bullet.*;
import tiletank.map.*;
import tiletank.dynamic.*;
/**
* ScreenManager causes all dynamic game elements to update their position and then runs collision
* logic on these elements
*/
public class ScreenManager extends EventDispatcher {
private static var _instance:ScreenManager;
private var _dynamicBodies:Vector.;
private var _gameData:GameData;
private var _player:PlayerTank;
function ScreenManager (instantiator:Instantiator) {}
public static function get instance():ScreenManager {
if(ScreenManager._instance == null) {
ScreenManager._instance= new ScreenManager (new Instantiator());
ScreenManager._instance.initInstance();
}
return ScreenManager._instance;
}
/**
* Create Vector objects
*
*/
private function initInstance ():void {
_gameData = GameData.instance;
_dynamicBodies = new Vector.();
}
public function get bodies ():Vector. {
return _dynamicBodies;
}
public function clearBodies ():void {
for (var i:int = _dynamicBodies.length -1 ; i >=0 ; i--) {
_dynamicBodies.splice(i,1);
}
}
public function addBody (body:GameSprite):void {
if (_dynamicBodies.indexOf(body) == -1) {
_dynamicBodies.push(body);
}
if (body is PlayerTank) _player = body as PlayerTank;
}
public function removeBody (body:GameSprite):void {
var index:int = _dynamicBodies.indexOf(body);
if (index != -1) _dynamicBodies.splice(index,1);
}
public function updateScreen ():void {
var i:int;
//update all dynamic elements (tanks and bullets)
dispatchEvent(new Event(GameConstants.UPDATE_SCREEN, true));
//check for tile collision
for (i = _dynamicBodies.length-1; i >= 0; i--) {
if (!_dynamicBodies[i].active) continue;
if (_dynamicBodies[i].trashme) {
_dynamicBodies[i].active = false;
_dynamicBodies[i].destroy();
_dynamicBodies.splice(i,1);
continue;
}
//update position in relation to current Maze
_dynamicBodies[i].checkMazeCollision();
if (_dynamicBodies[i] is AiTank) {
checkAiPlayer(_dynamicBodies[i]);
if (_player.bullet && _player.bullet.stage) checkPlayerBulletAi (_dynamicBodies[i] as AiTank);
}
if (_dynamicBodies[i] is AiBullet) {
checkAiBulletPlayer(_dynamicBodies[i]);
}
}
//render new screen
dispatchEvent(new Event(GameConstants.SHOW_SCREEN, true));
}
/*private function updateAll (show:Boolean = false):void {
for (var i:int = _dynamicBodies.length-1; i >= 0; i--) {
if (!show) {
_dynamicBodies[i].update();
} else {
_dynamicBodies[i].move();
}
}
}*/
/**
* Collision between AI bullets and Player Tank
*/
private function checkAiBulletPlayer (bullet:GameSprite):void {
//if too far, don't check
if (Math.abs(bullet.nextX - _player.nextX) > 2*_player.width) return;
if (Math.abs(bullet.nextY - _player.nextY) > 2*_player.height) return;
if (_player.isIntersecting (bullet.box)) {
if (!_player.trashme) {
_player.trashme = true;
bullet.trashme = true;
}
}
}
/**
* Collision between AI tanks and Player tank
*/
private function checkAiPlayer (ai:GameSprite):void {
//if too far, don't check
if (Math.abs(ai.nextX - _player.nextX) > 2*_player.width) return;
if (Math.abs(ai.nextY - _player.nextY) > 2*_player.height) return;
if (_player.isIntersecting (ai.box)) {
if (!_player.trashme) {
_player.trashme = true;
ai.trashme = true;
}
}
}
/**
* Collision between AI tanks and Player bullet
*/
private function checkPlayerBulletAi (ai:AiTank):void {
//if ai is currently invulnerable, don't check for collision
if (ai.blinking) return;
var bullet:BasicBullet = _player.bullet;
//if too far, don't check
if (Math.abs(ai.nextX - bullet.nextX) > 2*ai.width) return;
if (Math.abs(ai.nextY - bullet.nextY) > 2*ai.height) return;
if (bullet.isIntersecting (ai.box)) {
if (!ai.trashme) {
ai.trashme = true;
bullet.trashme = true;
}
}
}
}
}
internal class Instantiator {}

