敵が描画されません

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
isyy
記事: 19
登録日時: 10年前
住所: 北海道

敵が描画されません

#1

投稿記事 by isyy » 10年前

自作でシューティングゲームを制作しているのですが、敵を配列かさせて複製しようと思うのですが上手く描画されません
以下ソースコード
main.cpp

コード:

#include "DxLib.h"
#include "GV.h"
extern int counter;
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){
	ChangeWindowMode(TRUE);//ウィンドウモード
	if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化

	while(1){//メインループ
		ProcessMessage();
		ScreenFlip();
		ClearDrawScreen();
		GameInit();
		GameTitle();
        GameMain();
	break;
	
}
	if(CheckHitKey(KEY_INPUT_ESCAPE))DxLib_End();//DXライブラリ終了処理
	return 0;
}
	
struct.h

コード:

struct ch
{
	int x;
	int y;
	int img;
	int h;
	int w;
	int speed;
};
#include "difine.h"
struct shot
{
	int speed;
	int w;
	int h;
	int img;
	int flag;
	int bflag;
	int x;
	int y;
};
struct enemy
{
	int x;
	int y;
	int w;
	int h;
	int damageflag;
	int damageimg;
	int damagecounter;
	int speed;
	int muki;
	int flag;
	int counter;
	int pattern;
	int size;
};
struct haikei{
	int x;
	int y;
	int img;
};
struct eshot{
	int x;
	int y;
	int flag;
	int bflag;
	int img;
	int sw;
	int sh;
	int counter;
	double sb; 
	double sbx;
	double sby;
	double bx;
	double by;
	double sx;
	double sy;
};
 struct PointData{
	double x;
	double y;
};
inti.cpp

コード:

#include "DxLib.h"
#include "difine.h"
#include "struct.h"
extern struct enemy enemey[ENEMEY_MAX];
extern struct ch c;
extern struct shot s[SHOT];
extern struct haikei h;
extern struct eshot es;
extern int img_enemy1[];
int speed;
extern int i;
//extern int t;
void GameInit()
{
	SetDrawScreen(DX_SCREEN_BACK);
	h.img=LoadGraph("img/back.bmp");
	c.img=LoadGraph("img/kao.bmp");//自機の画像
	s[i].img = LoadGraph("img/kao.bmp");//ホーミング玉の画像
	img_enemy1[0]=LoadGraph("img/kao1_0.bmp");//敵の画像
	img_enemy1[1]=LoadGraph("img/kao1_1.bmp");//敵の画像
	img_enemy1[2]=LoadGraph("img/kao1_2.bmp");//敵の画像
	img_enemy1[3]=LoadGraph("img/kao1_3.bmp");//敵の画像
	enemey[i].damageimg=LoadGraph("img/kao.bmp");//敵のやられ画像
	es.img=LoadGraph("img/kao.bmp");
	////for(t=0;t<ENEMEY_MAX;t++){
	//}
	speed=5;
	c.x=320;
	c.y=500; 
	c.speed=5;
	//enemey[i].x=50;
	//enemey[i].y=200;
	enemey[i].speed=5;
	s[i].speed=10;
	enemey[i].muki=MOVE_RIGHT;
	es.flag =FLAG_OFF;
	es.counter = FLAG_OFF;
	for(i=0;i<SHOT;i++){
		s[i].flag=FLAG_OFF;
	}
	 for(i=0;i<ENEMEY_MAX;i++){
                enemey[i].flag=FLAG_OFF;
}
	s[i].bflag=FLAG_OFF;
	GetGraphSize(c.img,&c.w,&c.h);
	GetGraphSize(s[i].img,&s[i].w,&s[i].h);
	//GetGraphSize(img_enemy1[0],&enemey[i].w,&enemey[i].h);
	GetGraphSize( es.img , &es.sw , &es.sh );
}
haikei.cpp

コード:

#include "DxLib.h"
#include "struct.h"
#include "difine.h"
struct haikei h;
void haikei(){
	DrawGraph(h.x,h.y,h.img,FALSE);
	DrawGraph(h.x,h.y-460,h.img,FALSE);
	if(h.y==460+MARGIN)
		h.y=10;
	h.y+=SCROLL_SPEED;
}
GV.h

コード:

extern void GameInit();
extern void GameMain();
extern void KeyCheck();
extern void MyShotMove();
extern void EnemyDraw();
extern void MyDraw();
extern void haikei();
extern void GameTitle();
extern void enemeyshot();
extern void EnemyCalcDisp();
extern void EnemyControl();
Game.cpp

コード:

#include "DxLib.h"
#include "GV.h"
extern int i;
extern int counter;
void GameTitle(){
	while (1){
	ProcessMessage();
	ScreenFlip();
	ClearDrawScreen();
	if (CheckHitKey(KEY_INPUT_Z)){
		break;
	}
	DrawBox(0, 0, 640, 480, GetColor(255, 255, 255), TRUE);
	DrawString(30, 450, "Zキーでスタート", GetColor(0, 0, 0), 0);
	}
}
void GameMain(){
	while(1){
		ClearDrawScreen();
		KeyCheck();
		haikei();
		MyDraw();
		MyShotMove();
	    EnemyControl();
		EnemyCalcDisp();
		ScreenFlip();
		counter++;
		if(ProcessMessage()==-1)break;
		if(CheckHitKey(KEY_INPUT_ESCAPE)==1)break;
	}
}
enemey.cpp

コード:

#include "DxLib.h"
#include "struct.h"
#include "difine.h"
struct enemy enemey[ENEMEY_MAX];
struct eshot es;
int img_enemy1[4];
int counter=FLAG_OFF;
//int t;

void EnemyPattern1(int i){
        enemey[i].y+=1.5f;
}


void EnemyControl(){
        for(int i=0;i<100;i++)
                if(enemey[i].flag==FLAG_ON)
                        if(enemey[i].pattern==FLAG_ON)
                                EnemyPattern1(i);
}


void EnemyCalcDisp(){
	int i;
        for(i=0;i<100;i++)
                if(enemey[i].flag==FLAG_OFF)
                        break;
        switch(counter){
                case 100:
                case 150:
                case 200:
                case 250:
                        enemey[i].flag=FLAG_ON;   //出現フラグを立てる
                        enemey[i].counter=FLAG_OFF;//出現して何カウント目か測るカウンター初期化
                        enemey[i].pattern=FLAG_ON; //どういう軌道を描くか
                        enemey[i].size=0.5f;//敵の大きさ
                        enemey[i].x=100.0;  //xの初期座標
                        enemey[i].y=-10.0;  //yの初期座標
                        break;
                default:
                        break;
        }
        for(i=0;i<100;i++)
                if(enemey[i].flag==FLAG_ON)
                             DrawRotaGraph( (int)enemey[i].x , (int)enemey[i].y , enemey[i].size , 0.0f , img_enemy1[0] , TRUE ) ;

}
//void enemeyshot(){
//   // for(t=0;t<ENEMEY_MAX;t++)
//				 es.counter++ ;
//				if( es.counter == FLAG_ON )
//				{
//					if( es.flag == FLAG_OFF )
//					{
//						es.x = enemey[i].x + enemey[i].w / 2 - es.sw / 2 ;
//						es.y = enemey[i].y + enemey[i].h / 2 - es.sh / 2 ;
//						es.flag = FLAG_ON ;
//					}
//				}
//					es.counter = FLAG_OFF ;
//		if( es.flag == FLAG_ON )
//		  {
//			es.y += 8 ;
//			if( es.y > 480 ) es.flag = FLAG_OFF ;
//			DrawGraph( es.x , es.y , es.img , FALSE ) ;
//		  }
//	}
//                
define.h

コード:

#include "DxLib.h"
#define SHOT 2
#define FLAG_ON 1
#define FLAG_OFF 0
#define WINDOW_H 480
#define WINDOW_W 640
#define MOVE_UP 1
#define MOVE_DAWN 0
#define MOVE_RIGHT 1
#define MOVE_LEFT 0
#define SCROLL_SPEED 1
#define MARGIN 0
#define ENEMEY_MAX 20
my.cpp

コード:

#include "DxLib.h"
#include "struct.h"
#include "difine.h"
#include <math.h>
struct ch c;
struct shot s[SHOT];
extern struct enemy enemey[ENEMEY_MAX];
extern int img_enemy1[];
int i;
int put;
//extern int t;
PointData Tracking( double ax, double ay, double aw, double ah, double bx, double by, double bw, double bh, double speed );
void MyDraw()
{
			if(c.x>=620)c.x=c.x-10;
			if(c.y>=460)c.y=c.y-10;
			if(c.x==-10)c.x=c.x+10;
			if(c.y==-10)c.y=c.y+10;
			DrawGraph(c.x,c.y,c.img,TRUE);
			//SetBackgroundColor( 0, 0, 0 ) ;
}
//**
//* 衝突判定処理(
//*	→オブジェクトの座標と大きさをもとに衝突判定を行う
//*	戻り値1:衝突あり   0:衝突なし
//*/
int Colison( int Object1X, int Object1Y, int Object1W, int Object1H,
				int Object2X,int Object2Y, int Object2W, int Object2H ){
	int colflg;
	colflg = 0;

	if( ( ( Object1X > Object2X && Object1X < Object2X + Object2W )||
		( Object2X > Object1X && Object2X < Object1X + Object1W ) ) &&
	( ( Object1Y > Object2Y && Object1Y < Object2Y + Object2H ) ||
		( Object2Y > Object1Y && Object2Y < Object1Y + Object1H ) ) ){
	  colflg = 1;
	}
	return colflg;
}
//
////**
////* 追跡処理(
////	引数の座標から目的の座標へ指定速度で向かった際の新しい座標を求める
////	・引数1:基準オブジェクトのX座標
////	・引数2:基準オブジェクトのY座標
////	・引数3:基準オブジェクトの幅
////	・引数4:基準オブジェクトの高さ
////	・引数5:目標オブジェクトのX座標
////	・引数6:目標オブジェクトのY座標
////	・引数7:目標オブジェクトの幅
////	・引数8:目標オブジェクトの高さ
////	・引数9:目標に接近する速度(変化量)
////*/
//

	PointData Tracking( double ax, double ay, double aw, double ah, double bx, double by, double bw, double bh, double speed ){
		double obj1_x, obj1_y, obj2_x, obj2_y, abx, aby, sb;
		PointData newPoint;

		// オブジェクトの中心座標を求める
		obj1_x = ax + aw / 2;
		obj1_y = ay + ah / 2;
		obj2_x = bx + bw / 2;
		obj2_y = by + bh / 2;

		// 平方根を求めるのに標準関数の sqrt を使う


		abx = obj2_x - obj1_x ; 
		aby = obj2_y - obj1_y ;
		sb = sqrt( abx * abx + aby * aby ) ;

		// 1フレーム当たりspeed分だけ移動した座標を求める

		newPoint.x = ( ax + abx / sb * speed ) ;
		newPoint.y = ( ay + aby / sb * speed ) ;

		return newPoint;
	}
void KeyCheck()
{
			if(CheckHitKey(KEY_INPUT_LEFT)) c.x-=c.speed;
			
			if(CheckHitKey(KEY_INPUT_RIGHT))c.x+=c.speed;
			
			if(CheckHitKey(KEY_INPUT_UP))c.y-=c.speed;
		
			if(CheckHitKey(KEY_INPUT_DOWN))c.y+=c.speed;

			if(CheckHitKey(KEY_INPUT_A)){  //zで玉の発射

				if(s[i].bflag==FLAG_OFF){
					s[i].bflag=FLAG_ON;
					for( i=0;i<SHOT;i++){
						if(s[i].flag==FLAG_OFF){
						s[i].x=(c.w-s[i].w)/2+c.x;
						s[i].y=(c.h-s[i].h)/2+c.y;

						s[i].flag=FLAG_ON;
						break;
					}
				}
			}
		}else{
			s[i].bflag=FLAG_OFF;
		}
}
void MyShotMove() //ここでホーミング処理
{
	PointData p;	//下のpを定義的なもの
	//for(t=0;t<ENEMEY_MAX;t++)
	for(i=0;i<SHOT;i++){
		if(s[i].flag==FLAG_ON){

			p = Tracking( s[i].x,	//玉のx
						  s[i].y,	//玉のy
						  s[i].w,		//玉のw
						  s[i].h,		//玉のh
						  enemey[i].x,		//対象のx
						  enemey[i].y,		//対象のy
						  enemey[i].w,		//対象のw
						  enemey[i].h,		//対象のh
						  2.0);			//スピード

			s[i].x = p.x + 0.5;		//動きの計算x
			s[i].y=  p.y + 0.5;		//動きの計算y

			if(s[i].y<0){
					s[i].flag=FLAG_OFF;
			}
		}
			if(Colison(s[i].x,s[i].y,s[i].w,s[i].h,
				enemey[i].x,enemey[i].y,enemey[i].w,enemey[i].h)==FLAG_ON){
				s[i].flag=FLAG_OFF;
				if(enemey[i].damageflag=FLAG_ON)DeleteGraph(img_enemy1[0]);
				enemey[i].damageflag=FLAG_ON;
				enemey[i].damagecounter=FLAG_OFF;
				}
			DrawGraph(s[i].x,s[i].y,s[i].img,TRUE);
	}
	}
コンパイルするとエラーは起きないのですが敵が描画されません画像のハンドルはあっています
どなたかお力添えしてはいただけないでしょうか

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 敵が描画されません

#2

投稿記事 by みけCAT » 10年前

とりあえずコンパイルしてみました。
difine.hが無いと怒られたので、以下の内容で作成しました。

コード:

#include "define.h"
コンパイラの警告メッセージを以下に示します。

コード:

enemey.cpp: In function 'void EnemyControl()':
enemey.cpp:17:34: warning: iteration 20u invokes undefined behavior [-Waggressive-loop-optimizations]
                 if(enemey[i].flag==FLAG_ON)
                                  ^

enemey.cpp:16:9: note: containing loop
         for(int i=0;i<100;i++)
         ^

In function 'void EnemyCalcDisp()':
cc1plus.exe: warning: iteration 19u invokes undefined behavior [-Waggressive-loop-optimizations]

enemey.cpp:43:9: note: containing loop
         for(i=0;i<100;i++)
         ^

inti.cpp: In function 'void GameInit()':
inti.cpp:44:5: warning: array subscript is above array bounds [-Warray-bounds]
  s[i].bflag=FLAG_OFF;
     ^

main.cpp:4:12: warning: unused parameter 'hInstance' [-Wunused-parameter]
 int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){
            ^
main.cpp:4:12: warning: unused parameter 'hPrevInstance' [-Wunused-parameter]
main.cpp:4:12: warning: unused parameter 'lpCmdLine' [-Wunused-parameter]
main.cpp:4:12: warning: unused parameter 'nCmdShow' [-Wunused-parameter]

my.cpp: In function 'void MyShotMove()':
my.cpp:135:36: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
     if(enemey[i].damageflag=FLAG_ON)DeleteGraph(img_enemy1[0]);
                                    ^
すなわち
  • enemey.cppの15行目からのEnemyControl関数で、enemeyは20要素しか確保していないのに、
    enemey[99]までアクセスしていて、確保された領域の外にアクセスしています。何が起こるかわかりません。
  • enemey.cppの43,44行目でも、同様に確保された領域の外にアクセスしています。何が起こるかわかりません。
  • inti.cppの44行目で、直前のループでiは20に設定されているのに対し、sは2要素しか確保されていないので、
    確保された領域の外にアクセスしています。何が起こるかわかりません。46行目も同様です。
  • my.cppの135行目で、if文の条件式で代入を行っています。
    従って、ここが実行されると必ずDeleteGraph(img_enemy1[0]);が実行され、
    enemey.cppの45行目で利用されている画像ハンドルが無効になります。その結果、敵が描画されなくなるでしょう。
アドバイスとしては、
  • インデントを整えたほうがいいと思います。
  • ループで利用する要素数は、マジックナンバー(i<100のようにコード中に直接書かれた定数)ではなく、
    i<ENEMEY_MAXのように定義された定数を利用するべきです。
  • main.cppの「メインループ」は、1周目でbreak;しているのでループとしての役割が全く無さそうです。
    従って、while文とbreak;を消していいと思います。
  • GameTitle()とGameMain()で別々のメインループがある構造は良くないかもしれません。
  • DxLib_End()は必ず呼び出してください。
    main.cppの18行目で条件CheckHitKey(KEY_INPUT_ESCAPE)をチェックする必要はありません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

isyy
記事: 19
登録日時: 10年前
住所: 北海道

Re: 敵が描画されません

#3

投稿記事 by isyy » 10年前

ご指摘ありがとうございました
おかげさまで複製ができました。

閉鎖

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