Poly-Melo-Arpe2.0

by sir4shumman forked from MeloArpe (diff: 1)
♥0 | Line 195 | Modified 2010-02-07 23:20:25 | MIT License
play

ActionScript3 source code

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

// forked from sir4shumman's forked from: forked from: MeloBall ver.2.6
// forked from Kitosan1986's forked from: MeloBall ver.2.6
// forked from Kitosan1986's MeloBall ver.2.6
// forked from Kitosan1986's MeloBall ver.2.3
/*-------------------------------------------------
操作説明:
Aを入力



---------------------------------------------------*/
package {
    import flash.display.Sprite;
    import flash.events.*;
    import flash.geom.*;
    //SiONのインポート
	import org.si.sion.*;
	import org.si.sion.events.*;
	import org.si.sion.effector.*;
	import org.si.sion.utils.SiONPresetVoice;
	import org.si.sion.sequencer.SiMMLTrack;

    
    [SWF(backgroundColor="#FFFFFF",width='600',height='600', frameRate=60)]
    
    public class MeloBall extends Sprite {

    		// driver
		private var driver:SiONDriver = new SiONDriver();
		// preset voice
        	private var presetVoice:SiONPresetVoice = new SiONPresetVoice();
 
 
        // MML data
		private var part:Array;
		private var BassDrum:SiONData;
		private var SnareDrum:SiONData;
		private var Hihat:SiONData;
		private var CloseHihat:SiONData;
		private var Bass:SiONData;
		private var Percus:SiONData;
		// 音色
		private var voice1:SiONVoice;
		
		private var sw:Boolean = false;
		
		// Stage Const
    		private var centerX:Number = stage.width/2;
    		private var centerY:Number = stage.height/2;
    		// ボールの数
    		private var numBalls:uint = 0; 
    		//係数
		private var bounce:Number = -1.0;
		//ボールの参照を入れる配列
		private var balls:Array = new Array();
		//ボールのアルファ値
		private var xalpha:Number = 0.7;
		//速度係数
		private var velocity:Number = 1;//ここに速度を入れる
		//半径
		private var radius:Number = 25; //半径はみんな同じ。つまりmassも同じで属性的に全く同じ

		//コンストラクタ
        public function MeloBall() { 
        
            var bd:String = "t110;";
            var sd:String = "t110;";
            var ch:String = "t110;";
            var b:String = "t110;";
            //var lead:String = "t110;";
            	bd += "%6@0o3l8c.c.cc;";
			sd += "%6@1o3rcrc;";
			ch += "%6@2v8l16[crccrrcc];";
			b += "%6@4v8l16o4[c.c.c]2 >b.b.b <c.c.c;";
			//lead ;= "%6@4v8l16o4[];";
			BassDrum = driver.compile(bd);
			SnareDrum = driver.compile(sd);
			CloseHihat = driver.compile(ch);
			Bass = driver.compile(b);
			//Lead = driver.compile(lead);
             // set voices of "%6@0-5" from preset
			BassDrum.setVoice(0, presetVoice["valsound.percus1"]);
			SnareDrum.setVoice(0, presetVoice["valsound.percus28"]);
			//percus.setVoice(2, presetVoice["valsound.percus23"]);
			CloseHihat.setVoice(0, presetVoice["valsound.percus17"]);
			Bass.setVoice(0, presetVoice["valsound.bass3"]);
			//Lead.setVoice(0, presetVoice["valsound."]);




        		stage.addEventListener(KeyboardEvent.KEY_DOWN,KeyDownHandle)      	
        		
			//driver.setTimerInterruption(4, note);
        		driver.setTimerInterruption(16, _onTimerInterruption);
        		 // SiONイベントトリガー用のイベントリスナーを設定
			driver.addEventListener(SiONTrackEvent.NOTE_ON_STREAM,  _onNoteOn);
			driver.addEventListener(SiONTrackEvent.NOTE_OFF_STREAM, _onNoteOff);
			driver.play();//各種セッティングが終わってからplayするように
        		}
        		
		private function  KeyDownHandle(e:KeyboardEvent):void{
			
			stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
			
			if(e.keyCode == 65 ) CreateBall(1);
			else if(e.keyCode == 66 ) CreateBall(2);
			else if(e.keyCode == 67 ) CreateBall(3);
			else if(e.keyCode == 68 ) CreateBall(4);
			else if(e.keyCode == 69 ) CreateBall(5);
			else if(e.keyCode == 70 ) CreateBall(6);
			else if(e.keyCode == 71 ) CreateBall(7);
			else if(e.keyCode == 72 ) CreateBall(8);
			else if(e.keyCode == 73 ) CreateBall(9);
			else if(e.keyCode == 74 ) CreateBall(10);

		}
		
		private function CreateBall(n:uint):void{			
	 
			 var ball:Ball = new Ball(radius,Math.random()*0xffffff,xalpha);
			 ball.mass = radius;
			 ball.x = Math.random() * 600;
			 ball.y = Math.random() * 600;
			 ball.vx = (Math.random() * 10 - 5) * velocity; 
			 ball.vy = (Math.random() * 10 - 5) * velocity;
			 addChild(ball);
			 balls.push(ball);//参照を格納
			 numBalls += 1;//ボールの数を更新
			 

			//if(numBalls == 1){driver.sequenceOn(bass,null,0,0,2,0,true)}
			//else if(numBalls == 2){driver.sequenceOn(bass,null,0,0,2,0,true)}

        }
             	
       	
       	
       	 private function onEnterFrame(event:Event):void {
        

        		 for (var i:uint = 0; i < numBalls; i++) {
			  var ball:Ball = balls[i];
			  ball.x += ball.vx;
			  ball.y += ball.vy;
			  checkWalls(ball,i);
			 }
			 
			 for (i = 0; i < numBalls; i++) {
			  var ballA:Ball = balls[i];
			  	if(numBalls > 1){
				   for (var j:Number = i + 1; j < numBalls; j++) {
				   var ballB:Ball = balls[j];
				   checkCollision(ballA, ballB);
			   	  }
			  	}		  	
			 }			 
			}
		//壁に当たったときの処理	
		private function checkWalls(ball:Ball,i:uint):void {
			 if (ball.x + ball.radius > stage.stageWidth) {
			  ball.x = stage.stageWidth - ball.radius;
			  ball.vx *= bounce;
			  	
			 } else if (ball.x - ball.radius < 0) {
			  ball.x = ball.radius;
			  ball.vx *= bounce;
			  	
			 }
			 if (ball.y + ball.radius > stage.stageHeight) {
			  ball.y = stage.stageHeight - ball.radius;
			  ball.vy *= bounce;

			 } else if (ball.y - ball.radius < 0) {
			  ball.y = ball.radius;
			  ball.vy *= bounce;

 			 }
			}
			
			//それぞれのボールが衝突しているかどうかチェック
		private function checkCollision(ball0:Ball, ball1:Ball):void {
			 var dx:Number = ball1.x - ball0.x;
			 var dy:Number = ball1.y - ball0.y;
			 var dist:Number = Math.sqrt(dx*dx + dy*dy);
			 if (dist < ball0.radius + ball1.radius) {
			 	
			 	note(ball0.x,ball0.y);
			 	
			 /*	if(sw == false){
			 		sw = true;
			 		driver.noteOn(100,null,0.5,0,0,0,0,0,0,true);
			 	}else{
			 		sw = false;
			 		} //衝突スイッチ*/
				
			  var angle:Number = Math.atan2(dy, dx);
			  var cos:Number = Math.cos(angle);
			  var sin:Number = Math.sin(angle);
				
			  var pos0:Point = new Point(0, 0);
			  var pos1:Point = rotate(dx, dy, sin, cos, true);
			  var vel0:Point = rotate(ball0.vx, ball0.vy, sin, cos, true);
			  var vel1:Point = rotate(ball1.vx, ball1.vy, sin, cos, true);
				
			  var vxTotal:Number = vel0.x - vel1.x;
			  vel0.x = ((ball0.mass - ball1.mass) * vel0.x +
			    2 * ball1.mass * vel1.x) /
			  (ball0.mass + ball1.mass);
			  vel1.x = vxTotal + vel0.x;
				
			  var absV:Number = Math.abs(vel0.x) + Math.abs(vel1.x);
			  var overlap:Number = (ball0.radius + ball1.radius)
			  - Math.abs(pos0.x - pos1.x);
			  pos0.x += vel0.x / absV * overlap;
			  pos1.x += vel1.x / absV * overlap;
				
			  var pos0F:Object = rotate(pos0.x, pos0.y, sin, cos, false);
			  var pos1F:Object = rotate(pos1.x, pos1.y, sin, cos, false);
				
			 //注意!ball1を先に計算しないと、エラー発生
			  ball1.x = ball0.x + pos1F.x;
			  ball1.y = ball0.y + pos1F.y;
			  ball0.x = ball0.x + pos0F.x;
			  ball0.y = ball0.y + pos0F.y;
				
			  var vel0F:Object = rotate(vel0.x, vel0.y, sin, cos, false);
			  var vel1F:Object = rotate(vel1.x, vel1.y, sin, cos, false);
				
			  ball0.vx = vel0F.x;
			  ball0.vy = vel0F.y;
			  ball1.vx = vel1F.x;
			  ball1.vy = vel1F.y;
			 }
			}
			
			//計算できるように回転させる動作
		private function rotate(x:Number, y:Number, sin:Number, cos:Number, reverse:Boolean):Point {
				
			 var result:Point = new Point();
			 if (reverse) {
			  result.x = x * cos + y * sin;
			  result.y = y * cos - x * sin;
			 } else {
			  result.x = x * cos - y * sin;
			  result.y = y * cos + x * sin;
			 }
			 return result;
			}
			//音を鳴らす16×16の音
		private function note(x:Number,y:Number):void{
		//driver.noteOn(100,null,4,4,0,0,0,0,0,true);
			}
						
		private function _onTimerInterruption():void{
			if(numBalls > 0){driver.sequenceOn(BassDrum,null,0,0,0,0,true);}
			if(numBalls > 1){driver.sequenceOn(SnareDrum,null,0,0,0,0,true);}
			if(numBalls > 2){driver.sequenceOn(CloseHihat,null,0,0,0,0,true);}
			if(numBalls > 3){driver.sequenceOn(Bass,null,0,0,0,0,true);}
			}



    			//ノートオン時の効果処理
		private function _onNoteOn(e:SiONTrackEvent) : void {
					
	          for (var i:uint = 0; i < numBalls; i++) {
			  var ball:Ball = balls[i];
			  ball.graphics.beginFill(Math.random()*0xffffff); 
			  //ball.graphics.endFill();
				//ball.width = 100;
				//ball.height = 60;
			 }
			}
	         
	        
		private function _onNoteOff
	        (e:SiONTrackEvent) : void {
	        	
	          for (var i:uint = 0; i < numBalls; i++) {
			  var ball:Ball = balls[i];
			  
			  	//ball.width = 50;
				//ball.height = 50;

	        }
	        
	      }
	        
    }
}

/*-------------------------------------
			パッケージ外クラス定義
 ---------------------------------------*/

import flash.display.*;
class Ball extends Sprite
{
    public var vx:Number;
    public var vy:Number;
    public var mass:Number;
    public var radius:Number;
    //rd=半径、cl=色、al=アルファ値
    function Ball(rd:Number,cl:Number,al:Number)
    {       
    		
        this.graphics.beginFill(cl,al);
        this.graphics.drawCircle(0, 0, rd);
        this.graphics.endFill();
        radius = this.width/2 
        
        
    }
}