球の衝突でグラスハープ

ActionScriptで球の衝突の計算。衝突をするときに音を出すようにしてみたら、グラスハープのようなものができました。遊んでみてください。


遊び方

球をドラッグして、そぉっと割れモノを扱うような感じで投げると、演奏が始まります。※強く投げるとウルサくなります。

球の動きの速さは、パネルの矢印で調整。物足りないときはスピードを上げて、ウルサいときは下げてみてください。を押すと、いっせいに動きを止めます。球はいつでもドラッグできます。

サンプルXを押すと、プリセットしたコード進行になります(Eagles、BeatlesとMisiaの曲から拝借)。小節ごとにコードを変えられるので、音楽お好きな方はいじってみてください。用意しているコードは、メジャー、マイナー、7th、m7です。

偶然の音楽

ウチにある季節はずれの風鈴。4つ音が違う球があって、ぶつかるとチャリチャリ鳴ります。それで、「もし風鈴にコード進行があったら・・・」と思い、↑コレです。

いちおう、自然現象が偶然奏でる音楽ということで。いい感じの音がなるようになったら、流しっぱなしにしておくと、意外と良いヒーリングになるかも!?

球の衝突

次のような球のクラスがあるとすると、

 class Ball extends MovieClip{
  var vx = 0; //X方向の速度
  var vy = 0; //Y方向の速度
  var mass = 50; //質量
  var radius = 25; //半径

  function onEnterFrame(){
    this._x += this.vx;
    this._y += this.vy;
  }
 }

2つの球の衝突後の速度を計算するメソッドは、

 function collision(b1, b2) {

   var dx, dy, ds;
   var angle, cosval, sinval;
   var vx1p, vy1p, vx2p, vy2p;
   var p,v;

   //2つの球の距離を測る
   dx = b2._x-b1._x;
   dy = b2._y-b1._y;
   ds = Math.sqrt(dx*dx+dy*dy);

   //もし衝突してたら、
   if (ds > b1.radius + b2.radius ) return;

   // 2つの球が跳ね返る速度を計算して、
   // 設定してあげる。
   angle = Math.atan2(dy, dx);
   cosval = Math.cos( angle );
   sinval = Math.sin( angle );

   vx1p = cosval*b1.vx + sinval*b1.vy;
   vy1p = cosval*b1.vy - sinval*b1.vx;
   vx2p = cosval*b2.vx + sinval*b2.vy;
   vy2p = cosval*b2.vy - sinval*b2.vx;

   p = vx1p*b1.mass + vx2p*b2.mass;
   v = vx1p-vx2p;

   vx1p = (p-b2.mass*v)/(b1.mass+b2.mass);
   vx2p = v+vx1p;

   b1.vx = cosval*vx1p - sinval*vy1p;
   b1.vy = cosval*vy1p + sinval*vx1p;
   b2.vx = cosval*vx2p - sinval*vy2p;
   b2.vy = cosval*vy2p + sinval*vx2p;

 }

となります。物理的に解説すると、力積運動量保存などといった眠くなる何かがあるのですが、とりあえずはメソッドをパクッてもらえれば良いかと思います。


コメント
戸部
2006/11/30
初めまして。グラスハープで検索してきました。難しいことはわかりませんが、これは素晴らしく、なんとも言えずいい気持ちになります。サンプル2がすごく好きです。3はBeatlesのアレですね?すみません、おじゃましました。
武田ソフト
2006/12/01
戸部さん、初めまして。コメントありがとうございます。
触っていただけて感想までいただき、うれしいです。
3は、そうです、アレです!

コメントしてください

closed.