Starling numbered billiard ball
// Main.as
package {
import flash.display.*;
import starling.core.Starling;
[SWF (width="465", height="465", frameRate="60", backgroundColor="#ffffff")]
public class Main extends MovieClip {
private var starling : Starling;
public function Main () {
// wonderfl stage size seems to be 1px less than it should be
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
starling = new Starling (Game, stage);
starling.start ();
}
}
}
// Game.as
// package {
import starling.display.Sprite;
import starling.events.EnterFrameEvent;
/*public*/ class Game extends Sprite {
private var ball : Ball8;
private var time : Number = 0;
public function Game () {
addChild (ball = new Ball8 ());
addEventListener (EnterFrameEvent.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame (e : EnterFrameEvent) : void {
time += e.passedTime;
ball.x = 232 + 150 * Math.sin (time);
ball.y = 232 + 100 * Math.cos (time / 2);
}
}
// }
// Ball8.as
// package {
import flash.display.BitmapData;
import flash.display.GradientType;
import flash.display.Shape;
import flash.display.SpreadMethod;
import flash.geom.Matrix;
import flash.text.TextField;
import flash.text.TextFormat;
import starling.display.Image;
import starling.display.Sprite;
import starling.events.EnterFrameEvent;
import starling.textures.Texture;
/*public*/ class Ball8 extends Sprite {
private var radius : Number;
private var eight : Image;
public function Ball8 (r : Number = 16) {
radius = r;
// you don't have to do this in code, PNGs will do just fine :)
var s : Shape = new Shape ();
var m : Matrix = new Matrix ();
m.createGradientBox (r * 3, r * 3, 0, -r * 1.8, -r * 1.8);
s.graphics.beginGradientFill (GradientType.RADIAL, [0x3F3F3F, 0], [100, 100], [0x00, 0xFF], m, SpreadMethod.PAD);
s.graphics.drawCircle (0, 0, r * 0.95);
m.identity (); m.translate (Math.ceil (r), Math.ceil (r));
var b : BitmapData = new BitmapData (m.tx * 2, m.ty * 2, true, 0); b.draw (s, m);
var i : Image = new Image (Texture.fromBitmapData (b));
i.x = -r; i.y = -r; addChild (i);
s.graphics.clear ();
s.graphics.beginFill (0xFFFFFF);
s.graphics.drawCircle (r * 0.5, r * 0.5, r * 0.4);
b = new BitmapData (r, r, true, 0);
b.draw (s);
var tfd : TextField = new TextField ();
var tft : TextFormat = tfd.defaultTextFormat; tft.size = r; tfd.defaultTextFormat = tft;
tfd.autoSize = "left"; tfd.text = "8";
m.identity (); m.translate (0.5 * (r - tfd.width), 0.5 * (r - tfd.height)); b.draw (tfd, m);
addChild (eight = new Image (Texture.fromBitmapData (b)));
addEventListener (EnterFrameEvent.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame (e : EnterFrameEvent) : void {
var ir : Number = 1 / radius, ipr : Number = ir / Math.PI, ix : int, iy : int;
var rx : Number = Math.cos (ir * x);
var ry : Number = Math.cos (ir * y);
var r2 : Number = rx * rx + ry * ry;
if (r2 < 1) {
ix = ipr * x;
iy = ipr * y;
} else {
rx = Math.sin (ir * x);
ry = Math.sin (ir * y);
r2 = rx * rx + ry * ry;
ix = ipr * x + 1.5;
iy = ipr * y + 1.5;
}
if (ix % 2 == 1) rx *= -1;
if (iy % 2 == 1) ry *= -1;
var m : Matrix = eight.transformationMatrix;
m.a = 1 - rx * rx; m.c = 0 - rx * ry; m.tx = -(0.5 * (m.a + m.c) + 0.85 * rx) * radius;
m.b = 0 - rx * ry; m.d = 1 - ry * ry; m.ty = -(0.5 * (m.b + m.d) + 0.85 * ry) * radius;
}
}
// }