for ActionScript3
BulletMLAS Test - Source code
(C) Kenta Cho(ABA."Saba")
package {
import flash.display.Sprite;
import flash.display.TextField;
import flash.display.TextFieldAutoSize;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.Event;
import flash.events.EventType;
import flash.text.TextFormat;
import flash.geom.Matrix;
import flash.geom.Rectangle;
import flash.util.getTimer;
import abagames.util.bulletml.BulletML;
import abagames.util.bulletml.BulletsManager;
import abagames.util.bulletml.Bullet;
// Use '-default-size 360 480 -default-frame-rate 60 -optimize=true'
// as the additional compiler arguments.
public class Test extends Sprite {
var bmlXml:XML =
<bulletml>
<action label="top">
<repeat> <times>8</times>
<action>
<fire>
<direction>$rand*360</direction>
<bulletRef label="eye"/>
</fire>
<wait>30</wait>
</action>
</repeat>
<vanish/>
</action>
<bullet label="eye">
<speed>0</speed>
<action>
<changeSpeed>
<speed>10</speed>
<term>400</term>
</changeSpeed>
<changeDirection>
<direction type="sequence">$rand * 5 - 2.5</direction>
<term>9999</term>
</changeDirection>
<repeat> <times>99</times>
<action>
<fire>
<direction type="relative">0</direction>
<bulletRef label="shadow"/>
</fire>
<wait>16 - $rank * 13</wait>
</action>
</repeat>
</action>
</bullet>
<bullet label="shadow">
<speed>0</speed>
<action>
<wait>20</wait>
<fire>
<direction type="relative">90</direction>
<bullet/>
</fire>
<fire>
<direction type="relative">-90</direction>
<bullet/>
</fire>
<vanish/>
</action>
</bullet>
</bulletml>
public function Test() {
addEventListener(EventType.ENTER_FRAME, onEnterFrame);
}
private var isFirst:Boolean = true;
private var bulletsManager:BulletsManagerImpl;
private var prevTick:uint = 0;
private var fps:Number = 60;
private var buffer:BitmapData;
private var screen:Bitmap;
public function onEnterFrame(evt:Event) {
if (isFirst) {
isFirst = false;
init();
}
buffer.fillRect(buffer.rectangle, 0xaabbdd);
bulletsManager.run(buffer);
bulletNum.text = String(bulletsManager.bulletCount());
var t:uint = getTimer();
var cfps:Number = 1000 / (t - prevTick);
fps += (cfps - fps) * 0.2;
var fi:int = int(fps);
var ff:int = int((fps - fi) * 10);
fpsNum.text = String(fi) + "." + String(ff);
prevTick = t;
}
private function init() {
BulletImpl.rank = 1;
BulletImpl.screenWidth = 360;
BulletImpl.screenHeight = 480;
BulletImpl.scale = 1;
bulletsManager = new BulletsManagerImpl;
addBullet(bmlXml, bulletsManager, BulletImpl.screenWidth / 2, BulletImpl.screenHeight / 4);
addBullet(bmlXml, bulletsManager, BulletImpl.screenWidth / 3, BulletImpl.screenHeight / 3);
addBullet(bmlXml, bulletsManager, BulletImpl.screenWidth / 3 * 2, BulletImpl.screenHeight / 3);
buffer = new BitmapData(BulletImpl.screenWidth, BulletImpl.screenHeight, false, 0);
screen = new Bitmap(buffer);
addChild(screen);
initText();
}
private function addBullet(bmlXml:XML, bm:BulletsManager, x:Number, y:Number) {
var bml:BulletML = new BulletML;
bml.init(bmlXml);
bm.addBullet(bml, x, y, 0, 0);
}
private var bulletNum:TextField;
private var fpsNum:TextField;
public function initText() {
bulletNum = new TextField;
bulletNum.x = BulletImpl.screenWidth - 80 - 20 * BulletImpl.scale;
bulletNum.y = 10 * BulletImpl.scale;
bulletNum.autoSize = TextFieldAutoSize.RIGHT;
fpsNum = new TextField;
fpsNum.x = BulletImpl.screenWidth - 80 - 20 * BulletImpl.scale;
fpsNum.y = 30 * BulletImpl.scale;
fpsNum.autoSize = TextFieldAutoSize.RIGHT;
var format:TextFormat = new TextFormat;
format.font = "Verdana";
format.color = 0x000000;
format.size = 20 * BulletImpl.scale;
bulletNum.defaultTextFormat = format;
fpsNum.defaultTextFormat = format;
addChild(bulletNum);
addChild(fpsNum);
}
}
private class BulletsManagerImpl implements BulletsManager {
private var bullets:Array = new Array;
public function addBullet(bml:BulletML, x:Number, y:Number,
deg:Number, speed:Number):Bullet {
var b:BulletImpl = new BulletImpl(bml, this, x, y, deg, speed);
bullets.push(b);
return b;
}
public function run(buf:BitmapData) {
for each (var b:BulletImpl in bullets)
b.run(buf);
for (var i:int = 0; i < bullets.length; ) {
var b:BulletImpl = BulletImpl(bullets[i]);
if (b.isEnd()) {
bullets.splice(i, 1);
} else {
i++;
}
}
}
public function bulletCount():int {
return bullets.length;
}
}
private class BulletImpl implements Bullet {
public static var screenWidth:int = 360;
public static var screenHeight:int = 480;
public static var scale:Number = 1;
public static var rank:Number = 0.5;
private var bml:BulletML;
private var bm:BulletsManager;
private var x:Number;
private var y:Number;
private var rotation:Number;
private var speed:Number;
private var acx:Number;
private var acy:Number;
private var matrix:Matrix;
private var shape:BitmapData;
private var rect:Rectangle;
private var isVanished:Boolean;
public function BulletImpl(bml:BulletML, bm:BulletsManager,
x:Number, y:Number, deg:Number, speed:Number) {
this.bml = bml;
this.bm = bm;
this.x = x;
this.y = y;
rotation = deg;
this.speed = speed;
acx = acy = 0;
//matrix = new Matrix;
//shape = new BitmapData(2, 8, false, 0xffffff);
rect = new Rectangle(0, 0, 5, 5);
isVanished = false;
}
public function run(buf:BitmapData) {
bml.run(this, bm);
x += Math.sin(rotation * Math.PI / 180) * speed * scale;
y -= Math.cos(rotation * Math.PI / 180) * speed * scale;
x += acx * scale;
y += acy * scale;
if (x < 0 || x >= screenWidth || y < 0 || y >= screenHeight) {
vanish();
return;
}
/*matrix.identity();
matrix.rotate(rotation * Math.PI / 180);
matrix.translate(x, y);
buf.draw(shape, matrix);*/
rect.x = x;
rect.y = y;
buf.fillRect(rect, 0xffffff);
}
public function isEnd():Boolean {
return isVanished;
}
public function getDirection():Number {
return rotation;
}
public function setDirection(v:Number) {
rotation = v;
}
public function getAimDirection():Number {
return 180;
}
public function getSpeed():Number {
return speed;
}
public function setSpeed(v:Number) {
speed = v;
}
public function getX():Number {
return x;
}
public function getY():Number {
return y;
}
public function getHorizontal():Number {
return acx;
}
public function setHorizontal(v:Number) {
acx = v;
}
public function getVertical():Number {
return acy;
}
public function setVertical(v:Number) {
acy = v;
}
public function vanish() {
isVanished = true;
}
public function getRand():Number {
return Math.random();
}
public function getRank():Number {
return rank;
}
}
}