アプリ版:「スタンプのみでお礼する」機能のリリースについて

FlashCS5 ActionScript2.0で3つのボタンを制御しています。
それぞれインスタンス名はbt1,bt2,bt3です。
動きはマウスオーバーで120%大きくなり、ロールアウトで100%へと戻るものです。
しかし、ロールアウトの動作中に他のボタンに触ると、ロールアウトの動作が中断してしまいます。
なぜでしょうか?


////////////////////////////////////////
stop();

sx = 3;
var i;

//-----------
for( i = 1; i < 4; i++){
Nov = "bt" + i;
_root[Nov].onRollOver = function(){
Name = this._name;
btOverMotion(Name);
}
_root[Nov].onRollOut = function(){
Name = this._name;
btOutMotion(Name);
}
}

//-----------

function btOutMotion(eachNo){
No = eachNo;
onEnterFrame = function(){
if(_root[No]._xscale < 100){
delete this.onEnterFrame;
}else{
_root[No]._xscale -= sx*2;
_root[No]._yscale -= sx*2;
}
}
}

//-----------

function btOverMotion(eachNo){
No = eachNo;
onEnterFrame = function(){
if(_root[No]._xscale > 120){
delete this.onEnterFrame;
}else{
_root[No]._xscale += sx;
_root[No]._yscale += sx;
}
}
}

A 回答 (2件)

書かれていらっしゃるスクリプト中にある


onEnterFrame = function(){…} は
スクリプトを書かれていらっしゃるタイムラインに対して(_rootに対して)定義している
onEnterFrameイベントハンドラメソッドです。
つまり
_root.onEnterFrame = function(){…}
と書いているのと同じことです。

1つのムービークリップ(_rootもムービークリップの一種) に対して
同じ種類のイベントハンドラメソッド は1つしか定義できません。

_root.onEnterFrame = function(){A};
_root.onEnterFrame = function(){B};
_root.onEnterFrame = function(){C};

と書いた場合,結局
_root.onEnterFrame = function(){C};
だけ書いたのと同じになります。
(同じ関数名の関数を再定義し直しているだけ)


回避策としては,
ボタンをボタンインスタンスとして用意するのではなく
ボタンをムービークリップインスタンスとして用意し
そのムービークリップに対して
各ムービークリップ.onEnterFrame = function(){…};
を定義するのが一般的です。


しかし
ボタンはボタンインスタンスでしか用意できない場合は,
onEnterFrame 定義用のムービークリップを作成しても良いと思います。

それと...
var なしで関数内に変数を作成すると
その変数はグローバルなタイムライン変数になってしまいますよ。

その点も入れてスクリプトを修正↓

=================
stop();

sx = 3;
var i;

//-----------
for (i = 1; i < 4; i++) {
Nov = "bt" + i;
//_rootの深度iにムービークリップ「bt[1~4]_mc」を作成
_root.createEmptyMovieClip(Nov + "_mc", i);
_root[Nov].onRollOver = function() {
Name = this._name;
btOverMotion(Name);
};
_root[Nov].onRollOut = function() {
Name = this._name;
btOutMotion(Name);
};
}

//-----------

function btOutMotion(eachNo) {
//↓このNoはローカルであるべき
var No = eachNo;
//各ムービークリップに対してonEnterFrameを定義
_root[No + "_mc"].onEnterFrame = function() {
if (_root[No]._xscale < 100) {
delete this.onEnterFrame;
} else {
_root[No]._xscale -= sx * 2;
_root[No]._yscale -= sx * 2;
}
};
}

//-----------

function btOverMotion(eachNo) {
//↓このNoはローカルであるべき
var No = eachNo;
//各ムービークリップに対してonEnterFrameを定義
_root[No + "_mc"].onEnterFrame = function() {
if (_root[No]._xscale > 120) {
delete this.onEnterFrame;
} else {
_root[No]._xscale += sx;
_root[No]._yscale += sx;
}
};
}
=================



このままでも動作に支障はないようですが
意味合いからすると
Nov = "bt" + i;
なども本当は
var Nov = "bt" + i;
のようにすべきだと思います。
    • good
    • 0
この回答へのお礼

大変ありがとうございます!!
よくわかりました。ガッデム理解です!

なるほどonEnterFrameって個々に当てられるんですね。
これで解決です。

グローバル変数についてもよくわかっていないのですが、ここではvarを当てた方が「よりベター」ということですよね。まあ、動くかもしれないけど、あとあと重複したりすることになって動かなくなるよ、ということで理解しました。
グローバル変数にすると"いつでもどこでも"使うよ、っていうものになってしまうのでうまくないわけですね。勉強になりました。ありがとうございます。
取り急ぎ御礼までです。

お礼日時:2010/09/28 19:46

この場合の、onEnterFrameはいわゆる時計(タイマー)のようなものです。


同時に2つ以上の行動が起こせないのは、その時計が1つしかないからです。

たとえば、今回のロールオーバー・アウトのアクションは、「一定時間毎に大きさを3%づつ変化させ、ある大きさになったらストップする」というものですが、この一定時間を計測しているのがonEnterFrameです。ひとつのボタンからロールアウトして、時間を計測中にも関わらず、新たなロールオーバーによって計測をリセットしてしまうというのが、今回の現象です。

つまり時計の数を増やすことで、この問題は解決できます。
例の記述では、記述したタイムラインの時計を使っているので、それを各ムービークリップの時計を使用するようにすれば、よいかと思います。

具体的な方法は、BlurFiltanさんの例が参考になりますね。
    • good
    • 0
この回答へのお礼

おかげさまで理解できました。
なるほど、rootの時計、各ムービークリップの時計で分ければいろいろな時間を使えるっていうわけですね。

わかりやすい説明ありがとうございました!

お礼日時:2011/03/03 13:00

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