In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

ActionScript で弾幕ゲーをこしらえてみた Remix

Use The Arrow Keys To Move
And Use The Shift Key To Slow Down The Controls
Get Adobe Flash player
by FelixT 03 Nov 2010
/**
 * Copyright FelixT ( http://wonderfl.net/user/FelixT )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/g9Es
 */

// forked from asoiu7's forked from: ActionScript で弾幕ゲーをこしらえてみた
// forked from alpicola's ActionScript で弾幕ゲーをこしらえてみた
// Arrow Key で移動
// Shift で低速移動
// 今のところ避けることしかできません

package {
    import flash.display.Loader;
    import flash.media.Sound;  
    import flash.media.SoundChannel; 
    import flash.display.Sprite;
    import flash.display.BitmapData;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.events.KeyboardEvent;
    import flash.geom.Rectangle;
    import flash.geom.Point;
    import flash.net.URLRequest;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.system.LoaderContext;
    import flash.system.Security;
    import net.hires.debug.Stats;

    [SWF(backgroundColor="#191919", frameRate="60")] 

    public class Game extends Sprite {

        private var eField:BulletField;
        private var sound:Sound;
        private var channel:SoundChannel;
        private var pField:BulletField;
        private var player:Player;
        private var enemy:Enemy;
        private var status:TextField;
        private var t:uint;
        private var hit:uint;
        private var loader:Loader;

        public function Game() {
            sound =  new Sound(new URLRequest("http://www.looperman.com/00_assets/tracks/468214/looperman_track_468214_84894.mp3"));
            stage.align = "TL";
            stage.scaleMode = "noScale";

            Security.loadPolicyFile("http://5ivestar.org/misc/crossdomain.xml");
            loader = new Loader();
            loader.contentLoaderInfo.addEventListener("complete", loadingComplete);
            loader.load(new URLRequest("http://5ivestar.org/misc/bullets.png"), new LoaderContext(true));

            pField = new BulletField(380, 445);
            pField.x = 10, pField.y = 10;
            addChild(pField);
            eField = new BulletField(380, 445);
            eField.x = 10, eField.y = 10;
            addChild(eField);

            var frame:Sprite = new Sprite();
            frame.graphics.beginFill(0x000000);
            frame.graphics.drawRect(0, 0, 465, 465);
            frame.graphics.drawRect(10, 10, 380, 445);
            addChild(frame);

            var stats:Stats = new Stats();
            stats.x = 395;
            stats.y = 10;
            frame.addChild(stats);
            status = new TextField();
            status.defaultTextFormat = new TextFormat("_sans", 9);
            status.autoSize = "left";
            status.textColor = 0xffffff;
            status.x = 395;
            status.y = 110;
            frame.addChild(status);
        }

        public function loadingComplete(e:Event):void {
            var source:BitmapData = new BitmapData(55, 28, true, 0x00000000);
            source.draw(loader);

            var bmp1:BitmapData = new BitmapData(12, 12, true, 0x00000000);
            bmp1.copyPixels(source, new Rectangle(0, 0, 12, 12), new Point());
            Player.loadImage(bmp1);
            var bmp2:BitmapData = new BitmapData(15, 15, true, 0x00000000);
            bmp2.copyPixels(source, new Rectangle(12, 0, 15, 15), new Point());
            GrainBullet.loadImage(bmp2);
            var bmp3:BitmapData = new BitmapData(28, 28, true, 0x00000000);
            bmp3.copyPixels(source, new Rectangle(27, 0, 28, 28), new Point());
            BigBall.loadImage(bmp3);

            var s:Sprite = new Sprite();
            channel = sound.play(0,99999);
            s.graphics.beginFill(0x000000, 0.5);
            s.graphics.drawRect(10, 10, 380, 445);
            addChild(s);
            var tf:TextField = new TextField();
            tf.defaultTextFormat = new TextFormat("_sans", 18);
            tf.autoSize = "left";
            tf.textColor = 0xffffff;
            tf.text = "Start Game";
            tf.x = 200 - tf.width / 2;
            tf.y = 230 - tf.height / 2;
            s.addChild(tf);
            s.addEventListener(MouseEvent.MOUSE_UP, function(e:MouseEvent):void {
                removeChild(s);
                stage.focus = stage;
                start();
            });
        }

        public function start():void {
            t = 0;
            hit = 0;
            eField.clear();
            pField.clear();
            player = new Player(185, 390);
            pField.addBullet(player);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, player.keyDown);
            stage.addEventListener(KeyboardEvent.KEY_UP, player.keyUp);
            enemy = new Enemy(185, 75);
            eField.addBullet(enemy);
            Bullet.player = player;
            Bullet.enemy  = enemy;

            addEventListener(Event.ENTER_FRAME, update);
        }

        public function update(e:Event):void {
            t++;
            pField.update();
            var h:uint = eField.update();
            if (h) player.hit();
            if (player.dead) finish();
            hit += h;

            var s:String = ["BULLETS: " + eField.bullets.length.toString(),
                            "HITS: " + hit.toString(),
                            "LIVES: "].join("\n");
            for (var i:int = 0; i < player.life; i++) {
                s += "★";
            }
            status.text = s;
        }

        public function finish():void {
            removeEventListener(Event.ENTER_FRAME, update);
            stage.removeEventListener(KeyboardEvent.KEY_DOWN, player.keyDown);
            stage.removeEventListener(KeyboardEvent.KEY_UP, player.keyUp);
            var s:Sprite = new Sprite();
            s.graphics.beginFill(0x000000, 0.5);
            s.graphics.drawRect(10, 10, 380, 445);
            addChild(s);
            var tf:TextField = new TextField();
            tf.defaultTextFormat = new TextFormat("_sans", 18);
            tf.autoSize = "left";
            tf.textColor = 0xffffff;
            tf.text = "Game Over. Retry";
            tf.x = 200 - tf.width / 2;
            tf.y = 230 - tf.height / 2;
            s.addChild(tf);
            s.addEventListener(MouseEvent.MOUSE_UP, function(e:MouseEvent):void {
                removeChild(s);
                stage.focus = stage;
                start()
            });
        }

    }
}

import flash.display.Bitmap;
import flash.display.Sprite;

// 弾のコンテナ

class BulletField extends Bitmap {

    public var fieldWidth:Number;
    public var fieldHeight:Number;
    public var bullets:Vector.<Bullet>;

    public function BulletField(w:Number, h:Number) {
        fieldWidth = w;
        fieldHeight = h;
        bullets = new Vector.<Bullet>();
        var bmp:BitmapData = new BitmapData(w, h, true, 0x00000000);
        super(bmp);
    }

    public function addBullet(bullet:Bullet):void {
        bullet.field = this;
        bullets.push(bullet);
    }

    public function update():uint {
        bitmapData.lock();
        bitmapData.fillRect(bitmapData.rect, 0x00000000);
        var hit:uint = 0;
        var n:uint = bullets.length;
        while (n--) {
            var bullet:Bullet = bullets[n];
            bullet.update();
            bullet.draw();
            if (bullet.hitTest()) hit++;
            if (bullet.dead) {
                bullets.splice(n, 1);
            }
        }
        bitmapData.unlock()
        return hit;
    }

    public function clear():void {
        bullets.splice(0, bullets.length);
    }
}

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.geom.Matrix;

// BulletField 上に表示されるオブジェクトの基底クラス
// 動きを変更するには       update
// 当たり判定を変更するには hitTest
// をそれぞれオーバーライドする

class Bullet {

    public static var player:Player;
    public static var enemy:Enemy;
    public        var dead:Boolean = false;
    public        var x:Number = 0;
    public        var y:Number = 0;
    protected     var direction:Number;
    public        var field:BulletField;

    public function Bullet(x0:Number, y0:Number, d:Number) {
        x = x0, y = y0;
        direction = d;
    }

    public function update():void {
    }

    public function hitTest():Boolean {
        return false;
    }

    public function draw():void {
    }

    public function nWay(bullet:Class, n:int, direction:Number, range:Number, f:BulletField = null):void {
        if (n > 1) {
            for (var i:int = 0; i < n; i++) {
                (f || field).addBullet(new bullet(x, y, direction + range * (i/(n-1)-0.5)));
            }
        } else if (n == 1) {
            (f || field).addBullet(new bullet(x, y, direction));
        }
    }

}

import flash.display.Shape;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.geom.ColorTransform;
import flash.geom.Point;

// 自機

class Player extends Bullet {

    public static var images:Vector.<BitmapData>;
    private       var image:BitmapData;
    public        var life:int = 4;
    private       var t:uint;
    private       var damaged:uint;
    private       var slow:Boolean = false;
    private       var left:Boolean = false;
    private       var up:Boolean = false;
    private       var right:Boolean = false;
    private       var down:Boolean = false;
    private       var alpha:Number = 1;
    private       var p:Point;

    public static function loadImage(bmp:BitmapData):void {
        images = new Vector.<BitmapData>();
        images.push(bmp);
        var bmp1:BitmapData = bmp.clone();
        bmp1.colorTransform(bmp.rect, new ColorTransform(1.0, 1.0, 1.0, 0.8));
        images.push(bmp1);
        var bmp2:BitmapData = bmp.clone();
        bmp2.colorTransform(bmp.rect, new ColorTransform(1.0, 1.0, 1.0, 0.2));
        images.push(bmp2);
    }

    public function Player(x0:Number = 0, y0:Number = 0) {
        super(x0, y0, 0);
        image = images[0];
        p = new Point();
    }

    override public function update():void {
        t++;
        var vx:Number = 0;
        var vy:Number = 0;
        if (left && !right) vx = -1;
        if (!left && right) vx = 1;
        if (up && !down) vy = -1;
        if (!up && down) vy = 1;
        if (slow) {
            x += vx;
            y += vy;
        } else {
            x += vx * 3;
            y += vy * 3;
        }
        x = Math.max(0, x);
        x = Math.min(field.fieldWidth, x);
        y = Math.max(0, y);
        y = Math.min(field.fieldHeight, y);

        if (damaged) {
            var n:int = t - damaged;
            if (n % 8 < 4) {
                image = images[2];
            } else {
                image = images[1];
            }
            if (n > 75) {
                image = images[0];
                damaged = 0;
            }
        }

    }

    override public function draw():void {
        p.x = x - image.width / 2;
        p.y = y - image.height / 2;
        field.bitmapData.copyPixels(image, image.rect, p, null, null, true);
    }

    public function hit():void {
        if (!damaged) {
            damaged = t;
            life--;
            if (!life) {
                dead = true;
            }
        }
    }

    public function keyDown(e:KeyboardEvent):void {
        switch (e.keyCode) {
            case 16: slow  = true; break;
            case 37: left  = true; break;
            case 38: up    = true; break;
            case 39: right = true; break;
            case 40: down  = true; break;
        }
    }

    public function keyUp(e:KeyboardEvent):void {
        switch (e.keyCode) {
            case 16: slow  = false; break;
            case 37: left  = false; break;
            case 38: up    = false; break;
            case 39: right = false; break;
            case 40: down  = false; break;
        }
    }

}

// 敵機

class Enemy extends Bullet {

    private var t:uint;

    public function Enemy(x0:Number = 0, y0:Number = 0) {
        super(x0, y0, 0);
    }

    override public function update():void {
        t++;
        var d:Number = Math.atan2(y - player.y, player.x - x);
        if (t < 100) {
            if (!(t % 5)) nWay(GrainBullet1, 30, Math.PI * (t % 360) / 180, Math.PI * 2);
        } else if (t > 250 && t < 1050) {
            if (!(t % 25)) nWay(GrainBullet1, 31, d, Math.PI * 4/3);
            if (!(t % 20)) nWay(BigBall1, 10, -Math.PI * (t % 16) / 8, Math.PI * 2);
        } else if (t > 1250 && t < 2050) {
            if (!(t % 10)) nWay(GrainBullet1, 20, Math.PI * (t % 90) / 45, Math.PI * 2);
            if (!(t % 10)) nWay(GrainBullet1, 20, -Math.PI * (t % 90) / 45, Math.PI * 2);
            if (!(t % 50)) nWay(BigBall1, 11, d, Math.PI * 4/3);
        } else if (t > 2200 && t < 2800) {
            if (!(t % 250)) nWay(GrainBullet2, 20, 0, Math.PI * 2);
        }
    }
}

// Bullet に弾のイメージを管理する機能を付与したクラス
// AS3 では静的プロパティは継承されないため
// イメージ毎にこうしたクラスを作る必要がある

// 粒弾

class GrainBullet extends Bullet {

    private static var images:Vector.<BitmapData>;
    private static var p:Point;
    public         var image:BitmapData;

    public static function loadImage(source:BitmapData):void {
        images = new Vector.<BitmapData>();
        var s:Number = source.width;
        for (var i:int; i < 360; i++) {
            var bmp:BitmapData = new BitmapData(s, s, true, 0x00000000);
            var d:Number = i / 180 * Math.PI;
            var m:Matrix = new Matrix();
            m.translate(-s/2, -s/2);
            m.rotate(-d);
            m.translate(s/2, s/2);
            bmp.draw(source, m, null, null, null, true);
            images.push(bmp);
        }
        p = new Point();
    }

    public function GrainBullet(x0:Number, y0:Number, d:Number) {
        super(x0, y0, d);
        updateImage();
    }

    override public function draw():void {
        p.x = x - image.width / 2;
        p.y = y - image.height / 2;
        field.bitmapData.copyPixels(image, image.rect, p, null, null, true);
    }

    override public function hitTest():Boolean {
        return Math.sqrt(Math.pow(player.x - x, 2) + Math.pow(player.y - y, 2)) < 3;
    }

    protected function updateImage():void {
        var l:int = images.length;
        var i:int = direction / Math.PI * l * 0.5;
        image = images[((i %= l) < 0) ? i + l : i];
    }

}

// 大玉

class BigBall extends Bullet {

    private static var image:BitmapData;
    private static var p:Point;

    public static function loadImage(bmp:BitmapData):void {
        image = bmp;
        p = new Point()
    }

    public function BigBall(x0:Number, y0:Number, d:Number) {
        super(x0, y0, d);
    }

    override public function draw():void {
        p.x = x - image.width / 2;
        p.y = y - image.height / 2;
        field.bitmapData.copyPixels(image, image.rect, p, null, null, true);
    }

    override public function hitTest():Boolean {
        return Math.sqrt(Math.pow(player.x - x, 2) + Math.pow(player.y - y, 2)) < 10;
    }

}

// 等速直進運動する弾

class GrainBullet1 extends GrainBullet {

    private var vx:Number;
    private var vy:Number;

    public function GrainBullet1(x0:Number, y0:Number, d:Number, v:Number = 1.5) {
        super(x0, y0, d);
        vx =  Math.cos(direction) * v;
        vy = -Math.sin(direction) * v;
    }

    override public function update():void {
        x += vx;
        y += vy;

        if (x < -10 || x > field.fieldWidth + 10 ||
            y < -10 || y > field.fieldHeight + 10) {
            dead = true;
        }
    }

}

class BigBall1 extends BigBall {

    private var vx:Number;
    private var vy:Number;

    public function BigBall1(x0:Number, y0:Number, d:Number, v:Number = 1) {
        super(x0, y0, d);
        vx =  Math.cos(direction) * v;
        vy = -Math.sin(direction) * v;
    }

    override public function update():void {
        x += vx;
        y += vy;

        if (x < -10 || x > field.fieldWidth + 10 ||
            y < -10 || y > field.fieldHeight + 10) {
            dead = true;
        }
    }

}

// 敵機の周りを回った後はじける

class GrainBullet2 extends GrainBullet {

    private var t:uint = 0;

    public function GrainBullet2(x0:Number, y0:Number, d:Number) {
        super(x0, y0, d);
    }

    override public function update():void {
        t++;
        if (t < 300) {
            direction += 0.06 - t * 0.0002;
            updateImage();
            x += Math.cos(direction);
            y -= Math.sin(direction);
        } else {
            nWay(GrainBullet3, 50, 0, Math.PI * 2);
            dead = true;
        }

    }

}

// はじけた後落ちていく

class GrainBullet3 extends GrainBullet {

    private var t:uint = 0;
    private var vx:Number;
    private var vy:Number;

    public function GrainBullet3(x0:Number, y0:Number, d:Number) {
        super(x0, y0, d);
        vx =  Math.cos(direction) * 2.5;
        vy = -Math.sin(direction) * 2.5;
    }

    override public function update():void {
        t++;
        if (t < 100) {
            vx *= 0.99;
            vy *= 0.99;
            x += vx;
            y += vy;
        } else {
            vy += 0.01;
            x += vx;
            y += vy;
            direction = Math.atan2(-vy, vx);
            updateImage();

            if (x < -10 || x > field.fieldWidth + 10 ||
                y < -10 || y > field.fieldHeight + 10) {
                dead = true;
            }
        }
    }

}