友人に「C言語わくわくゲームプログラミング」をもらったので、ちょこちょこ読んでいます。
シューティングで銃を撃つプログラムがあるのですが、変数の宣言で疑問があるので、質問です。下記のプログラムが書籍内にあるプログラム(多少アレンジしています)ですが、Jitamamove関数の定義でjitama.lifeの値で場合分けしています。
---------------
#include "DxLib.h"
typedef struct CharaData{
int x;
int y;
int ghandle;
int life;
}CharaData;
CharaData jikidata;
CharaData jitama;
//JitamaMove関数の宣言
void JitamaMove();
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //ウィンドウ化と初期化処理
jikidata.x=50;
jikidata.y=50;
jikidata.ghandle=LoadGraph("media\\test_jiki.bmp"); //自機の画像を読み込み
jitama.ghandle=LoadGraph("media\\test_tama.bmp"); //弾の画像を読み込み
int i;
char Key[256];
SetDrawScreen( DX_SCREEN_BACK ) ;
while(!ProcessMessage()&&!GetHitKeyStateAll(Key)){
ClearDrawScreen();
if(Key[KEY_INPUT_RIGHT]){
jikidata.x++;
}
if(Key[KEY_INPUT_LEFT]){
jikidata.x--;
}
if(Key[KEY_INPUT_UP]){
jikidata.y--;
}
if(Key[KEY_INPUT_DOWN]){
jikidata.y++;
}
if(Key[KEY_INPUT_RIGHT]&&Key[KEY_INPUT_X]){
jikidata.x=jikidata.x+2;
}
if(Key[KEY_INPUT_LEFT]&&Key[KEY_INPUT_X]){
jikidata.x=jikidata.x-2;
}
if(Key[KEY_INPUT_UP]&&Key[KEY_INPUT_X]){
jikidata.y=jikidata.y-2;
}
if(Key[KEY_INPUT_DOWN]&&Key[KEY_INPUT_X]){
jikidata.y=jikidata.y+2;
}
DrawGraph(jikidata.x,jikidata.y,jikidata.ghandle,TRUE);
JitamaMove();
ScreenFlip();
if(Key[KEY_INPUT_SPACE])
break;
}
DxLib_End();
return 0;
}
//JitamaMove関数の定義
void JitamaMove(){
char Key[256];
GetHitKeyStateAll(Key);
if(Key[KEY_INPUT_A]){
if(jitama.life==0){
jitama.life=1;
jitama.x=jikidata.x+10;
jitama.y=jikidata.y+8;
}
}
if(jitama.life>0){
jitama.x=jitama.x+10;
DrawGraph(jitama.x,jitama.y,jitama.ghandle,TRUE);
//画面外に出たときの処理
if(jitama.x>640)
jitama.life=0;
}
}
--------------------------------------
ですが、そもそもjitama.lifeの値を宣言していないので、この場合分けは成立しない気がするのですが・・・・・・でもプログラムを実行するとうまくいきます。なぜでしょうか?
それで関数内で下記のようにjitama.lifeを宣言すると定義するとうまくいきません。(弾は表示されるのですが自機を離れない)これもなぜでしょう。
----------------------
void JitamaMove(){
char Key[256];
GetHitKeyStateAll(Key);
if(Key[KEY_INPUT_A]){
if(jitama.life==0){
jitama.life=1;
jitama.x=jikidata.x+10;
jitama.y=jikidata.y+8;
}
}
if(jitama.life>0){
jitama.x=jitama.x+10;
DrawGraph(jitama.x,jitama.y,jitama.ghandle,TRUE);
//画面外に出たときの処理
if(jitama.x>640)
jitama.life=0;
}
}
-----------------------------------
お手数をおかけいたしますが、よろしくお願いいたします。
変数の宣言で質問です。
Re:変数の宣言で質問です。
jikidata.x=50;
jikidata.y=50;
↓
jikidata.x=50;
jikidata.y=50;
jikidata.life = 0;
原因はおそらく
前半のプログラムで起動したときは、たまたまlife の値が正だった→if(jitama.life>0) にひっかかって初期化される。
二回目の時は、たまたまlifeの値が負だった。→どちらの文にもひっかからない。
jikidata.y=50;
↓
jikidata.x=50;
jikidata.y=50;
jikidata.life = 0;
原因はおそらく
前半のプログラムで起動したときは、たまたまlife の値が正だった→if(jitama.life>0) にひっかかって初期化される。
二回目の時は、たまたまlifeの値が負だった。→どちらの文にもひっかからない。
Re:変数の宣言で質問です。
いやいや、lifeを使っているのは、jikidataではなくjitamaです。
そしてjitamaはグローバル変数なので0で初期化されています。
ゲーム内での意味としては未使用といった所でしょう。
未使用ならば使用開始し、画面外に出たら未使用にもどしています。
そしてjitamaはグローバル変数なので0で初期化されています。
ゲーム内での意味としては未使用といった所でしょう。
未使用ならば使用開始し、画面外に出たら未使用にもどしています。
Re:変数の宣言で質問です。
なるほど、グローバル変数は0で初期化されるのですね。
勉強不足でした。
もう一つ質問なのですがJitamaMove関数の定義内で下記のように、jitama.life=0を定義すると弾が発射するのですが、自機から離れません。
これはなぜなのでしょうか。
お手数をおかけいたしますが、よろしくお願いいたします。
---------------------------
//JitamaMove関数の定義
void JitamaMove(){
char Key[256];
GetHitKeyStateAll(Key);
jitama.life=0;//←ココです。
if(Key[KEY_INPUT_A]){
if(jitama.life==0){
jitama.life=1;
jitama.x=jikidata.x+10;
jitama.y=jikidata.y+8;
}
}
if(jitama.life>0){
jitama.x=jitama.x+10;
DrawGraph(jitama.x,jitama.y,jitama.ghandle,TRUE);
//画面外に出たときの処理
if(jitama.x>640)
jitama.life=0;
}
}
勉強不足でした。
もう一つ質問なのですがJitamaMove関数の定義内で下記のように、jitama.life=0を定義すると弾が発射するのですが、自機から離れません。
これはなぜなのでしょうか。
お手数をおかけいたしますが、よろしくお願いいたします。
---------------------------
//JitamaMove関数の定義
void JitamaMove(){
char Key[256];
GetHitKeyStateAll(Key);
jitama.life=0;//←ココです。
if(Key[KEY_INPUT_A]){
if(jitama.life==0){
jitama.life=1;
jitama.x=jikidata.x+10;
jitama.y=jikidata.y+8;
}
}
if(jitama.life>0){
jitama.x=jitama.x+10;
DrawGraph(jitama.x,jitama.y,jitama.ghandle,TRUE);
//画面外に出たときの処理
if(jitama.x>640)
jitama.life=0;
}
}
Re:変数の宣言で質問です。
jitama.life=0;//←ココです。
if(Key[KEY_INPUT_A]){
if(jitama.life==0){ // ココ
jitama.life=1;
jitama.x=jikidata.x+10; // ココ
jitama.y=jikidata.y+8; // ココ
}
}
if(Key[KEY_INPUT_A]){
if(jitama.life==0){ // ココ
jitama.life=1;
jitama.x=jikidata.x+10; // ココ
jitama.y=jikidata.y+8; // ココ
}
}
Re:変数の宣言で質問です。
ええと……
jitama.life=0;
if(jitama.life==0){
jitama.life=1;
jitama.x=jikidata.x+10;
jitama.y=jikidata.y+8;
}
まずこの部分で、弾の位置を決めますよね。
(最初にjitama.life=0と宣言してるので、if文章の要件は満たすはず)
それでif内でjitama.lifeの値は1となり、つぎの
if(jitama.life>0){
jitama.x=jitama.x+10;
DrawGraph(jitama.x,jitama.y,jitama.ghandle,TRUE);
//画面外に出たときの処理
if(jitama.x>640)
jitama.life=0;
}
の中に入り、whileの繰り返しで弾が表示→動くと思うのですが。でもなにか重大な勘違いをしているような気もします。
jitama.life=0;
if(jitama.life==0){
jitama.life=1;
jitama.x=jikidata.x+10;
jitama.y=jikidata.y+8;
}
まずこの部分で、弾の位置を決めますよね。
(最初にjitama.life=0と宣言してるので、if文章の要件は満たすはず)
それでif内でjitama.lifeの値は1となり、つぎの
if(jitama.life>0){
jitama.x=jitama.x+10;
DrawGraph(jitama.x,jitama.y,jitama.ghandle,TRUE);
//画面外に出たときの処理
if(jitama.x>640)
jitama.life=0;
}
の中に入り、whileの繰り返しで弾が表示→動くと思うのですが。でもなにか重大な勘違いをしているような気もします。
Re:変数の宣言で質問です。
毎回 jitama.life=0; してるから
if(jitama.life>0){
jitama.x=jitama.x+10;
DrawGraph(jitama.x,jitama.y,jitama.ghandle,TRUE);
//画面外に出たときの処理
if(jitama.x>640)
jitama.life=0;
}
これは1回だけ
if(jitama.life>0){
jitama.x=jitama.x+10;
DrawGraph(jitama.x,jitama.y,jitama.ghandle,TRUE);
//画面外に出たときの処理
if(jitama.x>640)
jitama.life=0;
}
これは1回だけ