package { import flash.geom.Point; import net.flashpunk.Entity; import net.flashpunk.FP; /** * Collision class. * @author Yrael */ public class Collidable extends Entity { private var _v:Point; private var _hAcc:Number = 0; private var _vAcc:Number = 0; private var _onGround:Boolean = false; private var _inWater:Boolean = false; private var _swimming:Boolean = false; private var _bobDown:Boolean = false; private var _swimOY:Number; public function Collidable(p:Point, _width:int, _height:int):void { x = p.x; y = p.y; setHitbox(_width, _height); _v = new Point; type = "collidable"; } /* Collidable Class : Calls X collision check then Y collision check. */ override public function update():void { checkWater(); checkXCollision(); checkYCollision(); } public function get onGround():Boolean { return _onGround; } public function set onGround(nog:Boolean):void { _onGround = nog; } public function get v():Point { return _v; } public function set v(nv:Point):void { _v = nv; } public function get inWater():Boolean { return _inWater; } public function get vAcc():Number { return _vAcc; } public function set vAcc(n:Number):void { _vAcc = n; } public function get hAcc():Number { return _hAcc; } public function set hAcc(n:Number):void { _hAcc = n; } public function get swimming():Boolean { return _swimming; } public function set swimming(nB:Boolean):void { _swimming = nB; } public function get swimOY():Number { return _swimOY; } public function set swimOY(n:Number):void { _swimOY = n; } protected function checkWater():void { if (collide("_water_block", x, y)) { _inWater = true; //vAcc bobbing if (collide("_water_block", x, y - halfHeight)&&!_swimming) { if (y <= _swimOY-GameInfos.BOB_CAP) { _bobDown = true; } else if (y >= _swimOY+GameInfos.BOB_CAP) { _bobDown = false; } if (_bobDown) { _vAcc += GameInfos.BOB_ACCELERATION; } else { _vAcc -= GameInfos.BOB_ACCELERATION; } } // hAcc check if (_hAcc > 0) { _hAcc -= GameInfos.SWIM_DEACCELERATION; if (_hAcc < 0) { _hAcc = 0; } } else if (_hAcc < 0) { _hAcc += GameInfos.SWIM_DEACCELERATION; if (_hAcc > 0) { _hAcc = 0; } } // vAcc check if (_vAcc > 0 && collide("_water_block", x, y - halfHeight)) { _vAcc -= GameInfos.SWIM_DEACCELERATION; if (_vAcc < 0) { _vAcc = 0; } } else if (_vAcc < 0) { _vAcc += GameInfos.SWIM_DEACCELERATION; if (_vAcc > 0) { _vAcc = 0; } } } else { _inWater = false; _hAcc = 0; _vAcc = 0; } //Check if need to recalibrate swimOY if (_vAcc > GameInfos.MAX_SWIM_ACCELERATION) { _swimOY = y; } _swimming = false; } protected function checkXCollision():void { _v.x += _hAcc; x += _v.x; if (collide("_solid_block", x, y)) { if (FP.sign(_v.x) > 0) { _v.x = 0; x = Functions.baseReplace(x, GameInfos.TILEWIDTH) + GameInfos.TILEWIDTH * Functions.getNTiles(GameInfos.TILEWIDTH, width) - width; while (collide("_solid_block", x, y)) { x -= GameInfos.TILEHEIGHT; FP.console.log("Caught collision bug."); } } else { _v.x = 0; x = Functions.baseReplace(x, GameInfos.TILEWIDTH) + GameInfos.TILEWIDTH; while (collide("_solid_block", x, y)) { x += GameInfos.TILEHEIGHT; FP.console.log("Caught collision bug."); } } } } protected function checkYCollision():void { _onGround = false; _v.y += _vAcc; y += _v.y; if (collide("_solid_block", x, y)) { if (FP.sign(_v.y) > 0) { _onGround = true; if (_inWater) { _vAcc = 0; _bobDown = false; } _v.y = 0; y = Functions.baseReplace(y,GameInfos.TILEHEIGHT) + GameInfos.TILEHEIGHT * Functions.getNTiles(GameInfos.TILEHEIGHT, height) - height; while (collide("_solid_block", x, y)) { y -= GameInfos.TILEHEIGHT; FP.console.log("Caught collision bug."); } } else { if (_inWater) { _vAcc = 0; _bobDown = true; } _v.y = 0; y = Functions.baseReplace(y, GameInfos.TILEHEIGHT) + GameInfos.TILEHEIGHT; while (collide("_solid_block", x, y)) { y += GameInfos.TILEHEIGHT; FP.console.log("Caught collision bug."); } if (this as Weighted) { (this as Weighted).accGrav = 0; } } } } } }