Friday, March 18, 2011

Create a Flash prototype of The Moops – Combos of Joy

Create a Flash prototype of The Moops – Combos of Joy:

Did you play The Moops – Combos of Joy?

It’s a cute physics game we can build a prototype in a few minutes (don’t worry, Plants Vs Zombies fans, as next step is about to come).

Moops – Combos of Joy screenshot

Let’s see game’s features:

* It’s a physics game so we are using Box2D to create it.

* The player fires a ball with the mouse. The direction can be decided according to mouse position, but power can’t. Player fires balls with the same, predefined speed.

* A series of shapes “fall” down from the top of the stage. Actually they don’t fall because there is no gravity in the game. Let’s say they move from top to bottom at a constant speed.

* When the ball hits a square, the square reacts according to physics, changing its direction and speed, but the ball does not exactly follow physics rules as its speed never changes.

Obviously there are more features in the original game but at the moment we’ll see these ones. Since it’s a long time we don’t deal with Box2D, I am using a line by line approach to explain the code.

This is the script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package {
 import flash.display.Sprite;
 import flash.events.Event;
 import flash.events.MouseEvent;
 import flash.utils.Timer;
 import flash.events.TimerEvent;
 import Box2D.Dynamics.*;
 import Box2D.Collision.Shapes.*;
 import Box2D.Common.Math.*;
 public class moops extends Sprite {
  private var world:b2World=new b2World(new b2Vec2(0,0),true);
  private var worldScale:int=30;
  private var timeCount:Timer=new Timer(500);
  public function moops():void {
   timeCount.start();
   debugDraw();
   addEventListener(Event.ENTER_FRAME, update);
   stage.addEventListener(MouseEvent.CLICK,onClick);
   timeCount.addEventListener(TimerEvent.TIMER, onTime);
  }
  private function onClick(e:MouseEvent):void {
   var angle:Number=Math.atan2(mouseX,mouseY-480)-Math.PI/2;
   addball(20*Math.cos(angle),-20*Math.sin(angle));
  }
  private function onTime(event:TimerEvent):void {
   addBox(300+Math.random()*200,-100,40);
  }
  private function addball(xVel:Number,yVel:Number):void {
   var ball:b2BodyDef= new b2BodyDef();
   ball.userData="ball";
   ball.type=b2Body.b2_dynamicBody;
   ball.position.Set(20/worldScale, 460/worldScale);
   var circle:b2CircleShape=new b2CircleShape(15/worldScale);
   var ballFixture:b2FixtureDef = new b2FixtureDef();
   ballFixture.shape=circle;
   ballFixture.friction=0;
   ballFixture.density=1;
   ballFixture.restitution=1;
   var ballBody:b2Body=world.CreateBody(ball);
   ballBody.CreateFixture(ballFixture);
   ballBody.SetLinearVelocity(new b2Vec2(xVel,yVel));
  }
  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 addBox(xOrigin:Number,yOrigin:Number,size:Number):void {
   var box:b2BodyDef= new b2BodyDef();
   box.position.Set(xOrigin/worldScale,yOrigin/worldScale);
   box.type=b2Body.b2_dynamicBody;
   var square:b2PolygonShape = new b2PolygonShape();
   square.SetAsBox(size/2/worldScale, size/2/worldScale);
   var boxFixture:b2FixtureDef = new b2FixtureDef();
   boxFixture.shape=square;
   boxFixture.friction=0;
   boxFixture.density=4;
   boxFixture.restitution=1;
   var boxBody:b2Body=world.CreateBody(box);
   boxBody.CreateFixture(boxFixture);
   boxBody.SetLinearVelocity(new b2Vec2(0,5));
  }
  private function update(e:Event):void {
   world.Step(1/30,10,10);
   world.ClearForces();
   world.DrawDebugData();
   for (var currentBody:b2Body = world.GetBodyList(); currentBody; currentBody=currentBody.GetNext()) {
    if (currentBody.GetPosition().y*worldScale>600 || currentBody.GetPosition().y*worldScale<(100*-1)) {
     world.DestroyBody(currentBody);
    }
    if (currentBody.GetUserData()=="ball") {
     var velocity:b2Vec2=currentBody.GetLinearVelocity();
     if (velocity.Length()!=20) {
      var speedOffset:Number=20/velocity.Length();
      currentBody.SetLinearVelocity(new b2Vec2(velocity.x*speedOffset,velocity.y*speedOffset));
     }
    }
   }
  }
 }
}

Let’s see how does it work [...]

No comments:

Post a Comment