D0804242 onReleaseで変更する写真を一定のフレーム移動の時間経過で変更したい
Name KS
Date 2008年04月24日 (木) 15時00分
Message こんにちは、初めて書き込みさせていただきます。

http://www.mdn.co.jp/webcre/Volume/Vol31/Special/
こちらのページにある一章
09 Flashでつくるトランジション効果
サンプル(その1)
http://www.mdn.co.jp/webcre/Volume/Vol31/Special/09/index1.html
サンプル(その2)
http://www.mdn.co.jp/webcre/Volume/Vol31/Special/09/index2.html

はそれぞれ、

this.onRelease = function() {

によって写真の切り替えがされるのですが、これをフレームの移動
(たとえば30フレームごとの時間経過)
で繰り返すようにするにはどうしたらいいでしょうか?
初心者のため、簡単なことを聞いてるのかもしれないのですが、
ご指南いただけたら幸いです。
Response 01
2008年04月24日 (木) 21時01分> ロイド 
サンプルは見てないのですが、おそらくfunctionなので
その中身だけ30フレーム目に記述すればOKかと思います。
this.onRelease = function() {
中身



}

上記のようなスクリプトになっていると思いますので
{}このカッコの中だけコピーして好きなフレームに貼り付ければ動くのではないでしょうか。
Response 02
2008年04月25日 (金) 10時58分> KS 
>ロイドさん

レスありがとうございました。
下記はサンプル(その2)のコードなのですが、この場合


----------------ここから

function initCover(page){//次の画像を非表示状態で配置
for (var i = 0; i<7; i++) {
this.createEmptyMovieClip("cr"+i,i+10);//行のmcを作成
this["cr"+i]._y = i*50;
for (var j = 0; j<12; j++) {
this["cr"+i].attachMovie("masked", "cd"+j, j+10);//行内にmcを配置
this["cr"+i]["cd"+j]._x = j*50;
this["cr"+i]["cd"+j].image._x = -j*50;
this["cr"+i]["cd"+j].image._y = -i*50;
this["cr"+i]["cd"+j].image.gotoAndStop(page);
this["cr"+i]["cd"+j]._visible = false;//初期状態は非表示に
}
}
}
page = 1;//現在のページ
pageMax = 2;//ページの最大数
ch = new Array(7);//行の配列
for (var i = 0; i<7; i++) {
ch[i] = new Array(12);//blockの表示非表示フラグ配列
}
//トランジション関数
function transition(page) {
cnt = 0;
for (var i = 0; i<7; i++) {
for (var j = 0; j<12; j++) {
ch[i][j] = false;//blockのフラグをリセット
}
}
this.onEnterFrame = function() {
for (jj=0; jj<3; jj++) {//3blockずつ
var tmp = true;
while (tmp) {
selectR = Math.floor(Math.random()*7);//ランダムで行を選択
selectD = Math.floor(Math.random()*12);//ランダムで列を選択
tmp = ch[selectR][selectD];
}
ch[selectR][selectD] = true;//blockのフラグをtrueに
this["cr"+selectR]["cd"+selectD]._visible = true;//blockを表示
this["cr"+selectR]["cd"+selectD].gotoAndPlay(1);//blockのアニメーション開始
cnt++;
//終了
if (cnt>83) {
this.onEnterFrame = null;
photo_mc.gotoAndStop(page);
this.enabled = true;
}
}
};
}
this.onRelease = function() {
this.enabled = false;
page++;
if (page>pageMax) page = 1;
initCover(page);
transition(page);
};
stop();

-------------ここまで



this.enabled = false;
page++;
if (page>pageMax) page = 1;
initCover(page);
transition(page);

を対象MCの30フレーム目に記入するということでしょうか?
してみたのですが動く気配がなく、何か見当違いなことをしているのではないかと
レスをかえさせていただきました。

何度も聞いてすみません
Response 03
2008年04月25日 (金) 23時07分> ロイド   
09-1.flaサンプルを見てみました。

このサンプルの場合このようにすればフレームでトランジションを制御できます。

ムービークリップcontentsを開き1フレーム目にあるスクリプト
下の方にある
this.onRelease = function() {
this.enabled = false;
transition(false);
};
という部分がこのムービークリップをクリック(離された時)に実行させている部分ですので

これの中身をコピーし上記スクリプトを削除します。
コピーされる部分はこれです。
this.enabled = false;
transition(false);
それから最後のstop()も削除しておきます。
そしてその1フレームから30フレーム目にキーフレームを作り先ほどコピーしたスクリプトを貼り付けます。
そうすると30フレーム目でトランジションが実行されるはずです。
Response 04
2008年04月25日 (金) 23時10分> ロイド 
それからフレームを30まで増やした時に
レイヤーphoto_mcのフレームも同じ数増やしてください。
Response 05
2008年04月25日 (金) 23時42分> daniwell 
ロイドさんとは違うやり方になりますが
あと、30フレーム毎に、といった感じでもないですが、
以下のようにしてみてはいかがでしょうか。

以下の場合、4000ミリ秒 つまり、4 秒毎にトランジション(切り替え)されます。
setIntervalを用いています。setIntervalは、指定した関数を指定したミリ秒毎に呼び出す、というものです。


//this.onRelease = function() { コメントアウトする
function func_interval () {
    this.enabled = false;
    page++;
    if (page>pageMax) page = 1;
    initCover(page);
    transition(page);
};
setInterval( func_interval, 4000 );  // 4 秒毎に関数"func_interval"呼び出し

この場合、
this.enabled = false;
の部分は不要ですが、一応分かりやすいように残してあります。
(あってもなくても大丈夫です)


---------------
あと、以下は読み飛ばしちゃってもいいですが、
ちょっと気になった点について。

以下の部分のスクリプトはあまりヨロシクないので、それについて少し。

var tmp = true;
while (tmp) {
    selectR = Math.floor(Math.random()*7);  //ランダムで行を選択
    selectD = Math.floor(Math.random()*12);  //ランダムで列を選択
    tmp = ch[selectR][selectD];
}

何がヨロシクないかというと、
なんとなく分かるかもしれませんが、上のスクリプトは、有限回で終わってくれる保障がありません。
(まあ行と列を掛け合わせても 84 程度なので、膨大な回数のループになる前に終る確率の方が圧倒的に高いですが)

スクリプトを見てみると、
具体的には selectR と selectD をランダムで求めて
ch[selectR][selectD] が true であれば再びループを繰り返すとなっているワケですが、
ランダムに依存してループさせた場合、確率的には無限回続く可能性をはらんでいることになります。

このサンプルの場合、1つのブロックがトランジションする毎に
ch[selectR][selectD] に true が格納されていく風になっていると思います。

説明し易いように、例えば一番最後のブロック(84番目)が切り替わるときを例にとって考えると、
残り1ブロックとなった段階で、ループを脱出する確率は、1/84 (最後だと配列が false なのは1つしかないですからね)となります。
とすると、その逆の、脱出できない確率は 83/84 です。

ここで、 x 回ループするとすると、その確率は (83/84)^x
※ ^ は累乗の意味です(ex. 2^3 = 8)

さらに x 回以上ループする確率は、Σ(83/84)^n   (n = x から ∞ まで)

となります(高校数学レベルですかね)。
例えば、10,000回以上ループする確率は、n = 10,000から∞までの和なので

8.17×10^-51

となります。
まあブロックの個数が個数なので、確率的にはものすごい小さい値ですが、
一応 0 より大きい値ではあります。
当然、1億や1兆、はたまたもっとすごい回数のループになる確率も、
限りなく 0 に近くなりはしますが、0 よりは大きい値をとります。

ものすごく滅多にないことですが、無限に近い回数もループされたら困りますよね。

というわけで、ヨロシクないワケです。
まあ要点を簡単にひとことで説明すると、
「ループの終了条件をランダムに任せるのは避けましょう」
ということです(これだけ書けばよかったんじゃないかという気もしますが)。

そして最後に、
あんまりややこしくない(?)修正方法として、ひとつ提示しておきます。
まず不要なところはコメントアウトして、

// var tmp = true;
// while (tmp) {
    selectR = Math.floor(Math.random()*7);  //ランダムで行を選択
    selectD = Math.floor(Math.random()*12);  //ランダムで列を選択
//     tmp = ch[selectR][selectD];
// }

そのすぐ下に以下を追加します。

var i, j;

for( i = selectR; i < 7; i ++ ) {
    for( j = selectD; j < 12 && ch[ i ][ j ]; j ++ );
    if ( ! ch[ i ][ j ] ) break;
    for( j = 0; j < selectD && ch[ i ][ j ]; j ++ );
    if ( ! ch[ i ][ j ] ) break;
}
if ( ch[ i ][ j ] ) {
    for( i = 0; i < selectR; i ++ ) {
        for( j = selectD; j < 12 && ch[ i ][ j ]; j ++ );
        if ( ! ch[ i ][ j ] ) break;
        for( j = 0; j < selectD && ch[ i ][ j ]; j ++ );
        if ( ! ch[ i ][ j ] ) break;
    }
}
selectR = i;
selectD = j;

こうするとループ回数(の最大値)をある一定の有限回で抑えられます。
なんか修正後のがループ回数多いように見えますが、そんなことはないです。
こっちのほうは、例えばさっきと同じように最後のブロック(84番目)をとってみても
高々 84 回の繰り返しで済みます。どんなに運が悪くても 84、というわけです。

それに、こっちのほうが、
(全体のブロック数)÷(1フレームにつき変化させるブロックの枚数)
で割り切れなくても無限ループに陥る心配がない、というメリットもあります。

試しに修正する前の状態で、

for (jj=0; jj<3; jj++) {  // 3blockずつ

の 3 の部分を、(84では割り切れない) 5, 7 とかにしてみてください。

※事前にflash内の必要なデータは保存しておくと良いです。
 まあ「スクリプトの実行を中止しますか?」っていう警告が出るので大丈夫とは思いますが。


ちょっと長くなりましたが、
質問の解答として必要な部分は点線より上の部分のみ、です。
Response 06
2008年04月29日 (火) 13時27分> KS 
週末でていたものですから、お返事が遅くなってしまいましたこと、まずはおわび申し上げます。

丁寧なお返事有り難うございました。

ロイドさま>
了解しました(*>ω<*)ゞ
分かりやすい回答有り難う御座いました。
もう一度それでチャレンジしてみます。


daniwellさま>
おおお!
色々弄ってるときに「スクリプトの実行を中止しますか?」
で、でました…
これがでるので、きっと何かまずいことをしてるんだろうなと、恐くなってそれ以上弄れなくて、こちらに投稿させていただいた次第です。

ロイドさんにご指南頂いた方法と、その時に動かしたい状況によって使い分けると良い感じですね。
有り難う御座います(^^)


チャレンジするのが週明けになると思うので、きちんと動かせたかのご報告はまたその時にさせていただきます。

このページの先頭へ