プロが教えるわが家の防犯対策術!

Flashで携帯ゲームのブロック崩しを作りたくて、あるサイトからflaサンプルを見つけました。
製作者のコメントに「ブロックを全部崩しても何も起きませんので、エンディング等は自作してください。 」とあったので、早速4フレーム目にゲームオーバー画面を5フレーム目にクリア画面を作ってみました。
そして元々のソースから
if(ball._y>235){
gotoAndPlay(1);
}

if(ball._y>235){
gotoAndPlay(3);
}
にしたまではよかったのですが、
ブロックが全て無くなったらクリア画面に移動させる方法が分からず困っています。
元々のソースは↓になります。
// ボール移動
ball._x += vx;
ball._y += vy;
// 壁とボールの当たり判定
if(ball._x<5 && vx<0){
vx = -vx;
}
if(ball._x>235 && vx>0){
vx = -vx;
}
if(ball._y<5 && vy<0){
vy = -vy;
}
//ボールが下に落ちたらゲームオーバー
if(ball._y>235){
gotoAndPlay(1);
}
// パドルとの当たり判定
if(ball._x>pad._x-40-5 && ball._x<pad._x+40+5 && ball._y>pad._y-5-5 && ball._y<pad._y+5+5 && vy>0){
vy = -vy;
vx = (ball._x-pad._x)/80*15;
}
// ブロックとの当たり判定
for(i=1;i<=40;i++){
bx = eval("block" add i)._x;
by = eval("block" add i)._y;
if(ball._x>bx-20-5 && ball._x<bx+20+5 && ball._y>by-5-5 && ball._y<by+5+5 && eval("block" add i)._visible==true){
eval("block" add i)._visible = false;
//左端or右端に当たった場合
if(ball._x<bx-20 || ball._x>bx+20){
vx = -vx;
}else{
//上端or下端に当たった場合
vy = -vy;
}
}
}
どの場所にどのように書くべきかいろいろ探してみたのですが、パソコン用の作り方しか見つからす゜携帯用のFlash Lite1.1には対応していない物ばかりで困っています。
ActionScriptについては初心者であまり詳しくなく、本当に恥ずかしい限りです。
どうかお解かりになる方おりましたらお力をお貸し下さい。
宜しくお願い致します。

A 回答 (2件)

#1です。



#1の【補足】を拝見させていただきましたところ
なんとか全容が見えて来ました。

「スクリプトは フレーム2 に書かれていて,gotoAndPlay(2); はフレーム3に書いてある。」
ということで大筋は理解できました。



さらにまた,

> この状態で、ご回答いただいたスクリプトの追加を両方試してみたのですが、
> // ボールが下に落ちたらゲームオーバー
> if(ball._y>235){
> gotoAndStop(4);
> }
> このスクリプトがきかなくなるのか、
> ボールが下に落ちると5フレーム目のクリア画面に移動してしまいます。

この現象も確認できました。

こうなる原因ですが
(あくまでも「原因」であって「悪いこと」でも「対処法」でもありません),
フレーム4 のゲームオーバー画面に,
おそらくブロックが1個も置かれていないからです。
(「だから悪い」といっているわけではありません。あくまでも「原因」です。)


フレーム2 でボールの位置が
ball._y>235
の状態になれば(つまりボールが下に落ちれば)
gotoAndStop(4);
は実際に起こっているのですが,
スクリプト自体は
フレーム2 のその下に書かれてあることも引き続き責任を持って1回のみ実行されるのです。
(フレームの表示は フレーム4 になるのだけれど,フレーム2 のスクリプトは最後まで実行されるのです。)

したがって
フレーム4 に行ったときに
「ボールが1個もないぞ!」
ということになって,さらに
gotoAndStop(5);
も引き続き重なって実行されてしまうわけです。

したがって,見かけ上,

> if(ball._y>235){
> gotoAndStop(4);
> }

このスクリプトが効かなくなるように見えるのです。

実際は効いているのだけど,
すぐに次の命令が実行されるため,効いたように見えないだけです。



対処法は

> if(ball._y>235){
> gotoAndStop(4);
> }

これを下に持って行けば良いでしょう。

フレーム2 のスクリプト全文例です↓。




//-------------------------------------
// ボール移動
ball._x += vx;
ball._y += vy;
// 壁とボールの当たり判定
if (ball._x<5 && vx<0) {
vx = -vx;
}
if (ball._x>235 && vx>0) {
vx = -vx;
}
if (ball._y<5 && vy<0) {
vy = -vy;
}

// パドルとの当たり判定
if (ball._x>pad._x-40-5 && ball._x<pad._x+40+5 && ball._y>pad._y-5-5 && ball._y<pad._y+5+5 && vy>0) {
vy = -vy;
vx = (ball._x-pad._x)/80*15;
}
// ブロックとの当たり判定
for (i=1; i<=40; i++) {
bx = eval("block" add i)._x;
by = eval("block" add i)._y;
if (ball._x>bx-20-5 && ball._x<bx+20+5 && ball._y>by-5-5 && ball._y<by+5+5 && eval("block" add i)._visible == true) {
eval("block" add i)._visible = false;
// 左端or右端に当たった場合
if (ball._x<bx-20 || ball._x>bx+20) {
vx = -vx;
} else {
// 上端or下端に当たった場合
vy = -vy;
}
}
}

// ---残っている(表示されている)ブロックの有無を取得---
// 変数 visible_block の初期化
visible_block = 0;
//ブロックの個数分ループ
for (i=1; i<=40; i++) {
//もし block○ の _visible が true であれば
if (eval("block" add i)._visible) {
// 変数 visible_block の値を 1 にする
visible_block = 1;
//即この for 文を抜ける
break;
}
}
// もし変数 visible_block の値が 0 のままであれば
if (visible_block == 0) {
// フレーム5 へ行って停止
gotoAndStop(5);
}

// ボールが下に落ちたらゲームオーバー (★ココへ移動)
if (ball._y>235) {
gotoAndStop(4);//元々移動先が1フレーム目だったのを新たにつくった4フレーム目に変更しました。
}
//-------------------------------------
    • good
    • 0
この回答へのお礼

BlurFiltanさん、詳しいご回答有難うございます。
やはり// ボールが下に落ちたらゲームオーバー の部分下に移動させるべきだったのですね。
ついに実現できました。
私のような初心者にも分かるご説明、有難うございました。
本当に助かりました。

お礼日時:2013/06/26 20:29

スクリプトだけでは不明な点が多く


こちらで全く同じようなものを作って再現することはできませんが
書かれていらっしゃるスクリプトが
もし仮に フレーム3 に書かれたものであるとするなら
書かれていらっしゃるスクリプトの続き(下)にでも
次のようなスクリプトを付け足せば良いのではないかと思います。




// ---残っている(表示されている)ブロック数のカウント---
// 変数 visible_block の初期化
visible_block = 0;
//ブロックの個数分ループ
for (i=1; i<=40; i++) {
//もし block○ の _visible が true であれば
if (eval("block" add i)._visible) {
// 変数 visible_block をカウントアップ
visible_block++;
}
}
// もし変数 visible_block の値が 0 のままであれば
if (visible_block == 0) {
// フレーム5 へ行って停止
gotoAndStop(5);
} else {
//それ以外はループ再生
//(実際にはどう書いているのか不明)
gotoAndPlay(2);
}



最後の

//それ以外はループ再生
//(実際にはどう書いているのか不明)
gotoAndPlay(2);

この部分は
実際にはどのようなものを作られているのか知りませんから
本当はどう書くべきかなどわかりません。
(そもそもご質問に,どこに書かれたスクリプトなのかという説明が全くありませんし。)



上記スクリプトは
あくまでも考え方の一例です。
考え方をわかりやすくするために残っているブロック数をカウントしているだけです。

わざわざ残っているブロック数を全てカウントアップしなくても
eval("block" add i)._visible が true であるものが1つでも見つかった瞬間に
visible_block を 1 にでもして
その後すぐに break; しても良いと思います。
これの方が無駄な演算は少なくできます↓。


// ---残っている(表示されている)ブロックの有無を取得---
// 変数 visible_block の初期化
visible_block = 0;
//ブロックの個数分ループ
for (i=1; i<=40; i++) {
//もし block○ の _visible が true であれば
if (eval("block" add i)._visible) {
// 変数 visible_block の値を 1 にする
visible_block = 1;
//即この for 文を抜ける
break;
}
}
// もし変数 visible_block の値が 0 のままであれば
if (visible_block == 0) {
// フレーム5 へ行って停止
gotoAndStop(5);
} else {
//それ以外はループ再生
//(実際にはどう書いているのか不明)
gotoAndPlay(2);
}



とにかく
block○(block1~block40) の全ての _visible が false になったときに
通常のループ再生から抜け出て(通常のループ再生はさせないようにして)
gotoAndStop(5);
させるように考えれば良いでしょう。

この回答への補足

説明が不十分で申し訳ありませんでした。補足させていただきます。
元々からスクリプトは少々いじっておりますが、
3フレームまであり1フレーム目がスタートボタンのある場面でフレームには
//ボールの初期移動量
vx = 7;
vy = 7;
stop();
と言うスクリプト、スタートボタンは、
on (press) { //元々から操作方法は変更しました。
gotoAndPlay(2);
}
というスクリプトになっています。

また、2と3フレーム目には、40個のブロックとパドルとボールがあり、
2フレーム目のスクリプトが最初に記載した
// ボール移動
ball._x += vx;
ball._y += vy;
// 壁とボールの当たり判定
if(ball._x<5 && vx<0){
vx = -vx;
}
if(ball._x>235 && vx>0){
vx = -vx;
}
if(ball._y<5 && vy<0){
vy = -vy;
}
// ボールが下に落ちたらゲームオーバー
if(ball._y>235){
gotoAndStop(4); //元々移動先が1フレーム目だったのを新たにつくった4フレーム目に変更しました。
}
// パドルとの当たり判定
if(ball._x>pad._x-40-5 && ball._x<pad._x+40+5 && ball._y>pad._y-5-5 && ball._y<pad._y+5+5 && vy>0){
vy = -vy;
vx = (ball._x-pad._x)/80*15;
}
// ブロックとの当たり判定
for (i=1; i<=40; i++) {
bx = eval("block" add i)._x;
by = eval("block" add i)._y;
if (ball._x>bx-20-5 && ball._x<bx+20+5 && ball._y>by-5-5 && ball._y<by+5+5 && eval("block" add i)._visible == true) {
eval("block" add i)._visible = false;
// 左端or右端に当たった場合
if (ball._x<bx-20 || ball._x>bx+20) {
vx = -vx;
} else {
// 上端or下端に当たった場合
vy = -vy;
}
}
}
そして3フレーム目のスクリプトが
gotoAndPlay(2);
になっています。
また、ブロックのインスタンス名はご想像どおりblock1~block40が付けられています。
そこに新たにリプレイボタンの付いたゲームオーバー画面の4フレーム目とクリア画面の5フレーム目を作りました。
もちろんフレームのスクリプトは両方とも
stop();
で、リプレイボタンは
on (press) {
gotoAndPlay(2);
}
となっています。

この状態で、ご回答いただいたスクリプトの追加を両方試してみたのですが、
// ボールが下に落ちたらゲームオーバー
if(ball._y>235){
gotoAndStop(4);
}
このスクリプトがきかなくなるのか、
ボールが下に落ちると5フレーム目のクリア画面に移動してしまいます。
追加する位置が悪いのではとも考えたのですが、良く分からず困っています。
どうか宜しくお願い致します。

補足日時:2013/06/26 03:15
    • good
    • 0

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