プロが教える店舗&オフィスのセキュリティ対策術

先ほどの書き込みと被ってしまいすみません。

現在、花火の「ナイアガラの滝」をFlashで表現しようとしています。
その際にトゥイーンではなくすべてASにて制御したいのです。
そして、時間差で画面の両端から真ん中に向かって花火がつくようにしたいと思っています。
現時点では、花火の火の粉を表すMCを作成してこのMCに対して以下のようなAS(指定位置から真下に落ちる)を記述しています。
/////////////////////////////////////////////////////

onClipEvent (enterFrame) {
this._y = this._y+12;
if (this._y>140) {
this._y = 38.5;
}
}
//////////////////////////////////////////////////////

このMCと同じ階層に上のMCを複製したものを数個配置しており、scriptレイヤーの1フレーム目には以下のようなASを記述しています。

//////////////////////////////////////////////////////

stop();
myID = setInterval(function () {
gotoAndstop(2);
clearInterval(myID);
}, 3000);

//////////////////////////////////////////////////////

はじめに説明した火の粉のMCは1つずつレイヤー分けして2フレーム目に配置しているので、上のASのままでは、全てが同時に再生されてしまい、花火のナイアガラっぽくありません。
より、リアルにする為に時間差で花火をつけたいです。
火の粉のMCにはa、b、c、dといった感じでインスタンス名をつけています。
1フレーム目に記述している「gotoAndstop(2);」をインスタンス名で指定すればいいのでは…と思い「gotoAndstop(a);」と、指定してみたのですが、何も表示されなくなってしまいます。
まだまだ、ASについて詳しくないので、分かり易く説明していただけると助かります。
急ぎなので、分かる方返信お願いします。
よろしくお願いします。

A 回答 (2件)

#1です。



> 色線ではなくMCを使いたい場合はどの部分に
> MCを読み込むASを入れればよいのでしょうか?

色線ではなく,あえて言うならば色面(色塗り)です。
線は入れずに小さな二等辺三角形の塗りを作成しています。

MCを使う場合は,いちいち火の粉をASで書く必要もありませんし,
空(カラ)のMCを作成する部分をライブラリのMCを呼び出す文に変えれば良いと思います。

 // 火の粉を作成
 this.createEmptyMovieClip("spark"+c, c);
   ↓変更↓
 // ライブラリのリンケージ識別子 spark のMCを呼び出す
 this.attachMovie("spark","spark"+c, c);

MCを作成した時点で,ライブラリにはムービークリップシンボルが入るはずです。
ステージ上に用意したムービークリップは削除して,
ライブラリの火の粉ムービークリップシンボルを右クリックするなどして,
「リンケージ」で「リンケージプロパティ」のパネルを出し,
 □ActionScriptに書き出し
 と
 □最初のフレームに書き出し
にチェックを入れます。
すると 識別子 の部分に文字が打てるようになりますから,
そこで 識別子 を付けます。
この例では spark という識別子を付けておいたとします。
この識別子はシンボルの名前になりますから,
この名前でステージ上にムービークリップを呼び出します。


> 現在水面に映り込んでいる火の粉を表示させない場合

ですから,下側を消せば良いので,
次のようにだいぶんシンプルになります。

--------------------------------------------
// 滝の上端下端の y 座標を設定
top_y = 38.5;
bot_y = 140;

// 滝の左右両端の x 座標を設定
lef_x = 10;
rig_x = Stage.width-10;

// 火の粉が落ちるスピードを設定
spd = 4;

// 火の粉の本数を設定
fal_n = 24;

// 火の粉の本数が増える間隔の設定
int = 850;

// 火の粉が伸びる速さを設定
grow = 12;

// --- 以上が設定 ------------------

// 各火の粉の x 座標を算出
xArr = new Array();
for (i=0; i<fal_n; i++) {
xArr[i] = Math.round(lef_x+i*(rig_x-lef_x)/(fal_n-1));
}

// ---背景を描画---
this.beginFill(0x000000);
this.moveTo(0, 0);
this.lineTo(Stage.width, 0);
this.lineTo(Stage.width, Stage.height);
this.lineTo(0, Stage.height);
this.endFill();

// カウント数 c と frm の初期化
c = 0;
frm = 0;

// 1フレーム進む毎に随時実行(火の粉を作成する)
this.onEnterFrame = function() {
frm++;
// frm が 3 で割りきれたときのみ
if (frm%3 == 0) {
// x 方向のループ文
for (i=0; i<fal_n; i++) {
// 火の粉が出没する中央の制限
if (i<=lef_n || i>=rig_n) {
// ライブラリのリンケージ識別子 spark のMCを呼び出す
this.attachMovie("spark","spark"+c, c);
this["spark"+c]._x = xArr[i];
this["spark"+c]._y = top_y;
// 火の粉が落ちる関数を定義
this["spark"+c].onEnterFrame = function() {
// 落下速度のゆらぎ(※勝手に入れただけです)
this._y -= Math.random()*2;
this._y += spd;
this._yscale += grow;
if (this._y>bot_y) {
this.removeMovieClip();
}
};
if (c>10000) {
c = 0;
} else {
c++;
}
}
}
}
};

// 念のための重複防止(ループ再生時など)
if (IDflag == undefined) {
IDflag = true;
// 滝の左右の番号を初期化
lef_n = 0;
rig_n = fal_n-1;
// 一定間隔で左右の番号を増減させる
ID = setInterval(function () {
// 滝の左右の番号を1ずつ増減
lef_n++;
rig_n--;
if (lef_n>=fal_n/2) {
clearInterval(ID);
}
}, int);
}
--------------------------------------------
    • good
    • 0

なぜ


3000ミリ秒間隔で フレーム2 に行くのか(それもフレーム2に行ってstop),
それをする意味が全くわかりません。
また
「gotoAndstop(a);」が仮にできたとしても (できませんが),
それをすれば何が起こるのか,その意味することもわかりません。
したがって,
ご質問の延長(さらに何かを発展させる)回答は無理です。
意味不明すぎます。


しかし,日本語の意味はなんとなくわかりますから,
書かれていらっしゃるスクリプトの内容を解釈する方向ではなく全く違う方法を書きます。


> その際にトゥイーンではなくすべてASにて制御したいのです。

【急ぎ】ということですから全て AS の方都合が良いです。
回答する労力も使う労力も節約できて時間もかからないと思います。
全て AS にするのでしたら,
私なら次のような感じにするかもしれません。

新規ドキュメントを作成して,
次のスクリプトをフレーム1に書いてパブリッシュするだけです。

======================
// 滝の上端下端の y 座標を設定
top_y = 38.5;
bot_y = 140;

// 滝の左右両端の x 座標を設定
lef_x = 10;
rig_x = Stage.width-10;

// 火の粉が落ちるスピードを設定
spd = 4;

// 火の粉の本数を設定
fal_n = 24;

// 火の粉の色(上,下)の設定
colArr = new Array("0xFFFFA5", "0x828200");

// 火の粉の本数が増える間隔の設定
int = 850;

// 火の粉が伸びる速さを設定
grow = 12;

// --- 以上が設定 ------------------

// 上下の滝の y 座標を算出
yArr = new Array(top_y, 2*bot_y-top_y);

// 各火の粉の x 座標を算出
xArr = new Array();
for (i=0; i<fal_n; i++) {
xArr[i] = Math.round(lef_x+i*(rig_x-lef_x)/(fal_n-1));
}

// 滝の左右の番号を初期化
lef_n = 0;
rig_n = fal_n-1;

// ---背景を描画---
// 水平線とのずれ
dif = 15;
// 空を描画
this.beginFill(0x000000);
this.moveTo(0, 0);
this.lineTo(Stage.width, 0);
this.lineTo(Stage.width, bot_y+dif);
this.lineTo(0, bot_y+dif);
this.endFill();
// 水面を描画
this.beginFill(0x2B2B2B);
this.moveTo(0, bot_y-dif);
this.lineTo(Stage.width, bot_y-dif);
this.lineTo(Stage.width, Stage.height);
this.lineTo(0, Stage.height);
this.endFill();

// カウント数 c と frm の初期化
c = 0;
frm = 0;

// 1フレーム進む毎に随時実行(火の粉を作成する)
this.onEnterFrame = function() {
frm++;
// frm が 3 で割りきれたときのみ
if (frm%3 == 0) {
// x 方向のループ文
for (i=0; i<fal_n; i++) {
// 火の粉が出没する中央の制限
if (i<=lef_n || i>=rig_n) {
// 各火の粉のループ文
for (j=0; j<=1; j++) {
// 火の粉を作成
this.createEmptyMovieClip("spark"+c, c);
this["spark"+c]._x = xArr[i];
this["spark"+c]._y = yArr[j];
this["spark"+c].beginFill(colArr[j]);
if (j == 0) {
this["spark"+c].moveTo(0, -3);
this["spark"+c].lineTo(1, 1);
this["spark"+c].lineTo(-1, 1);
} else {
this["spark"+c].moveTo(-1, -1);
this["spark"+c].lineTo(1, -1);
this["spark"+c].lineTo(0, 6);
}
this["spark"+c].endFill();
this["spark"+c].n = j;
// 火の粉が落ちる関数を定義
this["spark"+c].onEnterFrame = function() {
// 落下速度のゆらぎ(※勝手に入れただけです)
this._y -= (1-this.n*2)*Math.random()*2;
this._y += (1-this.n*2)*spd;
this._yscale += grow;
if (this._y>bot_y && this.n == 0) {
this.removeMovieClip();
} else if (this._y<bot_y-spd && this.n == 1) {
this.removeMovieClip();
}
};
if (c>10000) {
c = 0;
} else {
c++;
}
}
}
}
}
};

// 念のための重複防止(ループ再生時など)
if (IDflag == undefined) {
IDflag = true;
// 滝の左右の番号を初期化
lef_n = 0;
rig_n = fal_n-1;
// 一定間隔で左右の番号を増減させる
ID = setInterval(function () {
// 滝の左右の番号を1ずつ増減
lef_n++;
rig_n--;
if (lef_n>=fal_n/2) {
clearInterval(ID);
}
}, int);
}
======================

一応,ご要望通り,setInterval を使用しています。
setInterval が使用できるのは Flash MX以上(MX,MX2004,8,CS3)です。
したがって,

 ActionScript1.0
 Flash MX 以上で使用可
 FlashPlayer6以上で閲覧可

というスクリプトにしました。

※上記のものまででしたら
 ロースペックなPCでも一応動作確認済みです。
 しかし火の粉の本数を増やすと
 ロースペックなPCではかなりフレームレートが下がると思います。
 また,
  // frm が 3 で割りきれたときのみ
  if (frm%3 == 0) {
 を変えて火の粉が出る間隔を調節することはできます

※すべて相対パスで書いているので
 ムービークリップ内のフレームに書いても,
 外部SWFとしてロードした場合も,
 このまま使えると思います。



~・~・~・~・~・~・~・~・~・~・~・~・
~・~・~・~・~・~・~・~・~・~・~・~・


ここまで書いてふと思ったのですが,

> 上のASのままでは、全てが同時に再生されてしまい、
> 花火のナイアガラっぽくありません。

ここまでできているのでしたら,
真ん中に近い火の粉ほど,
最初に上(y座標が小さい位置)に置いておけば良いだけのことではないのでしようか?
y = 38.5 より下にマスクをかけるとかすれば,それより上の火の粉は見えませんし。

状況がわかりませんから,これでうまく行くのか行かないのかはわかりませんが。
何にしても gotoAndStop() は関係ないと思いますよ(おそらく)。

この回答への補足

BlurFiltan様、分かりやすい説明ありがとうございます。
何点か質問があるのですが、現在火の粉は画像ではなく色線で指定されていますが、色線ではなくMCを使いたい場合はどの部分にMCを読み込むASを入れればよいのでしょうか?
あと、現在水面に映り込んでいる火の粉を表示させない場合はどうすればよいのでしょうか?

補足日時:2008/05/17 21:42
    • good
    • 0

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