![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?8acaa2e)
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については初心者であまり詳しくなく、本当に恥ずかしい限りです。
どうかお解かりになる方おりましたらお力をお貸し下さい。
宜しくお願い致します。
No.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フレーム目に変更しました。
}
//-------------------------------------
BlurFiltanさん、詳しいご回答有難うございます。
やはり// ボールが下に落ちたらゲームオーバー の部分下に移動させるべきだったのですね。
ついに実現できました。
私のような初心者にも分かるご説明、有難うございました。
本当に助かりました。
No.1
- 回答日時:
スクリプトだけでは不明な点が多く
こちらで全く同じようなものを作って再現することはできませんが
書かれていらっしゃるスクリプトが
もし仮に フレーム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フレーム目のクリア画面に移動してしまいます。
追加する位置が悪いのではとも考えたのですが、良く分からず困っています。
どうか宜しくお願い致します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) Pythonでのかんたんな物理シミュレーションについての書籍 5 2023/06/02 07:37
- その他(プログラミング・Web制作) 物理の斜方投射で目盛りに数値を入れたい 2 2023/05/27 06:32
- その他(プログラミング・Web制作) 物理の斜方投射の目盛り線とx軸、y軸の追加について 3 2023/05/26 21:11
- その他(プログラミング・Web制作) ボールの動きがスムーズに動いてかつ目盛り線描画を維持するためには 4 2023/05/31 10:01
- その他(プログラミング・Web制作) Pythonにおける物理のシミュレーションでの単位変換について 2 2023/06/02 17:11
- 物理学 英語表現についてどうもわからないので教えて貰えないでしょうか? 具体的には以下の文の中でreflec 1 2023/04/29 20:59
- その他(プログラミング・Web制作) Pythonによる物理の斜方投射の位置座標表示について 2 2023/06/05 12:46
- 英語 英語の形容詞句と副詞句 3 2022/05/14 23:35
- アニメ dragon ball superのキャラクター 1 2022/10/20 15:14
- その他(プログラミング・Web制作) 物理の斜方投射のシミュレーションにおける位置や速度の単位について 4 2023/05/31 09:50
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Flash Lite1.1について
-
Flashで右クリックメニューにつ...
-
ComboBoxの設定方法
-
gotoAndPlayでシーンの移動
-
CupCatの使い方
-
シンクライアントとMetaFrameの...
-
KSR2 車体番号
-
【C#】wavファイルの複数同時再生
-
フレーム内に移動したい
-
メガネのフレームが半分に折れ...
-
SDHCカードのデータをPCに取り...
-
リフレッシュ・レート、フレー...
-
オプションボタンを矢印キーで...
-
画像のフェードイン
-
フレームをまたいだ背景画像の...
-
actionscript3.0で親階層にある...
-
ページの切り替えのフェードイ...
-
ニュースティッカーの作り方
-
Gifアニメの再生について(検索...
-
パワーポイントにFLASHを埋め込...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
WEBブラウザの重複起動の禁止
-
AS3.0で子MCから他の子MCの...
-
Math.ramdom()を特定回数繰り返す
-
ループ再生のflashをタイムライ...
-
ASではどうやって記述するのか
-
Excel VBA SetFocus
-
フラッシュ初心者ですが
-
Smartyのテンプレートについて
-
ActionScriptで関数とは?
-
Flash lite1.0の計算クイズ
-
プルダウンメニューとフェード...
-
Error#1009 時計のシーン移動ボ...
-
秒と同期してMCを動作させる方法
-
as3 SharedObjectクラスを使用...
-
actionscriptでfor文が正常に動...
-
ムービーの早送りと巻き戻しが...
-
xmlから配列で取得したものを取...
-
FLASH LITE1.1のテキスト入力に...
-
ボタンとASが1フレーム目にない...
-
loadMovieで読み込んだswf
おすすめ情報