ページ 11

構造体の書き方について

Posted: 2011年11月05日(土) 18:24
by platyくん
たびたびお世話になります。
シューティングゲームで配列を使わない弾の描写をしようとしており、構造体を使おうとしているのですが、エラーが出てしまいます。
もしよろしければどこがいけないのか教えてください。
下のコードは、自分の弾がAボタンを押されたときに発射され、弾が進む処理をさせようとしています。

コード:

 
//weapon.cpp
#include "DxLib.h"
#include "GV.h"
#include "bullet_teigi.h"
#include "zikishot.h"

static int Bullet;
	zikishot *pHead = NULL;
	zikishot *pTail = NULL;
	zikishot *p;

int Weapon_shot(){

		   if( Key[ KEY_INPUT_A ] == 1){//Aボタンが押されてたら弾を発射!
		//ウエポン変数に追加する
			  
			   if(pHead == NULL){//Headが空ならpを代入
				   pHead = p;}
			   if(pTail){//Tailに何か入ってたら?
				   pTail->pNext = p;}
			   p->pBefore = pTail;
			   p->pNext = 0;
			   p->x = x;
			   p->y = y;
			  pTail = p; }


	   //移動処理を行う
		   p = pHead;
		   while(p->pNext != NULL){
               p->x = (p->x ) +30;
	   p = p->pNext;
}
		 

//描画処理を行うよ(注loop_timeは、描画回数を表す
	   if(loop_time == 0){
  Bullet = LoadGraph("picture/bullet.png");//球の画像をロード
	}
	   p = pHead;
	while(p->pNext != NULL){
		DrawRotaGraph( p->x, p->y, 1.0, 0.0, Bullet, TRUE );
		p = p->pNext;
		}
	return 0;
}

コード:

//ここからzikishot.h
class zikishot{
public:
	int x;
	int y;
	zikishot *pBefore;
	zikishot *pNext;
};

Re: 構造体の書き方について

Posted: 2011年11月05日(土) 18:39
by h2so5
具体的にどういったエラーが出るのか書いてください。
あと、インデントが無茶苦茶すぎてバグが出ないほうがおかしいです。

コード:

//weapon.cpp
#include "DxLib.h"
#include "GV.h"
#include "bullet_teigi.h"
#include "zikishot.h"
 
static int Bullet;
zikishot *pHead = NULL;
zikishot *pTail = NULL;
zikishot *p;
 
int Weapon_shot(){
 
	if( Key[ KEY_INPUT_A ] == 1){//Aボタンが押されてたら弾を発射!
	//ウエポン変数に追加する
	
		if(pHead == NULL){//Headが空ならpを代入
			pHead = p;
		}
		
		if(pTail){//Tailに何か入ってたら?
			pTail->pNext = p;
		}
		
		p->pBefore = pTail;
		p->pNext = 0;
		p->x = x;
		p->y = y;
		pTail = p; 
	
	}
	
	
	//移動処理を行う
	p = pHead;
	while(p->pNext != NULL){
		p->x = (p->x ) +30;
		p = p->pNext;
	}
	
	
	//描画処理を行うよ(注loop_timeは、描画回数を表す
	if(loop_time == 0){
		Bullet = LoadGraph("picture/bullet.png");//球の画像をロード
	}
	p = pHead;
	
	while(p->pNext != NULL){
		DrawRotaGraph( p->x, p->y, 1.0, 0.0, Bullet, TRUE );
		p = p->pNext;
	}
	
	return 0;

}

Re: 構造体の書き方について

Posted: 2011年11月05日(土) 18:46
by softya(ソフト屋)
構造体ではなくclassを使っている理由も教えて下さい。
C++の記述を目指されているんでしょうか?

Re: 構造体の書き方について

Posted: 2011年11月05日(土) 19:07
by box
platyくん さんが書きました: もしよろしければどこがいけないのか教えてください。
そのインデントが正しいと思っているところがおかしいです。

Re: 構造体の書き方について

Posted: 2011年11月05日(土) 19:54
by naohiro19
classは C++の標準規格のキーワードであって構造体のキーワードではありません
構造体は struct キーワードを用いなければなりません。

Re: 構造体の書き方について

Posted: 2011年11月06日(日) 08:27
by platyくん
>>naohiro19
そういえばそうです。structに直しました。


今まで、例えば自機の弾だとそれぞれに
int bullet_use[200]
int bullet_x[200]
int bullet_y[200]...って配列で名前付けていたんですけど、どうもこのままプログラミングを進めていくとメモリの問題にぶち当たるって聞いたので,(特に敵の弾は配列2000個ほど使ってます)
構造体を勉強してメモリに優しいゲームに作り替えようと思ったのがきっかけなんですけども、サンプルプログラムがネット上に充実していなくてどうしようと思ったんです・・・

エラーは
//移動処理を行う
p = pHead;
while(p->pNext != 0){
の辺りで
GameProg.exe の 0x00b0abaf でハンドルされていない例外が発生しました: 0xC0000005: 場所 0x0000000c を読み込み中にアクセス違反が発生しました。
と表示されました。

Re: 構造体の書き方について

Posted: 2011年11月06日(日) 08:46
by 史上最悪のデスペナ
えっと、一つ思ったのはFPSのミニガンなどのマシンガン系以外200発もマガジン内に入ってないので配列を200もとる必要がないのでは?
所詮人間や銃のスピードなんてPCの演算処理に勝てるはずがないので、いくらマシンガンでも配列を200もとる必要がないと思ったり。
例えば、
弾を発射
→移動
→敵なり味方なり壁なり地面に当たったら弾が消滅
→なんにも当たらなくても一定の距離or一定の時間が経ったら弾が消滅

とすれば、1ループ内に5進むとして、100進んだら消滅すると多くても21ループ目には最初の弾って消滅してますよね?
ということは、配列は20で済むんじゃないですか?
空になったらまたそこに21発目以降を入れればいいので

Re: 構造体の書き方について

Posted: 2011年11月06日(日) 08:54
by platyくん
史上最悪のデスペナ さんが書きました:えっと、一つ思ったのはFPSのミニガンなどのマシンガン系以外200発もマガジン内に入ってないので配列を200もとる必要がないのでは?
所詮人間や銃のスピードなんてPCの演算処理に勝てるはずがないので、いくらマシンガンでも配列を200もとる必要がないと思ったり。
例えば、
弾を発射
→移動
→敵なり味方なり壁なり地面に当たったら弾が消滅
→なんにも当たらなくても一定の距離or一定の時間が経ったら弾が消滅

とすれば、1ループ内に5進むとして、100進んだら消滅すると多くても21ループ目には最初の弾って消滅してますよね?
ということは、配列は20で済むんじゃないですか?
空になったらまたそこに21発目以降を入れればいいので
弾幕シューティングゲームを目指していて、自分の弾も一回押しただけで何十発も出るっていうのがやりたいし、
特に敵の弾は弾幕を張るので最低1000は確保したいところなんです。

Re: 構造体の書き方について

Posted: 2011年11月06日(日) 09:01
by 史上最悪のデスペナ
ふむふむ。そういうことでしたか。失礼しました。
確かに1ループで8方向にいっぺんに射出したら×8で200ぐらいになるか・・・・・・

オンラインゲームにも通用しそうだからこのスレの行方を見守るとしよう。

Re: 構造体の書き方について

Posted: 2011年11月06日(日) 09:16
by box
platyくん さんが書きました: エラーは
//移動処理を行う
p = pHead;
while(p->pNext != 0){
の辺りで
実行時のエラーが出る、ということは、少なくともコンパイルは通っていますね。一方、
最初に投稿されたコードはコンパイルが通りません。そこで、
いま手元にある(はずの)、コンパイルが通っているコードを見せてください。

Re: 構造体の書き方について

Posted: 2011年11月06日(日) 10:10
by platyくん
box さんが書きました:
platyくん さんが書きました: エラーは
//移動処理を行う
p = pHead;
while(p->pNext != 0){
の辺りで
実行時のエラーが出る、ということは、少なくともコンパイルは通っていますね。一方、
最初に投稿されたコードはコンパイルが通りません。そこで、
いま手元にある(はずの)、コンパイルが通っているコードを見せてください。
今現在のプログラムは、自機が移動してAボタンで弾を撃つ仕様になっています。で、コードは

コード:

//main.cpp
#include "DxLib.h"
#include "GV.h"
int loop_time;

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定

		 while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0 ){

       Chara_move();//自機キャラを動かす
	   Weapon_shot();//弾を発射する
	  loop_time = loop_time + 1;
		 }

	DxLib_End(); // DXライブラリ終了処理
	return 0;}

コード:

//Character.cpp
#include "DxLib.h"
#include "GV.h"

int Key[256]; // キーが押されているフレーム数を格納する
int x = 100;
int y = 240;//自機キャラの初期配置を定義
static int Handle;
int loop = 0;


// キーの入力状態を更新する
int  gpUpdateKey(){
	char tmpKey[256]; // 現在のキーの入力状態を格納する
	GetHitKeyStateAll( tmpKey ); // 全てのキーの入力状態を得る
	for( int i=0; i<256; i++ ){ 
		if( tmpKey[i] != 0 ){ // i番のキーコードに対応するキーが押されていたら
			Key[i]++;     // 加算
		} else {              // 押されていなければ
			Key[i] = 0;   // 0にする
		}
	}
	return 0;
}
void Chara_move(){
	if( loop == 0){
		loop = 1;
	   Handle = LoadGraph("picture/boy.png");
	}
        // while(裏画面を表画面に反映, メッセージ処理, 画面クリア, キーの更新)
      

        if( Key[ KEY_INPUT_RIGHT ] >= 1 ){ // 右キーが押されていたら
			x++;                       // 右へ移動
		}
		if( Key[ KEY_INPUT_DOWN  ] >= 1 ){ // 下キーが押されていたら
			y++;                       // 下へ移動
		}
		if( Key[ KEY_INPUT_LEFT  ] >= 1 ){ // 左キーが押されていたら
			x--;                       // 左へ移動
		}
		if( Key[ KEY_INPUT_UP    ] >= 1 ){ // 上キーが押されていたら
			y--;                       // 上へ移動
		}

		DrawRotaGraph( x, y, 1.0, 0.0, Handle, TRUE ); // x,y の位置にキャラを描画 
}

コード:

//Weapon.cpp
#include "DxLib.h"
#include "GV.h"
#include "zikishot.h"

static int Bullet;
bool shot_tyuu[30];
int bullet_x[30];
int bullet_y[30];//弾の座標を定義

	zikishot *pHead = NULL;
	zikishot *pTail = NULL;
	zikishot *p;

int Weapon_shot(){

		   if( Key[ KEY_INPUT_A ] == 1){//Aボタンが押されてたら弾を発射!
		//ウエポン変数に追加する
			  
			   if(pHead == 0){//Headが空ならpを代入
				   pHead = p;}
			   if(pTail){//Tailに何か入ってたら?
				   pTail->pNext = p;}
			   p->pBefore = pTail;
			   p->pNext = 0;
			   p->x = x;
			   p->y = y;
			  pTail = p; }


	   //移動処理を行う
		   p = pHead;
		   while(p->pNext != 0){
               p->x = 30;
			 p = p->pNext;
}
		 

//描画処理を行うよ
	   if(loop_time == 0){
  Bullet = LoadGraph("picture/bullet.png");//球の画像をロード
	}
	   p = pHead;
	while(p->pNext != 0){
		DrawRotaGraph( p->x, p->y, 1.0, 0.0, Bullet, TRUE );
		p = p->pNext;
		}
	return 0;
}

コード:

//GV.h
int  gpUpdateKey();//ボタン入力情報を得る
void Chara_move();//自機を移動させるL1
int Weapon_shot();

#ifdef GLOBAL_INSTANCE
#define GLOBAL
#else
#define GLOBAL extern 
#endif
GLOBAL int x; //自機のx座標
GLOBAL int y; //自機のy座標
extern int Key[256];//ボタン入力の変数
extern int Handle;//自機を表示させる
GLOBAL int loop_time;

コード:

//zikishot.h
struct zikishot{
	int x;
	int y;
	zikishot *pBefore;
	zikishot *pNext;
};
長くなってすみません。これでプログラム全部です。

Re: 構造体の書き方について

Posted: 2011年11月06日(日) 12:26
by h2so5
バグの元なのでインデントは直したほうがいいですよ。

あと、構造体zikishotのインスタンスがどこにもありません。
pがダングリングポインタになっています。

Re: 構造体の書き方について

Posted: 2011年11月06日(日) 16:30
by platyくん
h2so5 さんが書きました:バグの元なのでインデントは直したほうがいいですよ。

あと、構造体zikishotのインスタンスがどこにもありません。
pがダングリングポインタになっています。
すみません、もう少し詳しく教えていただけませんか?

Re: 構造体の書き方について

Posted: 2011年11月06日(日) 16:40
by box
platyくん さんが書きました:

コード:

//Weapon.cpp
	zikishot *p;
このpの値は、何ですか?
いいかえると、pはどこを指していますか?

Re: 構造体の書き方について

Posted: 2011年11月06日(日) 16:54
by platyくん
while構文の中を(p)にしたら直りりました。解決です。
本当にお手数をおかけしてすみませんでした。

Re: 構造体の書き方について

Posted: 2011年11月06日(日) 16:55
by platyくん
while構文の中を(p)にしたら直りりました。解決です。
本当にお手数をおかけしてすみませんでした。