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

forked from: ActionScript で弾幕ゲーをこしらえてみた

Arrow Key で移動
Shift で低速移動
今のところ避けることしかできません
/**
 * Copyright alpicola ( http://wonderfl.net/user/alpicola )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/pCQN
 */

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

package {
    import flash.display.Loader;
    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(width="465", height="465", backgroundColor="#262626", frameRate="60")] 

    public class Sakege extends Sprite {

        private var eField:BulletField;
        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 Sakege() {
            stage.align = "TL";
            stage.scaleMode = "noScale";

            var context:LoaderContext = new LoaderContext;
            context.checkPolicyFile = true;
            loader = new Loader();
            loader.contentLoaderInfo.addEventListener("complete", loadingComplete);
            loader.load(new URLRequest("http://assets.wonderfl.net/images/related_images/0/08/0844/08445684994346996daf69cea2874c4b0ed6a87a"), context);

            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();
            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 = "click start";
            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, 150);
            eField.addBullet(enemy);
            Bullet.player = player;
            Bullet.enemy  = enemy;
            Bullet.field  = eField;
            Player.field  = pField;

            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(),
                            "HIT: " + hit.toString(),
                            "LIFE: ∞"].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 = "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>;
    private var rect:Rectangle;

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

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

    public function update():uint {
        bitmapData.lock();
        bitmapData.fillRect(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.display.Shape;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;

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

class Bullet {

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

    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(bulletClass:Class, n:uint, direction:Number, range:Number, f:BulletField = null):void {
        var bullets:Vector.<Bullet> = (f || field).bullets;
        var length:uint = bullets.length;
        if (n == 1) {
            bullets[length] = new bulletClass(x, y, direction);
        } else {
            for (var i:int = 0; i < n; i++) {
                bullets[length + i] = new bulletClass(x, y, direction + range * (i/(n-1)-0.5));
            }
        }
    }

    public function allDirections(bulletClass:Class, n:uint, direction:Number, f:BulletField = null):void {
        var bullets:Vector.<Bullet> = (f || field).bullets;
        var length:uint = bullets.length;
        for (var i:int = 0; i < n; i++) {
            bullets[length + i] = new bulletClass(x, y, direction + Math.PI * 2 * i/n);
        }
    }

}

// 自機

class Player extends Bullet {

    public static var images:Vector.<BitmapData>;
    public static var field:BulletField;
    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;
    private       var rect:Rectangle;

    public static function loadImage(bmp:BitmapData):void {
        images = new Vector.<BitmapData>(3, true);
        images[0] = bmp;
        var bmp1:BitmapData = bmp.clone();
        bmp1.colorTransform(bmp.rect, new ColorTransform(1.0, 1.0, 1.0, 0.8));
        images[1] = bmp1;
        var bmp2:BitmapData = bmp.clone();
        bmp2.colorTransform(bmp.rect, new ColorTransform(1.0, 1.0, 1.0, 0.2));
        images[2] = bmp2;
    }

    public function Player(x0:Number = 0, y0:Number = 0) {
        super(x0, y0, 0);
        image = images[0];
        rect = image.rect;
        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 - rect.width / 2;
        p.y = y - rect.height / 2;
        field.bitmapData.copyPixels(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;
    private var n: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 % 200 > 26 && t % 200 < 74) allDirections(GrainBullet1, 15, Math.tan(Math.PI*t*0.02) * 0.03 + int(t*0.01)/3);
        if (t % 200 > 26 && t % 200 < 74) allDirections(GrainBullet1, 15, -Math.tan(Math.PI*t*0.02) * 0.03 + int(t*0.01)/3);
        if (t % 200 > 75 && t % 200 < 180 && !(t % 5)) allDirections(GrainBullet2, 8, Math.PI * t / 200);
        if (t % 200 > 75 && t % 200 < 180 && !(t % 5)) allDirections(GrainBullet2, 8, -Math.PI * t / 200);
        if (t % 200 == 10) nWay(BigBall3, 6, d, Math.PI / 2);
        if (t % 200 == 25) nWay(BigBall3, 4, d, Math.PI / 2);
    }
}

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

// 粒弾

class GrainBullet extends Bullet {

    private static var images:Vector.<BitmapData>;
    private static var p:Point;
    private static var rect:Rectangle;
    private static var centerX:Number;
    private static var centerY:Number;
    public         var image:BitmapData;

    public static function loadImage(source:BitmapData):void {
        images = new Vector.<BitmapData>(360, true);
        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[i] = bmp;
        }
        p = new Point();
        rect = images[0].rect;
        centerX = rect.width / 2;
        centerY = rect.height / 2;
    }

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

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

    override public function hitTest():Boolean {
        var dx:Number, dy:Number;
        return (dx = player.x - x) * dx + (dy = player.y - y) * dy < 9;
    }

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

}

// 大玉

class BigBall extends Bullet {

    private static var image:BitmapData;
    private static var p:Point;
    private static var rect:Rectangle;
    private static var centerX:Number;
    private static var centerY:Number;

    public static function loadImage(bmp:BitmapData):void {
        image = bmp;
        p = new Point()
        rect = image.rect;
        centerX = rect.width / 2;
        centerY = rect.height / 2;
    }

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

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

    override public function hitTest():Boolean {
        var dx:Number, dy:Number;
        return (dx = player.x - x) * dx + (dy = player.y - y) * dy < 100;
    }

}

// 等速直進運動する弾

class GrainBullet1 extends GrainBullet {

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

    public function GrainBullet1(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 {
        if (t < 25) {
            vx *= 0.98;
            vy *= 0.98;
            t++;
        }
        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 vx:Number;
    private var vy:Number;
    private var t:uint = 0;

    public function GrainBullet2(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 {
        if (t < 25) {
            vx *= 0.97;
            vy *= 0.97;
            t++;
        }
        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 BigBall2 extends BigBall {

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

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

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

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

}

// はじけた後自機狙い

class BigBall3 extends BigBall {

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

    public function BigBall3(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 < 50) {
            vx *= 0.98;
            vy *= 0.98;
            x += vx;
            y += vy;
        } else if (t == 50) {
            direction = Math.atan2(y - player.y, player.x - x) + (Math.random() - 0.5) * 0.5;
            vx =  Math.cos(direction) * 2;
            vy = -Math.sin(direction) * 2;
        } else {
            x += vx * (1 + (t-50) * 0.012);
            y += vy * (1 + (t-50) * 0.012);
            if (x < -10 || x > field.fieldWidth + 10 ||
                y < -10 || y > field.fieldHeight + 10) {
                dead = true;
            }
        }
    }

}