dポイントプレゼントキャンペーン実施中!

縦に並ぶアニメーションのナビボタンのスクリプトを横に並ぶ形のサンプルソースを元に書き換えしているのですが動作しません。補足でソースをコピーしますので、どこが誤りなのでしょうか。教えてください。

ボタン動き→onmouseでH=200%拡大、イメージがスワップ。その他のボタンはそれにつれてH=伸縮。
※辞書を引きながらのつたない間違いかと思いますが…宜しくお願い致します。

A 回答 (13件中1~10件)

つまり,


「質問欄には書ききれなかったスクリプトを補足するので,とりあえず何か言ってください。」
ということですか?

それでは,一応質問がさっぱりわからないので「補足要求」します。
(補足の字数制限もありますから,注意してください。)
私がわかるかどうかわかりません。どなたかもしおわかりであれば,回答おねがいします。↓

この回答への補足

大変ありがたいです。
回答がつかないと補足ができないのを知らなかったので
削除の依頼などかけてやきもきしていました。

昨日も辞書やネットで、横用の記述を縦用にするのに必要な変更点を調べていたのですが、私の頭では限界のようで
やはり動作しませんでした。(逆にswfが動かなくなってしまいました。)

補足日時:2005/08/30 10:53
    • good
    • 0
この回答へのお礼

this.init();
this.onEnterFrame = function() {
if (base.hitTest(_root._ymouse, _root._ymouse, false)) {
this.rollover();
} else {
this.rollout();
}
this.resize();
this.setalpha();
};
//値の初期化
function init() {
cntX = 5;
top = base._y-base._height/2;
bottom = base._y+base._height/2;
for (i=0; i<=cntY; i++) {
line = this["lineY"+i];
line._y = left+i*base._height/cntY;
}
//ロールオーバー時に開いているitemの高さ
openH = 94;
//ロールオーバー時に閉じているitemの高さ
closeH = (base._height-openH)/(cntY-1);
//ロールアウト時のitemの幅
homeH = base._height/cntY;
}
//分割線の位置をホームポジションに戻す
function rollout() {
for (i=1; i<=cntY; i++) {
line = this["lineY"+i];
line._y += (left+i*homeH-line._y)/3;
}
}
//カーソルの位置に応じて分割線を移動する
function rollover() {
for (i=1; i<=cntY; i++) {
line = this["lineY"+i];
if (line._y<_root._xmouse) {
line._y += (left+closeH*i-line._y)/2;
} else {
line._y += (right-closeH*(cntY-i)-line._Y)/2;
}
}
}
//分割線の間隔にitemの高さを合わせる
function resize() {
for (i=0; i<=cntY; i++) {
mc = this["item"+(i+1)];
lineT = this["lineY"+i];
lineB = this["lineY"+(i+1)];
mc._y = lineL._y;
mc._height = lineT._y-lineB._y;
}
}
//コンテンツの中身を表示する
function setalpha() {
for (i=0; i<=cntY; i++) {
mc = this["item"+i];
//透明度を決める
homeAlpha = (openH-mc._height)/(openH-homeH)*100;
openAlpha = 100-homeAlpha;
if (homeAlpha>10) {
//mc.homeを表示する
mc.home._visible = true;
mc.home._alpha = Math.ceil(homeAlpha);
} else {
//mc.homeを消す
mc.home._visible = false;
}
if (openAlpha>10) {
//mc.openを表示する
mc.open._visible = true;
mc.open._alpha = Math.ceil(openAlpha);
} else {
//mc.openを消す
mc.open._visible = false;
}
}
}

お礼日時:2005/08/30 17:35

ムービークリップの配置や階層構造などが不明なので、憶測まじりになりますが。




 > this.init();
 > this.onEnterFrame = function() {
 > if (base.hitTest(_root._ymouse, _root._ymouse, false)) {
    :

3行目の hitTest は、ムービークリップ同士、もしくはムービークリップとある1点の座標の衝突を判定でき、どちらの衝突を判定するかは渡すパラメータで決まります。
今回は後者の、ムービークリップとある1点の衝突を判定しているものと思われます。
この場合の書式は

 hitTest( X座標 , Y座標 , true または false );

です。
しかし、X・Y座標を渡さなければならないところを、両方ともマウスカーソルのY座標( _root._ymouse )を指定していますね。
動かなくなったのは、このためだと思います。
とりあえず、この部分を

 if (base.hitTest(_root._xmouse, _root._ymouse, false)) {

と変えてください。


それから、初期化をしている init 関数ですが。

 > //値の初期化
 > function init() {
 > cntX = 5;
 > top = base._y-base._height/2;
 > bottom = base._y+base._height/2;
 > for (i=0; i<=cntY; i++) {
 >line = this["lineY"+i];
 > line._y = left+i*base._height/cntY;
    :

cntX = 5; で cntX という変数が定義されますけれど、以降のスクリプトで実際に稼動している変数の名前は cntY のようです。
cntX を cntY に変更してみてください。


元のサンプルでは横並びということで、X座標等を扱うので” X ”が付いた変数やインスタンス名が付けられていたものを、縦並びに改造するために” X ”の部分を” Y ”に変更なさったのではないのでしょうか。
これは私の推測なのですが、元のサンプルには lineX0 ~ lineX5 というインスタンス名が付いたムービークリップがありませんか?
このムービークリップを、rollover ・ rollout 関数で操作していると思われます。
これらの関数で lineX +番号というムービークリップを操作していたのだとしますと、スクリプトを lineY +番号に変更しただけでは、実際にはムービークリップが存在しないのでスクリプトが空回りしてしまいます。
”分割線”と呼ばれているムービークリップのインスタンス名を確認して、lineX +番号 となっているようなら、これを lineY +番号 に変更してください。


最後に、rollover 関数ですが。

 > //カーソルの位置に応じて分割線を移動する
 > function rollover() {
 > for (i=1; i<=cntY; i++) {
 > line = this["lineY"+i];
 > if (line._y<_root._xmouse) {
    :

横並びのメニューではマウスカーソルのX座標と比較しているのは分かるのですけれど、縦並びにするならY座標と比較することになると思います。
上記の最後の行を

 if (line._y<_root._ymouse) {

にしてみてはいかがでしょう。


ざっと見たところ、気になったのは以上の点です。
実物を見ないと詳しくは言い切れませんけれど、ご参考までに。

この回答への補足

有難うございます。大変わかりやすいご説明で助かります。
タテの動きのほかのサンプルをみて、xとyの記述モレと、インスタンス名のlineX数字をlineY数字にする点に自分でも気づくことができました。(lineX数字の存在を言い当てていらしたことに感動でした)
これでswfは開くようになりましたが、以下のようになってしまいました。
現在の表示のされ方:
■5つのボタンのうち3つめしかみえていなくて他の部分は下に敷いたbaseがみえている。
■みえている3つめのボタンはyの位置が1/2分上にずれている。
■マウスをのせても反応がない。

実際にflaファイルを見ていただけたら一番なのですが…
現在レイヤーはactionと、lines,items,baseの3つです。 linesには、lineY0~5が、itemsにはitem1~5、baseにはbaseというインスタンス名のmcが入っています。ltem1~5は入れ子のmcで、「ボタン」であるmcと「onmouseすると現れるイメージ」であるmcをピッタリ重ねたものです。

サンプルをwebでみることができるらしいので
ご参考までに見ていただくことは可能でしょうか。
http://www.oshige.com/flash/mx/index.html
→サンプルメニューパネルを開く→17番→2行目:ロールオーバーしたマス目が開くコンテンツメニュー
これが、参考にしている横並びのスクリプトです。

補足日時:2005/09/01 17:00
    • good
    • 0

#2です。




init 関数の中に、

 > top = base._y-base._height/2;
 > bottom = base._y+base._height/2;

とあり、これは分割線のムービークリップ lineY0 ~ 5 の座標を計算する時に基準として使う変数だと思います。
ところが、実際の計算では


 ・ init 関数内
  > line._y = left+i*base._height/cntY;

 ・ rollout 関数内
  > line._y += (left+i*homeH-line._y)/3;

 ・ rollover 関数内
  > line._y += (left+closeH*i-line._y)/2;
  > } else {
  > line._y += (right-closeH*(cntY-i)-line._Y)/2;


・・・と、top と bottom (上下端)が、いつのまにか left と right (左端・右端)に変わってしまっています。
これが怪しいですね。
多分ですが、left → top 、right → bottom だと思います。
上手くいかないようなら、逆に、left → bottom、right → top にして試してみてください。

ボタンである item1 ~ 5 の位置と高さは、enterFrame イベントで常時呼ばれている resize 関数で、lineY0 ~ 5 の位置から決定されているようです。
つまり、lineY0 ~ 5 の座標が正しく計算されていないと、これに引きずられてボタンもおかしなところに表示されてしまったり、高さが0になるなどで表示されなくなる可能性があります。


それから、resize 関数で

 > function resize() {
 > for (i=0; i<=cntY; i++) {
 > mc = this["item"+(i+1)];
 > lineT = this["lineY"+i];
 > lineB = this["lineY"+(i+1)];
 > mc._y = lineL._y;
    :

mc._y = lineL._y; は変数 lineL ではなく、lineT._y (これでおかしい場合は lineB._y )ではないでしょうか。


スクリプトがらみで怪しいのは大体こんなところで、他に考えられる原因としては、インスタンス名が違っているといった些細な誤りだと思います。

この回答への補足

救いのお返事、ありがとうございます。
ご指摘の部分、昨日自分でも気づいたもののモレがあり、ご指示いただいて助かりました。またご推測のとおり、インスタンス名が間違っていたり、モレている部分がありました。これらを修正したところ、すべての画像は表示され、マウスを載せるとボタンとラインが動きを見せるようになりました。(ご説明の仕方のおかげでスクリプトのしくみも少しづつわかってきました。)
これだけでも感動なのですが、、まだヘンです。

□下に敷いてあるbase、ボタン、ライン、すべてが
縦方向にズレて見えている。→下2つのボタンと下3本のラインはbaseの上にのっているが、それより上は、baseから上にはみ出ている。
□baseに乗っていない部分のボタンとラインはonmouseに反応しない。

またonmouseしたときの動きもヘンで、
□ラインとラインの間にマウスをおくとライン同士の距離は2倍に広がるが、ボタンはそのままの状態で上下に移動している。
□マウスをおくとボタンが広がって徐々に現れるはずの、ボタンの下に重ねてある画像が見えない。

サンプルは7つのボタンなので、5つのボタンにすることで数値を変えなければならない箇所があるのでしょうか。
ロールオーバー時に開いているitemの高さ、閉じているitemの高さ、という箇所が気になっています。開いているとき=94は画像サイズです。違っていますか。

書き出しの際のflashのバージョンなども関係あるのでしょうか。現在は7.0で書き出しています。(5.0以下は更に正しく表示されません)

補足日時:2005/09/02 18:57
    • good
    • 0

まず、ボタンのサイズが変わらない点ですが。


よく考えてみますと、resize 関数内の

 > mc._height = lineT._y-lineB._y;

これ、逆ですね。
lineB._y - lineT._y だと思います。

lineT は上の線、lineB は下の線と思われます。
Y座標はステージの下方向にいくにつれて大きくなります。
上の線から下の線の座標を減算したのでは、ムービークリップの高さである _height プロパティに負の数が入ってしまい、変形が無効になります。


ボタンのアルファも、実は _height プロパティと関係があります。
setalpha 関数で

 > homeAlpha = (openH-mc._height)/(openH-homeH)*100;

この部分に、item1 ~ 5 の _height プロパティを使ってアルファを求める計算が含まれています。
ボタンの下の画像が見えないのも、_height の計算が正しくなかったためではないでしょうか。
なお、item1 ~ 5 の入れ子のムービークリップは、それぞれ home と open というインスタンス名でなければならないようです。
この間違いもないか、合わせてご確認ください。


残るは位置のズレですけれど、これは根が深そうですね。
正直言いますと、原因の目星がつかないのですが ^^;

base から外れているものにカーソルを合わせても反応しないのは、これは当然です。
base とマウスカーソルとの衝突判定を取り、メニュー全体のどこかにカーソルが重なっていれば rollover 関数が、重なっていなければ rollout 関数が呼び出されます。
base から外れているボタンにカーソルを合わせた場合は、base からカーソルが外れているので rollout 関数が呼び出され、ボタンが初期状態に戻されてしまい、反応していないように見えます。

とりえず、this.onEnterFrame = function()・・・の部分をコメントにして、init 関数だけを呼び出すようにしてみてください。
この時点で、ボタンはさておき、分割線は base の上に正しく配置されますでしょうか?
スクリプトを見た限りでは、base の中心点は中央にあるものとして計算されていると思われます。
base のシンボルの編集画面を開き、+マークの位置を確認してみてください。
これが中央以外にあると、base の座標をもとに算出しているもの(特に top および bottom 変数を使った計算)全てに狂いが生じます。
中心点がズレているようなら、+マークが中央にくるように base の絵を移動してください。


openH は画像のサイズ、つまりボタンが開いた状態のサイズで、間違いないと思います。
ただ、サンプルでは横長の画像が使われており、openH(元は openW でしょうか?)には画像の幅が入っていたはずです。
これを縦並びに改造するなら画像の高さを代入すべきですが、このあたりに問題はありませんでしょうか?

元のスクリプトは変数を多用して柔軟に設計されている(おかげでややこしいですが)ので、変更するのは、ボタンの数である cntY とこの openH だけだと思います。
あとの変数は、これらの数値をもとに算出されていますので。
まあ、base や item の大きさと数によっては計算に端数が生じ、拡大/縮小した時に画像が歪んで見えたりわずかにズレるといった害は出るかもしれませんけれど、全く動かなかったりおかしいほどズレるようなことはないかと思います。


書き出すバージョンは、さしあたって関係なさそうです。
on*** = function という書き方やムービークリップに on アクションが書けるようになったのは Flash Player 6 からで、Flash Player 5 以前では動作しません。
ですが、分割線の位置やボタンの配置を決める部分は、文法上は Flash Player 5 でも動く( Flash Player 4 以前では無理ですが)スクリプトになっています。
強いて言えば精度の問題で多少はズレることはあっても、全体的に上手くいっていないこととは直接関係はないと思いますよ。

この回答への補足

お忙しい中ありがとうございます。助かっています。
おっしゃるとおり、lineB._y - lineT._yにしたらサイズとアルファの点が解決しました。itemの入れ子のmcのインスタンス名はopenとhomeで間違いありませんでした。
残る位置の問題なのですが、ご推測の通り、baseの×が左上にあったのでbaseを動かして中央点をそこにもっていったら、lineとbaseがきちんと揃い、itemがxは揃って、yが高さ半分上にずれている状態まで改善されました。this.onEnterFrame = function()・・・をコメントにすると、確かに全ての画像がピタリと揃います。openHの94は開いたボタンの高さで間違いありません。ステージに配置されている座標はきちんと揃っているのになぜなのでしょうか。ためしにステージ上でボタンを高さ半分、下にずらしてみても、書き出した状態には変化がありません。
たまにでてくる整数、例えば、line._y += (top+i*homeH-line._y)/2; とか closeH = (base._height-openH)/(cntY-1); の1や2を調整する必要はないのですよね?
(私は、なぜここで1をひくのか、2で割るのか、がよくわかっていません…無知ですみません)

補足日時:2005/09/05 10:43
    • good
    • 0

item のズレも中心点の問題だと思います。


ある方向に”半分だけ”ズレるのは、スクリプトの問題でなければ、大抵は中心点が違っていることが原因です。

item1 ~ 5 の中心点が、中央になっていませんか?
各ボタンは上下の分割線をもとに座標と幅を決めるため、item は base とは逆に、中心点が上端になければならないと思います。
ActionScript での _x と _y プロパティには、インスタンスの中心点の座標が入ります。
item1 ~ 5 の位置を、これの上端に接する分割線の位置から決めるのであれば、_x と _y 、特にY座標を表す _y プロパティにはインスタンスの上端の座標が入っていた方が計算しやすいです。

_x は今回は触らないので、item の中心点は上端でさえあれば左上・上中央・右上のどれでもいいと思います。
分かりやすいのは左上でしょうか。item1 ~ 5 の中心点を左上にしてみてください。
インスタンスの中心点は元になっているシンボルの中心点と同じ場所になり、インスタンスごとに変更はできません。元のシンボルを編集して、中心点を決めます。
item シンボルの編集画面を開き、入れ子になっている home と open の両方を、+マークが左上にくるように移動してください。


this.onEnterFrame = function()・・・をコメントにすると、分割線やボタンの座標などを決める関数が呼び出されなくなります。
これらの関数が呼び出されなければボタンは移動しませんから、編集画面で配置した通りの位置に表示されます。
しかし、この部分をコメントからスクリプトに戻した時は、フレームレート分の1秒ごとに関数が呼び出され、ボタンの位置を計算する処理が行われます。
この部分に問題があると、ムービーがロードされた次の瞬間には、ボタンは誤った位置に配置されてしまいます。

分割線は init 関数で base の大きさと座標から初期配置を決めているようなので、base や line0 ~ 5 に問題があるのかどうかは init 関数だけを実行してみれば分かります。
これで分割線が所定の位置に配置されるのであれば、base から分割線の位置を決める計算や処理はとりあえず問題なしとなります。
この時点で既に分割線がズレているようなら、線を配置する計算か、あるいは基準になる base に問題がありそうだと推測できます。

base と line0 ~ 5 に問題がないとすると、item 自体か、あるいは item1 ~ 5 を動かす処理が怪しいことになります。
曲がりなりにも分割線の位置と幅に合わせて item1 ~ 5 の位置と幅が変化しているなら、動かす処理にはさしあたって問題はなさそうで、となると残る可能性は中心点のズレではないか・・・と絞っていくわけです。
不具合や不可解なことが起きたら、少しずつスクリプトを動かしていって、どの部分は正常に動くのか、何をしたらどうなるのかを考えながら原因を突き止めていくといいですよ。

--------------------------------------------------------

closeH の 計算に出てくる - 1 は、これは変更してはいけません。
メニュー全体の高さは常に固定で、base の高さと一致しています。
従って、あるボタンが1つ開いた時、閉じている残りのボタンの高さの合計は、base の高さ( _height プロパティ)から開いたボタンの高さを差し引いた値になります。
ボタンが開いた状態の高さは変数 openH に入っていますので、残りのボタンの高さの合計は

 base._height - openH

で求められます。

変数 closeH には、もう1歩進んで、閉じているボタン1つあたりの高さを入れておきたいのです。
閉じているボタンはどれも同じサイズですから、高さの合計を閉じているボタンの数で割れば1つあたりの高さが出てきます。
ボタンは全部で5つあり、そのうちの1つが開いているのでこれを除きますと、閉じているボタンはボタンの総数( = cntY ) - 1 で4つです。
よって、base の高さから openH を引いた値をボタンの総数 cntY - 1で割ったものが、閉じたボタン1つあたりの高さとなります。


rollout 関数と rollover 関数で、_y の値を決める時に用いられている / 2 や / 3 は詳しくは分かりませんが、おそらくはアニメのコマ数を決める数だと思います。
つまり、/ 2 なら2コマ、/ 3 なら3コマで移動が完了するといった意味ではないでしょうか。
例えば、これを / 1 にするかこの部分を削除すると、なめらかなアニメではなく分割線がいきなり所定の位置に戻ったり開いたりするようになり、逆に値を増やすと、アニメにかかる時間が長くなる代わりにゆっくりなめらかに動くようになると思います。

メニューをストレスなく開閉させるためには、ある程度のスピードやアニメのキレの良さも必要です。
まあ、ダラダラと長いアニメにするとボロも出やすくなりますしね。
そのあたりの兼ね合いから、閉じる時は3コマ、開く時は2コマでアニメが完了するようにしているのだと思います。


init 関数で変数 top と bottom の値を決める時にも、/ 2 という数値が出てきます。
図を描いてみると分かりますが、base の中心点が中央にある場合、base の上端の座標は base の _y から高さの半分を引いた位置、下端は逆に、_y に高さの半分を足した位置であるといえます。
(↑この部分から、base の中心点が中央にあるものとして作られていることが推測できます)
この / 2 は base の高さの半分を、との意味ですから、これは変更してはいけません。
余談ですが、あるムービークリップがどの座標空間を占めているかは MovieClip クラスが持っている getBounds というメソッドでも取得できます。

--------------------------------------------------------

ところで、#4で書きました、パブリッシュのバージョンについてですが。

this.onEnterFrame = function・・・という書き方は Flash Player 5 以前のバージョンにはないため、この部分が正常に動作しません。
つまり、分割線やボタンを開閉させるスクリプトは、this.onEnterFrame = function の部分以外は Flash Player 5 でも動くのですが、onEnterFrame = function ・・・の書き方を利用して各関数を呼び出している限りは Flash Player 5 では動きません。
Flash Player 6 では問題なく動きます。6以降のバージョンでパブリッシュしてください。

何だか脳回路がショートしていたみたいで(^^;)訳の分からない説明をしてしまい、失礼いたしました。

この回答への補足

ご指摘のとおりでした。ついに美しく動くようになりました。ありがとうございました。DPEさんがいらっしゃらなかったらデザイン変更を余儀なくされているところでした。
インスタンス名open、homeの+が、編集画面上では左上になっていることを確認してあったのですが、今回初めてopen,homeであるシンボルのno1~5とimg1~5というMCをライブラリでダブルクリックして+を移動しました。
ご説明のとおり、私はインスタンスごとに中心点を動かして、動かしたつもりになっていたということなのでしょうか。昨日はご説明を印刷して家でじっくり理解したのですが、それで初めて見えてくることがたくさんありました。スクリプトの意味を理解することは、間違い部分に気づくためにとても大事だとすごく思いました。
ところで、引き続き教えていただきたいことがございます。もしお疲れでなければDPEさんにご教授頂きたいのですが…。

作成したのは左ナビなので、homeが第2階層のコンテンツ、openが第3階層のコンテンツになるのですが、それぞれリンクを貼らなければなりません。
以前にDPEさんにリンクの貼り方を教えていただきましたが(途中で気づきました…!)これは、itemのMCのなかのhomeのインスタンスに直接アクションを指定するのでよいのですよね。ただ、openの第3階層のほうでは、一つの画像内に、2箇所、3箇所のリンク先を指定しなければならないので、これは(第3階層が1ページだけのところと、2ページ、3ページあるところとあります)、htmlのホットマップのように、任意の位置に透明ボタンを配置してボタンにアクションを指定すればよいのですか?

補足日時:2005/09/06 10:46
    • good
    • 0

とりあえず無事に動くようになって何よりです。


以前、No.1197851 で回答したことがありましたね。覚えております。
あの時はバナーの話でしたから、ムービー内のどこをクリックしても反応するように、透明なボタンを1つ重ねる方法をご紹介しました。
今回も、透明なボタンを使ってはいかがでしょうか。


サンプルでは番号が書いてあるインスタンス home は、ボタンが開いている間は徐々に薄れて、やがて非表示( _visible プロパティが false )になって消えてしまいます。
home に on アクションを使ってリンクを設定したとしても、_visible プロパティが false になっているインスタンスでは release 等のボタンイベントが発生しなくなり、ボタンとしては機能しなくなります。
ビジュアル的な面から見ても、home は見えなくなるのですから、これをボタンとして使うのは無理ではないでしょうか。

例えば、リンク先が

 表紙
  ・ページ1
  ・ページ2
   :

と、このようになっていて、open に配置した画像の一部にページ1と2へのリンク、そのリンク以外の部分を表紙へのリンクにしたいということであれば、home を使わず open だけで何とかできます。


親子階層になっているムービークリップや、今回の home と open のように上にムービークリップがぴったり重なっている状況で、親や上のムービークリップがボタンとしての機能を使うと、子および下に配置されているムービークリップでは、on アクションを設定しても各イベントが検出されなくなります。

しかしこれは、ムービークリップが親子階層になっていたり、覆うようにかぶさっているムービークリップがある時の話です。
例えば、大きな四角いムービークリップと小さい丸のムービークリップを用意し、この2つを重ねて両方に on アクションを設定すると、それぞれでボタンイベントは検出されます。


open も、この特徴を利用してリンクボタンを作ってはいかがでしょう。
仮に先述のような構成のコーナーがあり、open 内の画像の一部に各ページへのリンク、これ以外の部分をクリックした時には表紙を表示するものとします。
open の元になっているシンボルを開き、次のようにレイヤーを追加してください。

 レイヤー1:各ページへのリンクボタンを配置
 レイヤー2:表紙へのリンクボタンを配置
 レイヤー3:画像を配置

レイヤーは上のものほど上に重なって表示されます。
このようにレイヤーを重ねておくことで、画像の上に表紙へのリンクボタン、そのボタンの上に更に各ページへのボタンが重なります。

表紙へのリンクボタンは、ただの四角形で構いません。
なお、open (の元になっているシンボル)のサイズは全て同じはずですから、各コーナーの表紙(第2階層)へのリンクボタンシンボルは、他の open のシンボルでも再利用できます。
各ページ(第3階層)へのリンクボタンは、リンクさせたい部分の形に合わせて作ってください。

各ボタンができたら、それぞれアルファを0%にして透明にし、on アクションでリンクを設定してできあがりです。
こんなところで、いかがでしょうか。

この回答への補足

あれ…?週末に補足を書いたつもりなのですが、今みたら未記入のままです。ちゃんと送れていなかったのかな。
お返事遅れてすみません。
すぐに印刷して熟度し、よく理解できました。
今クライアントからの返事まちで、またアクションが変更になるかもしれなくて先に進めないのですが、
決まり次第着手します。そしたらまたご連絡しますので
引き続き、よろしくお願いします。

補足日時:2005/09/13 14:06
    • good
    • 0
この回答へのお礼

DPE、大分時間があいてしまってすみません。
ご指示のとおり制作したらリンクが貼れました。
一度でうまくいって感動しました。どうもありがとうございました。
それで、やはりクライアント側からアクションの変更がでて、各ボタン内の文字がロールオーバーして色が変わるようにするように言われました。確かに今のままではボタンのどこにマウスを載せてもクリックできる印になっていて、実際に飛んでみないと任意のページにいけたかどうかわかりずらいようです。文字に色がついたバージョンのopen画像を作るのまではわかるのですが、それをどのレイヤーに配置して、どこにアクションが必要なのか、おわかりになりますでしょうか。情報に不足があれば補足させていただきます。長丁場で申し訳ないのですが…ご説明がとてもわかりやすいので、できればまたよろしくお願いいたします。

お礼日時:2005/09/23 14:30

Flash ではビットマップ画像をピクセル単位で書き換えることができません。


open が1枚のビットマップ画像でできていて、その中に各項目へのリンクボタンのテキストやイラストが描き込まれている状態ですと、そのままでは無理だと思います。
色を変えた画像を多数用意しておいて切り替えるとか、そういった無理をすれば何とかならないこともないですけれど、ビットマップ系画像を多数使うとムービーが重くなってしまい、メニューとしてはちょっと現実的ではありません。
メニュー用の各ボタンを、背景から独立したパーツとして用意できるなら、各ボタンをそれぞれボタンシンボルとして作り、「オーバー」のフレームを利用すると簡単です。


とりあえずメニューの各ボタンがテキストとして説明しますが、これがイラストの場合でも基本的な考え方は同じです。
テキストを入力し、ボタンシンボルに変換してください。
ロールオーバーで色を変えるには、ボタンシンボルの編集画面を開き、「オーバー」のフレームにキーフレームを作って、文字の色を変えておきます。
これで、ロールオーバーの時に色が変わるボタンシンボルになります。
ついでに「ダウン」のフレームでも同様の作業をしておくと、クリックした時にも色が変わって分かりやすくなります。

それから「ヒット」にキーフレームを作り、テキストが収まるくらいの四角形を描画してください。線のない、塗りだけの四角形で構いません。
「ヒット」フレームはマウスが反応する部分を定義するもので、ムービーには表示されません。「ヒット」が未定義の場合は、「アップ」と同じ絵がヒット領域として採用されます。
ボタンが丸や四角のような形であればあまり問題はないのですが、テキストの場合は、「ヒット」が未定義だとテキストの線がない部分にはマウスが反応しなくなり、クリックしにくいボタンになってしまいます。
テキストが収まるくらいの四角いヒット領域を定義しておくと、線のない部分にもマウスが反応し、普通のボタンのようにクリックできるようになります。


メニューの数だけボタンシンボルを用意したら、これを、#6と同じ要領で配置します。
要するに、透明なリンクボタンが「オーバー」のフレーム付きのボタンシンボルに変わるだけです。
スクリプトも同様に、配置したメニュー用の各ボタンのインスタンスと、背景画像に重ねた透明ボタンに on アクションを設定してください。

--------------------------------------------------------

メニュー用のボタンがテキストで、単に色が変わればいいだけでしたら、項目名として表示するテキストとリンク先の URL をパラメータとして持つコンポーネントにし、テキストやリンク先のページだけを変更可能にするという方法もあります。
メニューの項目がいくつあってもシンボルは1つだけで済むので、仕様やデザインが変更になった時も楽に対応できますし、スクリプトをいじることなくムービーの編集画面で文字やリンク先を変更できて管理や編集も簡単です。
ただし、項目名をダイナミックテキストで表示するため、あまり凝ったフォントが使えないことと、ボタンごとに細かく違うデザインにはできないといった難点があります。

コンポーネントとは、編集可能なパラメータを持っているムービークリップのことです。
メニュー用のボタンは、ロールオーバーでテキストの色を変更・ロールアウトで元の色に戻す・クリックでリンク先のページを開くという動作は全て共通です。
共通する動作はムービークリップの動作として作り、違う部分だけを編集できるパラメータにして、後から簡単に変更できるようにします。


まずはムービークリップを作ります。
「挿入」→「新規シンボル」でムービークリップを作り、空白のテキストフィールドを描画します。
「プロパティ」パネルで、「ダイナミックテキスト」「単一行」「選択不可」(” Ab ”のボタンを OFF )「 HTML なし」(” <> ”ボタンを OFF )に設定してください。
大きさは適当で構いませんが、ムービークリップの中心点が左端になるよう、シンボルの+マークがテキストフィールドの左上に来る位置に配置してください。
それから、このテキストフィールドにインスタンス名を付けます。ここでは仮に、” btn_name ”とします。


次に、コンポーネントのパラメータを定義します。
コンポーネントの作り方やコンポーネント定義パネルの使い方は以前別の質問で回答しましたので、こちらをご参考になさってください。
#3の中ほどで説明しております。

 ・縦のメニューバー作成方法で困っています。Part2
  http://okweb.jp/kotaeru.php3?q=1612380

今回のパラメータは、項目名として表示する名前とリンク先の URL の2つです。
「コンポーネント定義」パネル(シンボルを選択して右クリック→「コンポーネント定義...」)を開き、+ボタンを2回クリックしてパラメータを追加してください。
変数はとりあえず、項目名を item_name 、リンク先を page_url とします。タイプはどちらも String (文字列)です。
これで、ムービークリップがコンポーネントシンボルになります。


このシンボルのタイムラインに、ボタンとしての動作を定義します。
シンボル内に定義しておくと、このシンボルから作られたインスタンスは全て同じ振る舞いをするようになります。
シンボルのタイムラインのフレーム1に、次のようなスクリプトを設定してください。

(↓各行頭に全角のスペースが入っています。コピーする際は、全て半角のスペースかタブに置き換えてください)


 //テキストの長さに合わせて幅を伸縮させる
 btn_name.autoSize = "left";

 //項目名を表示
 //テキストはコンポーネントパラメータ:item_name
 btn_name.text = item_name;

 //デフォルトのテキストの色を保存
 org_color = btn_name.textColor;


 /*ロールオーバー時、テキストの色を赤にする*/
 this.onRollOver = function()
 {
  btn_name.textColor = 0xff0000;
 };

 /*ロールアウト時、テキストの色を元に戻す*/
 this.onRollOut = function()
 {
  btn_name.textColor = org_color;
 };

 /*クリックされた時、指定のページを表示*/
 this.onRelease = function()
 {
  //リンク先はコンポーネントパラメータ:page_url
  getURL( page_url , "blank" );
 };


「ダイナミックテキスト」または「テキスト入力」にしたテキストフィールドは、TextField というクラスで細かく制御できます。
TextField には、テキストフィールド内に表示する内容を管理している text というプロパティがあります。書き換えることで、直接内容を更新できます。上記のスクリプトでは、text プロパティにコンポーネントパラメータの item_name の内容を代入して、項目名を表示しています。

テキストの文字色は、同じく TextField クラスの textColor というプロパティに入っています。
ロールオーバー/アウトの時には、このプロパティを操作して文字色を変更します。
textColor には、最初は、テキストフィールドを配置した時に設定した文字色が入っています。この色を変数 org_color に保存しておき、ロールアウト時に元の色に戻せるようにしています。


ムービークリップ内にテキストフィールドを1つだけ配置し、ムービークリップにボタンイベント( rollOver や release など)を利用するスクリプトを書くと、テキストフィールド全体がヒット領域になります。四角い透明なボタンを重ねる必要はありません。
ただ、何も指示しないとテキストフィールドが伸縮せず最初に配置したサイズの通りのボタンになるため、文字列の長さと大きさが合わないとテキストが途中で切れたり、空白の部分なのにマウスが反応するなどのおかしな現象が起きてしまいます。

テキストの長さに合わせてテキストフィールドを伸縮させるには、autoSize というプロパティを使います。
left は左端を固定し、右方向に伸縮させる設定です。メニューを左揃えにしたい時に便利です。
その他のスタイルについては、よろしければこちらをご参考になさってください。

 ・ダイナミックテキストの幅を広げるには?
  http://okweb.jp/kotaeru.php3?q=1510682


以上でコンポーネントは完成です。
open のシンボルに、各項目へのリンクボタンの代わりにコンポーネントシンボルのインスタンスを配置してください。
これらのインスタンスは既にボタンとしての機能を備えていますから、on アクションを設定する必要はありません。画像に重ねている透明ボタンにだけ、別途 on アクションを設定します。
コンポーネントの持っているパラメータは、「プロパティ」パネルに表示されている「パラメータ」のタブ(パネルの右上にあるタブを切り替えると表示されます)で編集できます。
項目名とリンク先を入力して、動作を確認してみてください。

ちなみに、文字色をパラメータに追加し、そのパラメータを元に文字色を変更するようにスクリプトを変更すると、ボタンごとに色を変えられる、より柔軟なコンポーネントになります。
textColor プロパティに設定するのは色の RGB 成分値ですから、パラメータのタイプは Color ( RGB 成分の 16 進数表記)がオススメです。
タイプを Color にしたパラメータでは、色のサンプル部分をクリックするとカラーピッカーが表示され、ピッカーから拾った色や作成した色の RGB 成分が 16 進数形式に直されて設定されます。


コンポーネントにする場合でも、画像の一部分をクリックできるようにするための透明なボタンの代わりに、別のリンクボタンを大きなボタン(メニュー以外の部分に対するボタン)の上に重ねておくという考え方は全く同じです。
コンポーネントも万能ではありません。何か問題があるようでしたら、容量やメンテナンス面では多少難がありますけれど、各項目用のボタンを片っ端からボタンシンボルとして作るのもアリかなとは思います。
    • good
    • 0
この回答へのお礼

早速ありがとうございました。
画像上にあったメニューの文字を、FLASH上でテキストにして、それをボタンシンボルにする方法でつくってみたところ、すごく簡単にロールオーバーするようになりました。
今回のが今までで一番スムーズに作業ができました。
コンポーネントについては、噛み砕いて説明してくださっているのに、私には何度読んでもなるほどというところまで理解ができませんでした。どうにも太刀打ちできないレベルなんでしょうか。。もっと勉強します。
それで、いつのまにかこうなってしまっていたのですが、
フラッシュ開始と同時に一番上のメニューが開いてしまうのです。なので、ページを移動するたび一番上のメニューが開いてしまい、とてもうっとおしいです。当初はマウスを載せてから開いていたはずだったのですが。
これは、シンボルが1ピクセル上に移動してしまっているとかの問題でしょうか。不要なアクションが入っていないか調べてみたのですが、見当たらないようなのですが…
たびたびすみませんがよろしくお願いいたします。

お礼日時:2005/09/27 12:14

そのような怪現象の原因は、さすがに現物を見ないことには何とも言えませんが、、、


最初から開くとは、通常通りアニメーション付きで開くということでしょうか。
それとも、アニメがなくいきなり open が見えている状態でしょうか?

おそらく、おかしいのは最初の1回だけで、1度でもいずれかのボタンにカーソルを合わせたりロールアウトした後は正常に戻ると思うのですが。
最初から open が見えており、なおかつ、何も操作していない最初の1度だけがおかしいのであれば、item1 の open に何か問題がありそうです。


この作品のコンセプトは、

 ・ base とマウスカーソルとの衝突判定を取り、メニュー内にカーソルが重なっているかどうかを検知する。
 ・カーソルが重なっている場合、その位置から分割線の配置を決定。
 ・分割線の位置から、各メニューボタンの位置と高さを決める。
 ・メニューボタンの高さをもとに home のアルファを決め、更に open のアルファを算出。

となっています。
メニューボタンのアルファ値でさえもムービークリップの位置や高さから求めるため、どれか1つでも位置の計算や高さ・中心点のズレなどの些細な誤差があるとアルファの計算にまで響きかねない、非常に繊細な設計になっています。
スクリプトに問題がなくても、シンボルの作り方(高さおよび中心点)や並べ方の誤りが原因で不具合が起こる可能性はあります。


さしあたって、open と同じ大きさの四角形を描画してムービークリップシンボルにし、item1 の open と入れ替えてみてください。
(テスト用のムービークリップを作る時は、中心点や大きさにはご注意ください。open の代わりに使うので、open と全く同じように作ります)
インスタンスを選択した状態で「プロパティ」パネルを見ると、中央あたりに「入れ替え...」というボタンがあるかと思います。クリックするとシンボルのリストが出てきますので、目的のシンボルを選択して入れ替えてください。
これで正常に動くようならば、item1 の open の作り方に問題があることになります。

スクリプト等をいじっていないとすると、後から変更した部分が怪しいです。
特に、後で作り直した open のシンボルの大きさや配置が狂っていないか、確認してみてはいかがでしょう。

この回答への補足

早速のお返事ありがとうございます。
教えていただいたように、同じ大きさ、同じ中心点の四角形を描画して入替えをしてみましたが、やっぱり勝手に、アニメしながら1番うえのメニューが開いてしまいます。
その他のopenも、確かに画像の内容を変更するという作業を施してはいるのですが、そのときもムービークリップシンボルに変換するときに、入替えますか?ときかれて
入れ替える方を選んでいるので、位置のズレはなかったと思うのです。
ただ、その作業より前からこの現象がおきていたかもしれません。保存していた過去のファイルを開いてみたら、動作はきちんとしているのだけれど、上から3番目のメニューが最初から(アニメしつつ)開いてしまう症状のものがでてきました。3番目が開いてしまうのと、1番上が開いてしまうのとでは、原因は異なるのでしょうか。

それと、先ほど書き忘れましたが、この症状は見た目には2箇所の異常があります。もう1箇所は1番下のメニューなのですが、マウスが下にちょっとズレると、すべてのメニューが上に寄って(下にもう1つ6個目のメニューがあるかのような動きをして)しまいます。そのため下に敷いてある黒色のbaseがみえ、うっとおしいだけでなく大変目立ちます。なので、全体が1ピクセル程度上に上がってしまっていたりするのかなと思い、base以外の全てを選択し、1ピクセル下に下げてみたのですが、いずれの症状も変わりありませんでした。

それとも、item(open+home)同士の間に配置されているlineの位置がずれているのでしょうか。
今、lineのy軸の位置は、実は46.5とか、整数でないところもあり、また間隔も正確ではないんです。配置の際、見た目に二重線にみえないようにあわせただけでした。これはどのように決めるべきだったのでしょうか。先ほど頂いた作品のコンセプトから考えると、これをきちんと配置していないことで、スクリプトが正しく動作しない可能性があるように思いましたが、いかがでしょうか。

補足日時:2005/09/28 15:09
    • good
    • 0

何だか、本当に怪奇現象ですね。


原因は見当もつかないので、この先回答できるかどうか自信はありませんが、、、


base が見えてしまう件については、最終手段で、base のアルファを0%にして透明にしておけば何とかなります。
しかし、サンプルではこんな小細工をせずとも、両端のボタンも普通に動いていますよね。
となると、どこかに何か問題があるのだと思います。

分割線の lineY は最初に呼び出される init 関数で所定の位置に配置し直されるようなので、編集画面で多少ズレていたとしても問題はありません。
ただし、init 関数内の

 > line._y = left+i*base._height/cntY;

(実際は left ではなく top だと思いますが)この計算式で base._height / cntY が割り切れず端数になっていると、細かい誤差が生じます。
1ピクセルのズレは、こうしたところから生じているのではないでしょうか。
これは計算で位置を決めている以上はどうにもなりません。base をボタンの総数で割り切れるサイズにするしかないと思います。
ボタンの高さはメニューが開いた時に調整されるので、割り切れるかどうかと動作・表示位置などには特に関係はないと思いますけれど、元のサイズとリサイズされた後のサイズが違っていると、画像が意図しない大きさに拡大/縮小されて微妙に汚くなる場合があります。


もしかしたら、for ループのカウントの取り方など、細かいところにまだ誤りがあるのかもしれません。
1度、変更する前の、サンプルに書かれていたオリジナルのスクリプトを見てみたいのですが、補足していただけませんでしょうか。

この回答への補足

よろしくお願いします。

this.init();
this.onEnterFrame = function() {
if (base.hitTest(_root._xmouse, _root._ymouse, false)) {
this.rollover();
} else {
this.rollout();
}
this.resize();
this.setalpha();
};
//値の初期化
function init() {
cntX = 7;
left = base._x-base._width/2;
right = base._x+base._width/2;
for (i=0; i<=cntX; i++) {
line = this["line"+i];
line._x = left+i*base._width/cntX;
}
//ロールオーバー時に開いているitemの幅
openW = 180;
//ロールオーバー時に閉じているitemの幅
closeW = (base._width-openW)/(cntX-1);
//ロールアウト時のitemの幅
homeW = base._width/cntX;
}
//分割線の位置をホームポジションに戻す
function rollout() {
for (i=1; i<=cntX; i++) {
line = this["line"+i];
line._x += (left+i*homeW-line._x)/3;
}
}
//カーソルの位置に応じて分割線を移動する
function rollover() {
for (i=1; i<=cntX; i++) {
line = this["line"+i];
if (line._x<_root._xmouse) {
line._x += (left+closeW*i-line._x)/3;
} else {
line._x += (right-closeW*(cntX-i)-line._x)/3;
}
}
}
//分割線の間隔にitemの幅を合わせる
function resize() {
for (i=0; i<=cntX; i++) {
mc = this["item"+(i+1)];
lineL = this["line"+i];
lineR = this["line"+(i+1)];
mc._x = lineL._x;
mc._width = lineR._x-lineL._x;
}
}
//コンテンツの中身を表示する
function setalpha() {
for (i=0; i<=cntX; i++) {
mc = this["item"+i];
//透明度を決める
homeAlpha = (openW-mc._width)/(openW-homeW)*100;
openAlpha = 100-homeAlpha;
if (homeAlpha>10) {
//mc.homeを表示する
mc.home._visible = true;
mc.home._alpha = Math.ceil(homeAlpha);
} else {
//mc.homeを消す
mc.home._visible = false;
}
if (openAlpha>10) {
//mc.openを表示する
mc.open._visible = true;
mc.open._alpha = Math.ceil(openAlpha);
} else {
//mc.openを消す
mc.open._visible = false;
}
}
}

補足日時:2005/09/28 19:59
    • good
    • 0
この回答へのお礼

DTPさんにいわれて改めてスクリプトをみてみたところ、気になった点がありました。
line = this["line"+i];
という記述がいくつかあるかと思うのですが、
作成しているスクリプトではこれが、
line = this["lineY"+i];
とlineのあとにYがはいっているのです。最初にお見せした時点ですでにこのようになっていたと思うのですがなぜそのように書き換えてしまったのか自分でもよく覚えていないのです。(すみません・・)
ためしにYを外してみたのですが、ボタンが開かなくなった
だけでした。このYの役割はなんなのでしょうか。やはりこの現象はこれが原因しているのでしょうか。

1度目だけ勝手に開いてしまう件は、たまに大丈夫なとき(正常に閉じていてマウスをのせるとはじめて開く)もあったりして、でも再読み込みするとダメになったりしています。また、3番目とか4番目とか、他のメニューが勝手に開いてしまうときもあったりするようです。

お礼日時:2005/09/29 11:22

一応、



 ・W×H= 100 × 235 px の base (中心点は中央)を1番下に敷く

 ・太さ1 pt の分割線のムービークリップ lineY0 ~ 5 (中心点は中央)を、等間隔(Y座標を 47 px おきに、左端は base の左端に合わせる)に base の上に配置

 ・閉じた状態の大きさW×Hが 100 × 47 px の home と open を重ねた item1 ~ 5 (中心点は左上)を lineY0 ~ 5 の間に並べる

という配置にして作り、オリジナルのスクリプトの、これまで考えてきた部分を変更してざっと試してみたのですが、メニューが勝手に開くことはありませんでした。


ActionScript では、文字列からインスタンスや変数等を参照することができます。
文字列を参照に変換するには、eval 関数か配列演算子 [ ] を使います。
今回のスクリプトでは、配列演算子 [ ] を使って変換しています。
lineY0 ~ 5 をループを使ってまとめて操作するには、

 this[ "lineY" + i ]._y = ・・・

このような表記で操作できます。

この作品の制作者のスタイルだと思うのですが、このようにするとターゲットパスが長くなるので、

 line = this[ "lineY" + i ];

と、予め line という変数に分割線のムービークリップへの参照を格納しておいて、

 line._y = ・・・

というように、コンパクトにターゲットパスを書けるようにしているだけです。

要するに、this[ "lineY" + i ] の” Y ”はターゲット名の一部ということです。
このようなスクリプトに変更したのであれば、分割線のムービークリップのインスタンス名を lineY +通し番号で付けておけば問題はありません。
これはメニューが勝手に開いてしまう理由とは特に関係はないと思います。


あとは、オフラインではちょっと考えにくいことなのかも知れませんが・・・
open シンボルには、おそらくビットマップ画像を使用しているのだと思います。
ビットマップ系画像は容量が大きいので読み込まれるまでに時間がかかり、読み込みが完了するまでは open シンボルの height プロパティが0になっているために、勝手に開くこともあるのではないでしょうか。
item のアルファを決める setalpha 関数では、開いているボタンがあろうがなかろうが、全ての item をチェックし、ムービークリップの高さからアルファを算出しています。
もし、この中にどれか1つでも height が0のものがあれば、マウス操作によらずボタンが開いてしまうこともありうるのかもしれません。
時々上手くいったりいかなかったり、3番や4番が勝手に開くという不可解な不具合は、スクリプトや根本的な考え方・作り方の間違いというよりは、むしろ、読み込みの問題ではないかと思います。

とりあえず、プリロードを付けて、全シンボルの読み込みの完了を待ってから表示してみてはいかがでしょうか。
プリロードには様々な作り方がありますが、簡単なところで、2フレームでできる作り方をご紹介します。

ムービーの先頭に空白のキーフレームを2つ作り、2フレーム目に、次のようなスクリプトを設定してください。


 //完了率の算出
 loaded = _root.getBytesLoaded();
 total = _root.getBytesTotal();
 per = Math.floor( loaded / total * 100 );

 //読み込み完了を待つ
 if( per < 100 )
 {
  gotoAndPlay( _currentframe - 1 );
 }


変数 per に、完了率がパーセントで入ります。
よく見かける、バーが伸びたり Now Loading ○%といった表示を作るのに利用できますが、メニューならそこまで読み込みに時間はかからないでしょうから、待ち時間の退屈しのぎの演出は作らなくてもいいと思います。


これでもダメだったら、申し訳ありませんが、あとはちょっと心当たりがありません。。。

この回答への補足

わざわざサンプルを作っていただいて恐縮です・・・。
ささっとそのようなことができるDTPさんがうらやましいです。

プリロードを付ける方法も伝授して頂いてありがとうございます。確認させていただきたいのですが、同じムービー内に新しいレイヤーを設けるのですよね?
全体を2フレーム右にずらして、新規のレイヤーに空白キーフレームを2つ作って、その2つ目にスクリプトを記述する、というふうにやってみたら、正しく表示されませんでした。(全体がペカペカと点滅する)
知識不足ですみませんが、もう少し詳しく設定の仕方を教えて頂けないでしょうか。

補足日時:2005/10/05 10:35
    • good
    • 0

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