Ball Physics
Overview
An app demoing the use of the loom Physics class, featuring the creation and destruction of a series of various sized physics-enabled sprite objects.
Clicking on an empty space on the screen will create a randomly sized Poly. Clicking on an existing Poly will remove it.
Try It
Use the following Loom CLI commands to run this example:
loom new MyBallPhysicsDemo --example BallPhysicsDemo
cd MyBallPhysicsDemo
loom run
Screenshot
Code
src/BallPhysicsDemo.ls
package
{
import loom.Application;
import loom2d.display.StageScaleMode;
import loom2d.display.Image;
import loom2d.textures.Texture;
import loom2d.ui.SimpleLabel;
import loom2d.events.Touch;
import loom2d.events.TouchEvent;
import loom2d.events.TouchPhase;
import loom.gameframework.AnimatedComponent;
import loom.gameframework.LoomComponent;
import loom.gameframework.LoomGroup;
import loom.gameframework.LoomGameObject;
import loom.physics.Physics;
import loom.physics.PhysicsWall;
import loom.physics.PhysicsBall;
public class BallRenderer extends AnimatedComponent
{
public var x:Number = 10, y:Number, rotation:Number;
public var sprite:Image;
public function onFrame():void
{
super.onFrame();
if(!sprite)
return;
sprite.x = x;
sprite.y = y;
sprite.rotation = rotation;
}
public function onRemove():void
{
if(sprite)
{
sprite.parent.removeChild(sprite, true);
}
super.onRemove();
}
}
public class PhysicsMover extends LoomComponent
{
public var ball:PhysicsBall;
public function onRemove():void
{
super.onRemove();
// tell the native side we are done with the ball
ball.deleteNative();
ball = null;
}
}
public class BallPhysicsDemo extends Application
{
public var wallGroup = new LoomGroup();
public var walls = new Vector.<PhysicsWall>();
public var physicsActive = false;
public function onFrame():void
{
//tick physics simulation
if(physicsActive)
Physics.tick();
}
function spawnBall(x:Number, y:Number)
{
// create a new ball game object
var ballGO = new LoomGameObject();
// create a new physics component.
var physicsComp = new PhysicsMover();
var rad:Number = Math.random() * 20 + 5;
physicsComp.ball = Physics.spawnBall(x, y, rad, 1);
ballGO.addComponent(physicsComp, "mover");
// Sprite for the ball
var sprite = new Image(Texture.fromAsset("assets/logo.png"));
sprite.width = sprite.height = rad * 2;
// We want the pivot point of the ball to be in the center
sprite.center();
sprite.x = x;
sprite.y = y;
sprite.addEventListener( TouchEvent.TOUCH, function(e:TouchEvent) {
var touch = e.getTouch(sprite, TouchPhase.BEGAN);
if (touch)
{
e.stopImmediatePropagation();
ballGO.destroy();
}
} );
// add the sprite to the scenegraph
stage.addChild(sprite);
// And set up the renderer.
var renderComp = new BallRenderer();
renderComp.sprite = sprite;
// initialize the data bindings
renderComp.addBinding("x", "@mover.ball.x");
renderComp.addBinding("y", "@mover.ball.y");
renderComp.addBinding("rotation", "@mover.ball.angle");
ballGO.addComponent(renderComp, "renderer");
// Initialize the GO.
ballGO.initialize();
}
// Add any managers to group here
override public function installManagers():void
{
// Call super to install default managers first
super.installManagers();
Physics.init();
physicsActive = true;
}
override public function run():void
{
// setup our physics wall constraints based on display size
var width = stage.stageWidth;
var height = stage.stageHeight;
stage.scaleMode = StageScaleMode.FILL;
// Setup anything else, like UI, or game objects.
// Create a nice background
var bg = new Image(Texture.fromAsset("assets/bg.png"));
bg.width = width;
bg.height = height;
stage.addChild(bg);
// Listen for touch.
stage.addEventListener( TouchEvent.TOUCH, function(e:TouchEvent) {
var touch = e.getTouch(stage, TouchPhase.BEGAN);
if (touch)
spawnBall(touch.globalX, touch.globalY);
});
// Setup wall physics colliders
// Top wall
walls.push(Physics.spawnWall( 0, width, height, height + 16));
// Bottom wall
walls.push(Physics.spawnWall( 0, width, 0, -16));
// Left wall
walls.push(Physics.spawnWall( -16, 0, 0, height));
// Right wall
walls.push(Physics.spawnWall( width, width + 16, 0, height));
// Spawn some initial balls
for (var cnt = 0; cnt < 100; cnt++)
{
var x = (cnt % 10) * (width / 12);
var y = (cnt / 10) * (height / 12);
spawnBall(x, y);
}
// Ensure that we don't have gravity turned on between objects.
Physics.setInterObjectGravityEnabled(false);
// add some gravity
Physics.setGravity(0, 256);
}
}
}