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: KATAMARU? OR NOTをズルしてみた(逐次非再帰版)

最小半径のを打つ。高速だけど次の手を考えていない。
Get Adobe Flash player
by uwi 30 Oct 2009
/**
 * Copyright uwi ( http://wonderfl.net/user/uwi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/pHL8
 */

// 最小半径のを打つ。高速だけど次の手を考えていない。
// forked from uwi's KATAMARU? OR NOTをズルしてみた(逐次版)
// forked from uwi's forked from: KATAMARU? OR NOT
// forked from beinteractive's KATAMARU? OR NOT
package

{

    import flash.display.Bitmap;

    import flash.display.BitmapData;

    import flash.display.PixelSnapping;

    import flash.display.Sprite;

    import flash.display.StageAlign;

    import flash.display.StageQuality;

    import flash.display.StageScaleMode;
    import flash.display.Graphics;

    import flash.events.Event;
    import flash.events.KeyboardEvent;

    import flash.geom.ColorTransform;

    import flash.geom.Point;
    import flash.geom.Matrix;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    import flash.ui.Keyboard;
    import com.bit101.components.Label;

    

    public class KatamaruOrNot extends Sprite

    {
        private static const ZERO:Point = new Point(0, 0);
        
        private static const STATE_INPUT:uint = 0;
        private static const STATE_SHOT:uint = 1;
        private static const STATE_GAMEOVER:uint = 2;
        
        private var _algo : Algorithm;
        
        public function KatamaruOrNot()
        {
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.quality = StageQuality.LOW;
            
            var sw:Number = stage.stageWidth;
            var sh:Number = stage.stageHeight;
            
            _ballBackground = new Sprite();
            
            _ballBackground.x = sw / 2;
            _ballBackground.y = sh / 2 - 80;
            
            _ballBackground.graphics.clear();
            _ballBackground.graphics.lineStyle(0, 0xcccccc);
            _ballBackground.graphics.drawCircle(0, 0, 100);
            
            addChild(_ballBackground);
            
            _ballLayer = new Sprite();
            _ballLayer.x = sw / 2;
            _ballLayer.y = sh / 2 - 80;
            
            addChild(_ballLayer);
            
            _shotLayer = new Sprite();
            
            addChild(_shotLayer);
            
            _particleLayer = new Sprite();
            
            addChild(_particleLayer);
            
            _ballsBitmapData = new BitmapData(sw, sh, true, 0x00000000);
            _ballsBitmapData.lock();
            
            _shotBitmapData = new BitmapData(sw, sh, true, 0x00000000);
            _shotBitmapData.lock();
            
            _ballsBitmapDataMatrix = new Matrix();
            
            _scoreField = new Label(this, 5, 3);
            
            _titleField = new Label(this, 0, 3, 'KATAMARU? OR NOT');
            _titleField.autoSize = true;
            
            new Label(this, 5, (sh - (21 + 14 * 3)), '[SPACEKEY]: SHOOT');
            new Label(this, 5, (sh - (21 + 14 * 2)), 'KATAMATTA: +20');
            new Label(this, 5, (sh - (21 + 14 * 1)), 'KATAMARANAI: -10');
            new Label(this, 5, (sh - (21 + 14 * 0)), 'HAMIDETA: GAMEOVER');
            
            deb = new Label(this, 5, 30);
            _algo = new Algorithm(deb, this);
            
            startGame();
            
            stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
            stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
            
            addEventListener(Event.ENTER_FRAME, initialEnterFrameHandler);
        }
        
        private var _ballBackground:Sprite;
        private var _ballLayer:Sprite;
        private var _shotLayer:Sprite;
        private var _particleLayer:Sprite;
        
        private var _scoreField:Label;
        private var _titleField:Label;
        
        private var _shotBall:KatamariBall;
        
        private var _ballsBitmapData:BitmapData;
        private var _shotBitmapData:BitmapData;
        
        private var _ballsBitmapDataMatrix:Matrix;
        
        private var _shotAngle:Number;
        private var _shotAngleCounter:Number;
        
        private var _particles:Array = [];
        
        private var _isSpaceDown:Boolean = false;
        
        private var _nowState:uint;
        
        private var _score:int;
        
        private function initialEnterFrameHandler(e:Event):void
        {
            removeEventListener(Event.ENTER_FRAME, initialEnterFrameHandler);
            
            _titleField.x = stage.stageWidth - (_titleField.width + 5);
            
            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }
        
        private var deb : Label;
        
        private function startGame():void
        {
            while (_ballLayer.numChildren > 0) {
                _ballLayer.removeChild(_ballLayer.getChildAt(0));
            }
            
            _ballLayer.addChild(new KatamariBall(40));
            
            _shotBall = null;
            
            _score = 0;
            deb.text = "";
            
            _t = 0;
            startInput();
        }
        
        private function startInput():void
        {
            _nowState = STATE_INPUT;
            
            _shotAngleCounter = 0;
            
            _shotBall = new KatamariBall();
            _shotBall.x = stage.stageWidth / 2;
            _shotBall.y = stage.stageHeight - 30;
            
            _targ = _algo.algo(_ballLayer, _shotBall);
            
            _shotLayer.addChild(_shotBall);
        }
        
        private function keyDownHandler(e:KeyboardEvent):void
        {
            if (e.keyCode == Keyboard.SPACE) {
                _isSpaceDown = true;
            }
        }
        
        private function keyUpHandler(e:KeyboardEvent):void
        {
            if (e.keyCode == Keyboard.SPACE) {
                _isSpaceDown = false;
            }
        }
        
        private var _targ : int;
        private var _t : int;
        
        private function enterFrameHandler(e:Event):void
        {
            updateParticles();
            
            
            if (_nowState == STATE_GAMEOVER) {
                
                _scoreField.text = 'GAMEOVER: ' + _score;
                
                if (_isSpaceDown) {
                    _isSpaceDown = false;
                    startGame();
                }
                return;
            }
            
            _ballLayer.rotation += 2;
            _ballBackground.rotation = _ballLayer.rotation;
            
            if (_nowState == STATE_INPUT) { 
                
                var bx:Number = stage.stageWidth / 2;
                var by:Number = stage.stageHeight;
                
                _shotAngle = (150 - Math.sin(_shotAngleCounter) * 120) / 360 * Math.PI;
                _shotAngleCounter += Math.PI / 60;
                
                _shotBall.x = bx + Math.cos(_shotAngle) * 50;
                _shotBall.y = by - Math.sin(_shotAngle) * 50;
                
                _shotLayer.graphics.clear();
                _shotLayer.graphics.lineStyle(0, 0xcccccc);
                _shotLayer.graphics.drawCircle(bx, by, 50);
                _shotLayer.graphics.lineStyle(0, 0x333333);
                _shotLayer.graphics.moveTo(bx, by);
                _shotLayer.graphics.lineTo(_shotBall.x, _shotBall.y);
                
                if (_isSpaceDown) {
                    _nowState = STATE_SHOT;
                    
                    _shotBall.positionX = _shotBall.x;
                    _shotBall.positionY = _shotBall.y;
                    _shotBall.velocityX = Math.cos(_shotAngle) * 18;
                    _shotBall.velocityY = Math.sin(_shotAngle) * -18;
                }else{
                    if(_t == _targ - 1){
                        dispatchEvent(new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 0, Keyboard.SPACE));
                        _t = 0;
                    }else{
                        _t++;
                    }
                }
            }
            if (_nowState == STATE_SHOT) {
                    dispatchEvent(new KeyboardEvent(KeyboardEvent.KEY_UP, true, false, 0, Keyboard.SPACE));
                
                moveBall(_shotBall);
                
                _ballsBitmapDataMatrix.identity();
                _ballsBitmapDataMatrix.rotate(_ballLayer.rotation / 360 * Math.PI * 2);
                _ballsBitmapDataMatrix.translate(_ballLayer.x, _ballLayer.y);
                
                _ballsBitmapData.fillRect(_ballsBitmapData.rect, 0x00000000);
                _ballsBitmapData.draw(_ballLayer, _ballsBitmapDataMatrix);
                
                _shotBitmapData.fillRect(_shotBitmapData.rect, 0x00000000);
                _shotBitmapData.draw(_shotLayer);
                
                if (_ballsBitmapData.hitTest(ZERO, 128, _shotBitmapData, ZERO, 128)) {
                    
                    _shotLayer.removeChild(_shotBall);
                    
                    var p:Point = _ballLayer.globalToLocal(new Point(_shotBall.x, _shotBall.y));
                    _shotBall.x = p.x;
                    _shotBall.y = p.y;
                    _ballLayer.addChild(_shotBall);
                    
                    var l:Number = Math.sqrt(p.x * p.x + p.y * p.y);
                    
                    for (var i:uint = 0; i < 4; ++i) {
                        var particle:KatamariBall = new KatamariBall(2 + Math.random() * 3, _shotBall.color + 30 + 360 / 4 * i);
                        var ppos:Point = _ballLayer.localToGlobal(new Point(p.x * ((l - 10) / l), p.y * ((l - 10) / l)));
                        particle.positionX = ppos.x;
                        particle.positionY = ppos.y;
                        particle.velocityX = (Math.random() * 16 + 2) - 9;
                        particle.velocityY = Math.random() * -9 - 4;
                        _particleLayer.addChild(particle);
                        _particles.push(particle);
                    }
                    
                    _score += 20;
                    
                    if (l > 90) {
                        _nowState = STATE_GAMEOVER;
                        _isSpaceDown = false;
                    }
                    else {
                        startInput();
                    }
                }
                if (_shotBall != null && isOut(_shotBall)) {
                    _shotLayer.removeChild(_shotBall);
                    _shotBall = null;
                    
                    _score -= 10;
                    
                    startInput();
                }
            }
            
            _scoreField.text = 'SCORE: ' + _score;
        }
        
        private function updateParticles():void
        {
            for (var i:int = 0; i < _particles.length; ++i) {
                var particle:KatamariBall = _particles[i] as KatamariBall;
                moveBall(particle);
                if (isOut(particle)) {
                    _particleLayer.removeChild(particle);
                    _particles.splice(i, 1);
                    --i;
                }
            }
        }
        
        private function moveBall(ball:KatamariBall):void
        {
            ball.positionX += ball.velocityX;
            ball.positionY += ball.velocityY;
            ball.velocityY += 0.45;
            
            ball.x = ball.positionX;
            ball.y = ball.positionY;
        } 
        
        private function isOut(ball:KatamariBall):Boolean
        {
            return ball.positionX < -30 || ball.positionX > stage.stageWidth + 30 || ball.positionY < -30 || ball.positionY > stage.stageHeight + 30;
        }
    }

}

import flash.display.Sprite;
import flash.display.Graphics;
import frocessing.color.ColorHSV;



class KatamariBall extends Sprite
{
    public function KatamariBall(size:Number = 20, color:Number = NaN)
    {
        var g:Graphics = graphics;
        var radius:Number = size;
        var d:Number = size / 5;
        var resolution:Number = 10;
        
        if (isNaN(color)) {
            color = Math.random() * 360;
        }
        
        _color = color;
        
        g.clear();
        g.beginFill(new ColorHSV(color, 0.8, 1.0).value);
        g.moveTo(Math.cos(0) * radius, Math.sin(0) * radius);
        for (var i:uint = 1; i < resolution; ++i) {
            var angle:Number = Math.PI * 2 / resolution * i;
            var r:Number = radius + (Math.random() * d - d / 2);
            g.lineTo(Math.cos(angle) * r, Math.sin(angle) * r);
        }
        g.endFill();
        
        cacheAsBitmap = true;
        blendMode = 'multiply';
    }
    
    private var _color:Number;
    
    public var positionX:Number = 0;
    public var positionY:Number = 0;
    public var velocityX:Number = 0;
    public var velocityY:Number = 0;
    
    public function get color():uint
    {
        return _color;
    }
}

import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.geom.Point;
import flash.geom.Matrix;
import flash.utils.getTimer;
import com.bit101.components.Label;

class Algorithm
{
    private var _ballLayer : Sprite;
    private var _shot : KatamariBall;
    private var _field : Sprite;
    private var _deb : Label;
    private var _vtimes : Array;
    private var _debs : Sprite;
    
    private var _ballsBitmapDataMatrix:Matrix;
    private var _shotBitmapDataMatrix:Matrix;
    private var _ballsBitmapData : BitmapData;
    private var _shotBitmapData : BitmapData;
    private static const ZERO:Point = new Point(0, 0);
    private var _p : Point;
    
    public function Algorithm(deb : Label, debs : Sprite)
    {
        _deb = deb;
        _debs = debs;
        
        _ballLayer = new Sprite();
        _ballLayer.x = 465 / 2;
        _ballLayer.y = 465 / 2 - 80;
        
        _shot = new KatamariBall();
        
        _field = new Sprite();
        _field.addChild(_ballLayer);
        _field.addChild(_shot);
        
        _ballsBitmapData = new BitmapData(50, 50, true, 0x00000000);
        _ballsBitmapData.lock();
        _ballsBitmapDataMatrix = new Matrix();
        
        _shotBitmapData = new BitmapData(50, 50, true, 0x00000000);
        _shotBitmapData.lock();
        
        _p = new Point();
        _vtimes = enumValidTime();
    }
    
    public function algo(orig : Sprite, shot : KatamariBall) : int
    {
        // 序盤は垂直うちでうまく埋まる
        if(orig.numChildren < 8)return 65;
        
        var i : int;
        
        for(i = _ballLayer.numChildren - 1;i >= 0;i--){
            _ballLayer.removeChildAt(0);
        }
        for(i = 0;i < orig.numChildren;i++){
            var cl : Sprite = new Sprite();
            cl.graphics.copyFrom(Sprite(orig.getChildAt(i)).graphics);
            cl.x = orig.getChildAt(i).x;
            cl.y = orig.getChildAt(i).y;
            _ballLayer.addChild(cl);
        }
        _ballLayer.rotation = orig.rotation;
        
        _shot.graphics.clear();
        _shot.graphics.copyFrom(shot.graphics);
        _shotBitmapDataMatrix = new Matrix();
        _shotBitmapDataMatrix.translate(25, 25);
        _shotBitmapData.fillRect(_shotBitmapData.rect, 0x00000000);
        _shotBitmapData.draw(_shot, _shotBitmapDataMatrix);
        
        /*
        _ballsBitmapDataMatrix.identity();
        _ballsBitmapDataMatrix.rotate(_ballLayer.rotation / 360 * Math.PI * 2);
        _ballsBitmapDataMatrix.translate(_ballLayer.x, _ballLayer.y);
        var bmd : BitmapData = new BitmapData(465, 465, true, 0x00000000);
        bmd.draw(_ballLayer, _ballsBitmapDataMatrix);
        _debs.addChild(new Bitmap(bmd));
        */
        
        var s : int = getTimer();
        
        var maxt : int = 65;
        var minL : Number = Number.MAX_VALUE;
        var orot : int = _ballLayer.rotation;
//        var onc : int = _ballLayer.numChildren;
        for each(var t : int in _vtimes){
            stepToShot(t);
            var res : Array = stepToHit();
            if(res[0] >= 1 && res[2] < minL){
                minL = res[2];
                maxt = t;
            }
        
            // 元の状態に戻す
//            if(_ballLayer.numChildren > onc)_ballLayer.removeChildAt(_ballLayer.numChildren - 1);
            _ballLayer.rotation = orot;
        }
                
        var g : int = getTimer();
        _deb.text += "" + (g - s) + " ms " + minL + "\n";
        return maxt;
    }
    
    private function stepToShot(t : int) : void
    {
        _ballLayer.rotation += 2 * t;
        
        var shotAngle : Number = (150 - Math.sin(Math.PI / 60 * t) * 120) / 360 * Math.PI;
        _shot.x = 465 / 2 + Math.cos(shotAngle) * 50;
        _shot.y = 465 - Math.sin(shotAngle) * 50;
        
        _shot.velocityX = Math.cos(shotAngle) * 18;
        _shot.velocityY = Math.sin(shotAngle) * -18;
        _shot.positionX = _shot.x;
        _shot.positionY = _shot.y;
    }
    
    
    // 0 : no hit
    // 1 : hit
    // 2 : hit but gameover
    private function stepToHit() : Array
    {
        for(var t : int = 0;;t++){
            _shot.positionX += _shot.velocityX;
            _shot.positionY += _shot.velocityY;
            _shot.velocityY += 0.45;
            _shot.x = _shot.positionX;
            _shot.y = _shot.positionY;
            
            _p.x = _shot.x;
            _p.y = _shot.y;
            var p:Point = _ballLayer.globalToLocal(_p);
            var l : Number = p.length;
            if(l < 120){
                
                _ballsBitmapDataMatrix.identity();
                _ballsBitmapDataMatrix.rotate(_ballLayer.rotation / 360 * Math.PI * 2);
                _ballsBitmapDataMatrix.translate(_ballLayer.x - _shot.x + 25, _ballLayer.y - _shot.y + 25); 
                
                _ballsBitmapData.fillRect(_ballsBitmapData.rect, 0x00000000);
                _ballsBitmapData.draw(_ballLayer, _ballsBitmapDataMatrix);
                
                if (_ballsBitmapData.hitTest(ZERO, 128, _shotBitmapData, ZERO, 128)) {
                    _ballLayer.rotation += 2; // XXX
                    
                    return [l > 90 ? 2 : 1, t, l];
                }
            }
            
            if (isOut(_shot)) {
                return [0, t];
            }
            _ballLayer.rotation += 2;
        }
        return null;
    }
    
    private function enumValidTime() : Array
    {
        var ret : Array = [];
        for(var t : int = 0;t < 360;t++){ // 3往復以内
            var shotAngle : Number = (150 - Math.sin(Math.PI / 60 * t) * 120) / 360 * Math.PI;
            var x : Number = 465 / 2 + Math.cos(shotAngle) * 50;
            var y : Number = 465 - Math.sin(shotAngle) * 50;
            
            var vx : Number = Math.cos(shotAngle) * 18;
            var vy : Number = Math.sin(shotAngle) * -18;
            
            var l : Number = Number.MAX_VALUE;
            var prevl : Number = Number.MAX_VALUE;
            while(prevl >= l){
                prevl = l;
                
                x += vx;
                y += vy;
                vy += 0.45;
                
                l = (465 / 2 - x) * (465 / 2 - x) + (465 / 2 - 80 - y) * (465 / 2 - 80 - y);
                if(l < 90 * 90){
                    ret.push(t);
                    break;
                }
            }
        }
        return ret;
    }
    
    private static function isOut(ball:KatamariBall):Boolean
    {
//        return ball.positionX < -30 || ball.positionX > 465 + 30 || ball.positionY < -30 || ball.positionY > 465 + 30;
        return ball.positionX < 0 || ball.positionX > 465 || ball.positionY > 465 + 30;
    }
}