STGについてです

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

STGについてです

#1

投稿記事 by ボラ天神 » 13年前

私はシューティングゲームを作り始めたのですが、弾を決めた角度で発射したいと思っています。上方向に扇型に東方のように撃ちたいと考えていたのですが、綺麗に発射されず、バラバラに発射されます。

コードは

コード:

#include"DxLib.h"
#include<math.h>
//グローバル変数(mymain.cpp only)定数 構造体---------------------------------------------------
#define TAMAKAZU 10
#define TEKIKAZU 1
#define TEKITAMA 10
#define PI 3.141592654f
#define PLAYER_MAX_SHOT 11

struct Chara {
	int x;
	int y;
	int g;
	int life;
	int image_h;
	int image_w;
	int bounds_h;
	int bounds_w;
	int count;
	int rand;
};

struct Chara jiki;
struct Chara shot[TAMAKAZU][PLAYER_MAX_SHOT];
struct Chara teki[TEKIKAZU];
struct Chara tekitama[TEKITAMA];

int i, j, p;
int Teki_y_flag[TEKIKAZU];//xxx:
int Teki_x_flag[TEKIKAZU];//xxx:
int Count;


int IsAtari(Chara, Chara);
int AtariHantei();
void PlayerShot();
//----------------------------------------------------------------------------------



int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow )
{
	AllocConsole();
	freopen("CONOUT$", "w",stdout);
	ChangeWindowMode(TRUE);				//ウィンドウモード
	if( DxLib_Init() == -1 ) return -1;				//初期化7
		for(i=0;i<TEKIKAZU;i++) {
			if(teki[i].life == 1) {
				teki[0].count++;
			}
		}



//-----------------------------LOADゾーン-------------------------------------------



	jiki.x = 640/2-16;
	jiki.y = 480-32;
	jiki.g = LoadGraph("media\\test001.png",TRUE);
	jiki.image_w = 32;
	jiki.image_h = 32;
	jiki.bounds_w = 20;
	jiki.bounds_h = 20;

	for(i=0;i<TAMAKAZU;i++) {
		for(j=0;j<PLAYER_MAX_SHOT;j++) {
			shot[i][j].life = 0;
			shot[i][j].x = 0;
			shot[i][j].y = 0;
			shot[i][j].g = LoadGraph("media\\tama1.png",TRUE);
			shot[i][j].image_w = 8;
			shot[i][j].image_h = 16;
			shot[i][j].bounds_w = 6;
			shot[i][j].bounds_h = 12;
		}
	}

	for(i=0;i<TEKIKAZU;i++) {
		teki[i].x = 16+i*640/TEKIKAZU;
		teki[i].y = GetRand(400);//10*i;
		teki[i].g = LoadGraph("media\\teki.bmp",TRUE);
		teki[i].life = 1;
		teki[i].image_w = 32;
		teki[i].image_h = 32;
		teki[i].bounds_w = 20;
		teki[i].bounds_h = 20;

		Teki_x_flag[i] = 1;
		Teki_y_flag[i] = 1;
	}

	

	for(i=0;i<TEKITAMA;i++) {
		tekitama[i].x = 0;
		tekitama[i].y = 0;
		tekitama[i].g = LoadGraph("media\\tama.png",TRUE);
		tekitama[i].life = 0;
		tekitama[i].image_w = 13;
		tekitama[i].image_h = 13;
		tekitama[i].bounds_w = 10;
		tekitama[i].bounds_h = 10;
		tekitama[i].rand = 1;
	}


//----------------------------------------------------------------------------------


	SetDrawScreen( DX_SCREEN_BACK ) ;


//------------------------------ループ----------------------------------------------


	while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ){

		ClearDrawScreen() ;

		if(CheckHitKey(KEY_INPUT_UP) == TRUE)	jiki.y -= 4;
		if(CheckHitKey(KEY_INPUT_DOWN) == TRUE)	jiki.y += 4;
		if(CheckHitKey(KEY_INPUT_RIGHT) == TRUE)jiki.x += 4;
		if(CheckHitKey(KEY_INPUT_LEFT) == TRUE) jiki.x -= 4;

		
		PlayerShot();


		for(i=0;i<TEKIKAZU;i++) {
			if(teki[i].life) {
				
				teki[i].y += 2*Teki_y_flag[i]*10;	//敵速さ
				teki[i].x += 2*Teki_x_flag[i]*5;

				
				if(teki[i].y <= 0){	Teki_y_flag[i] = 1;			}
				if(teki[i].y > 480-32){	Teki_y_flag[i] = -1;	}
				if(teki[i].x <= 0) { Teki_x_flag[i] = 1;		}	
				if(teki[i].x > 640-32) { Teki_x_flag[i] = -1;	}

				
				DrawGraph(teki[i].x,teki[i].y,teki[i].g,TRUE);
			}
			
		}
		Count++;

		if(jiki.x < 0)	jiki.x = 0;
		if(jiki.x > 640-32)	jiki.x = 640-32;
		if(jiki.y < 0)	jiki.y = 0;
		if(jiki.y > 480-32)	jiki.y = 480-32;
		/*

		for(i=0;i<TEKITAMA;i++) {
			tekitama[i].rand = GetRand(100);
			if(tekitama[i].rand == 0 && tekitama[i].life == 0) {
				tekitama[i].x = teki[i].x + 16;
				tekitama[i].y = teki[i].y + 16;
				tekitama[i].life = 1;
				break;
			}

			if(tekitama[i].life == 1) {
				tekitama[i].y += 4;
				if(tekitama[i].y > 480)	{
					tekitama[i].life = 0;
				}
				DrawGraph(tekitama[i].x,tekitama[i].y,tekitama[i].g,TRUE);
				//printf("X: %d Y: %d \n",tekitama[0].x,tekitama[0].y);
				printf("%d\n",tekitama[0].rand);
			} 

			
		}
		*/
	


		DrawGraph(jiki.x,jiki.y,jiki.g,TRUE);

		if(AtariHantei() == 1)	printf("HIT\n");



		

		ScreenFlip() ;
	}



//---------------------------------------------------------------------------------

	DxLib_End() ;				

	return 0 ;					
}

int IsAtari(Chara a, Chara b) {
	int retval = 0;
	int ax1 = a.x + (a.image_w - a.bounds_w)/2;
	int ay1 = a.y + (a.image_h - a.bounds_h)/2;
	int ax2 = a.x + (a.image_w + a.bounds_w)/2;
	int ay2 = a.y + (a.image_h + a.bounds_h)/2;
	int bx1 = b.x + (b.image_w - b.bounds_w)/2;
	int by1 = b.y + (b.image_h - b.bounds_h)/2;
	int bx2 = b.x + (b.image_w + b.bounds_w)/2;
	int by2 = b.y + (b.image_h + b.bounds_h)/2;

	if( (ax1<bx2) && (bx1<ax2) && (ay1<by2) && (by1<ay2) ) {
		retval = 1;
	}
	return (retval);
}

int AtariHantei() {
	for(i=0;i<TEKIKAZU;i++) {
		if(teki[i].life > 0) {
			if(IsAtari(jiki,teki[i])==1)	return(1);

			for(j=0;j<TAMAKAZU;j++) {
				for(p=0;p<PLAYER_MAX_SHOT;p++) {
					if(shot[j][p].life > 0) {
						if(IsAtari(shot[j][p], teki[i]) == 1) {
							shot[j][p].life = 0;
							teki[i].life = 0;
							printf("TEKI  HIT!!\n");
						}
					}
				}
			}
		}
	}
	return(0);
}

void PlayerShot() {
		if((CheckHitKey(KEY_INPUT_Z) == TRUE) && (Count%5 == 0)){
			for(i=0;i<TAMAKAZU;i++) {
				for(j=0;j<PLAYER_MAX_SHOT;j++) {
					if(shot[i][j].life == 0) {
						shot[i][j].life = 1;
						switch(j) {
						case 0:
							shot[i][j].x = jiki.x+0;
							shot[i][j].y = jiki.y-15;
							break;
						case 1:
							shot[i][j].x = jiki.x-15;
							shot[i][j].y = jiki.y-6;
							break;
						case 2:
							shot[i][j].x = jiki.x+15;
							shot[i][j].y = jiki.y-6;
							break;
						case 3:
							shot[i][j].x = jiki.x-10;
							shot[i][j].y = jiki.y-2;
							break;
						case 4:
							shot[i][j].x = jiki.x+10;
							shot[i][j].y = jiki.y-2;
							break;
						case 5:
							shot[i][j].x = jiki.x-10;
							shot[i][j].y = jiki.y+2;
							break;
						case 6:
							shot[i][j].x = jiki.x+10;
							shot[i][j].y = jiki.y+2;
						case 7:
							shot[i][j].x = jiki.x-10;
							shot[i][j].y = jiki.y+6;
							break;
						case 8:
							shot[i][j].x = jiki.x+10;
							shot[i][j].y = jiki.y+6;
							break;
						case 9:
							shot[i][j].x = jiki.x-10;
							shot[i][j].y = jiki.y+10;
							break;
						case 10:
							shot[i][j].x = jiki.x+10;
							shot[i][j].y = jiki.y+10;
							break;
						default :
							for(p=0;p<100;p++) {
								printf("EEEEEEE\n");
							}
							break;
						}
						break;
					}
				}
			}
		}
		for(i=0;i<TAMAKAZU;i++) {
			for(j=0;j<PLAYER_MAX_SHOT;j++) {
				if(shot[i][j].life > 0) {
					shot[i][j].y -= 10;
					switch(j) {
						case 0:
						case 1:
						case 2:
							shot[i][j].x += 0;
							break;
						case 3:
							shot[i][j].x -= 1;
							break;
						case 4:
							shot[i][j].x += 1;
							break;
						case 5:
							shot[i][j].x -= 2;
							break;
						case 6:
							shot[i][j].x += 2;
						case 7:
							shot[i][j].x -= 3;
							break;
						case 8:
							shot[i][j].x += 3;
							break;
						case 9:
							shot[i][j].x -= 5;
							break;
						case 10:
							shot[i][j].x += 5;
							break;
					}
				
					
					DrawGraph(shot[i][j].x,shot[i][j].y,shot[i][j].g,TRUE);
					if(shot[i][j].y < 0) {
						shot[i][j].life = 0;
					}
				}
			}
		}
}
とても汚いですがすみません。余計なものが含まれていますが気にしないでください。
なぜ弾が汚く撃たさってしまうのでしょう?
教えていただけると助かります。

jay
記事: 314
登録日時: 15年前
住所: 大阪市
連絡を取る:

Re: STGについてです

#2

投稿記事 by jay » 13年前

何の為に”PI”という定数を宣言したのですか
宣言したのなら使ってあげて下さい!

弾に角度を示す変数を用意してあげて、その角度とスピードを元に計算する仕様にしてあげてください
STGではそれが一番ベターです
弾の計算の移動際にはmath.hのsin関数とcos関数を使ってやればいいでしょう
このあたりも参考になると思います


あとこれはお節介ですが
他人に見せるのならもう少しコードを解説するためのコメントを残してあげた方がいいと思います
コメントあった方が読み解く方も楽ですし、後々自分でコードをメンテナンスするときにもかなり楽になりますよ~
♪僕たちは まだ森の中 抜け出そう 陽のあたる場所へ

sperobo

Re: STGについてです

#3

投稿記事 by sperobo » 13年前

さらっと見ただけなので間違っているかもしれませんが…

jのループのswitch文の直後のbreakでjのループから抜けてiのループの処理に移るのが原因ではないでしょうか。
初期化された状態では全部の弾のLifeフラグが0なので、switch文のcase 0に必ず入り、switch文の外のbreakで外のループに抜けます。
結果、最初のフレームで発射されるのは、shot[0][0], shot[1][0], shot[2][0]....
つまり、jが0の時の弾(直進するだけの弾)が10個生成される事になります。
さらにその弾が敵に当たりLifeフラグが0になる弾が出てくるので、弾を発射すればする程バラバラになっていくんだと思います。

とはいえ、breakを消すだけで解決する事では無いので、
弾を2次元配列で管理するのとインデックスで弾の移動量を決めるのをやめ、
配列のどこに弾を格納しても意図した動きをするような設計にする必要があります。

閉鎖

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