Beautifl - Flash Gallery

Preview

方向一定しつつ衝突判定 forked from: Yawaraka Balls
HaraMakoto 2009年11月18日 MIT License
?
      package
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.TimerEvent;
    import flash.utils.Timer;
    
    import net.hires.debug.Stats;
    
    [SWF(width="465", height="465", backgroundColor="#000000", frameRate=60)]
    public class HitTest3 extends Sprite
    {
        private var elemList:Array = new Array();
        private var elemNum:int = 20;
        private var colManager:EasyColosionManager = new EasyColosionManager();
        private var RoadList:Array = new Array();
        
        public function HitTest3()
        {
            super();
            addChild(new Stats());
            init();
            addEventListener(Event.ENTER_FRAME, handleEnterFrame);
        }
        
        private function init():void {
            //道路一覧
            RoadList = [
                new RoadUnit(80,445,"y",-1),new RoadUnit(140,20,"y",1),
                new RoadUnit(200,445,"y",-1),new RoadUnit(240,20,"y",1),
                new RoadUnit(340,445,"y",-1),new RoadUnit(400,20,"y",1),
                new RoadUnit(445,90,"x",-1),new RoadUnit(20,140,"x",1),
                new RoadUnit(445,180,"x",-1),new RoadUnit(20,210,"x",1),
                new RoadUnit(445,280,"x",-1),new RoadUnit(20,340,"x",1)
            ]
            var i:int;
            for(i=0; i<elemNum; i++) {
                var elem:Elemet = new Elemet();
                addChild(elem);
                colManager.addElement(elem); //衝突マネージャ
                elemList.push(elem);
                var ru:RoadUnit = RoadList[int(RoadList.length*Math.random())];
                elem.px = ru.x;
                elem.py = ru.y;
                if(ru.vecType=="x") {
                    if(ru.posinega==1) {
                        elem.px += 100*Math.random();
                    } else {
                        elem.px -= 100*Math.random();
                    }
                } else {
                    elem.py += 100*Math.random();                    
                }
                elem.init((ru.vecType=="x"),(ru.vecType=="y"),0.01*ru.posinega, 0.01*ru.posinega,ru.x, ru.y);
            }
//            var too:TooSenBoo = new TooSenBoo();
//            addChild(too);
//            colManager.addElement(too);
//            elemList.push(too);
//            elemNum++;
            
            this.graphics.clear();
            for(i=0; i<RoadList.length; i++) {
                var rr:RoadUnit = RoadList[i];
                this.graphics.lineStyle(1,0x333333);
                this.graphics.moveTo(rr.x,rr.y);
                var goalNum:Number = 465;
                if(rr.posinega==-1) goalNum = 0;
                if(rr.vecType=="x") {
                    this.graphics.lineTo(goalNum, rr.y);
                } else {
                    this.graphics.lineTo(rr.x, goalNum);                    
                }
            }
        }
        
        
        private function handleEnterFrame(event:Event):void {
            for (var t:int = 0; t < 4; t++) {
                var i:int;
                for(i=0; i<elemNum; i++) {
                    elemList[i].update();
                }
                colManager.checkColision();
            }
            for(i=0; i<elemNum; i++) {
                elemList[i].render();
            }
        }
        
    }
}
    import flash.events.EventDispatcher;
    import flash.display.Sprite;
    import flash.utils.Timer;
    import flash.events.TimerEvent;
    import flash.geom.Point;
    import caurina.transitions.Tweener;
    import caurina.transitions.Equations;
    

class EasyColosionManager extends EventDispatcher {
    private var elemList:Array = new Array();
    private var elemlen:int = 0;
    private var spring:Number = 0.2;
    private var bounce:Number = -0.5;
    private var gravity:Number = 0.1;
    public function EasyColosionManager() {
        
    }
    
    public function addElement(elem:Elemet):void {
        elemList.push(elem);
        elemlen = elemList.length;
    }
    
    public function checkColision():void {
        var i:int;
        for(i=0; i<elemlen-1; i++) {
            var elem0:Elemet = elemList[i];
            for(var j:int=i+1; j<elemlen; j++) {
                var elem1:Elemet = elemList[j];
                elem0.hitTest(elem1);
            }
        }
        
    }
    
    //2者間の距離を返す
    private function culcDistBetElems(mc1:Sprite, mc2:Sprite):Number {
        var pt1:Point = new Point(mc1.x, mc2.x);
        var pt2:Point = new Point(mc2.x, mc2.y);
        var dist:Number = Point.distance(pt1, pt2);
        return dist;
    }
    
}

class Elemet extends Sprite {
    public var px:Number = 0;
    public var py:Number = 0;
    public var vx:Number = 0;
    public var vy:Number = 0;
    public var maxX:Number = 465;
    public var maxY:Number = 465;
    public var started:Boolean = false;
    public var radious:Number = 10;
    private var spring:Number = 0.1;
    private var bounce:Number = -0.5;
    
    private var cx:Number = 0;
    private var cy:Number = 0;
    private var priority:int = 0;
    
    private var isXAddition:Boolean = false;
    private var isYAddition:Boolean = true;
    private var additionalVx:Number = 0.1;
    private var additionalVy:Number = 0.01;
    private var fixX:Number = 200;
    private var fixY:Number = 200;
    
    private var startPt:Point = new Point(0,0);
    private var startVx:Number, startVy:Number;
    
    private var timer:Timer = new Timer(1000);
    public function Elemet() {
        radious = 16 * Math.random();
        makeBody();
    }
    
    private function makeBody():void {
        this.graphics.beginFill(0xFFFFFF*Math.random());
        this.graphics.drawCircle(0,0,radious);
        this.graphics.endFill();
    }
    
    public function attacked():void {
        Tweener.addTween(this, {alpha:0, time:0.2, transition:Equations.easeOutInBounce});
        Tweener.addTween(this, {alpha:1, time:0.2, delay:0.2, transition:Equations.easeOutInBounce});
    }
    
    public function contact(contactX:Number, contactY:Number, _priority:int, force:Number):void {
        var tx:Number = contactX - px;
        var ty:Number = contactY - py;
        
        var angle:Number = Math.atan2(ty, tx);
        var length:Number = Math.sqrt(tx*tx+ty*ty);
        
        vx -= (1-length/radious)*0.5*Math.cos(angle);
        vy -= (1-length/radious)*0.5*Math.sin(angle);
        
        if(this.priority < _priority) {
            this.priority = _priority;
            cx = tx;
            cy = ty;
        }
    }
    public function hitTest(elm:Elemet):void {
        var dx:Number = elm.px - px;
        var dy:Number = elm.py - py;
        var distanceSquared:Number = dx*dx+dy*dy;
        var contactDistance:Number = radious + elm.radious;
        if(distanceSquared < contactDistance*contactDistance) {
            var tx:Number = linearTransform(radious, 0, contactDistance, px, elm.px);
            var ty:Number = linearTransform(radious, 0, contactDistance, py, elm.py);
            contact(tx, ty, 2, 0.5);
            elm.contact(tx, ty, 2, 0.5);
        }
    }
    private function linearTransform(n:Number, s0:Number, s1:Number, d0:Number, d1:Number):Number {
        return ( d0+(n-s0)*(d1-d0) / (s1-s0) );
    }
    
    
    public function update():void {
        cx = 0;
        cy = 0;
        priority = 0;
    
        px += vx;
        py += vy;
        
        if(px-radious<0) {
            setStartPosition();
        }
        if(px+radious>465) {
            setStartPosition();
        }
        if(py-radious<0) {
            setStartPosition();
        }
        
        //端までいったら戻る
        if(isContactWall())
            setStartPosition();
            
        mainAdditionalVec();
        vy *= 0.9796;
        vx *= 0.9796;
    }
    public function init(xAnable:Boolean=true, yAnable:Boolean=false, _vx:Number=0.001, _vy:Number=0.001, _x:Number=200, _y:Number=200):void {
        startPt.x = _x; startPt.y = _y;
        startVx = _vx; startVy = _vy;
        changeAction(xAnable,yAnable,_vx,_vy,_x,_y);
    }
    private function setStartPosition():void {
        px = startPt.x;
        py = startPt.y;
        vx = startVx;
        vy = startVy;
    }
    public function changeAction(xAnable:Boolean=true, yAnable:Boolean=false, _vx:Number=0.001, _vy:Number=0.001, _x:Number=200, _y:Number=200):void {
        isXAddition = xAnable;
        isYAddition = yAnable;
        additionalVx = _vx;
        additionalVy = _vy;
        fixX = _x;
        fixY = _y;
    }
    private function isContactWall():Boolean {
        var truth:Boolean = false;
        if(isXAddition){
            if(px-radious>maxX)
                truth = true;
        } else if(isYAddition) {
            if(py-radious>maxY)
                truth = true;
        }
        return truth;
    }
    private function mainAdditionalVec():void {
        if(isXAddition) {
            vx+=additionalVx;
            py = fixY;
        }
        if(isYAddition) {
            vy+=additionalVy;
            px = fixX;
        }
        
        
    }
    
    public function render():void {
        this.x = px;
        this.y = py;
    }
}

class TooSenBoo extends Elemet {
    public function TooSenBoo() {
        
    }
    public override function update():void {
        px = 400;
        py = 200;
    }
}

class RoadUnit {
    public var x:Number;
    public var y:Number;
    public var vecType:String = "x";
    public var posinega:int = 1;
    public function RoadUnit(_x:Number=0,_y:Number=0, _vec:String="x", _pn:int=1 ) {
        x = _x;
        y = _y;
        vecType = _vec;
        posinega = _pn;
    } 
}