2Dゲーム制作(途中経過のソースコード)

(Enemy.h)

#pragma once
#include "main.h"


//-----------------
// 定数定義
//-----------------
// 敵キャラ
const int ENEMY_WID = 32;				// 敵の画像の横サイズ
const int ENEMY_HIG = 23;				// 敵の画像の縦サイズ
const int ENEMY_PATTERNS = 2;			//敵のアニメーション配列数
const int ENEMY_DISP_X_DISTANCE = 8;	//敵キャラ同士の横の間隔
const int ENEMY_DISP_Y_DISTANCE = 4;	//敵キャラ同士の縦の間隔

// 敵キャラの画面表示関連
const int ENEMY_DISP_XNUM = 8;				// 敵キャラの横の表示個数
const int ENEMY_DISP_YNUM = 7;				// 敵キャラの縦の表示個数
const int ENEMY_DISP_ALL_NUM = ENEMY_DISP_XNUM * ENEMY_DISP_YNUM;

// 敵キャラの移動関連
const int ENEMY_MOVE_X_SPEED = 4;			//敵の横方向の移動量
const int ENEMY_MOVE_Y_SPEED = (ENEMY_HIG + ENEMY_DISP_Y_DISTANCE);//敵の縦方向移動量
const int ENEMY_MOVE_INTERVAL_COUNT = 8;	//敵移動のインターバル

extern int enemyPosxArray[][ENEMY_DISP_XNUM];	// 敵のX座標表示位置テーブル
extern int enemyPosyArray[][ENEMY_DISP_XNUM];	// 敵のY座標表示位置テーブル
extern bool enemyFlgArray[][ENEMY_DISP_XNUM];	// 敵の存在フラグテーブル(フレーム数)

//----------------------------------------
//プロトタイプ宣言
//----------------------------------------
bool EnemySysInit(void);
void EnemyInit(void);
void EnemyDraw(void);
void EnemyMove(void);
bool EnemyRelease(void);

eEnemyHitEdgeDir CheckHitEdgeProc(void);

(Enemy.cpp)

#include<DxLib.h>
#include"main.h"
#include"Enemy.h"
#include"Player.h"

//-----------------
// 変数の宣言
//-----------------

// 敵キャラ
int enemyImage[ENEMY_PATTERNS];						// 敵の画像ハンドル番号
int enemyPosxArray[ENEMY_DISP_YNUM][ENEMY_DISP_XNUM];	// 敵のX座標表示位置テーブル
int enemyPosyArray[ENEMY_DISP_YNUM][ENEMY_DISP_XNUM];	// 敵のY座標表示位置テーブル
bool enemyFlgArray[ENEMY_DISP_YNUM][ENEMY_DISP_XNUM];	// 敵の存在フラグテーブル

eEnemyMoveDirection enemyMoveDirection;		//敵キャラの現在の移動方向
eEnemyMoveDirection enemyNextMoveDirection;	//敵キャラの下移動後の移動方向
int enemyMoveIntervalCounter;				//敵キャラ移動の間隔調整用カウンタ

bool EnemySysInit(void) {

	//敵の画像の読込み
	int err = LoadDivGraph("image/enemy_1.png", ENEMY_PATTERNS, ENEMY_PATTERNS, 1, ENEMY_WID, ENEMY_HIG, enemyImage);
	if (err == -1)return false;
	
	return true;
}

void EnemyInit(void) {


	//-----------------
	// 変数の初期化
	//-----------------

	// 敵キャラの変数テーブルの初期化
	for (int yy = 0; yy < ENEMY_DISP_YNUM; yy++) {
		for (int xx = 0; xx < ENEMY_DISP_XNUM; xx++) {
			enemyPosxArray[yy][xx] = (ENEMY_WID + ENEMY_DISP_X_DISTANCE) * xx;
			enemyPosyArray[yy][xx] = (ENEMY_HIG + ENEMY_DISP_Y_DISTANCE) * yy;
			enemyFlgArray[yy][xx] = true;
		}
	}

	enemyMoveDirection = ENEMY_DIR_RIGHT;
	enemyNextMoveDirection = ENEMY_DIR_NON;

	enemyMoveIntervalCounter = -1;//カウンタ初期化(00:15~)


}

void EnemyMove(void) {
	enemyMoveIntervalCounter++;
	if (enemyMoveIntervalCounter > 0) {
		if (enemyMoveIntervalCounter >= ENEMY_MOVE_INTERVAL_COUNT) {
			enemyMoveIntervalCounter = -1;
		}
		return;
	}

	for (int yy = 0; yy < ENEMY_DISP_YNUM; yy++) {
		for (int xx = 0; xx < ENEMY_DISP_XNUM;xx++) {
			if (enemyFlgArray[yy][xx]) {
				switch (enemyMoveDirection) {
				case ENEMY_DIR_RIGHT:
					enemyPosxArray[yy][xx] += ENEMY_MOVE_X_SPEED;
					break;
				case ENEMY_DIR_LEFT:
					enemyPosxArray[yy][xx] -= ENEMY_MOVE_X_SPEED;
					break;
				case ENEMY_DIR_DOWN:
					enemyPosyArray[yy][xx] += ENEMY_MOVE_Y_SPEED;
					break;

				}
			}
		}
	}
	// エリアの端にぶつかっていないかのチェック
	eEnemyHitEdgeDir hitdir = CheckHitEdgeProc();
	switch (hitdir) {
	case ENEMY_HIT_EDGE_NON:
		// 通常移動:次の方向に移る
		if (enemyNextMoveDirection != ENEMY_DIR_NON) {
			enemyMoveDirection = enemyNextMoveDirection;
			enemyNextMoveDirection = ENEMY_DIR_NON;
		}
		break;

	case ENEMY_HIT_EDGE_RIGHT:
		enemyMoveDirection = ENEMY_DIR_DOWN;
		enemyNextMoveDirection = ENEMY_DIR_LEFT;
		break;

	case ENEMY_HIT_EDGE_LEFT:
		enemyMoveDirection = ENEMY_DIR_DOWN;
		enemyNextMoveDirection = ENEMY_DIR_RIGHT;
		break;

	case ENEMY_HIT_EDGE_DOWN:
		// 敵が最下段に到達 → 負け処理へ
		break;
	}
	
}


void EnemyDraw(void) {
	// 敵の描画
	for (int yy = 0; yy < ENEMY_DISP_YNUM; yy++) {
		for (int xx = 0; xx < ENEMY_DISP_XNUM;xx++) {
			if (enemyFlgArray[yy][xx]) {
				DrawGraph(enemyPosxArray[yy][xx], enemyPosyArray[yy][xx], enemyImage[0], true);
			}
		}
	}
}

//エリアの端にぶつかっていないかのチェック処理
eEnemyHitEdgeDir CheckHitEdgeProc(void) {
	
	int restnum;//その列に生き残っている敵の数を格納する変数(ローカル)
	eEnemyHitEdgeDir hitdir = ENEMY_HIT_EDGE_NON;
		switch(enemyMoveDirection) {
		//右方向に移動中なので、右端に接触していないかをチェックする
		case ENEMY_DIR_RIGHT:
			for (int xx = ENEMY_DISP_XNUM-1; xx >= 0;xx--){
				restnum = 0;//敵が残っていなかった場合、チェックする列を移行するたびにチェックを初期化する
				for (int yy = 0;yy < ENEMY_DISP_YNUM;yy++) {
					if (enemyFlgArray[yy][xx] == true) {
						restnum++;
						if (enemyPosxArray[yy][xx] >= (WINDOW_WID - ENEMY_WID)) {
							hitdir = ENEMY_HIT_EDGE_RIGHT;
							break;
						}
					}
				}
				if(hitdir != ENEMY_HIT_EDGE_NON || restnum > 0)break;	//端に接触しているか、端に接触していなくても残っている敵がいる場合にbreak
			}
			break;

		//左方向に移動中なので、左端に接触していないかをチェックする
		case ENEMY_DIR_LEFT:
			for (int xx = 0; xx < ENEMY_DISP_XNUM ;xx++){
				restnum = 0;//敵が残っていなかった場合、チェックする列を移行するたびにチェックを初期化する
				for (int yy = 0;yy < ENEMY_DISP_YNUM;yy++){
					if (enemyFlgArray[yy][xx] == true) {
						restnum++;
							if (enemyPosxArray[yy][xx] <= 0){
								hitdir = ENEMY_HIT_EDGE_LEFT;
								break;
							}
					}
				}
				if (hitdir != ENEMY_HIT_EDGE_NON || restnum > 0)break;	//端に接触しているか、端に接触していなくても残っている敵がいる場合にbreak

			}
			break;

		//下方向に移動中なので、下端に接触していないかをチェックする
		case ENEMY_DIR_DOWN:
			for (int yy = ENEMY_DISP_YNUM-1; yy > 0; yy--){
				restnum = 0;
				for (int xx = 0;xx < ENEMY_DISP_XNUM;xx++){
						if (enemyFlgArray[yy][xx] == true){
							restnum++;
								if (enemyPosyArray[yy][xx] >= (WINDOW_HIG - ENEMY_HIG)){
									hitdir = ENEMY_HIT_EDGE_DOWN;
									break;
								}
						}
				}
				if (hitdir != ENEMY_HIT_EDGE_NON || restnum > 0)break;	//端に接触しているか、端に接触していなくても残っている敵がいる場合にbreak
			}
			break;
		}


	return hitdir;
}

bool EnemyRelease(void)
{
	for (int ii = 0; ii < ENEMY_PATTERNS; ii++) {
		if (DeleteGraph(enemyImage[ii] )== -1)return false;
	}
	return true;
}

(EnemyBullet.h)

#pragma once

//-----------------------
// 定数定義
// -----------------------
const int ENEMY_BULLET_MOVE = 3;	//敵弾の移動量
const int ENEMY_BULLET_WID = 16;	//敵弾の画像幅
const int ENEMY_BULLET_HIG = 25;	//敵弾の画像高さ
const int ENEMY_BULLET_RAND_MAX = 99;
const int ENEMY_BULLET_RAND_VALUE = 10;


//-------------------------------
//プロトタイプ宣言
//-------------------------------
bool EnemyBulletSysInit(void);
bool EnemyBulletInit(void);
bool EnemyBulletRelease(void);
void EnemyBulletShot(void);
void EnemyBulletMove(void);
void EnemyBulletDraw(void);	

extern int enemyBulletPosXArray[][ENEMY_DISP_XNUM];
extern int enemyBulletPosYArray[][ENEMY_DISP_XNUM];
extern bool enemyBulletFlgArray[][ENEMY_DISP_XNUM];

(EnemyBullet.cpp)

#include<DxLib.h>
#include"Enemy.h"
#include"EnemyBullet.h"

//--------------------------------
//変数宣言
//--------------------------------
int enemyBulletImage;	//敵弾画像のハンドル番号
int enemyBulletPosXArray[ENEMY_DISP_YNUM][ENEMY_DISP_XNUM];
int enemyBulletPosYArray[ENEMY_DISP_YNUM][ENEMY_DISP_XNUM];
bool enemyBulletFlgArray[ENEMY_DISP_YNUM][ENEMY_DISP_XNUM];

//-------------------------------
//敵弾の初期化処理
//-------------------------------
bool EnemyBulletSysInit(void)
{
	enemyBulletImage = LoadGraph("image/enemyBullet.png");
	if (enemyBulletImage == -1)return false;
	return true;
}

bool EnemyBulletInit(void)
{
	for (int yy = 0; yy < ENEMY_DISP_YNUM; yy++){
		for (int xx = 0; xx < ENEMY_DISP_XNUM; xx++) {
			enemyBulletPosXArray[yy][xx] = enemyBulletPosYArray[yy][xx] = 0;//弾の位置初期化
			enemyBulletFlgArray[yy][xx] = false;							//弾の存在フラグを初期化

		}
	}
	return true;
}

void EnemyBulletShot(void)
{
    static int cooldown = 0;
    if (cooldown > 0) {         // クールダウン中は撃たない
        cooldown--;
        return;
    }

    // 次の発射までのフレーム数をランダム化(例:15〜45F)
    cooldown = 15 + GetRand(30); // ← SRand は Init で呼ばれてるのでOK

    // ---- 撃つ列をランダムに選ぶ ----
    // 何回かトライして、敵の残ってる列を引けたら撃つ
    for (int tries = 0; tries < ENEMY_DISP_XNUM; ++tries) {
        int xx = GetRand(ENEMY_DISP_XNUM - 1);  // 列をランダム選択

        // その列で一番下の生存敵を探す(下→上へ走査)
        int shooterY = -1;
        for (int yy = ENEMY_DISP_YNUM - 1; yy >= 0; --yy) {
            if (enemyFlgArray[yy][xx]) {
                shooterY = yy;
                break;
            }
        }
        if (shooterY < 0) continue; // この列は全滅。別列を試す

        // ★列に弾が既に1発あるなら見送り(「1列1発」ルール)
        bool columnBusy = false;
        for (int yy = 0; yy < ENEMY_DISP_YNUM; ++yy) {
            if (enemyBulletFlgArray[yy][xx]) {
                columnBusy = true;
                break;
            }
        }
        if (columnBusy) continue;

        // 発射:敵の現在座標から出す(中央下端)
        enemyBulletFlgArray[shooterY][xx] = true;
        enemyBulletPosXArray[shooterY][xx] = enemyPosxArray[shooterY][xx] + (ENEMY_WID - ENEMY_BULLET_WID) / 2;
        enemyBulletPosYArray[shooterY][xx] = enemyPosyArray[shooterY][xx] + ENEMY_HIG;

        break; // 1フレームに1発だけ
    }
}


void EnemyBulletMove(void)
{
	for (int xx=0; xx < ENEMY_DISP_XNUM; xx++) {
		for (int yy = ENEMY_DISP_YNUM - 1; yy >= 0; yy--) {
			if (enemyBulletFlgArray[yy][xx] == true) {
				//存在している敵弾のみ移動させる
				enemyBulletPosYArray[yy][xx] += ENEMY_BULLET_MOVE;
				if (enemyBulletPosYArray[yy][xx] > WINDOW_HIG) {
					//弾が画面外に移動
					enemyBulletFlgArray[yy][xx] = false;
				}
			}
		}
	}
}

void EnemyBulletDraw(void)
{
	for (int xx = 0; xx < ENEMY_DISP_XNUM; xx++) {
		for (int yy = ENEMY_DISP_YNUM - 1; yy >= 0; yy--) {
			if (enemyBulletFlgArray[yy][xx] == true) {
				//存在している敵弾のみ描画
				DrawGraph(enemyBulletPosXArray[yy][xx], enemyBulletPosYArray[yy][xx], enemyBulletImage, true);
			}
		}
		}
}

bool EnemyBulletRelease(void)
{
	if (DeleteGraph(enemyBulletImage) == -1)return false;
	return true;
}

(main.h)

#pragma once
//-----------------
// 定数定義
//-----------------
const int WINDOW_WID = 800;				// ウィンドウの横サイズ
const int WINDOW_HIG = 600;				// ウィンドウの縦サイズ


//------------------
// 列挙型定数
//------------------
//シーンの種類
enum eSceneKind {
	SCENE_KIND_TITLE,	//タイトルシーン
	SCENE_KIND_GAME,	//ゲームシーン
	SCENE_KIND_GAMEOVER,	//ゲームオーバー

	SCENE_KIND_MAX,		//
};

//ゲーム進行状況
enum eStageExitConditionsKind {
	ESTAGE_EXIT_NON = -1,			//戦闘中
	ESTAGE_EXIT_CLEAR,				//条件1:プレイヤーの勝利
	ESTAGE_EXIT_ENEMY_SHOT,			//条件2:敵弾がプレイヤーにヒット
	ESTAGE_EXIT_ENEMY_OCCUPATION,	//条件3:敵が最下段に到達

	ESTAGE_EXIT_KIND_MAX,
};

// 移動方向
enum eEnemyMoveDirection {
	ENEMY_DIR_NON = -1,	//方向設定がない場合
	ENEMY_DIR_RIGHT,	//0 :右方向
	ENEMY_DIR_LEFT,		//1 :左方向
	ENEMY_DIR_DOWN,		//2 :下方向

	ENEMY_DIR_MAX,		//
};

//接触している端の方向
enum eEnemyHitEdgeDir {
	ENEMY_HIT_EDGE_NON = -1,	//どの端にも接触していない
	ENEMY_HIT_EDGE_RIGHT,		//0:右方向
	ENEMY_HIT_EDGE_LEFT,		//1:左方向
	ENEMY_HIT_EDGE_DOWN,		//2:下端に接触

	ENEMY_HIT_EDGE_MAX,
};

//-----------------------------------------------
//他のファイルでも参照が必要なもののextern宣言
//-----------------------------------------------
extern eSceneKind sceneKind;
extern int nowSpaceKey;
extern int prevSpaceKey;


//プロトタイプ宣言
bool Init(void);
void Update(void);
void Draw(void);

(main.cpp)

//-----------------------------------------------------------------------------
// インベーダーゲーム
// 氏 名:
//-----------------------------------------------------------------------------
#include <DxLib.h>
#include <time.h>
#include"main.h"
#include"Player.h"
#include"PlayerBullet.h"
#include"Enemy.h"
#include"SceneTitle.h"
#include"SceneGame.h"
#include"SceneGameOver.h"

//定数定義


//変数宣言
eSceneKind sceneKind;	//現在のシーンを格納する変数
eStageExitConditionsKind StageExitConditionsKind; //ゲームの進行状況を格納する変数
int nowSpaceKey;		//スペースキーの現在のフレームでの状態を格納
int prevSpaceKey;		//スペースキーの直前のフレームでの状態を格納

//-----------------
// WinMain関数
//-----------------
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
{
	if (Init() == false)return -1;

	SceneTitleInit();
	SceneGameInit();

	//-----------------
	// ゲームループ
	//-----------------
	while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0) {
		//スペースキーの状態を更新
		prevSpaceKey = nowSpaceKey;					//現在のスペースキーの状態を前のキー状態にコピー
		nowSpaceKey = CheckHitKey(KEY_INPUT_SPACE);	//現在のスペースキーの状態を更新
		//テスト用処理
		prevWKeyPress = nowWKeyPress;
		nowWKeyPress = CheckHitKey(KEY_INPUT_W);
		prevLKeyPress = nowLKeyPress;
		nowLKeyPress = CheckHitKey(KEY_INPUT_L);
		prevOKeyPress = nowOKeyPress;
		nowOKeyPress = CheckHitKey(KEY_INPUT_O);
		prevBKeyPress = nowBKeyPress;
		nowBKeyPress = CheckHitKey(KEY_INPUT_B);


		//シーンごとに呼び出す処理を変える
		switch (sceneKind) {
		case SCENE_KIND_TITLE:
			SceneTitleMainProc();
			break;
		case SCENE_KIND_GAME:
			SceneGameMainProc();
			break;
		case SCENE_KIND_GAMEOVER:
			SceneGameOverMainProc();
			break;
		default:
			break;
		}

	}

	//----------------------
	// システムの終了処理
	//----------------------
	int result = 0;
	if (SceneTitleRelease() == false)result = -1;
	if (SceneGameRelease() == false)result = -1;
	if (SceneGameOverRelease() == false)result = -1;
	if(DxLib_End() == -1)result = -1;				// DXライブラリの終了処理

	return result;					// ゲームの正常終了
}
//---------------------------
//初期化処理
//---------------------------
bool Init(void)
{
	//-----------------
	// システム設定
	//-----------------
	SetWindowText("2505889 ****");			// ウィンドウのタイトルの設定
	SetGraphMode(WINDOW_WID, WINDOW_HIG, 32);		// ウィンドウのサイズと色モードの設定
	ChangeWindowMode(true);							// ウィンドウの表示モード(true=ウィンドウモード/false=フルスクリーン)

	int err = DxLib_Init();							// DXライブラリの初期化
	if (err == -1)return false;

	SRand((unsigned int)time(NULL));

	//--------------------------
	//初期化処理
	//--------------------------
	SceneTitleInit();
	SceneGameSysInit();
	SceneGameOverInit();

	sceneKind = SCENE_KIND_TITLE;

	nowSpaceKey = prevSpaceKey = 0;

	// ------------------------------------------------------------------
	// テスト用処理
	//------------------------------------------------------------------
		prevWKeyPress = nowWKeyPress = 0;
		prevLKeyPress = nowLKeyPress = 0;
		prevOKeyPress = nowOKeyPress = 0;

	return true;
}

//---------------------------
//更新処理
//---------------------------
void Update(void)
{	// プレイヤーの移動

}
//---------------------------
//描画処理
//---------------------------
void Draw(void)
{

}

(Player.h)

#pragma once

//-----------------
// 定数定義
//-----------------
// プレイヤー
const int PLAYER_WID = 32;				// プレイヤー画像の横サイズ
const int PLAYER_HIG = 19;				// プレイヤー画像の縦サイズ
const int PLAYER_MOVE_SPEED = 6;		// プレイヤーの左右の移動速度
const int PLAYER_PLANE_MAX = 3;			// プレイヤーの最大保有機数

//------------------------------------------
//他のファイルでも参照が必要な変数の extern宣言
//------------------------------------------
extern int playerPosX;				// 自機のX座標
extern int playerPosY;				// 自機のY座標
extern bool playerFlg;				// 自機の表示状態管理用フラグ(true:表示、false:非表示)
extern int playerStock;				// プレイヤーの現在の機数
//-------------------------------------------
//プロトタイプ宣言
//-------------------------------------------
bool PlayerSysInit(void);
void PlayerInit(void);
void PlayerMove(void);
void PlayerDraw(void);
bool PlayerRelease(void);

(Player.cpp)


//-----------------------------------------------------------------------------
// インベーダーゲーム
// 氏 名:****
//-----------------------------------------------------------------------------
#include <DxLib.h>
#include"main.h"
#include"Player.h"

//-----------------
// 変数の宣言
//-----------------
// プレイヤー
int playerImage;		// 自機の画像ハンドル番号
int playerPosX;			// 自機のX座標
int playerPosY;			// 自機のY座標
bool playerFlg;			// 自機の表示状態管理用フラグ(true:表示、false:非表示)
int playerStock;		//プレイヤーの現在の機数


bool PlayerSysInit(void)
{
	// プレイヤー画像の読込み
	playerImage = LoadGraph("image/player.png");
	if (playerImage == -1)return false;
	
	return true;
}

void PlayerInit(void)
{

	//-----------------
	// 変数の初期化
	//-----------------
	// プレイヤー
	playerPosX = WINDOW_WID / 2 - PLAYER_WID / 2;		// ウィンドウの中央X座標
	playerPosY = WINDOW_HIG - PLAYER_HIG;				// プレイヤーの中心座標
	playerFlg = true;
	playerStock = PLAYER_PLANE_MAX;						// プレイヤー機数を初期化

}

void PlayerMove(void)
{
	// プレイヤーの移動
	if (playerFlg) {
		//右キーが押されたか
		if (CheckHitKey(KEY_INPUT_RIGHT) == 1) {
			playerPosX += PLAYER_MOVE_SPEED; //右に移動
		}
		//左キーが押されたか
		if (CheckHitKey(KEY_INPUT_LEFT) == 1) {
			playerPosX -= PLAYER_MOVE_SPEED; //左に移動
		}
		//左端のチェック
		if (playerPosX < 0)playerPosX = 0;
		//右端のチェック
		if (playerPosX > (WINDOW_WID - PLAYER_WID - 1))playerPosX = (WINDOW_WID - PLAYER_WID - 1);
	}
}

void PlayerDraw(void)
{
	// プレイヤーの描画
	if (playerFlg) {
		DrawGraph(playerPosX, playerPosY, playerImage, true);
	}

}

bool PlayerRelease(void)
{
	if (DeleteGraph(playerImage) == -1)return false;
	return true;
}

(PlayerBullet.h)

#pragma once

//-----------------
// 定数定義
//-----------------
// プレイヤー弾
const int PLAYER_BULLET_WID = 6;		// プレイヤー弾の画像の横サイズ
const int PLAYER_BULLET_HIG = 30;		// プレイヤー弾の画像の縦サイズ
const int PLAYER_BULLET_MOVE = 12;		// プレイヤー弾の移動速度
const int BOMB_MAX = 4;					// 押し戻しの最大回数

//----------------------------------------------
//他のファイルでも参照が必要な変数の extern宣言
//----------------------------------------------
extern int playerBulletPosX;		// プレイヤー弾のX座標
extern int playerBulletPosY;		// プレイヤー弾のY座標
extern bool playerBulletFlg;		// プレイヤー弾の発射状態管理用フラグ(true:表示、false:非表示)
extern int bombStock;				//押し戻しの使用回数

//---------------------------------------
// プロトタイプ宣言
//---------------------------------------
bool PlayerBulletSysInit(void);
void PlayerBulletInit(void);
void PlayerBulletShot(void);
void PlayerBulletMove(void);
void PlayerBulletDraw(void);
void Bomb(void);
bool PlayerBulletRelease(void);

(PlayerBullet.cpp)

//-----------------------------------------------------------------------------
// インベーダーゲーム
// 氏 名:
//-----------------------------------------------------------------------------
#include <DxLib.h>
#include"main.h"
#include"PlayerBullet.h"
#include"Player.h"
#include"Enemy.h"

//-----------------
// 変数の宣言
//-----------------

// プレイヤー弾
int playerBulletImage;						// プレイヤー弾の画像ハンドル番号
int playerBulletPosX;						// プレイヤー弾のX座標
int playerBulletPosY;						// プレイヤー弾のY座標
bool playerBulletFlg;						// プレイヤー弾の発射状態管理用フラグ(true:表示、false:非表示)
int bombStock;								//押し戻しの残り回数

bool PlayerBulletSysInit(void) {

	// プレイヤー弾の画像の読込み
	playerBulletImage = LoadGraph("image/playerBullet.png");
	if (playerBulletImage == -1)return false;

	return true;
}

void PlayerBulletInit(void) {

	// プレイヤー弾
	playerBulletPosX = playerBulletPosY = 0;
	playerBulletFlg = false;
	bombStock = BOMB_MAX;

}

void PlayerBulletShot(void) {
	if (playerBulletFlg == false) {
		//弾が未発射状態なので射撃可能
		if (nowSpaceKey == 1 && prevSpaceKey == 0) {
			playerBulletPosX = (playerPosX + PLAYER_WID / 2) - (PLAYER_BULLET_WID / 2);
			playerBulletPosY = playerPosY - PLAYER_BULLET_HIG;
			playerBulletFlg = true;
		}
	}

}

void PlayerBulletMove(void) {
		if(playerBulletFlg) {
			//弾の移動処理
			playerBulletPosY -= PLAYER_BULLET_MOVE;
			if (playerBulletPosY < 0)playerBulletFlg = false;
	}
}

void PlayerBulletDraw(void) {
	if (playerBulletFlg) {
		DrawGraph(playerBulletPosX, playerBulletPosY, playerBulletImage, true);
	}

}

//敵の押し戻し処理
void Bomb(void) {

	if(bombStock > 0){
	bombStock--;
	for (int yy = 0;yy < ENEMY_DISP_YNUM;yy++) {
		for (int xx = 0; xx < ENEMY_DISP_XNUM;xx++) {
			if (enemyFlgArray[yy][xx] == true) {
				enemyPosyArray[yy][xx] -= ENEMY_MOVE_Y_SPEED;
			}
		}
	}
	}
	else {
		return;
	}
}

//プレイヤー弾画像の解放
bool PlayerBulletRelease(void)
{
	if (DeleteGraph(playerBulletImage) == -1)return false;
	return true;
}

(SceneGame.h)

#pragma once

//---------------------------------
// 定数定義
//---------------------------------
const int STAGE_NUM_MAX = 5;	//最大ステージ数

//---------------------------------
//他のファイルでも参照が必要な変数のextern宣言
//---------------------------------
extern int nowStageNum;
// テスト用のキーの状態
extern int nowWKeyPress;
extern int prevWKeyPress;
extern int nowLKeyPress;
extern int prevLKeyPress;
extern int nowOKeyPress;
extern int prevOKeyPress;
extern int nowBKeyPress;
extern int prevBKeyPress;



//-------------------------------------------------
// プロトタイプ宣言
//-------------------------------------------------
bool SceneGameSysInit(void);//ゲーム起動時の初期化処理
void SceneGameInit(void);//ゲームシーンの初期化処理
void SceneGameNextStageInit(void);//ステージクリア時の初期化処理
void SceneGameMainProc(void);//ゲームシーンのメイン処理
void SceneGameUpdate(void);//ゲームシーンの更新処理
void SceneGameDraw(void);//ゲームシーンの描画処理
bool SceneGameRelease(void);//ゲームシーンの解放処理

eStageExitConditionsKind StageExitConditionsCheck(void);

bool CollisionCheckPlayerBullet(void);//衝突判定
bool CollisionCheckEnemyBullet(void); //敵弾との衝突判定

(SceneGame.cpp)

#include <DxLib.h>
#include "main.h"
#include "SceneGame.h"
#include "Player.h"
#include "PlayerBullet.h"
#include "Enemy.h"
#include "EnemyBullet.h"

// 変数宣言
int nowStageNum; //現在のステージ番号
// テスト用のキーの状態
int nowWKeyPress;	//デバッグ用(W)
int prevWKeyPress;
int nowLKeyPress;	//デバッグ用(L)
int prevLKeyPress;
int nowOKeyPress;	//デバッグ用(O)
int prevOKeyPress;
int nowBKeyPress;	//デバッグ用(B)
int prevBKeyPress;

//ゲームシーンの初期化処理
bool SceneGameSysInit(void)
{
	if (PlayerSysInit() == false)return false;			//画像の読み込みを行っている為、エラー(falseが返されたとき)に処理を終了させる
	if (PlayerBulletSysInit() == false)return false;	//画像の読み込みを行っている為、エラー(falseが返されたとき)に処理を終了させる
	if (EnemySysInit() == false)return false;			//画像の読み込みを行っている為、エラー(falseが返されたとき)に処理を終了させる
	if (EnemyBulletSysInit() == false)return false;		//画像の読み込みを行っている為、エラー(falseが返されたとき)に処理を終了させる
	return true;
}

void SceneGameInit(void)
{
	PlayerInit();
	PlayerBulletInit();
	EnemyInit();
	EnemyBulletInit();

}

//プレイヤー勝利時の再初期化処理
void SceneGameNextStageInit(void) {
	//敵キャラ関連の初期化
	EnemyInit();
	//プレイヤー関連の初期化
	//プレイヤーのY座標は常に最下段なので初期化不要
	//プレイヤー勝利時の呼び出しになるためPlayerFlagの更新も不要
	playerPosX = (WINDOW_WID - PLAYER_WID) / 2;	//横方向の画面中央に位置を設定
}


//ゲームシーンのメイン処理
void SceneGameMainProc(void)
{
	SceneGameUpdate();
	SceneGameDraw();

	//ステージが終了したか
	eStageExitConditionsKind exit = StageExitConditionsCheck();
	if (exit != ESTAGE_EXIT_NON) {
		switch (exit) {
		case ESTAGE_EXIT_CLEAR:
			//条件1:プレイヤー勝利
			//ステージ番号を1加算
			nowStageNum++;
			//ステージ番号が最大ステージ数を超えたらゲーム終了
			if (nowStageNum > STAGE_NUM_MAX)
			{
				sceneKind = SCENE_KIND_GAMEOVER;
			}
			else {
				//次のステージに進む際に敵の位置やフラグを再初期化
				SceneGameNextStageInit();
			}
			break;

		case ESTAGE_EXIT_ENEMY_SHOT:
			//条件2:プレイヤーが敵弾にやられた
			playerStock--;
			if (playerStock < 0) {
				//保有機数がなくなったらゲームオーバー
				sceneKind = SCENE_KIND_GAMEOVER;
			}
			else {
				//保有機数が残っていた場合に続行
				//プレイヤーのみ初期化
				playerPosX = WINDOW_WID / 2 - PLAYER_WID / 2;//横方向の画面中央
				playerFlg = true;
			}

			break;
		case ESTAGE_EXIT_ENEMY_OCCUPATION:
			SceneGameNextStageInit();//配置初期化
			sceneKind = SCENE_KIND_GAMEOVER;
			break;
		}
	}

}

//ゲームシーンの更新処理
void SceneGameUpdate(void)
{
	PlayerMove();


	// プレイヤー弾の移動処理
	PlayerBulletMove();

	// プレイヤー弾の発射処理
	PlayerBulletShot();


	//敵の移動処理
	EnemyMove();

	//敵弾の移動処理
	EnemyBulletMove();

	//敵弾の発射処理
	EnemyBulletShot();


	// 当たり判定
	CollisionCheckPlayerBullet();
	CollisionCheckEnemyBullet();

	//--------------------------------------------
	// テスト用処理
	//--------------------------------------------
#ifdef _DEBUG
	if (nowWKeyPress == 0 && prevWKeyPress == 1) {
		//条件1:プレイヤーが勝った
		//敵キャラを無条件にすべてやられた状態にする
for (int yy = 0; yy < ENEMY_DISP_YNUM; yy++) {
	for (int xx = 0; xx < ENEMY_DISP_XNUM; xx++) {
		enemyFlgArray[yy][xx] = false;
	}
}
	}
	else if (nowLKeyPress == 0 && prevLKeyPress == 1) {
		//条件2:敵弾にプレイヤーが撃たれた
		playerFlg = false;
	}
	else if (nowOKeyPress == 0 && prevOKeyPress == 1) {
		//条件3:敵に最下段まで到達された
		//敵キャラをすべてのY座標を最下段に変更
		int chkpos = WINDOW_HIG - ENEMY_MOVE_Y_SPEED; //あと一歩で下端に到達する位置
		for (int yy = ENEMY_DISP_YNUM - 1; yy >= 0; yy--) {
			for (int xx = 0; xx < ENEMY_DISP_XNUM; xx++) {
				if (enemyFlgArray[yy][xx] == true) {
					enemyPosyArray[yy][xx] = chkpos - (ENEMY_MOVE_Y_SPEED * (ENEMY_DISP_YNUM - (yy + 1)));
				}
			}
		}
	}
	else if (nowBKeyPress == 0 && prevBKeyPress == 1) {
		//敵を1段押し戻す
		Bomb();
	}
#endif
}


//ゲームシーンの描画処理
void SceneGameDraw(void)
{
	SetDrawScreen(DX_SCREEN_BACK);			// 描画する画面を裏の画面に設定する
	ClearDrawScreen();						// 描画する画面の内容を消去する

	// プレイヤーの描画
	PlayerDraw();

	// プレイヤー弾の描画
	PlayerBulletDraw();

	// 敵の描画
	EnemyDraw();

	// 敵弾の描画
	EnemyBulletDraw();

	//文字列表示
	DrawFormatString(10, 10, 0xffffff, "PlayerStock:%d", playerStock);
	DrawFormatString(10, 28, 0xffffff, "BombStock:%d", bombStock);
	DrawFormatString(10, 46, 0xffffff, "NowStage:%d", nowStageNum);

	ScreenFlip();							// 裏の画面を表の画面に瞬間コピー
}

//衝突判定
bool CollisionCheckPlayerBullet(void)
{
	if (playerBulletFlg == true) {
		for (int yy = 0; yy < ENEMY_DISP_YNUM; yy++) {
			for (int xx = 0; xx < ENEMY_DISP_XNUM; xx++) {
				if (enemyFlgArray[yy][xx] == false)continue;
				if (
					(enemyPosyArray[yy][xx] + ENEMY_HIG > playerBulletPosY) &&			//判定1:敵の下端のY座標 > 弾の上端のY座標
					(enemyPosyArray[yy][xx] < playerBulletPosY + PLAYER_BULLET_HIG) &&	//判定2:敵の上端のY座標 < 弾の下端のY座標
					(enemyPosxArray[yy][xx] < playerBulletPosX + PLAYER_BULLET_WID) &&	//判定3:敵の左端のX座標 < 弾の右端のX座標 
					(enemyPosxArray[yy][xx] + ENEMY_WID > playerBulletPosX)				//判定4: 敵の右端のX座標 > 弾の左端のX座標
					)
				{
					// プレイヤー弾は消滅
					playerBulletFlg = false;
					// 敵キャラも消滅
					enemyFlgArray[yy][xx] = false;
					return true;
				}
			}

		}
	}
	return false;
}

//衝突判定
bool CollisionCheckEnemyBullet(void)
{
	if (playerFlg == false) return false;
	{
		for (int yy = 0; yy < ENEMY_DISP_YNUM; yy++) {
			for (int xx = 0; xx < ENEMY_DISP_XNUM; xx++) {
					if (enemyBulletFlgArray[yy][xx] == true) {
						//敵弾が存在している
						int posx = enemyBulletPosXArray[yy][xx];
						int posy = enemyBulletPosYArray[yy][xx];
						if ((playerPosY + PLAYER_HIG > posy)
							&& (playerPosY < posy + ENEMY_BULLET_HIG)
							&& (playerPosX < posx + ENEMY_BULLET_WID)
							&& (playerPosX + PLAYER_WID > posx)){
							//プレイヤーに命中
							enemyBulletFlgArray[yy][xx] = false;
							playerFlg = false;
							return true;
						}
					}
			}

		}
	}
	return false;
}


//ゲームシーンの解放処理
bool SceneGameRelease(void)
{
	if (PlayerRelease() == -1)return false;
	if (PlayerBulletRelease() == -1)return false;
	if (EnemyRelease() == -1)return false;
	if (EnemyBulletRelease() == -1)return false;
	return true;
}

/**
* -----------------------------------------------------
* ステージ終了状況のチェック
* 引数:なし
* 戻り値:
*  ESTAGE_EXIT_NON				--->まだ戦闘中
*  ESTAGE_EXIT_CLEAR			--->条件1:プレイヤーが勝った
*  ESTAGE_EXIT_ENEMY_SHOT		--->条件2:敵弾にプレイヤーが撃たれた
*  ESTAGE_EXIT_ENEMY_OCCUPATION--->条件3:敵に最下段まで到達された
* -----------------------------------------------------
**/

eStageExitConditionsKind StageExitConditionsCheck(void)
{
	eStageExitConditionsKind exitCondition = ESTAGE_EXIT_NON;

	//敵の残機数を取得する
	int enemyNum = 0;
	for (int yy = 0; yy < ENEMY_DISP_YNUM; yy++) {
		for (int xx = 0;xx < ENEMY_DISP_XNUM;xx++) {
			if (enemyFlgArray[yy][xx] == true)enemyNum++;
		}
	}
	if (enemyNum == 0) {
		//敵の残機数が0なので、プレイヤーがステージをクリアした
		exitCondition = ESTAGE_EXIT_CLEAR;
	}
	else if (playerFlg == false) {
		//プレイヤーがやられた
		exitCondition = ESTAGE_EXIT_ENEMY_SHOT;
	}
	else if (CheckHitEdgeProc() == ENEMY_HIT_EDGE_DOWN) {
		//敵が最下段に到達した
		exitCondition = ESTAGE_EXIT_ENEMY_OCCUPATION;
	}
	return exitCondition;
}

(SceneGameOver.h)

#pragma once

#include"SceneGame.h"
#include"Player.h"

//---------------------------------
// 定数定義
//---------------------------------
const int GAME_OVER_GRAPH_WID = 800;	//ゲームオーバー画像の幅
const int GAME_OVER_GRAPH_HID = 500;	//ゲームオーバー画像の高さ

//---------------------------------
//他のファイルでも参照が必要な変数のextern宣言
//---------------------------------




//-------------------------------------------------
// プロトタイプ宣言
//-------------------------------------------------
bool SceneGameOverInit(void);		//ゲームオーバーシーンの初期化処理
void SceneGameOverMainProc(void);	//ゲームオーバーシーンのメイン処理
void SceneGameOverUpdate(void);		//ゲームオーバーシーンの更新処理
void SceneGameOverDraw();			//ゲームオーバーシーンの描画処理
bool SceneGameOverRelease(void);	//ゲームオーバーシーンのリリース処理

(SceneGameOver.cpp)

#include <DxLib.h>
#include"main.h"
#include"SceneGameOver.h"

//-----------------
// 変数の宣言
//-----------------
int gameOverImage;	//ゲームオーオバー画像のハンドル番号


//ゲームオーバーシーンの初期化処理
bool SceneGameOverInit(void)
{
	gameOverImage = LoadGraph("image/gameOver.png");
	if (gameOverImage == -1)return false;//画像読み込みに失敗したら終了

//	PlayerInit();
//	SceneGameInit();

	return true;
}
//ゲームオーバーシーンのメイン処理
void SceneGameOverMainProc(void)
{
	SceneGameOverUpdate();
	SceneGameOverDraw();
}
//ゲームオーバーシーンの更新処理
void SceneGameOverUpdate(void)
{
	if (nowSpaceKey == 0 && prevSpaceKey == 1) {
		sceneKind = SCENE_KIND_TITLE;
	}
}
//ゲームオーバーシーンの描画処理
void SceneGameOverDraw(void) 
{
	SetDrawScreen(DX_SCREEN_BACK);	//描画する画面を裏画面に設定
	ClearDrawScreen();				//描画する画面の内容を消去

	int xx = (WINDOW_WID - GAME_OVER_GRAPH_WID) / 2;
	int yy = (WINDOW_HIG - GAME_OVER_GRAPH_HID) / 2;
	DrawGraph(xx, yy, gameOverImage, true);

	xx = WINDOW_WID / 2 -40;
	yy = (WINDOW_HIG - 40);
	//文字列表示
	DrawString(xx, yy, "Hit Space Key!!!", 0xffffff);


	ScreenFlip();					//裏画面を表画面と入れ替え
}
//ゲームオーバーシーンのリリース処理
bool SceneGameOverRelease(void)
{
	if (DeleteGraph(gameOverImage) == -1)return false;
	return  true;
}

(SceneTitle.h)

#pragma once

//---------------------------------
// 定数定義
//---------------------------------
const int TITLE_WID = 800;	//タイトル画像の幅
const int TITLE_HIG = 475;	//タイトル画像の高さ

//---------------------------------
//他のファイルでも参照が必要な変数のextern宣言
//---------------------------------


//---------------------------------
// プロトタイプ宣言
// --------------------------------
bool SceneTitleInit(void);// タイトルシーンの初期化処理
void SceneTitleMainProc(void);// タイトルシーンのメイン処理
void SceneTitleUpdate(void);// タイトルシーンの更新処理
void SceneTitleDraw(void);// タイトルシーンの描画処理
bool SceneTitleRelease(void);// タイトルシーンの解放処理

(SceneTitle.cpp)

#include <DxLib.h>
#include <time.h>
#include"main.h"
#include"SceneTitle.h"
#include"SceneGame.h"
#include"SceneGameOver.h"



//-------------------------
// 変数の宣言
//--------------------------
int titleImage;		//タイトル画像のハンドル番号

// タイトルシーンの初期化処理
bool SceneTitleInit(void)
{
	titleImage = LoadGraph("image/title.png");
	if (titleImage == -1)return false;
	
	return true;
}
// タイトルシーンのメイン処理 ※ほかの処理を盛り込んで、こちらを他から呼び出す。
void SceneTitleMainProc(void)
{
	SceneTitleUpdate();
	SceneTitleDraw();
}
// タイトルシーンの更新処理
void SceneTitleUpdate(void)
{
	if (nowSpaceKey == 0 && prevSpaceKey ==1) {
		//アップトリガーでスペースキーの押下を判定
		//SceneGameSysInit();
		SceneGameInit();
		nowStageNum = 1;
		sceneKind = SCENE_KIND_GAME;
	}
}
// タイトルシーンの描画処理
void SceneTitleDraw(void)
{
	SetDrawScreen(DX_SCREEN_BACK);		//描画する画面を裏の画面に設定する
	ClearDrawScreen();					//描画する画面の内容を消去する

	//タイトル画像表示
	int xx = (WINDOW_WID - TITLE_WID) / 2;
	int yy = (WINDOW_HIG - TITLE_HIG) / 2;
	DrawGraph(xx, yy, titleImage, true);

	//文字列表示
	xx = (WINDOW_WID - 100) / 2;
	yy = (WINDOW_HIG - 200);
	DrawString(xx,yy,"HIT SPACE KEY!", 0xffffff);

	ScreenFlip();						//裏の画面を表の画面に切り替え
}
// タイトルシーンの解放処理
bool SceneTitleRelease(void)
{
	if (DeleteGraph(titleImage) == -1)return false;
	return true;
}

2025.08.09時点。

コメント

タイトルとURLをコピーしました