• ベストアンサー

#ifdefはどうやって使う?

よろしくお願いします。 現在趣味でゲームを作っています。 普通の#ifdefの使い方は存じているのですが、以下のような場合どうすればいいのでしょうか。 ゲームにはイージーと、ノーマルで2種類のレベルが設定出来ます。 イージーの場合は、最初の定義から、ボスのショットである boss_shot1()関数は上のイージー用の関数を通ります。 ノーマル設定の場合、 #define EASYを注釈にすることで、ノーマルの設定のboss_shot1();を通ります。 #define EASY #ifdef EASY void boss_shot1(){   //イージー用のショット } #else void boss_shot1(){   //ノーマル用のショット } #endif しかしこれでは、プログラム内でレベル設定をする事が出来ません。 注釈にしてコンパイルしたものと、#define EASYをそのままにしてコンパイルしたもの、2つの実行ファイルで レベル分けをしないといけません。 うまくプログラム内でこの条件分岐が出来ないでしょうか? 内容の違う関数は関数名を変えて記述するしかないのでしょうか? よろしくお願いします。

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

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

普通動作中のプログラムの設定を変える場合に プリプロセッサは使いません。 というより、使えません。 ゲームなどの難易度の変数、または引数を つくり関数の中で普通のif文を使って処理を 分けるだけです。 typedef enum {  HAERD = 0,  NOMALE,  EASY, }GAME_LEVEL; /* ゲームの難易度を引数かグローバルにでも */ void boss_shot1( GAME_LEVEL lv ){  if ( lv == HAERD ){   //ハード用のショット  } else if ( lv == NOMALE ){   //ノーマル用のショット  } else {   //イージー用のショット  } } #今回は意味不明なレベルが渡されると全て #EASYにしていますが特に意味はありません。 #(インデントは全て全角です)

Directxq
質問者

お礼

やはりそうですよね。 ご回答ありがとう御座いました。 内容の違うショットは違う関数名にでもして分けようと思います。 ありがとうございました。

その他の回答 (2)

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.3

#ifや#ifdefは、デモバージョン/配布バージョン/デバックバージョンなどをコンパイル時にオプション指定で実行ファイルを作り分ける時などに使います。 敵やボスの強さを難易度分けするのは、やはり難易度を変数に入れて、その変数をif文やswitch文で条件分岐して、難易度別の処理を書くしかないですね。 敵の数や攻撃タイミングだけだったらレベル別のテーブル持つだけで簡単に処理出来ますが、攻撃モーションとかまで違うと専用のプログラムが必要になりますね。

Directxq
質問者

お礼

わかりました。違う関数名などを使って対処しようと思います。ご回答ありがとう御座いました。

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.2

普通はそういった要望には変数で場合わけでしょう #ifdefでコードレベルで変える必要は無いと思います int nGameLabel; などと宣言しておいて 2つの場合わけなら if ( nGameLavel == 1 ) { // Normalレベルの処理 } else { // Easyレベルの処理 } といった具合になると思います 3個以上なら switchなどで処理したほうがすっきりするかもしれません #ifdefは デバッグ時などはログデータを出力したい OSの違いが吸収できないのでEXEを分けざるを得ない UNICODEとMBCSで呼び出すAPI関数名の違いを吸収したい などの場合に使います

Directxq
質問者

お礼

用途が違ったのですね。 わかりました。ありがとうございます。関数名をかえるなどして対処しようと思います。

関連するQ&A

  • #ifdef _DEBUGが効かない

    こんにちは。 Win2000、VC++6.0使用。 今までC言語でプログラムを組んではいましたが、 #define _DEBUG #ifdef _DEBUG print(...); #endif というようにデバッグ用のコードを入れたことはありませんでした。 このような便利なものがあると知り、早速使ってみたのですが、 #define _DEBUG の一文をコメントアウトして、再コンパイル(リビルド) して実行してみたのですが、 普通に #ifdef _DEBUG #endif で囲まれた部分が実行されてしまいます。 #define _DEBUG を宣言しなければ、実行されないと思っていたのですが 自分の勘違いでしょうか? よくわかりません。 どなたかご存知の方、よろしくお願いします。

  • #ifdef の使い方

    組み込み系のプログラムを現在勉強しています。 #ifdefについて質問させて頂きます。 下記コードの場合 #ifdef A ---- (1) Y = Z; #else -----#if B ------- (2) X = Z; ----#endif #endif ("-"は空白と思ってください。) この場合、Aが定義されていれば(1)が実行しコンパイル終了(#endif)。 Aが定義されていない場合、#else に行き、Bが定義されている場合は (2)を実行してコンパイル終了(#endif)という理解であっていますか? またこうした方が分かりやすいなど、アドバイス頂けると幸いです。 ご返答よろしくお願いします。

  • プリプロセッサ#ifdef~#endifについて

    C言語のプリプロセッサ#ifdef~#endifを使用して以下のソースファイルを作成しました。コンパイルするとエラーになります。 (pre.c)*********************** /* 各行の頭は行番号を表しています。*/ /* 実際のソースには記述していません。 */ 1: #include <stdio.h> 2: 3: #define TAB 0x61 4: #ifdef TAB 5: printf("%c", TAB); 6: #endif 7: 8: int main(void) { 9: return 0; 10: } ****************************** C:\>cl pre.c Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. pre.c pre.c(5) : error C2143: 構文エラー : ')' が '文字列' の前にありません。 pre.c(5) : error C2143: 構文エラー : '{' が '文字列' の前にありません。 pre.c(5) : error C2059: 構文エラー : '<不明>' pre.c(5) : error C2059: 構文エラー : ')' 原因について、どなたか教えて頂けませんでしょうか?

  • コンパイル時のスイッチについて

    C言語初心者なので申し訳ありませんが,コンパイル時のスイッチについて困っております. 現在, #define tmp ... #ifdef tmp  関数1 #else  関数2 #endif とtmpを定義して切り替えようとしております. 現在コンパイルの切替は,毎回 //#define tmp とコメントアウトして切り替えているのですが, gcc等のコンパイラのコマンドラインから 切り替える方法はあるのでしょうか. 色々調べたら, cc -D tmp みたいな?感じにするのかと思ったのですがうまくいきません. 初歩の質問ですがご教授よろしくお願いします.

  • マクロ初級 #define

    #include <iostream.h> #define mkr(a) {cout << a;\cout << b;\} void main(void){ cout << "2数を表示するマクロ" << endl; mkr(1,9); } ↑これをコンパイルするとエラーになりました。 エラー 5行目 マクロ 'mkr' の呼び出しにおける引数の個数が 誤っている(関数 main() ) ネット上で見つけたものなんですが、このプログラムを 正しく修正するとどうなるんですか? マクロのソースを見たのは初めてだったので分かりませんでした。

  • 関数の容量を知るには?

    MAPファイルで調べるのではなく、プログラム中からある関数の大きさ(コンパイル後のバイナリのバイト数)を調べる方法は無いでしょうか? 例えば、 void abc(void) { printf("dummy\n"); } というabc関数があったとします。 この関数のコンパイル後のバイナリのバイト数を、 int i; i = sizeof( abc ); みたいな形で調べられないでしょうか? 宜しくお願いします。

  • #defineで置き換えられない

    C言語です。詳しい方、よろしくお願いします。 下記のプログラムをコンパイルして実行したら、画像のようになってしまいます。 コンパイラは、CPad for LSI C-86 ver2.31です。 #include<stdio.h> #define clr() printf("\x1b[2J") void main(void) { while(1){ clr(); printf("test"); } } #defineがどうも置き換えられていないようです。 詳しい方、考えられる原因を教えてください。 よろしくお願いします。

  • 分割コンパイルの#defineについて

    分割コンパイルで ファイル1 #include <stdio.h> #define number 10 char string[number]; int main(void){ string[0]='a'; string[1]='b'; file_to(); return 0; } ファイル2 #include <stdio.h> #define number 10 extern char string[number]; void file_to(void){ /***何かの処理をする*****/ } って感じなんですけども、配列string の中身の値をdefineによって指定しているのですが、片方のdefineの値を変更する時、もう一つのdefineも手動で変更しています。関係するファイル数が多くなってくると大変なので、どれかのdefineの値を変化させたら自動的に他のdefineの値も変更するプログラムの組み方はありませんか? 質問がわかりにくいかも知れませんがよろしくお願いします。

  • PICのプログラミングについて

    16F88をC言語でプログラムしています。 HI-TECH cでコンパイルしたところ、delay関数がうまく動作しません。 delay関数の直前までは動作するのですが、そこでストップしてしまいます。 どうもincludeの設定のところに問題があると思うのですが、 初心者なもので原因がいまひとつ掴めません。 とりあえず、delayが動作しているか確かめるために作った下記のプログラムでいろいろと試しているのですが、おかしいところがあればご指摘お願いします。 **************************** //RB0~RB4にはLEDを接続 #include <pic.h> #include <htc.h> #define _XTAL_FREQ 8000000 // 8Mhz __CONFIG(0x3F22); void main(){ TRISA = 0b00000100; TRISB = 0b00000000; PORTB = 0b00000101; __delay_ms(500); PORTB = 0b00000111; }

  • javaの簡単なソースがコンパイル出来ません

    Javaを始めてみましたが、最も簡単なjavaのソースがどうしてもコンパイル出来ません。 どうしたらいいのか教えて下さい。 デスクトップの以下の Hello.java に対して、 public class Hello { public static void main(String[] args) { System.out.println("Hello,World"); } } 以下の3通りの方法でコンパイルを掛けてみると、 ‥デスクトップ>javac Hello.java javac:ファイルが見つかりません:Hello.java 使い方:javac <ptions> <source files> 使用可能なオプションのリストについては-helpを使用します >javac Hello.java.txt エラー:クラス名 ‘Hello.java.txt’が受け入れられるのは、注釈処理が明示的に要求された場合だけです エラー1個 >javac Hello エラー:クラス名 ‘Hello’が受け入れられるのは、注釈処理が明示的に要求された場合だけです エラー1個 でどの場合もコンパイルされません。 なお、javaのバージョンは “1.6.0_06”で、パスも C:\Program Files\Java\jdk1.6.0_06\bin\; と設定してあります。 どうしたらコンパイルが出来るのか、教えて下さい。

    • ベストアンサー
    • Java