• ベストアンサー

C言語ゲーム製作途中(勉強中)

プレイヤーが画面を四方八方に移動まで。コードを一通り見ていただきたいです 現在、定番で見やすいプログラムを意識しています。又、今後質問が宜しく願います 以下よりダウンロードです(実行ファイル、ソースコード(234行)等) http://gamdev.org/up/img/10376.lzh 環境 OS:VISTS、統合開発環境:VC++2005 EE、言語:C ライブラリ:DXライブラリ、画像エディタ:ペイント、 自動作曲:Random various music v1.5、MP3変換ソフト:iTunes 聞きたい優先順位(下に行くほど無視してもよいです) (1) 関数名(頭は大文字)、変数名(全て小文字、アンダーバー使用)、グローバル変数名(g_をつけたほうがいいのか…)、 などの区別化 関数分け(他の方法)、マクロ定義名(名称つけ方がよくない等) (2) 関数ごとのヘッダコメント。用途と引数くらいは書いたほうがいいのか (3) ウインドウのアクティブ、非アクティブで一時停止と再生の処理の仕方 動作はうまくいっているようですがやり方は正しいのか DXライブラリを使っていますが、コメントで大体理解できると思います 他に気になった点、こうしたほうがいい等、色々な意見を願います <(_ _)>

質問者が選んだベストアンサー

  • ベストアンサー
  • precog
  • ベストアンサー率22% (966/4314)
回答No.2

まず一般論。 ・コードを見てわかるような事をコメントする必要は無い。 ・名前もコメントの一部。 ・書法に頼りすぎりるとバグを見逃す。(g_がついてないのでローカルだと思い込んでいた等) ・コメントはコードを読むときの手助けになるような、より上位の概念を中心に書く (コードを読むときの前提情報や、他のモジュールとのつながりを示唆するもの) > #include <stdio.h> //fopen,fclose,fwrite > #include <math.h> //sqrt ここのコメントは有害。 まず、ソースの読解を助けていない。 必要なら呼び出し関数は機械的に検出可能である。 さらに、このコメントが正しいことを将来にわたって保証することはできない。(大いなる無駄な作業が発生する) > //マクロ定義 このコメントも上記同様。 定数の定義はマクロという意識は通常無い。 > #define DIV_IMAGE_NUM 24 //画像分割数 > #define IMAGE_X_SIZE 32 //画像サイズ > #define IMAGE_Y_SIZE 32 > #define IMAGE_SIDE_NUM 6 //分割画像縦横の数 > #define IMAGE_LENGTH_NUM 4 ここのコメントも意味が無い。 定数名は、名が体を現していない点で表現として弱い。名前が属性しか表してない。ここだけ読んで何を決めているのかわかるだろうか? 説明が長くなるなら、プロなら設計書を書くので、それとリンクする名前にすればよい。 > #define P_START_POSI_X 290 //プレイヤースタートポジション > #define P_START_POSI_Y 200 ここは固定で良いのか? ↓の画面サイズとリンクすべきでは? これは書法というよりバグに近い。 > #define DISP_MODE_SIZE_X 640 //ウインドウ画面モードサイズ > #define DISP_MODE_SIZE_Y 480 > //構造体定義 構造体の定義をしているのは見ればわかる。なんの構造体を定義しているのか等を書かないと意味が無い。 > struct player > { > int px; //x位置 0-35(4byte)。小数点単位で移動 バイト数は通常処理系依存。こう書かれると4byteでないといけない理由があるのかと心配すると同時に、並び順にも依存があるのではないかと疑いたくなる。 整数なのに、「小数点単位で移動」というのも意味がわからない。(実数でも意味がわからないですけど) > int py; //y位置 0-17(4byte) > int pspd; //スピード 1-2(4byte) > int direc; //向き、方向 向きは、マジックナンバーになるので定義が必要になるのではないか? > //float ptx; //弾x位置 0-35(4byte) > //float pty; //弾y位置 0-17(4byte) > //char ptflg; //弾発射フラグ 0-1(1byte(アライメントのためパディング効果4byte)) > }; このパディングは恐らく意味が無いが、そもそも何故必要なのか? バグの予感がする。 > //グローバル変数 > int m_count = 0; //ゲームが終了するまでカウント > > int ikey_up = 0; //上キーフラグ > int ikey_down = 0; //下キーフラグ > int ikey_left = 0; //左キーフラグ > int ikey_right = 0; //右キーフラグ > > > //プロトタイプ宣言 通常ソースの中にプロトタイプは書かない。子を上に書くか、外部から呼び出しがあるならヘッダーファイルに含めることで兼用可能。 > // プログラムは WinMain から始まります > int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, > LPSTR lpCmdLine, int nCmdShow ) > { > struct player ply; //XXXbyte、プレイヤー このコメントも有害。 > InitFunc( &ply ); //初動時の初期化 関数の説明を呼び出し側で書くのはおかしい。このコメントも有害。 開発環境を使って読めば、すぐになんの関数なのかはわかる。 > if( DxLib_Init() == -1 ) return -1; // DXライブラリ初期化処理、エラーが起きたら直ちに終了 読めば分る。有害なコメント。 > int strclr = 0; 処理の途中で宣言するのはあまり良い習慣ではない。通常、Cのプログラマーはローカル変数は関数の先頭に書かれる物と思っている。バグ見逃しの可能性が高い。 > //今回のように、ループ処理には必要。ProcessMessage 関数はDXライブラリが > //Windows というマルチタスクOS上で動作するために必要不可欠な関数です。-1ならループを抜ける > //システムから送られてくる指令や情報を常に監視し、それを処理しなくてはなりません > //ProcessMessage 関数をただ実行するだけです。OSから送られてくる情報を処理して帰ってきます。 > > //ウインドウがアクティブではない状態でも処理を続行するか、フラグをセットする メインの処理は説明が多くなりがちなのは仕方なく、書くべきかどうかは微妙だが、ここがイベントループであるという程度のコメントで十分伝わるのでは? メインの中に長く書きすぎ。初期化とメインと終了処理の三つに分解して関数にしたほうが見通しがよくなる。 > //キー入力 > void KeyBoard( void ) キーをグローバル変数で共有すると、デバイスに依存したコードがあちこちに散らばることになる。一旦、内部メッセージに置き換えたほうが変更/拡張しやすいブログラムになる。 > //プレイヤー > void PlayerSyori( player *ply, int *pkenGraph, int *strclr ) > { > //1ボタン有効30回ループ分 > //6*4:0~5(正面)、6~11(右)、12~17(左)、18~23(上) > //0~1(徒歩)、2~3(剣を出す途中)、4~5(剣を出した) > > // 左に移動 > if( ikey_left == 1 ) > { > ply->px -= 2 ; > if( ply->px < 0 ) ply->px = 0 ; // プレイヤーが画面左端に来たときの処理 > > if( (m_count % 10) < 5 ) ply->direc = 12; > else ply->direc = 13; > } > // 右に移動 > if( ikey_right == 1 ) > { > ply->px += 2 ; > if( ply->px > 640 - 32 ) ply->px = 640 - 32 ; // プレイヤーが画面右端に来たときの処理 マジックナンバーが入っている。なんのために定数定義したのか? ☆全体的に マジックナンバーが多いです。全部定数定義にしましょう。メンテする人 (他人) は通常、関数の中を書き換えることなく変更したいのです。 エラー後処理が入ってない。練習としてはこれでよいが、安定したPgを作れるようになりたいなら、そこをきっちりコーディングできる必要がある。それと、CではなくC++でコーディングしたほうが、可読性 / メンテナンス性の高いコードが書けますけど、、、 これは先の話で良いですが、読み込むデータ数をハードコーディングするのはおかしいです。本来、提示されたデータから読み取るべき。恐らく、データ数があわないデータを与えられると暴走するのでは?

wdam7
質問者

お礼

指摘を受けての今後の改善点。多くの意見を感謝です! ・自分のコメントのつけかた。不必要が多すぎ、コードないでの  コメントの必要性を認識する。プログラムを書く上での思考レベルの修正。やはり必要最低限か… ・グローバル変数名のつけ方g_以外で検討してみる ・メンテナンスで将来保障できる柔軟なプログラムになるか ・定数名で名が体を現していない。わかりにくい。プログラム設計書とリンクする形でもOK ・画面サイズとプレイヤーの位置のリンク ・構造体の意識は大きく改善すること。コメントについては昔のが残っていました。すみません  マジックナンバーというのは数字(定数)と理解しました ・プロトタイプは一つのファイルという前提があったのであえて入れていました。 ・関数説明は本体で ・ローカル変数は関数先頭で ・ここがイベントループであるという程度のコメントで十分伝わるという方向で対応 ・メインを関数3分割で ・>キーをグローバル変数で共有すると、デバイスに依存したコードがあちこちに散らばることになる。  >一旦、内部メッセージに置き換えたほうが変更/拡張しやすいブログラムになる。  どういうことか…もう一度コードを見直します。改善の方向で確認   ・プレイヤー処理で>マジックナンバーが入っている。なんのために定数定義したのか?   ・>☆全体的に メンテを考えマジックナンバー(数字の定数)は全て定数定義にしたほうがいいのですね。了解です  エラー処理を対応の方向で ・C言語がある程度できたらC++に移行したいです ・>これは先の話で良いですが、読み込むデータ数をハードコーディングするのはおかしいです。  >本来、提示されたデータから読み取るべき。恐らく、データ数があわないデータを  >与えられると暴走するのでは? ・これはどういうことだろう。もう少し見直します。 ここまでコードの悪いところを全て教えてくれたと思います。…自分でもある程度意識はしていたが… 指摘内容がすばらしく個人的には、ありがとうポイント2000以上はあげてもいいくらいです。 もう、なんというか、ありがとうございました!

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.3

プロでだと確かに突っ込み所は多いですが、 勉強中でこのレベルまで書ければ、 後はルールと慣れという感じがします。 がんがんコードを書いていくと良いと思います。 他の方が指摘している部分はある程度のけて、 こんな風にやるとすっきりするかも、というレベルで書きます。 列挙型を使うかと結構まとまりやすいかも。 例えば「独自型」とか typedef enum {  PLAYER_DIR_DOWN = 0,  //間に追加すれば段階も分けられる  PLAYER_DIR_RIGHT = 6,  PLAYER_DIR_LEFT = 12,  PLAYER_DIR_UP = 18, }PLAYER_DIR; int direc;//向き、方向 ↓ PLAYER_DIR direc;//向き 列挙型にすることでtypedefで型を作れる為、 direcにPLAYER_DIR型以外が代入されたら、 コンパイルの時点で警告を出したりすることができます。 注意が要るのは、ありふれた名前で定義すると、 他とかぶる可能性があること。 キーフラグがありますが、 ボタンが増えるといろいろ大変。 typedef enum {  KEY_UP = 0,  KEY_DOWN,  KEY_LEFT,  KEY_RIGHT,  //ここに追加するとフラグの配列も勝手に増える。  KET_MAX, }KEY_IDX; int KeyStat[KET_MAX]; KeyStat[KEY_UP]; //上キーフラグの参照 こんな感じでしょうか。C言語での連想配列風な感じです。 あと終了処理の関数はDxLib_End関数を呼び出しているだけですが、 これをやるのであれば、終了する前にやる処理をEndFunc関数で 書いて、DxLib_End関数はWinMainで呼んでも問題ないかなと思います。 移動量、せっかくスピードメンバがあるのにもったいない :-(

wdam7
質問者

お礼

勉強中というか長い間やってはいます コードをすっきりする列挙型(向き、キー)を使い慣れていないため 少し使い方を調べて使いたいと思います。 >終了する前にやる処理をEndFunc関数で >書いて、DxLib_End関数はWinMainで呼んでも問題ないかなと思います。 その処理があれば対応します >移動量、せっかくスピードメンバがあるのにもったいない どいうことか…見直して対応します ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
  • morigann
  • ベストアンサー率17% (57/329)
回答No.1

はっきり言って、めちゃくちゃ良く出来てますね。 (質問者様は学生さんでしょうか?将来有望です) で、解答ですが 1:関数名や変数名に「絶対」という名前の付け方はありません。   質問者様がルールを決めて付けられたら良いと思います。   今後、会社等でお仕事されるでしょうがその時はその会社のルールがありますし。 2:そうですね、概要説明、引数、戻り値、禁止事項、引数不正時の処理などぐらいは書いておいた方が便利かと思います。 3:これは自分には分かりません 以下、あげ足取りみたいな指摘事項ですが気付いた点を上げておきます。 4:PlayerSyori内で画面端判断にdefineを使用していないのは意図的?   (移動量の2もdefineにした方が今後便利と思う) 5:KEYを2つ同時押ししたら、押した人は違和感感じないか?(特に「上・下同時」「右・左同時」)   将来斜め移動のグラフィック作成時を考慮して今の作りになっている? 6:DrawFormatStringはPlayerSyoriの外の方が良くないかな?

wdam7
質問者

お礼

返答ありがとうございます。学生ではないです。 それなりに、C言語は長く学んでいます。 そして、一つ形にするのも、ものすごく時間が掛かるのです。要領が悪いと思われ… まだまだ未熟ですがゲームを通じて覚えようと思いました。 1、なるほど、そのシステムのルールで作ればいいのですね。 今回は自分でマイルールで!まぁ一般的にどうなのかなと思ったのです^^ 2、概要説明、引数、戻り値、禁止事項、引数不正時の処理 あーこの辺が重要ですね。了解です 4、気づいていたのですが…保留にしていました 5、画像が上下を向いているのに斜めに動くというのはゲームでたまにあったりするのでいいかなと… 個人的には違和感ないですが指摘で他の人にはあるのか…と気づきました 6、そうですね。ゲームシステム残りの時間という感じで外の方がよいと判断しました。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • C言語ゲーム製作中 ソース公開

    プレイヤーが画面を四方八方に移動までです。コードを一通り見ていただきたいです 現在、定番で見やすいプログラムを意識しています。又、今後質問が宜しく願います 以下よりダウンロードです(実行ファイル、ソースコード(268ステップ)等) http://gamdev.org/up/img/10406.lzh 環境 OS:VISTS、統合開発環境:VC++2005 EE、言語:C ライブラリ:DXライブラリ、 ----------------------------------------------------------------- 前回の質問時の修正としてコメント、マジックナンバー、メイン3分割等を行った。 ファイルは分割せずに1ファイルにまとめています。 ----------------------------------------------------------------- 聞きたい優先順位(下に行くほど無視してもよいです) 1: 以下の164行目と166行目のマジックナンバーを#define or typedef enum or それ以外の方法はあるのか…           赤、緑、青 SetTransColor( 255 , 255 , 255 ) ; // 透過色を変更 *strclr = GetColor( 255 , 255 , 255 ) ; // 白色の値を取得 2: WinMain関数で多くのローカル変数を宣言しているが他の関数でやったほうがいいか struct player ply や int KeyStat[KET_MAX] を他のローカルで宣言するとstaticに しなければいけないとか考えてしまいます。メインで宣言したほうが都合が良さそうと思っていますが… 他に気になった点、こうしたほうがいい等、色々な意見を願います <(_ _)>

  • C言語ゲーム製作(3)

    お世話になっています。 一般、定番的で見やすいプログラムを意識しています。(コメント等) 気になる所があれば意見を宜しくお願いします。 引数を減らすために関数化、マップの表示、キー入力、後は全般的に修正しました。 まだまだ力不足です。できれば具体的な意見を宜しく願いたいです。 ----------------------------------------------------------------- 以下よりダウンロードです(実行ファイル、ソースコード等) ****://gamdev.org/up/img/10414.lzh ----------------------------------------------------------------- 環境はOS:VISTA、統合開発環境:VC++2005 EE、言語:C、ライブラリ:DXライブラリ 過去の質問リスト C言語ゲーム製作途中(勉強中) (1) http://okwave.jp/qa3460149.html C言語ゲーム製作中 ソース公開 (2) http://okwave.jp/qa3470422.html ----------------------------------------------------------------- 聞きたい優先順位 1:関数の分け方と引数のやりとりが怪しいかも…OKならばファイル分割作業に入る予定です 2:KeyBoard関数で2つ以上ボタンが押されていたら クリアする処理は必要か(指摘があったため組み込み) 他に気になった点、こうしたほうがいい等、色々な意見を願います <(_ _)>

  • 現在C言語を勉強しています、以前はHSPでゲームをいくつか作りました。

    現在C言語を勉強しています、以前はHSPでゲームをいくつか作りました。 最近DXライブラリの存在を知ったのですがC言語の知識だけ使えるという事で興味がわきリファレンスページを見て簡単な物を作りましたが気になる事ができました。 今までは「printf」で文字を表示していたのですがDXライブラリだと「DrawString」で文字が表示できます。 今C言語で学んでいる事で「ライブラリ関数」で「rand」がありますがDXライブラリでも同じような「GetRand」があります。 条件やループなどは結構使用していますがそれ以外はC言語のサイトで学ぶのは無意味でしょうか?、DXライブラリを使用するのに「この部分を学べば(知っていれば)大丈夫」というのはあるのでしょうか?。

  • C言語ゲーム製作4 ソース公開 勉強中 ファイル分割

    お世話になっています。 前回より迷路のカドを移動しやすく修正、ファイル分割を重点的に対応しました。プレイヤーが十字方向に動くまでです。 (敵の処理は途中なので気にしないでください) ダウンロード(ソース10、ヘッダ10、その他)1.0M http://gamdev.org/up/img/10466.lzh 疑問点が以下の2点です ・関数定義のstaticの使い方 ・ヘッダーの取り込みの仕方がわからないコードの上で (#include "..\\include\\player.h")と記述している  メニューから設定するか、環境変数設定のようなのですが… まだまだ力不足です。他にも多々突っ込みどころがあると思います できれば具体的な意見を宜しく願いします<(_ _)>

  • C言語に関することについて教えてください

    学校の問題集にでてきた問題がわかりません、どうか教えてください 1 プログラムの役割、必要性について説明せよ 2 プログラムにおける変数と定数の役割を説明せよ。また、ローカル変数の有効な範囲について説明せよ。 3 C言語で使う変数が他について、宣言子と、printf関数、scanf関数それぞれにおいて対応する書式指定子を対応表にせよ。また、変数名を決める際に守るべき文法上の規則と、プログラマとして配慮すべき事項を説明せよ。 4 配列について、その役割と定義方法を説明せよ。 5 コンピュータにおける文字処理に必須なアスキーコードについて説明せよ。 6 C言語における文字列について、文字列定数、文字列変数を説明せよ。 7 C言語における繰り返し処理の文法(for,while,do~while)を、プログラムコード列を示して説明せよ。 8 C言語における条件判断の文法(if,else,else if)を、プログラム列を示して説明せよ。 9 繰り返し、条件判断において利用する論理式(等値演算子、関係演算子、論理演算子等で記迷する式)について、その記迷の方法を論理和、論理積も含めて説明せよ。 10 変数のアドレスについて説明せよ。また、ポインタについて、アドレスとの関連性を踏まえて、その役割と定義方法を説明し、具体的な使い方のプログラムコード例を示せ。 11 ポインタと配列の関係について、ポインタによる配列操作を列に説明せよ。 12 関数について、その役割と定義方法について説明せよ(戻りがた、関数名、引数リスト)。また、自作関数をそれらを利用するmain関数のプログラムコード例を示せ。 13 scanf関数の戻り値について、その内容を説明して、どのような際に利用すると便利か、プログラムコード例を示して説明せよ。 14 引数にポインタを利用する関数のプログラムコード例を示して、ポインタの必要性、重要性を説明せよ。 15 構造体について、その役割と定義方法を説明し、具体的な使い方のプログラムコード例を示せ。 16 ファイルポインタについて説明し、ファイル入出力の方法についてプログラムコード例を示して説明せよ。

  • C/C++言語で変数名から変数のアドレスを取得する

    C/C++言語で変数名から変数のアドレスを取得する方法があれば、ご教示願います。 例えばですが、関数GetProcAddress()は、関数の文字列からエクスポート済みの関数のアドレスを戻り値で返しています。 GetProcAddress()と同じようにアドレスを取得したい変数名の文字列を渡して、変数のアドレスを取得したいです。 よろしくお願いします。

  • c言語の変数一覧の取得

    c言語で書かれたコードについて、使われている変数名や関数名の一覧を取得することはできるのでしょうか? 何か方法がありましたら教えてください。

  • C++勉強中なんですが

    クラス等を使ってソースを書く練習中なのですが、思ったように結果が出ません。 #include<iostream> #include<string> using namespace std; class Cats { private://クラス「Cats」の中でのみ使う文字列の入れ物変数「name」を作る string name; public://クラス「Cats」の外からでも引数で呼び出せば使える Cats(string x)//クラスCatsの関数Cats(コンストラクタ)を使いますよって宣言 { name=x;//8行目で作った文字列の入れ物に変数xを入れる } void naku()//voidの意味が正確には分からないけど、何も返さないって意味らしいので、何も返さないnakuって関数を作る { cout<<"にゃっふぅーん、ボク、"<<name<<"ってゆーの。よろしくネ!"<<endl;//関数nakuが呼び出されると文字列を表示する } }; int main()//全体のプログラム { string x;//まず文字列の入れ物になる変数xを作る cout<<"今日新たな家族になるにゃんこが産まれました。"<<endl; cout<<"名前を決めてあげましょう!"<<endl; Cats aisatsu(x);//クラスCatsのメンバーaisatsuを作る(中身は文字列の変数x) cin>> x;//変数xにキーボードで書いた文字列を入れる aisatsu.naku();//メンバー関数のaisatsuがグローバル関数(クラスの外からでも呼べるはずw)nakuを呼び出す } cin>>x;で入力した文字がnameに代入されてないのか、表示されません・・・。 もし分かる方いたら是非教えていただきたいです。 あと、コメントアウトしてる部分なんですが、ここもおかしい認識があればご指摘いただきたいです。

  • ライブラリ作成時のグローバル変数の対応(C言語)

    C言語を用いてライブラリを作成しています。 ライブラリは機能ごとにファイルを分けています。 今、ライブラリの中でのみ使用するグローバル変数やグローバル関数が必要になりました。 このグローバル変数や関数は複数ファイルで参照するため、static宣言はできません。 しかし、このグローバル変数や関数は公開する必要はありません(ライブラリの中でのみ使用します)。 このようなことをC言語で実現するためにはどうしたらよいのでしょうか? 開発環境は Windows7 VisualC++2010 です。 VisualC++2010を使うなら C++で書けばいいのではないかといわれそうですが、 C言語でプログラミングしたいのです。 以下のようなサイトがあったのですが、これを使うしかないでしょうか? http://0xcc.net/blog/archives/000108.html

  • ゲームを作るためのスクリプト言語の勉強について。

    ゲームを作るために、プログラミングについて勉強を始めたいと思っている者です。 またDXライブラリやUnityなど比較的高難易度なツールを使っているわけではなく、RPGツクールやMMF2など初心者向けのツールを使っています。 RPGツクールやMMF2の初歩的な扱いには大分慣れてきたと思うので、変数を使ってより複雑なゲームを作りたいと考えているのですが、いまひとつ変数について理解できず、アルゴリズムもよくわかりません。 色々なサイトを調べたところ、いきなりC言語などのプログラミング言語から入るよりも、Rubyなどのスクリプト言語から勉強したほうがとっつきやすいし比較的簡単だという話だったので、スクリプト言語を勉強したいと思っているのですが、何かおすすめの言語とかはありますか? 今現在は、lua、Rubyのどちらにするかで悩んでいます。おすすめの参考書などありましたら教えてください。 またスクリプト言語の勉強はRPGツクールやMMF2といったツールの変数やアルゴリズムを理解するのに役立つのでしょうか? もし大して役に立たないということであれば、何か効果的な勉強法などありましたら教えていただけると嬉しいです。 ご回答、よろしくお願いします。