構造体の書き方について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
platyくん

構造体の書き方について

#1

投稿記事 by platyくん » 14年前

たびたびお世話になります。
シューティングゲームで配列を使わない弾の描写をしようとしており、構造体を使おうとしているのですが、エラーが出てしまいます。
もしよろしければどこがいけないのか教えてください。
下のコードは、自分の弾が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;
};

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

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

#2

投稿記事 by h2so5 » 14年前

具体的にどういったエラーが出るのか書いてください。
あと、インデントが無茶苦茶すぎてバグが出ないほうがおかしいです。

コード:

//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;

}

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

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

#3

投稿記事 by softya(ソフト屋) » 14年前

構造体ではなくclassを使っている理由も教えて下さい。
C++の記述を目指されているんでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

box
記事: 2002
登録日時: 15年前

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

#4

投稿記事 by box » 14年前

platyくん さんが書きました: もしよろしければどこがいけないのか教えてください。
そのインデントが正しいと思っているところがおかしいです。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

naohiro19
記事: 256
登録日時: 15年前
住所: 愛知県

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

#5

投稿記事 by naohiro19 » 14年前

classは C++の標準規格のキーワードであって構造体のキーワードではありません
構造体は struct キーワードを用いなければなりません。

platyくん

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

#6

投稿記事 by platyくん » 14年前

>>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 を読み込み中にアクセス違反が発生しました。
と表示されました。

史上最悪のデスペナ
記事: 521
登録日時: 14年前

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

#7

投稿記事 by 史上最悪のデスペナ » 14年前

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

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

platyくん

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

#8

投稿記事 by platyくん » 14年前

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

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

史上最悪のデスペナ
記事: 521
登録日時: 14年前

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

#9

投稿記事 by 史上最悪のデスペナ » 14年前

ふむふむ。そういうことでしたか。失礼しました。
確かに1ループで8方向にいっぺんに射出したら×8で200ぐらいになるか・・・・・・

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

box
記事: 2002
登録日時: 15年前

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

#10

投稿記事 by box » 14年前

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

platyくん

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

#11

投稿記事 by platyくん » 14年前

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;
};
長くなってすみません。これでプログラム全部です。

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

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

#12

投稿記事 by h2so5 » 14年前

バグの元なのでインデントは直したほうがいいですよ。

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

platyくん

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

#13

投稿記事 by platyくん » 14年前

h2so5 さんが書きました:バグの元なのでインデントは直したほうがいいですよ。

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

box
記事: 2002
登録日時: 15年前

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

#14

投稿記事 by box » 14年前

platyくん さんが書きました:

コード:

//Weapon.cpp
	zikishot *p;
このpの値は、何ですか?
いいかえると、pはどこを指していますか?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

platyくん

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

#15

投稿記事 by platyくん » 14年前

while構文の中を(p)にしたら直りりました。解決です。
本当にお手数をおかけしてすみませんでした。

platyくん

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

#16

投稿記事 by platyくん » 14年前

while構文の中を(p)にしたら直りりました。解決です。
本当にお手数をおかけしてすみませんでした。

閉鎖

“C言語何でも質問掲示板” へ戻る