■ ボールをつかむ、投げる
それでは、次にボールをつかんで投げれるようにしましょう。
それにはまず、ボールをつかめるように、ボールのムービークリップの上にボタンを作ります。ムービークリップのボールをダブルクリックすると、シーン1 ball となり、ballというムービークリップを編集している状態になります。そこで、さらにボールをダブルクリックするか、すべて囲むようにドラッグし、ボールを全選択状態にします。そのまま、「挿入」→「シンボルに変換」を選択して、名前は適当に入力し、タイプをボタンに設定します。これで、ボタンの準備ができました。
それでは、次にボタンにつかんで離すアクションスクリプトを記述していきます。
アクションウインドウのタイトルが▼アクション-ボタン になっていることを確認して、ボタンに次のスクリプトを入力してください。
on (press) {
startDrag(this, true);
}
on (release) {
stopDrag();
}
この意味は、ボタンを押した時(on (press))に、これ(this:ボタンのアクションに記述されたthisはそのボタンが配置されているムービークリップを指します。今回の場合はボールのムービークリップ)のドラッグを始める(startDrag)という意味です。trueというのは、ドラッグを始めたとき、その物体の中心をマウスの位置に自動的に合わす、ということになります。逆にfalseと記述すると、マウスのボタンをを押した位置のまま物体をドラッグできるようになります。
その次のスクリプトは、ボタンを離したとき(on (release))に、ドラッグをストップさせる(stopDrag())というスクリプトです。
基本的なドラッグアンドドロップのスクリプトは上記のものですが、今回の場合、今の状態でプレビューするとわかるようにうまくいきません。とてもぎこちなく変な動きになってしまいます。それは、ドラッグ中もボールのムービークリップが動きつづけている為です。そこで、ドラッグ中はボールを動かさないようにしましょう。言い換えれば、ドラッグをしていない時だけ、動きつづけるようにすれば良いのです。
わかりやすくするため、適当な変数を用意します。ここではpickupということにします。
たとえば、このpickupが1の時はドラッグ中、0の時はドラッグしていない時とします。
つまり、pickupが1でないときだけ、ボールが動くようにします。
実際にスクリプトを追加してみましょう。
まず、先ほどのボタンのアクションにpickupの式を追加します。
on (press) {
pickup = 1;
startDrag(this, true);
}
on (release) {
pickup = 0;
stopDrag();
}
ボタンを押したときpickupを1(ドラッグ中)とします。そしてボタンを離したときpickupを0(ドラッグ中でない)とします。
次に、ボールが絶えず動くスクリプトを変更しますから、ムービークリップのアクションを変更します。シーン1を押してムービークリップのボールを選択すると、アクションウインドウには先に記述したスクリプトが表示されるはずです。
そして、ボールの動きを延々計算しているところ、つまり、onClipEvent (enterFrame)内をpickupが1(ドラッグ中)の場合と0(ドラッグ中でない)の場合に分けます。
すると、
if (pickup == 1) {
// ドラッグ中の処理
} else {
// ドラッグしていない時の処理・・・動きつづける
}
このようになります。ドラッグ中の処理は結構重要なので後述しますが、とりあえず、今の状況は次のようになっています。
onClipEvent (load) {
speedx = 5;
speedy = 4;
pickup = 0;
}
onClipEvent (enterFrame) {
if (pickup == 1) {
} else {
if (this._x>600-this._width/2) {
speedx = speedx*-1;
}
if (this._x<0+this._width/2) {
speedx = speedx*-1;
}
if (this._y>400-this._width/2) {
speedy = speedy*-1;
}
if (this._y<0+this._width/2) {
speedy = speedy*-1;
}
this._x = this._x+speedx;
this._y = this._y+speedy;
}
}
ついでに、ボールが読み込まれたとき(onClipEvent (load))にドラッグ中ではなく、動き回るようにpickup=0を追加しておきました。
この状態でプレビューすると一応ちゃんとボールをつかんでドラッグできるようになっています。ドラッグしている間はボールが動かず正常に動作しているようです。しかし、ボールを離すとまた動き出しますが、投げた感じがしません。では、ここで、投げる動作のスクリプトを記述しましょう。投げるスピードや方向をどうやって計算しているのか、ちょっとわかりにくいかもしれませんが、これを覚えると結構応用が効きますのでしっかり理解してください。
では、投げたときのスピードや方向は何を求めれば計算できるかといえば、ボールを離した時の位置と、その直前の位置がわかりさえすれば求めることができます。
簡単にするために横方向、つまりx方向だけを考えることにします。ボールを離した時の位置(仮にx2とします。)、その直前の位置(仮にx1とします)がわかれば、x方向のスピードはx2-x1で求めることができます。
ボールを離した時のx2の位置はそのままボールの現在位置ですので、すぐわかりますが、
その直前の位置はどうやればわかるでしょうか?
結論から言うと直前の位置x1に前回計算したx2の位置を代入してやります。そうすると、常にx1はx2の直前の値が入ることになります。スクリプトで書くとこうなります。
x1 = x2;
x2 = this._x;
speedx = (x2-x1);
この3行の式をこの順番で延々計算を繰り返していると考えると、x2には現在の位置、x1には前回計算したときの現在位置つまり直前の位置が入っていることになります。そして、x方向のスピードspeedxは常にx2とx1との差として求められています。
同じようにy方向も考慮すると
x1 = x2;
y1 = y2;
x2 = this._x;
y2 = this._y;
speedx = (x2-x1);
speedy = (y2-y1);
こうなります。そして、これをどこに記述するのかと言えば、この計算はドラッグ中のボールの動きですから、onClipEvent
(enterFrame)内のpickupが1(ドラッグ中)の場合に記述してやります。
onClipEvent (load) {
speedx = 5;
speedy = 4;
pickup = 0;
}
onClipEvent (enterFrame) {
if (pickup == 1) {
x1 = x2;
y1 = y2;
x2 = this._x;
y2 = this._y;
speedx = (x2-x1);
speedy = (y2-y1);
} else {
if (this._x>600-this._width/2) {
speedx = speedx*-1;
}
if (this._x<0+this._width/2) {
speedx = speedx*-1;
}
if (this._y>400-this._width/2) {
speedy = speedy*-1;
}
if (this._y<0+this._width/2) {
speedy = speedy*-1;
}
this._x = this._x+speedx;
this._y = this._y+speedy;
}
}
これで、だいぶそれらしく見えるようになってきました。ただ、あまり強く投げると、枠外に出ておかしな動きをすることがあります。それは、枠外に出たとき、枠外で延々スピードの符号を反転しつづけ、枠内に戻ってこない場合です。そこで、その回避策のひとつとして枠外に出たときは強制的に枠内の位置に戻ってこさせることにします。
一案:(xが右枠を越えた場合の処理に追加) x位置を枠内の位置まで戻す
this._x = 600-this._width/2;
つまり、上下左右の枠を越えた時の処理にこの1行を追加しておくと強制的にボールを枠内に戻し、枠外で振動するような状況を避けることができます。これを各枠外処理に追加しておきます。
onClipEvent (load) {
speedx = 5;
speedy = 4;
pickup = 0;
}
onClipEvent (enterFrame) {
if (pickup == 1) {
x1 = x2;
y1 = y2;
x2 = this._x;
y2 = this._y;
speedx = (x2-x1);
speedy = (y2-y1);
} else {
if (this._x>600-this._width/2) {
this._x = 600-this._width/2;
speedx = speedx*-1;
}
if (this._x<0+this._width/2) {
this._x = 0+this._width/2;
speedx = speedx*-1;
}
if (this._y>400-this._width/2) {
this._y = 400-this._width/2;
speedy = speedy*-1;
}
if (this._y<0+this._width/2) {
this._y = 0+this._width/2;
speedy = speedy*-1;
}
this._x = this._x+speedx;
this._y = this._y+speedy;
}
}
|