一方通行

by medadotter
左から右は素通り。右から左は反射。
♥0 | Line 188 | Modified 2012-03-13 09:14:23 | MIT License
play

ActionScript3 source code

/**
 * Copyright medadotter ( http://wonderfl.net/user/medadotter )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/ie2k
 */

package
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.filters.BlurFilter;
    import flash.filters.GlowFilter;
    import flash.geom.ColorTransform;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    
    /**
     * ...
     * @author DT
     */
    [SWF(backgroundColor="0xffffff",width="465",height="465")]
    
    public class STGMain extends Sprite
    {
        private var bullet:BitmapData;
        private var canvas:BitmapData;
        
        private var bullets:Vector.<Bullet> = new Vector.<Bullet>();
        private var beginX:Number = 40;
        private var beginY:Number = stage.stageHeight / 2;
        private var reflect:Rectangle = new Rectangle(stage.stageWidth / 4, -100, stage.stageWidth / 2, stage.stageHeight + 100);
        private var frames:int = 0;
        static private const speed:Number = 20;
        private var radius:Number = 15;
        private var bgColor:uint = 0x000000;
        
        public function STGMain()
        {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            
            canvas = new BitmapData(stage.stageWidth, stage.stageHeight,false, bgColor);
            addChild(new Bitmap(canvas));
            
            var circle:Sprite = new Sprite();
            circle.graphics.lineStyle(2.0);
            circle.graphics.drawCircle(3 / 2 * radius, 3 / 2 * radius, radius);
            //様々な色の弾を出そうと思ったらもう少し工夫が必要に。
            circle.filters = [new GlowFilter(Math.random()*0xffffff)];
            
            bullet = new BitmapData(3 * radius, 3 * radius,true,0);
            bullet.draw(circle);
            
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }
        
        private function onEnterFrame(event:Event):void
        {
            refreshCanvas();
            
            if (frames++ % 1 == 0)
            {
                bullets.push(makeBullet());
            }
            
            for (var i:int = bullets.length - 1; i >= 0; i--)
            {
                var point:Point = new Point(bullets[i].x - 3/2*radius, bullets[i].y - 3/2*radius);
                canvas.copyPixels(bullet, bullet.rect, point);
                
                bullets[i].update();
                reflectBullet(bullets[i]);
                if (!onArea(bullets[i])) removeBullet(i);
            }
        }
        
        private function onArea(bullet:Bullet):Boolean {
            var right:Number = bullet.x + bullet.radius;
            var left:Number = bullet.x - bullet.radius;
            var bottom:Number = bullet.y + bullet.radius;
            var top:Number = bullet.y - bullet.radius;
            //完全に境界オーバするまで。
            if (right >= 0 && left <= stage.stageWidth &&
                bottom >= 0 && top <= stage.stageHeight)
                return true;
            return false;            
        }
        
        private function reflectBullet(bullet:Bullet):void {
            //radius考慮してないので注意。
            var prevX:Number = bullet.x - bullet.velocity.x;
            if (prevX > reflect.left && bullet.x < reflect.left) {
                bullet.x = 2 * reflect.left - bullet.x;
                bullet.velocity.x *= -1;
            }
            if (prevX < reflect.right && bullet.x > reflect.right) {
                bullet.x = 2 * reflect.right - bullet.x;
                bullet.velocity.x *= -1;
            }
        }
        
        //可読性を上げるために明示的な命名を。
        private function refreshCanvas():void {
            //canvas.fillRect(canvas.rect, 0);
            canvas.colorTransform(canvas.rect, new ColorTransform(1, 1, 1, 0.9));
        }
        
        private function removeBullet(i:int):void
        {
            bullets.splice(i, 1);
        }
        
        private function refreshBullet(bullet:Bullet):Bullet
        {
            var color:uint = Math.random() * 0xffffff;
            var radius:Number = Math.random() * 15 + 5;
            bullet.color = color;
            bullet.radius = radius;
            bullet.x = beginX;
            bullet.y = beginY;
            var angle:Number = angleToMouse();
            bullet.velocity.x = speed * Math.cos(angle);
            bullet.velocity.y = speed * Math.sin(angle);
            return bullet;
        }
        
        private function angleToMouse():Number
        {
            var dx:Number = mouseX - beginX;
            var dy:Number = mouseY - beginY;
            return Math.atan2(dy, dx);
        }
        
        private function makeBullet():Bullet
        {
            return refreshBullet(new Bullet());
        }
    
    }

}


import flash.geom.Point;

class Bullet
{
    private var _position:Point = new Point();
    private var _velocity:Point = new Point();
    private var _radius:Number;
    private var _color:uint;
    
    public function Bullet(radius:Number = 40, color:uint = 0xff0000, x:Number = 0, y:Number = 0)
    {
        this.radius = radius;
        this.color = color;
        this.x = x;
        this.y = y;
    }
    
    public function update():void
    {
        x += velocity.x;
        y += velocity.y;
    }
    
    public function onArea(width:Number, height:Number):Boolean
    {
        if (x + radius >= 0 && x - radius <= width && y + radius >= 0 && y - radius <= height)
            return true;
        return false;
    }
    
    private function draw():void
    {
    }
    
    public function set x(value:Number):void
    {
        position.x = value;
    }
    
    public function get x():Number
    {
        return position.x;
    }
    
    public function set y(value:Number):void
    {
        position.y = value;
    }
    
    public function get y():Number
    {
        return position.y;
    }
    
    public function get position():Point
    {
        return _position;
    }
    
    public function set position(value:Point):void
    {
        _position = value;
    }
    
    public function get velocity():Point
    {
        return _velocity;
    }
    
    public function set velocity(value:Point):void
    {
        _velocity = value;
    }
    
    public function get radius():Number
    {
        return _radius;
    }
    
    public function set radius(value:Number):void
    {
        _radius = value;
        draw();
    }
    
    public function get color():uint
    {
        return _color;
    }
    
    public function set color(value:uint):void
    {
        _color = value;
        draw();
    }

}