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

境符「波と粒の境界」

#2011-7-14: recovered using Base64 image.

境符「波と粒の境界」 再現する!!! 
私は東方シリーズ(STG)が大好き!
Arrow Key で移動
Shift で低速移動
今のところ避けることしかできません
/**
 * Copyright kimo0517 ( http://wonderfl.net/user/kimo0517 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/vjjw
 */

// 境符「波と粒の境界」 再現する!!! 
// 私は東方シリーズ(STG)が大好き!
//
// 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;

    import org.libspark.betweenas3.BetweenAS3;
    import org.libspark.betweenas3.events.TweenEvent;
    import org.libspark.betweenas3.tweens.ITween;
    import org.libspark.betweenas3.easing.Quadratic;
    
    import mx.utils.Base64Decoder;


    [SWF(width=465, height=465, backgroundColor="#262626", frameRate="60")]

    public class Game 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;
        private var title:TextField;

        private var startTime:int;

        private var updateHit:uint;
        private var updateStatusStr:String;


        public function Game() {
            stage.align = "TL";
            stage.scaleMode = "noScale";

            /*
            Security.loadPolicyFile("http://5ivestar.org/misc/crossdomain.xml");
            */
            var point:Base64Decoder = new Base64Decoder;
            point.decode("iVBORw0KGgoAAAANSUhEUgAAADcAAAAcCAYAAADFsCezAAAACXBIWXMAAAsTAAALEwEAmpwYAAAK"
+"TWlDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVN3WJP3Fj7f92UPVkLY8LGXbIEAIiOsCMgQ"
+"WaIQkgBhhBASQMWFiApWFBURnEhVxILVCkidiOKgKLhnQYqIWotVXDjuH9yntX167+3t+9f7vOec"
+"5/zOec8PgBESJpHmomoAOVKFPDrYH49PSMTJvYACFUjgBCAQ5svCZwXFAADwA3l4fnSwP/wBr28A"
+"AgBw1S4kEsfh/4O6UCZXACCRAOAiEucLAZBSAMguVMgUAMgYALBTs2QKAJQAAGx5fEIiAKoNAOz0"
+"ST4FANipk9wXANiiHKkIAI0BAJkoRyQCQLsAYFWBUiwCwMIAoKxAIi4EwK4BgFm2MkcCgL0FAHaO"
+"WJAPQGAAgJlCLMwAIDgCAEMeE80DIEwDoDDSv+CpX3CFuEgBAMDLlc2XS9IzFLiV0Bp38vDg4iHi"
+"wmyxQmEXKRBmCeQinJebIxNI5wNMzgwAABr50cH+OD+Q5+bk4eZm52zv9MWi/mvwbyI+IfHf/ryM"
+"AgQAEE7P79pf5eXWA3DHAbB1v2upWwDaVgBo3/ldM9sJoFoK0Hr5i3k4/EAenqFQyDwdHAoLC+0l"
+"YqG9MOOLPv8z4W/gi372/EAe/tt68ABxmkCZrcCjg/1xYW52rlKO58sEQjFu9+cj/seFf/2OKdHi"
+"NLFcLBWK8ViJuFAiTcd5uVKRRCHJleIS6X8y8R+W/QmTdw0ArIZPwE62B7XLbMB+7gECiw5Y0nYA"
+"QH7zLYwaC5EAEGc0Mnn3AACTv/mPQCsBAM2XpOMAALzoGFyolBdMxggAAESggSqwQQcMwRSswA6c"
+"wR28wBcCYQZEQAwkwDwQQgbkgBwKoRiWQRlUwDrYBLWwAxqgEZrhELTBMTgN5+ASXIHrcBcGYBie"
+"whi8hgkEQcgIE2EhOogRYo7YIs4IF5mOBCJhSDSSgKQg6YgUUSLFyHKkAqlCapFdSCPyLXIUOY1c"
+"QPqQ28ggMor8irxHMZSBslED1AJ1QLmoHxqKxqBz0XQ0D12AlqJr0Rq0Hj2AtqKn0UvodXQAfYqO"
+"Y4DRMQ5mjNlhXIyHRWCJWBomxxZj5Vg1Vo81Yx1YN3YVG8CeYe8IJAKLgBPsCF6EEMJsgpCQR1hM"
+"WEOoJewjtBK6CFcJg4Qxwicik6hPtCV6EvnEeGI6sZBYRqwm7iEeIZ4lXicOE1+TSCQOyZLkTgoh"
+"JZAySQtJa0jbSC2kU6Q+0hBpnEwm65Btyd7kCLKArCCXkbeQD5BPkvvJw+S3FDrFiOJMCaIkUqSU"
+"Eko1ZT/lBKWfMkKZoKpRzame1AiqiDqfWkltoHZQL1OHqRM0dZolzZsWQ8ukLaPV0JppZ2n3aC/p"
+"dLoJ3YMeRZfQl9Jr6Afp5+mD9HcMDYYNg8dIYigZaxl7GacYtxkvmUymBdOXmchUMNcyG5lnmA+Y"
+"b1VYKvYqfBWRyhKVOpVWlX6V56pUVXNVP9V5qgtUq1UPq15WfaZGVbNQ46kJ1Bar1akdVbupNq7O"
+"UndSj1DPUV+jvl/9gvpjDbKGhUaghkijVGO3xhmNIRbGMmXxWELWclYD6yxrmE1iW7L57Ex2Bfsb"
+"di97TFNDc6pmrGaRZp3mcc0BDsax4PA52ZxKziHODc57LQMtPy2x1mqtZq1+rTfaetq+2mLtcu0W"
+"7eva73VwnUCdLJ31Om0693UJuja6UbqFutt1z+o+02PreekJ9cr1Dund0Uf1bfSj9Rfq79bv0R83"
+"MDQINpAZbDE4Y/DMkGPoa5hpuNHwhOGoEctoupHEaKPRSaMnuCbuh2fjNXgXPmasbxxirDTeZdxr"
+"PGFiaTLbpMSkxeS+Kc2Ua5pmutG003TMzMgs3KzYrMnsjjnVnGueYb7ZvNv8jYWlRZzFSos2i8eW"
+"2pZ8ywWWTZb3rJhWPlZ5VvVW16xJ1lzrLOtt1ldsUBtXmwybOpvLtqitm63Edptt3xTiFI8p0in1"
+"U27aMez87ArsmuwG7Tn2YfYl9m32zx3MHBId1jt0O3xydHXMdmxwvOuk4TTDqcSpw+lXZxtnoXOd"
+"8zUXpkuQyxKXdpcXU22niqdun3rLleUa7rrStdP1o5u7m9yt2W3U3cw9xX2r+00umxvJXcM970H0"
+"8PdY4nHM452nm6fC85DnL152Xlle+70eT7OcJp7WMG3I28Rb4L3Le2A6Pj1l+s7pAz7GPgKfep+H"
+"vqa+It89viN+1n6Zfgf8nvs7+sv9j/i/4XnyFvFOBWABwQHlAb2BGoGzA2sDHwSZBKUHNQWNBbsG"
+"Lww+FUIMCQ1ZH3KTb8AX8hv5YzPcZyya0RXKCJ0VWhv6MMwmTB7WEY6GzwjfEH5vpvlM6cy2CIjg"
+"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"
+"AElFTkSuQmCC");
            
            loader = new Loader();
            loader.contentLoaderInfo.addEventListener("complete", loadingComplete);
            //loader.load(new URLRequest("http://5ivestar.org/misc/bullets.png"), new LoaderContext(true));
            loader.loadBytes(point.toByteArray());

            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 to start";
            tf.x = 200 - tf.width / 2;
            tf.y = 230 - tf.height / 2;
            tf.selectable = false;
            s.addChild(tf);
            s.addEventListener(MouseEvent.MOUSE_UP, function(e:MouseEvent):void {
                removeChild(s);
                stage.focus = stage;
                start();
            });
        }

        public function start():void {
                        if (!title) {
                            title = addChild(new TextField) as TextField;
                            title.autoSize = "left";
                            title.defaultTextFormat = new TextFormat("_sans", 16);
                            title.text = "境符「波と粒の境界」";
                            title.textColor = 0xffffff;
                            title.selectable = false;
                        }
                        title.x = 465;
                        title.y = 440;
                        var tween:ITween = BetweenAS3.serial(BetweenAS3.tween(title, {x:390 - title.width}, {x:title.x}, 1, Quadratic.easeOut), BetweenAS3.tween(title, {y:10}, {y:title.y}, 2, Quadratic.easeOut))
                        tween.play();
                        
            startTime = (new Date()).time;
            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 {
            var i:int;
            t++;
            pField.update();
            updateHit = eField.update();
            if (updateHit) player.hit();
            if (player.dead) finish();
            hit += updateHit;

            updateStatusStr = "BULLETS: " + eField.bullets.length.toString() + 
                            "\nHIT: " + hit.toString() +
                            "\nLIFE: ";
            for (i = 0; i < player.life; i++) {
                updateStatusStr += "★";
            }
            status.text = updateStatusStr;
        }

        public function finish():void {
            var endTime:int = (new Date()).time;
            var diffTime:Number = (endTime-startTime)/1000;
            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 = "Survival Time: "+diffTime.toFixed(2) + "s\nClick to Retry";
            tf.x = 200 - tf.width / 2;
            tf.y = 230 - tf.height / 2;
                        tf.selectable = false;
            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 {
        var bullet:Bullet;
        bitmapData.lock();
        bitmapData.fillRect(bitmapData.rect, 0x00000000);
        var hit:uint = 0;
        var n:uint = bullets.length;
        while (n--) {
            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<0) {
                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;
        }
    }

}

// 敵機

import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.events.TweenEvent;
import org.libspark.betweenas3.tweens.ITween;
import org.libspark.betweenas3.easing.Quadratic;

class Enemy extends Bullet {

    private var t:uint;    
    private var shootDirection:Object;
    public function Enemy(x0:Number = 0, y0:Number = 0) {
        super(x0, y0, 0);
        shootDirection = {d:(30 / 180 * Math.PI+Math.random())};
        _startTween(null);
    }
    
    private function _startTween(e:TweenEvent):void {
        var tween3:ITween = BetweenAS3.serial(BetweenAS3.tween(shootDirection, { d:-65.5+Math.random()}, null, 15, Quadratic.easeInOut), 
                                    BetweenAS3.tween(shootDirection, { d:30 / 180 * Math.PI+Math.random()}, null, 15, Quadratic.easeInOut));
        tween3.addEventListener(TweenEvent.COMPLETE, _startTween);
        tween3.play();
    }

    override public function update():void {
        t++;
        if (t < 10) return;
        var d:Number = Math.atan2(y - player.y, player.x - x);
        if (!(t % 2)) nWay(GrainBullet1, 11, shootDirection.d, 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 GrainBullet1 extends GrainBullet {

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

    public function GrainBullet1(x0:Number, y0:Number, d:Number, v:Number = 2.7) {
        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;
        }
    }

}