てとりす
投稿者 : たちこう(kd125028206095.ppp-bb.dion.ne.jp)
- 2011/04/24(Sun) 20:50
No.12966
|
|
|
|
|
こんにちは。 いつもいつもBBSをぶんどってしまい、 もうしわけありません。 また、返信していない記事がいくつかあり、 もうしわけありません。m(_ _)m
現在、途中であきらめた・飽きたプログラムが沢山あり、 プログラムの墓場が完成しつつありますが、 ブロックを使ったテトリスみたいなものを作っています。
積み上げて、一列揃ったら消す、みたいな所までいったのですが、 消えた後、全体が一列下に落ちる、みたいのがうまくいきません。 ちなみにまだ試作状態で、四つ直線状の(■■■■)テトリミノしかでてきません。
|
Re: てとりす
投稿者 : たちこう(kd125028206095.ppp-bb.dion.ne.jp)
- 2011/04/24(Sun) 21:16
No.12967
|
|
|
|
分かりにくいと思うので、 分かりにくい絵を添えます。
□ □ □ □ □ □ □ ■ □ □ ■■ □ □■■■■■□←揃う □□□□□□□ ↓ □ □ □ □ □ □ □ ■ □ □ ■■ □ □ □←消える □□□□□□□ ↓ □ □ □ □ □ □ □ □ □ ■ □ □ ■■ □←落ちる □□□□□□□
|
Re: てとりす
投稿者 : たちこう(kd125028206095.ppp-bb.dion.ne.jp)
- 2011/04/24(Sun) 21:24
No.12968
|
|
|
|
あと、言い忘れましたが、 まだ、一番下の列しか反応しません・・。
添えるプログラムで分かってもらえるとうれしいのですが、 下から二列目より上の列が揃っても消えません。
一列目のマスを監視して、どれも空気でなくなると(ブロックが入ると) 消えます。
このままいくと全てのマスを監視しなくてはならなくなり、 めんどくさいです。
簡単な方法を知っている方がおりましたら、 教えてください。
分かりにくくてすみません。
extends SecretChar; s=18; while(1){ while($ok==1){ //ブロックが下についたら。 if( $map.get(1,s)!=$pat_tile+5 && $map.get(2,s)!=$pat_tile+5 && $map.get(3,s)!=$pat_tile+5 && $map.get(4,s)!=$pat_tile+5 && $map.get(5,s)!=$pat_tile+5 && $map.get(6,s)!=$pat_tile+5 && $map.get(7,s)!=$pat_tile+5 && $map.get(8,s)!=$pat_tile+5 && $map.get(9,s)!=$pat_tile+5 && $map.get(10,s)!=$pat_tile+5 && $map.get(11,s)!=$pat_tile+5 && $map.get(12,s)!=$pat_tile+5 && $map.get(13,s)!=$pat_tile+5 && $map.get(14,s)!=$pat_tile+5 ){ $map.set(1,s,$pat_tile+5); $map.set(2,s,$pat_tile+5); $map.set(3,s,$pat_tile+5); $map.set(4,s,$pat_tile+5); $map.set(5,s,$pat_tile+5); $map.set(6,s,$pat_tile+5); $map.set(7,s,$pat_tile+5); $map.set(8,s,$pat_tile+5); $map.set(9,s,$pat_tile+5); $map.set(10,s,$pat_tile+5); $map.set(11,s,$pat_tile+5); $map.set(12,s,$pat_tile+5); $map.set(13,s,$pat_tile+5); $map.set(14,s,$pat_tile+5); } update(); } update(); }
|
ループ
投稿者 : リセッタ(em1-112-182-203.pool.e-mobile.ne.jp)
- 2011/04/25(Mon) 12:48
No.12969
|
|
|
|
たちこうさんのプログラムってコピペが多くてくどい。 ループやメソッド化をして可読性を上げる様にしたほうがよい。 ※ 画面の大きさ変えたりする度に、判定増やしたり減らしたり あちこちいじるの面倒じゃないの?バグも出やすいと思うんだけど?
ヒント
n枚のお皿があります。 お皿には果物が一つだけ乗せられるとします。 みかん・りんごを沢山用意しました。 適当にお皿の上に果物を乗せていきました。 全部のお皿に果物が乗っているとき、お皿に乗っている果物は幾つあるか?
行が埋まっているとは↑の状態だろ?
|
トップダウンで設計
投稿者 : リセッタ(em114-48-91-126.pool.e-mobile.ne.jp)
- 2011/04/25(Mon) 18:51
No.12970
|
|
|
|
プログラムを効率的かつ保守しやすい設計方法としてトップダウンがあります。 やり方は簡単です。 大まかに処理の流れを記述。その処理を少し細かく記述。 少し細かい処理をさらに細かく記述……として完成させて行きます。 処理の記述をメソッドにすれば、可読性が上がります。
1.大まかな流れ extends SecretChar; initial(); // 初期化処理 while(1){ if($gStep==0) { mkBlock(); $gStep=1; } // ブロック作成 else if($gStep==1) { if(mvBlock()) $gStep=2; } // ブロック移動(ブロックオブジェクト) else if($gStep==2) { chBlock(); $gStep=0; } // ブロック判定 update(); } function initial() {} function mkBloack() {} function mvBloack() {} function chBloack() {}
2.少し細かく function initial() { $gStaep=0; blockTypeSize=1; $Block=null; } function mkBloack() { var t; t=rnd(blockTypeSize); $Block=appear(new Block(t)); // ブロックオブジェクト作成 } function mvBloack() { var r; r=0; if($Block.isDied) { // ブロックオブジェクト終了? $Block=null; // (最終行まで行った?) r=1; } return r; } function chBloack() { chLine(10); // 10行目チェック&削除 } function chLine(l) {}
3.さらに細かく function chLine(l) { if(isFill(l)) { // 指定行が全て埋まっているなら clLine(l); // 行を消す } } function isFill(l) {} function clLine(l) {}
という風に記述すれば、自然にトップダウンになる。
|
Re: てとりす
投稿者 : Percentage(p39206-ipngn1002souka.saitama.ocn.ne.jp)
- 2011/04/25(Mon) 22:48
No.12971
|
|
|
|
んー...昔「横一列ブロックで埋まったら全部die」ていうプログラムを作った感じがしますが...。どうでしょう↓ (ブロックが接地したと考えてください){ ty = trunc(y / 16);//16はマップチップ(ブロック)の大きさです。 block_line = 0; for(tx = 1; tx <= 11; tx++){ if($map.get(tx, ty) == -1){ block_line = 0; break; } } //ここでblock_lineが1ならこの横列は埋まったことになります。
あと、プログラムの書き方。 どうも無駄な部分が多い気がします。 ゲームプログラムは速さが命。 リセッタさんみたく関数で小分けしてもいいけど、関数呼び出しは基本的に遅いです。引数を積んで、帰る先の番地を積んで、関数に飛ぶわけですから。 その点、ループを使うのは有利。 ループ(特にwhile)であればループ内の先頭に飛んでしまえばいいだけですから、楽ですし速いです。 特に、関数の中身が1行とかそれ相応になってしまう小規模なものであれば、関数は使う必要は無いと考えてください。 あと一応言っておきますが、ゲームプログラムにおいて「保守的」は二の次です。逆に動作効率が悪くなってしまっては本末転倒ですから。つまり可読性をあげるならコメントで十分です。 それよりもアピールする点といえば、「どれくらい速く動いてくれるか」だと思います。 長文失礼。
|
Re: てとりす
投稿者 : Percentage(p39206-ipngn1002souka.saitama.ocn.ne.jp)
- 2011/04/25(Mon) 23:00
No.12972
|
|
|
|
追記: 関数を乱発する(つまり使いすぎる)と、逆に「本処理どこだっ!!(汗」みたいなことになりかねません。 あとコード読むのが逆に面倒になることもあります(少なくとも私は)。ソースコード中のいろいろなところに処理が飛ぶので。最悪、クラス間を飛び越えることもあり、ますます面倒になります。 Tonyuのエディタ自体がctags的な能力を持つとこの問題は解消されるかもしれません。 流石にVisual Studio並のエディタの機能(リファクタ)までは要求しませんが。
|
メソッド化
投稿者 : リセッタ(em111-188-62-58.pool.e-mobile.ne.jp)
- 2011/04/26(Tue) 01:28
No.12973
|
|
|
|
12970 訂正 (誤)処理の記述をメソッドにすれば、可読性が上がります。 (正)処理の記述をメソッドにすれば、保守性が上がります。
>リセッタさんみたく関数で小分けしてもいいけど、関数呼び出しは基本的に遅いです。引数を積んで、帰る先の番地を積んで、関数に飛ぶわけですから。
遅いと感じる程、オーバーヘッドは大きくないよ。
※ メソッドを使わない場合は、処理単位毎にコメントを入れる
while(1) { if(gStep==0) { //=ブロック作成========= t=rand(blockTypeSize); $Block=appear(new Block(t)); gStep=1; } else if(gStep==1){ //=ブロック移動中======= : : (以下略)
速さよりまず完成(動作)させることが大事だと思う。 たちこうさんレベルで速さをうんぬん言うよりまず動作させることが大事。 ゲームプログラミングより、まずプログラミングができなきゃ意味がないよ。 速度向上は、動いてからメソッドの中身を呼び出し元で展開すればいい。 それでもだめならループも展開。それでだめなら処理方法がだめなのだから設計の見直しです。 数をこなして行けば自然とどの程度までメソッドにするべきかは覚える。
あくまで設計段階の話で、最終ソースではありません。 設計中は、汎用性、拡張性を考慮してメソッド化する方がいい どうせ思いつきで仕様がころころ変わるんだから。
メソッドの多用は、逆に可読性を下げるのを心配してますが、 ソースの記述順をメイン・サブ・各処理ルーチンにしてコメントを書く様にすればそこそこ読めるはず。
# サンプルのプログラムじゃ動かないよ。初期設定block_lineは1にしなきゃ # 自分ならtxが11より大きいかどうかで判定しちゃうけどね。>Percentageさん
|
Re: てとりす
投稿者 : Precentage(p39206-ipngn1002souka.saitama.ocn.ne.jp)
- 2011/04/27(Wed) 19:55
No.12974
|
|
|
|
>リセッタさん すいませんその通りです。 ループ前のblock_lineは1に設定して下さい。
また保守性を上げるとはいっても、いくらなんでも初期化処理までメソッドにする必要はないと思います(ただしクラスを継承して、継承元で共通の初期化をしたいという場合を除く)。 Tonyuのエディタにはctags機能がないため、一度関数の記述場所をミスると一気に可読性が下がります。 初期化処理なんて、所詮は変数への代入やArray::add()の羅列。 プログラムの頭にくっつけておけば一目で初期化処理と分かります。 作成中は仕様がころころ変わると言っても、完全に同じ初期化処理がない限り変数への代入やArray::add()を1行つけ足せばいいだけの話です。
>たちこうさん あるブロックの下が空白になったら自動で落ちる、というプログラムはすでに完成しているのですよね?
|
Re: てとりす
投稿者 : たちこう(kd125028206095.ppp-bb.dion.ne.jp)
- 2011/04/27(Wed) 21:44
No.12975
|
|
|
|
忙しくて返信が大変遅れてしまいました。
僕の場合、 動けばいいんだろ、動けば。 みたいな感じでやってるんで、 読みにくいし すぐバグるので、 めんどくさくなってすぐやめます。
簡単なプログラムをコピペ多用して動かしていたので、 ちょっと難しい(?)プログラムは分かりません(T_T)
ぶっちゃけて言うと、 メソッド化 や function らへんは分かりません。 for文もつい最近知りました・・。
ですので、できる限り簡単に解説をお願いします。
〜〜今からやりたいこと〜〜 一列揃ったら消す。消したらテトリスみたいに、一列分下がる。
ブロックがオブジェクトなら簡単(?)そうなんですが、 mapを使うと訳が分からなくなってしまいます。
どうか返信お願いします(T_T)
|
行下げ(行単位)
投稿者 : リセッタ(em1-112-42-201.pool.e-mobile.ne.jp)
- 2011/04/27(Wed) 23:19
No.12976
|
|
|
|
行単位で移動なら下の様に上のチップを移動させればいいんだよ。
●●●● ●●●● ●●●● ●●●● ●●●● ●●●● ●●●● ●●●● ●●●● ●●●● ●●●● ●●●● ○●●● ○○●● ●●●●→○●●●→○○●●→○○○●→○○○○→● ●● ● ●● ●●● ●●●● ●●●● ●●●●
※ 但し、最上段は空白行を入れる。
たとえば、 こんな感じ?
// 行が埋まっていたら、一つ下に移動する // l,t,r,b: ゲーム画面範囲(左上右下) // s: 空白パターン番号 function ckLine(l,t,r,b,s) { var x,y; for(y=t; y<=b; y++) { for(x=l; x<=r; x++) { if($map.get(x,y)==s) break; } if(x>r) mvLine(l,t,r,y); // 埋まっていた(空白無)→その行からtまで行下げ } } // 行下げ // l,t,r,b: 移動範囲(左上右下) // s: 空白パターン番号 function mvLine(l,t,r,b,s) { var x,y; for(y=b; y>t; y++) { // 下から2行目まで for(x=l; x<=r; x++) { $map.set(x,y,$map.get(x,y-1)); } } for(x=l; x<=r; x++) { $map.set(x,t,s); } }
|
メソッド化手順
投稿者 : リセッタ(em1-112-42-201.pool.e-mobile.ne.jp)
- 2011/04/28(Thu) 00:34
No.12977
|
|
|
|
Re: てとりす
投稿者 : たちこう(kd125028206095.ppp-bb.dion.ne.jp)
- 2011/04/28(Thu) 19:23
No.12978
|
|
|
|
すみません。 色々答えて頂いたのに、 自己解決してしまいました。
すごく汚いプログラムになってしまいましたが、 なんとか行けそうです。
もっと勉強して、 レベルを上げていきます。
|
|