敵弾がたまに消失する

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

敵弾がたまに消失する

#1

投稿記事 by Iseuma14 » 4年前

たびたび質問失礼します
私は現在、練習用のプログラムとしてインベーダーゲームもどきを作っております
敵弾をランダムにばら撒くように実装したのですが、放たれた球が画面外に行かないうちに消えてしまうことがあります
以下、関係ありそうなコード部分です 少し長いかもしれませんがご容赦ください

コード:

//main.cpp
#include "DxLib.h"
#include "struct.h"
#include "define.h"
#include "load.h"
#include "draw.h"
#include "init.h"
#include "player.h"
#include "shot.h"
#include "enemy.h"

int key_input(int*);

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
	ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);
	int key[256],process = 0,stage_count = 0,se[5],level = 1;
	player_t player;
	enemy_t enemy[12][4];
	shot_t shot[SHOT_MAX];
	shot_t p_shot;

	while(ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && key_input(key)==0)
	{
		switch(process)
		{
			case 0:
				init_player(&player);
				init_enemy(enemy);
				init_se(se);
				init_shot(shot,&p_shot);
				load_player(&player);
				load_enemy(enemy);
				load_shot(shot,&p_shot);
				process = 1;
				break;

			case 1:
				draw_player(&player);
				draw_enemy(enemy);
				draw_shot(shot);
				player_move(&player,key);
				enemy_front(enemy);
				enemy_move(enemy,se,&stage_count);
				enemy_shot_rand(enemy,shot,level);
				shot_move(shot,enemy);
				stage_count++;
				break;
		}
		
	}


	DxLib_End();
	return 0;
}

int key_input(int *key)
{
	char temp[256];
	GetHitKeyStateAll(temp);
	int i;
	for(i=0;i<256;i++)
	{
		if(temp[i] != 0)
		{
			key[i]++;
		}
		else
			key[i] = 0;
	}
	return 0;
}

//struct.h
#ifndef INCLUDE_STRUCT
#define INCLUDE_STRUCT

struct player_t
{
	bool flag; //フラグ
	bool shot_flag; //弾を撃っているか
	int life;  //残機
	int x;     //x座標
	int y;     //y座標
	int img;   //画像
	int score; //スコア
};

struct enemy_t
{
	bool life_flag;  //フラグ
	bool front_flag; //最前列のフラグ
	bool shot_flag; //弾を撃っているか
	int x;			 //x座標
	int y;			//y座標
	int sy;         //撃った弾の座標
	int img;		 //画像
	int down_count;	 //下がるまでの時間
};

struct shot_t
{
	bool flag; //フラグ
	int x; //x座標
	int y; //y座標
	int vy; //yの移動スピード
	int img; //画像
};



#endif

//define.h
#ifndef INCLUDE_DEFINE
#define INCLUDE_DEFINE

#define WHITE GetColor(255,255,255) //白の取得

#define PLAYER_LIFE_FIRST 3 //プレイヤーの初期の残機

#define PLAYER_LIFE_MAX 5 //プレイヤーの最大残機

#define X_MAX 630 //プレイヤーの右の最高点

#define X_MIN 10 //プレイヤーの左の最低点

#define X_START 320 //プレイヤーのx座標の初期値

#define Y_POINT 360 //プレイヤーのy座標

#define CHOOSE 0 //ここからTOまで音楽用

#define HIT 1 

#define PI 2 

#define PO 3 

#define TO 4 

#define RAND_FIRST 60 

#define SHOT_MAX 10 //ばら撒き弾の最高数

#endif

//enemy.cpp

#include "DxLib.h"
#include "enemy.h"
#include "shot.h"
#include "draw.h"
#include "rand.h"
#include "define.h"
#include "struct.h"
#include <math.h>

void enemy_move(enemy_t enemy[][4],int se[],int *stage_count) //敵を動かす関数
{
	static bool flag = 0; //右移動時は0,左移動時は1
	static int move_count = 0,se_flag = 2; //動いた回数の記録 8回動いたらflagを反転
	int i,j;
	int timing = 120; //移動のタイミング 敵を一定以下に減らすと速くなる
	if(*stage_count % timing == 0)
	{
		if(flag == FALSE)
		{
			for(i=0;i<12;i++)
			{
				for(j=0;j<4;j++)
				{
					enemy[i][j].x += 25;
					if(se_flag % 2 == 0)
						PlaySoundMem(se[TO],DX_PLAYTYPE_BACK);
					else if(se_flag % 2 == 1)
						PlaySoundMem(se[PO],DX_PLAYTYPE_BACK);
				}
			}
			se_flag++;
			move_count++;
		}
		else if(flag == TRUE)
		{
			for(i=0;i<12;i++)
			{
				for(j=0;j<4;j++)
				{
					enemy[i][j].x -= 25;
					if(se_flag % 2 == 0)
						PlaySoundMem(se[TO],DX_PLAYTYPE_BACK);
					else if(se_flag % 2 == 1)
						PlaySoundMem(se[PO],DX_PLAYTYPE_BACK);
				}
			}
			move_count++;
			se_flag++;
		}
		if(move_count % 8 == 0 && flag == FALSE)
			flag = TRUE;
		else if(move_count % 8 == 0 && flag ==TRUE)
			flag = FALSE;
	}
}

void enemy_shot_rand(enemy_t enemy[][4],shot_t *shot,int level) //rand.cppから関数を呼び出し敵にランダムで弾を撃たせる関数
{
	int i;
	int temp;
	int keep;
	int front;
	for(i=0;i<SHOT_MAX;i++)
	{
		if((temp=shot_search(shot)) != -1)
		{
			if(rand_shot_enemy()==0)
			{
				shot[i].flag = 1;
				keep = rand_enemy(enemy);
				front = enemy_front_search(enemy,keep);
				enemy[keep][front].shot_flag = 1;
				shot[i].x = enemy[keep][front].x;
				shot[i].y = enemy[keep][front].y+5;
				shot[i].vy = 5;
				enemy[keep][front].sy = shot[i].y;
			}

		}
	}
}

void enemy_front(enemy_t enemy[][4]) //最前列フラグを動かす関数
{
	int i;
	for(i=0;i<12;i++)
	{
		
		if(enemy[i][3].life_flag == 0 && enemy[i][2].life_flag==1)
		{
			enemy[i][3].front_flag = 0;
			enemy[i][2].front_flag = 1;
		}
		if(enemy[i][2].life_flag == 0 && enemy[i][1].life_flag==1)
		{
			enemy[i][2].front_flag = 0;
			enemy[i][1].front_flag = 1;
		}
		if(enemy[i][1].life_flag == 0 && enemy[i][0].life_flag==1)
		{
			enemy[i][1].front_flag = 0;
			enemy[i][0].front_flag = 1;
		}
		if(enemy[i][0].life_flag == 0) 
			enemy[i][0].front_flag = 0;
	}
}
int enemy_front_search(enemy_t enemy[][4],int temp) //敵の指定された行の最前列の敵の要素番号を返す
{
	int i;
	for(i=3;i>-1;i--)
	{
		if(enemy[temp][i].life_flag == 1)
			return i;
	}
	return -1;
}

//shot.cpp
#include "DxLib.h"
#include "enemy.h"
#include "shot.h"
#include "define.h"
#include "struct.h"

int shot_search(shot_t *shot) //空いているshotの要素番号を返す
{
	int i;
	for(i=0;i<SHOT_MAX;i++)
	{
		if(shot[i].flag == 0)
			return i;
	}
	return -1;
}

void shot_move(shot_t *shot,enemy_t enemy[][4]) //フラグがたっている弾を動かす
{
	int i,j;
	for(i=0;i<SHOT_MAX;i++)
	{
		if(shot[i].flag == 1)
		{
			shot[i].y += shot[i].vy;
		}

		if(shot[i].y > 500)
		{
			shot[i].flag = 0;
			shot[i].x = 0;
		}
	}
}

//rand.cpp
#include "DxLib.h"
#include "rand.h"
#include "enemy.h"
#include "define.h"
#include "struct.h"

int rand_shot_table(int level) 
{
	return GetRand(RAND_FIRST / level);
}

int rand_shot_enemy() //敵のショットを撃つタイミングのランダムテーブル
{
	return GetRand(600);
}

int rand_enemy(enemy_t enemy[][4]) //どの敵が弾を打つかを返す関数
{
	int hoge,front;
	while(1)
	{
		hoge = GetRand(11);
		if((front=enemy_front_search(enemy,hoge)) == -1 || enemy[hoge][front].shot_flag == 1)
		{
			continue;
		}
		else
		{
			return hoge;
		}
	}
}
おそらく関係ある部分全部です 長くて申し訳ないです もしかしたら張ってない部分があるかもしれません
何卒ヒントをよろしくお願いいたします 
また、その他も改良すべき点や挙動がおかしいところがあれば教えていただけるとうれしいです

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