重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【GOLF me!】初月無料お試し

先日、Flashで、ドラッグしたムービークリップ(MC)を常に表示する方法を教えてもらい、
うまく表示することができましたが、今回は、このMCに色を変化させるスクリプトをつけ加えたいので
教えてください(色の変化は、別の質問者の回答を参考にしましたが、うまくいかないので・・・。)
私が作成したいイメージは以下の通り((1)~(3))です。
(1)赤の□のMCが2つ(インスタンス名:「R_mc1」「R_mc2」)と白の□のMCが2つ(インスタンス名:「W_mc1」 「W_mc2」)。 赤のMCはそれぞれMC内の2フレーム目に黄色の□を置いている。
(2)赤の□をドラッグして白の□にふれると、赤の□が黄色の□に変化する。
 (R_mc1はW_mc1とふれたときにだけ黄色に変化。R_mc2はW_mc2とふれたときにだけ黄色に変化。)
(3)赤の□は、どのMCに重なっても常に上に表示されるようにする。

以下にスクリプトを書いてあります。以下のスクリプトは赤や白のMCが置いてあるフレームに書いてみましたがうまくいきません。教えてgooでいただいた2種類のスクリプトを単純にくっつけただけなので、うまくいかないのは当然だと思いますが・・・。
すみませんが、わかりやすく教えてください。どうぞよろしくお願いいたします。

補足 Flashバージョン CS5.5   アクションスクリプト2.0  FlashPlayer6 です。

//------------------------------------
//深度カウント用変数を用意
var dep_cnt:Number = 1;

//変数 i に 1~2 を入れながらループ
for (var i:Number = 1; i<=2; i++) {
//「R_mc○」押下時に関数 dragMC を実行
this["R_mc"+i].onPress = dragMC;
//「R_mc○」を放した時に関数 dropMC を実行
this["R_mc"+i].onRelease = dropMC;
//「R_mc○」をMC外で放した時にも関数 dropMC を実行
this["R_mc"+i].onReleaseOutside = dropMC;
}

//関数 dragMC の定義
function dragMC():Void {
//深度カウント用変数をカウントアップ
dep_cnt++;
//押下されたMCをその深度に移動
this.swapDepths(dep_cnt);
//押下されたMCのドラッグを開始
this.startDrag();
}

//関数 dropMC の定義
function dropMC():Void {
//放されたMCのドラッグを終了
this.stopDrag();
}
//------------------------------------

//---------------------------
//「R_mc1」上でマウスダウン時に実行するメソッドを定義
R_mc1.onPress = function():Void {

//「R_mc1」のドラッグを開始
R_mc1.startDrag();

//マウスが動く度に関数 watchHitW_mc1R_mc1を実行
this.onMouseMove = watchHitW_mc1R_mc1;
};



//「R_mc1」上でマウスアップ時に実行するメソッドを定義
R_mc1.onRelease = R_mc1.onReleaseOutside = function():Void {
//このMC(R_mc1)のドラッグを終了
this.stopDrag();
//マウスが動く度に関数 watchHitW_mc1R_mc1 を実行するのを解除
delete this.onMouseMove;
}


//関数 watchHitW_mc1R_mc1の定義
function watchHitW_mc1R_mc1():Void {
//もし「R_mc1」が「W_mc1」にヒットしていれば
if (R_mc1.hitTest(W_mc1)) {
//「R_mc1」内の再生を フレーム2 で停止
R_mc1.gotoAndStop(2);
} else {
//ヒットしていなければ「R_mc1」内の再生を フレーム1 で停止
R_mc1.gotoAndStop(1);
}
}


//---------------------------
//「R_mc2」上でマウスダウン時に実行するメソッドを定義
R_mc2.onPress = function():Void {

//「R_mc2」のドラッグを開始
R_mc2.startDrag();

//マウスが動く度に関数 watchHitW_mc2R_mc2を実行
this.onMouseMove = watchHitW_mc2R_mc2;
};



//「R_mc2」上でマウスアップ時に実行するメソッドを定義
R_mc2.onRelease = R_mc2.onReleaseOutside = function():Void {
//このMC(R_mc2)のドラッグを終了
this.stopDrag();
//マウスが動く度に関数 watchHitW_mc2R_mc2 を実行するのを解除
delete this.onMouseMove;
}


//関数 watchHitW_mc2R_mc2の定義
function watchHitW_mc2R_mc2():Void {
//もし「R_mc2」が「W_mc2」にヒットしていれば
if (R_mc2.hitTest(W_mc2)) {
//「R_mc2」内の再生を フレーム2 で停止
R_mc2.gotoAndStop(2);
} else {
//ヒットしていなければ「R_mc2」内の再生を フレーム1 で停止
R_mc2.gotoAndStop(1);
}
}

「Flashで、ドラッグしたMCを上に表示」の質問画像

A 回答 (1件)

1つのインスタンスに対して


同じ種類のイベントハンドラメソッドを
重複していくつも定義することはできません。

もし重複定義した場合は
後から定義した方だけが残って
前に定義した方は消えます。

ご質問で書かれて書かれていらっしゃるスクリプトを
同じフレームに全てまとめて書かれたのであれば,
うまく行かない原因はこの辺にあるのではないかと思います。


例えば A という MC があったとして
次のようなスクリプトを書くと
A をクリックしても
2つ目に定義したメソッドしか実行されません。

A.onRelease = function() {
trace("1つ目のイベントハンドラメソッド実行");
};

A.onRelease = function() {
trace("2つ目のイベントハンドラメソッド実行");
};


これは
同じ変数に違う値を入れて行くのと同じことで
普通は1つの変数には違う値を重複して入れることはできないので
次のようなことをすると 変数a の値は結局 8 になりますよね?

a = 5;
a = 3;
a = 8;

これと同じ現象が起こります。


ちなみに本題とは関係ありませんが
ボタンやMCに直接書くイベントハンドラの方は重複定義できます。

例えばある MC があったとして
その MC 自体に次のようなスクリプトを書くと
2つとも実行されます。

on (release) {
trace("1つ目のイベントハンドラ実行");
}

on (release) {
trace("2つ目のイベントハンドラ実行");
}



==================================

話を本題に戻して対処法です。

考え方やスクリプトの書き方などは無数にありますが
次のように書くのも1つの方法でしょう。


//---------------------------
//深度カウント用変数を用意
var dep_cnt:Number = 1;

//変数 i に 1~2 を入れながらループ
for (var i:Number = 1; i<=2; i++) {
//★「R_mc○」内の再生を停止
this["R_mc"+i].stop();
//★「R_mc○」内の変数 target_mc に「W_mc○」の参照を代入
this["R_mc"+i].target_mc = this["W_mc"+i];
//「R_mc○」押下時に関数 dragMC を実行
this["R_mc"+i].onPress = dragMC;
//「R_mc○」を放した時に関数 dropMC を実行
this["R_mc"+i].onRelease = dropMC;
//「R_mc○」をMC外で放した時にも関数 dropMC を実行
this["R_mc"+i].onReleaseOutside = dropMC;
}

//関数 dragMC の定義
function dragMC():Void {
//深度カウント用変数をカウントアップ
dep_cnt++;
//押下されたMCをその深度に移動
this.swapDepths(dep_cnt);
//押下されたMCのドラッグを開始
this.startDrag();
//★マウスが動く度に関数 watchHitW_mc を実行
this.onMouseMove = watchHitW_mc;
}

//関数 dropMC の定義
function dropMC():Void {
//放されたMCのドラッグを終了
this.stopDrag();
//★マウスが動く度に関数 watchHitW_mc を実行するのを解除
delete this.onMouseMove;
}

//★関数 watchHitW_mc の定義
function watchHitW_mc():Void {
//★ドラッグ中のMCがそのMC内の変数 target_mc に
// 代入したMCとヒットしていれば
if (this.hitTest(this.target_mc)) {
//★ドラッグ中のMC内をフレーム2で停止
this.gotoAndStop(2);
} else {
//★それ以外はドラッグ中のMC内をフレーム1で停止
this.gotoAndStop(1);
}
}
//---------------------------



 
注釈行で★を付けたところが 主な変更部分です。


上記スクリプトのミソは

//★「R_mc○」内の変数 target_mc に「W_mc○」の参照を代入
this["R_mc"+i].target_mc = this["W_mc"+i];

だと思います。

例えば「R_mc1」でしたらその「R_mc1」内に
「target_mc」という変数(プロパティとも言える)を用意して
その変数にドラッグするターゲットとなる「W_mc1」の参照を代入しておくわけです。

for文 や i を使わず
単純に書けば次のようになります。

R_mc1.target_mc = W_mc1;

そしてドラッグ中の「R_mc1」が
それ自身の変数に格納した「W_mc1」とヒットしていれば
ドラッグ中の「R_mc1」内をフレーム2に進めるているわけです。


ちなみに
文字列 や 数値 や ブール値 などを除いて
ActionScript の代入とは基本的に参照代入です。
ActionScript 1.0 でも 2.0 でも 3.0 でも
(ついでに JavaScript でも) その点は共通です。

R_mc1.target_mc = W_mc1;

これで
「R_mc1」内の変数 target_mc に「W_mc1」への参照が格納されます。
決して
「R_mc1」内に target_mc という名で「W_mc1」自体が入り込むわけではありません。



 
==================================

あと,ちょっと気になったので確認まで。

"質問文" のMCのインスタンス名の後に付けてある 1 とか 2 とかの数字が
半角になってたり全角になってたりしていますが
実際の作成物では全角など使わずちゃんと半角を使ってますよね?
「Flashで、ドラッグしたMCを上に表示」の回答画像1
    • good
    • 0
この回答へのお礼

BlurFiltanさん、今回も迅速な対応本当にありがとうございます。
Flashを手掛けたばかりで毎日悪戦苦闘している私に温かいご回答をしてくださる
BlurFiltanさんには本当に感謝しきれないくらいの気持ちでいっぱいです。
私のスクリプトの間違いにもわかりやすく説明をしてくださり、また、正しいスクリプトを
示してその重要な箇所をお教えいただき、本当にありがたいです。
早速、いただいたスクリプトを試してみます。
初心者にもわかりやすく説明してくださるBlurFiltanさんに感謝m(__)m
また、つまずいたときにはご指導よろしくお願いいたします!(^^)!
ps.質問文ではインスタンス名に全角が入り込んでいましたが、実際にはそういうことは
ありません。ミスをしてしまいました・・・お気遣いありがとうございました(^.^)

お礼日時:2013/07/30 20:00

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!