Talking about Mikey Hooks game, Actionscript 3, Box2D, Flash and Game development.
Did you play Mikey Hooks? It’s an excellent platform where the hero can fire hooks and jump over spikes, holes and monster… and obviously the game is much more than this but I wanted to create some kind of hook with Box2D.
I made a very basic hook some time ago in the post Simulating a hook with Box2D but this is way better, here is how it works:
Each time you click on a static body (let’s say a rock), you create a distance joint between a dynamic body (let’s say the hero) and the static body.
Keeping the mouse down will rewind the hook, that is the distance joint is shortened, giving you a “Bionic Commando” effect.
Releasing mouse button will destroy the joint and you will be able to fire another hook.
This way you can swing around the stage.
Here is the code:
package { import flash.display.Sprite; import flash.events.MouseEvent; import flash.events.Event; import Box2D.Dynamics.*; import Box2D.Collision.Shapes.*; import Box2D.Common.Math.*; import Box2D.Dynamics.Joints.*; public class Main extends Sprite { private var world:b2World=new b2World(new b2Vec2(0,10),true); private var worldScale:Number=30; private var hero:b2Body; private var distanceJoint:b2DistanceJoint; private var isHooked:Boolean=false; public function Main() { // this is the ground addBox(320,480,640,20,b2Body.b2_staticBody); // let's add some random stuff for (var i:Number=1; i<=12; i++) { addBox(Math.random()*600+20,Math.random()*300,Math.random()*30+15,Math.random()*30+15,b2Body.b2_staticBody); } // and finally the hero hero=addBox(320,460,20,20,b2Body.b2_dynamicBody); addEventListener(Event.ENTER_FRAME,update); stage.addEventListener(MouseEvent.MOUSE_DOWN,fireHook); stage.addEventListener(MouseEvent.MOUSE_UP,releaseHook); debugDraw(); } private function fireHook(e:MouseEvent):void { // when firing the hook, let's remove old joints, if any if (distanceJoint) { world.DestroyJoint(distanceJoint); } // checking the body under the mouse world.QueryPoint(queryCallback,new b2Vec2(mouseX/worldScale,mouseY/worldScale)); } private function queryCallback(fixture:b2Fixture):Boolean { var touchedBody:b2Body=fixture.GetBody(); if (touchedBody.GetType()==b2Body.b2_staticBody) { // if I have a body under the mouse, I create a distance joint between the hero and mouse position var distanceJointDef:b2DistanceJointDef=new b2DistanceJointDef(); distanceJointDef.Initialize(hero,touchedBody,hero.GetWorldCenter(),new b2Vec2(mouseX/worldScale,mouseY/worldScale)); distanceJointDef.collideConnected=true; distanceJoint=world.CreateJoint(distanceJointDef) as b2DistanceJoint; isHooked=true; } return false; } private function releaseHook(e:MouseEvent):void { // if I release the mouse, I destroy the distance joint if (distanceJoint) { world.DestroyJoint(distanceJoint); } } private function manageHook():void{ // as long as the hook is active, I shorten a bit joint distance if (isHooked) { // BODY MUST BE AWAKE!!!!!! hero.SetAwake(true) distanceJoint.SetLength(distanceJoint.GetLength()*0.99); } } private function addBox(pX:Number,pY:Number,w:Number,h:Number,bodyType:Number):b2Body { var bodyDef:b2BodyDef=new b2BodyDef(); bodyDef.position.Set(pX/worldScale,pY/worldScale); bodyDef.type=bodyType; var polygonShape:b2PolygonShape=new b2PolygonShape(); polygonShape.SetAsBox(w/2/worldScale,h/2/worldScale); var fixtureDef:b2FixtureDef=new b2FixtureDef(); fixtureDef.shape=polygonShape; fixtureDef.density=1; fixtureDef.restitution=0.4; fixtureDef.friction=0.5; var body:b2Body=world.CreateBody(bodyDef); body.CreateFixture(fixtureDef); return body; } private function debugDraw():void { var debugDraw:b2DebugDraw=new b2DebugDraw(); var debugSprite:Sprite=new Sprite(); addChild(debugSprite); debugDraw.SetSprite(debugSprite); debugDraw.SetDrawScale(worldScale); debugDraw.SetFlags(b2DebugDraw.e_shapeBit|b2DebugDraw.e_jointBit); debugDraw.SetFillAlpha(0.5); world.SetDebugDraw(debugDraw); } private function update(e:Event):void { world.Step(1/30, 10, 10); manageHook(); world.ClearForces(); world.DrawDebugData(); } } }
And this is the result:
Click and hold your mouse over a static body to create a hook and rewind it, release mouse button to destroy the hook. Try to swing like a tarzan geek.
Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.