// forked from tmn's flash on 2009-7-16 //参考文献「ActionScript3.0 アニメーション」Keith Peters 永井 勝則 package{ import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.events.MouseEvent; import funnel.*; [SWF(backgroundColor="0xFFFFFF", frameRate="30")] public class ballballball extends Sprite{ private var ball:Ball; private var ball1:Ball; private var vx:Number; private var vy:Number; private var spring:Number = 0.05; private var gravity:Number = .5; private var oldX:Number; private var oldY:Number; private var gio:Gainer; private var flasher0:Osc; private var flasher1:Osc; private var balls:Array; private var numBalls:Number = 10; public function ballballball(){ init(); } private function init():void{ stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; balls = new Array(); for(var i:uint = 0; i < numBalls; i++){ var ball:Ball = new Ball(Math.random() * 30 + 20, Math.random() * 0xFFFFFF); ball.x = Math.random() * stage.stageWidth; ball.y = Math.random() * stage.stageHeight; ball.vx = Math.random() * 6 - 3; ball.vy = Math.random() * 6 - 3; addChild(ball); ball.addEventListener(MouseEvent.MOUSE_DOWN, onMousedown); balls.push(ball); } addEventListener(Event.ENTER_FRAME, onEnterframe); gio = new Gainer(); flasher0 = new Osc(Osc.IMPULSE, 1, 1, 0, 0, 1); gio.digitalOutput(0).filters = [flasher0]; flasher1 = new Osc(Osc.IMPULSE,1, 1, 0, 0, 1); gio.digitalOutput(1).filters = [flasher1]; } private function onEnterframe(event:Event):void{ var left:Number = 0; var right:Number = stage.stageWidth; var top:Number = 0; var bottom:Number = stage.stageHeight; for(var i:uint = 0; i < numBalls - 1; i++){ var ball0:Ball = balls[ i ]; for(var j:uint = 0; j < numBalls; j++){ var ball1:Ball = balls[ j ]; var dx:Number = ball1.x - ball0.x; var dy:Number = ball1.y - ball0.y; var dist:Number = Math.sqrt(dx * dx + dy * dy); var minDist:Number = ball0.radius + ball1.radius; if(dist < minDist){ var angle:Number = Math.atan2(dy, dx); var tx:Number = ball0.x + Math.cos(angle) * minDist; var ty:Number = ball0.y + Math.sin(angle) * minDist; var ax:Number = (tx - ball1.x) * spring; var ay:Number = (ty - ball1.y) * spring; ball0.vx -= ax; ball0.vy -= ay; ball1.vx += ax; ball1.vy += ay; } } } for(i = 0; i < numBalls; i++){ var ball:Ball = balls[ i ]; move(ball); } } private function move(ball:Ball):void{ ball.y += ball.vy; if(ball.x + ball.radius > stage.stageWidth){ ball.x = stage.stageWidth - ball.radius; ball.vx *= -1; } else if(ball.x - ball.radius < 0){ ball.x = ball.radius; ball.vx *= -1; } if(ball.y + ball.radius > stage.stageHeight){ ball.y = stage.stageHeight - ball.radius; ball.vy *= -1; flasher0.reset(); flasher0.start(); gio.digitalOutput(0).value = 1; } else if (ball.y - ball.radius < 0){ ball.y = ball.radius; ball.vy *= -1; flasher1.reset(); flasher1.start(); gio.digitalOutput(1).value = 1; } } private function onMousedown(event:MouseEvent):void{ for(var i:uint = 0; i < balls.length; i++){ if(balls[i] == Ball(event.target)){ oldX = Ball(event.target).x; oldY = Ball(event.target).y; stage.addEventListener(MouseEvent.MOUSE_UP, onMouseup); Ball(event.target).startDrag(); removeEventListener(Event.ENTER_FRAME, onEnterframe); addEventListener(Event.ENTER_FRAME, trackVelocity); } } for(var n:Number = 0; n < 4; n++){ gio.digitalOutput(n).value = 0; } } //ボールを離した時、enterFrameハンドラを入れ替え、trackVelocityを削除し、onEnterFrameを追加 private function onMouseup(event:MouseEvent):void{ for(var i:uint = 0; i < balls.length; i++){ if(balls[i] == Ball(event.target)){ stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseup); Ball(event.target).stopDrag(); removeEventListener(Event.ENTER_FRAME, trackVelocity); addEventListener(Event.ENTER_FRAME, onEnterframe); } } } //ボールの現在のx, y位置からそれぞれoldX,oldYを引き=現在の速度が分かる → その値をvx, vyに保持 oldX, oldYをボールの現在位置に再設定 private function trackVelocity(event:Event):void{ for(var i:uint = 0; i < balls.length; i++){ if(balls[i] == event.target){ vx = Ball(event.target).x - oldX; vy = Ball(event.target).y - oldY; oldX = Ball(event.target).x; oldY = Ball(event.target).y; } } } } } import flash.display.Sprite; class Ball extends Sprite{ public var radius:Number; public var color:uint; public var vx:Number = 0; public var vy:Number = 0; public function Ball(radius:Number = 10, color:uint = 0xFFFFFF){ this.radius = radius; this.color = color; init(); } public function init():void{ graphics.beginFill(color); graphics.drawCircle(0, 0, radius); graphics.endFill(); } } forked from: flash on 2009-7-16