2Dゲーム制作㉔(2025/10/06)

空の関数を準備。
(PlayerBullet.cpp)

PlayerBullet::PlayerBullet(SceneManager* scm, Player* pl)
{
	scmInst = scm;
	pInst = pl;
}
PlayerBullet::~PlayerBullet(void)
{

}
bool PlayerBullet::SystemInit(void)
{
	return true;
}
void PlayerBullet::GameInit(void)
{

}
void PlayerBullet::UpdateShot(void)
{

}
void PlayerBullet::UpdateMove(void)
{

}
void PlayerBullet::Draw(void)
{

}
bool PlayerBullet::Release(void)
{
	return true;
}

ゲッター関数をインライン関数として定義。
(PlayerBullet.h)

#pragma once
#include"StDefine.h"

class SceneManager;
class Player;

class PlayerBullet
{
public:
	constexpr int PLAYER_BULLET_WID = 6;		// プレイヤー弾の画像の横サイズ
	constexpr int PLAYER_BULLET_HIG = 30;		// プレイヤー弾の画像の縦サイズ
	constexpr int PLAYER_BULLET_MOVE = 12;		// プレイヤー弾の移動速度
	constexpr int BOMB_MAX = 4;					// 押し戻しの最大回数

	PlayerBullet(SceneManager* scm, Player* pl); //Player型のインスタンスのポインタをうけられるように準備
	~PlayerBullet(void);

	bool BulletSysInit(void);
	void BulletInit(void);
	void BulletShot(void);
	void BulletMove(void);
	void BulletDraw(void);
	void Bomb(void);
	bool BulletRelease(void);

	POSITION GetPos(void) { return pos; }
	bool GetAlive(void) { return aliveFlg; }
	int GetPlayerStock(void) { retrun PlayerStock; }

private:
	SceneManager* csmInst;		//SceneManagerクラスのインスタンスのポインタ
	Player* pInst;				//Playerクラスのインスタンスのポインタ

	int img;					//プレイヤー弾の画像ハンドル番号
	POSITION pos;				//プレイヤー弾の座標
	bool aliveFlg;				//プレイヤー弾の存在フラグ(true:表示、false:非表示)
	int bombStock;				//ボム弾数
}

//-----------------
// 定数定義
//-----------------
// プレイヤー弾

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

//---------------------------------------
// プロトタイプ宣言
//---------------------------------------

関数の中身を作っていく。
(PlayerBullet.cpp)

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


PlayerBullet::PlayerBullet(SceneManager* scm, Player* pl)
{
	scmInst = scm;
	pInst = pl;
}
PlayerBullet::~PlayerBullet(void)
{

}
bool PlayerBullet::SystemInit(void)
{
	// プレイヤー弾の画像の読込み
	image = LoadGraph("image/playerBullet.png");
	if (image == -1)return false;

	return true;
}
void PlayerBullet::GameInit(void)
{
	pos.x = pos.y = 0;
	aliveFlg = false;
	bombStock = BOMB_MAX;

}
void PlayerBullet::UpdateShot(void)
{
	int prev = scmInst->GetPrevSpaceKey();
	int now = scmInst->GetNowSpaceKey)();

	if (aliveFlg == false) {
		//弾が未発射状態なので射撃可能
		if (now == 1 && prev == 0) {
			pos.x = (pInst->GetPos().x + Player::PLAYER_WID / 2) - (PLAYER_BULLET_WID / 2);
			pos.y = pInst->GetPos().y - PLAYER_BULLET_HIG;
			aliveFlg = true;
		}
	}

}
void PlayerBullet::UpdateMove(void)
{
	if (aliveFlg) {
		//弾の移動処理
		pos.y -= PLAYER_BULLET_MOVE;
		if (pos.y < 0)aliveFlg = false;
	}
}
void PlayerBullet::Draw(void)
{
	if (aliveFlg) {
		DrawGraph(pos.x, pos.y, image, true);
	}

}
bool PlayerBullet::Release(void)
{
	if (DeleteGraph(image) == -1)return false;
	return true;
}

void PlayerBullet::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;
	}
}

Enemy.cppとEnemy.hを[追加]して修正していく。
(Enemy.h)

#pragma once
#include "Stdefine.h"

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

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

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

public:
	Enemy(void);
	~Enemy(void);

	bool SystemInit(void);
	void GameInit(void);
	void OccupationInit(void);
	void Update(void);
	void Draw(void);
	bool Release(void);

	eEnemyHitEdgeDir CheckHitEdgeProc(void);

private:
	// 敵キャラ
	int imageArray[ENEMY_PATTERNS];						// 敵の画像ハンドル番号
	POSITION posArray[ENEMY_DISP_YNUM][ENEMY_DISP_XNUM];	// 敵のX座標表示位置テーブル
	bool flgArray[ENEMY_DISP_YNUM][ENEMY_DISP_XNUM];	// 敵の存在フラグテーブル

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

};

※領域選択(VisualStudio)
Alt+Shiftを押しながらカーソルやマウスで領域選択 ⇒ コピーや切り取りが可能
行をまたいで、任意の列まで選択することが可能。

旧関数の中身を移植して関数を定義。
(Enemy.cpp)

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

Enemy::Enemy()
{

}

Enemy::~Enemy()
{

}
bool Enemy::SystemInit(void)
{
	//敵の画像の読込み
	int err = LoadDivGraph("image/enemy_1.png", ENEMY_PATTERNS, ENEMY_PATTERNS, 1, ENEMY_WID, ENEMY_HIG, imageArray);
	if (err == -1)return false;

	return true;

}
void Enemy::GameInit(void)
{
	//-----------------
	// 変数の初期化
	//-----------------

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

	eMoveDirection = ENEMY_DIR_RIGHT;
	eNextMoveDirection = ENEMY_DIR_NON;

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

}
void Enemy::OccupationInit(void)
{

}
void Enemy::Update(void)
{
	eMoveIntervalCounter++;
	if (eMoveIntervalCounter > 0) {
		if (eMoveIntervalCounter >= ENEMY_MOVE_INTERVAL_COUNT) {
			eMoveIntervalCounter = -1;
		}
		return;
	}

	for (int yy = 0; yy < ENEMY_DISP_YNUM; yy++) {
		for (int xx = 0; xx < ENEMY_DISP_XNUM; xx++) {
			if (flgArray[yy][xx]) {
				switch (eMoveDirection) {
				case ENEMY_DIR_RIGHT:
					posArray[yy][xx].x += ENEMY_MOVE_X_SPEED;
					break;
				case ENEMY_DIR_LEFT:
					posArray[yy][xx].x -= ENEMY_MOVE_X_SPEED;
					break;
				case ENEMY_DIR_DOWN:
					posArray[yy][xx].y += ENEMY_MOVE_Y_SPEED;
					break;

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

	case ENEMY_HIT_EDGE_RIGHT:
		eMoveDirection = ENEMY_DIR_DOWN;
		eNextMoveDirection = ENEMY_DIR_LEFT;
		break;

	case ENEMY_HIT_EDGE_LEFT:
		eMoveDirection = ENEMY_DIR_DOWN;
		eNextMoveDirection = ENEMY_DIR_RIGHT;
		break;

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


}
void Enemy::Draw(void)
{
	// 敵の描画
	for (int yy = 0; yy < ENEMY_DISP_YNUM; yy++) {
		for (int xx = 0; xx < ENEMY_DISP_XNUM; xx++) {
			if (flgArray[yy][xx]) {
				DrawGraph(posArray[yy][xx].x, posyArray[yy][xx].y, imageArray[0], true);
			}
		}
	}
}


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

//エリアの端にぶつかっていないかのチェック処理
eEnemyhitEdgeDir Enemy::CheckHitEdgeProc(void)
{
	eEnemyHitEdgeDir hitdir = ENEMY_HIT_EDGE_NON;
	int restnum;//その列に生き残っている敵の数を格納する変数(ローカル)
	switch (eMoveDirection) {
		//右方向に移動中なので、右端に接触していないかをチェックする
	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 (flgArray[yy][xx] == true) {
					restnum++;
					if (posArray[yy][xx].x >= (Application::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 (flgArray[yy][xx] == true) {
					restnum++;
					if (posArray[yy][xx].x <= 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 (flgArray[yy][xx] == true) {
					restnum++;
					if (posArray[yy][xx].y >= (Application::WINDOW_HIG - ENEMY_HIG)) {
						hitdir = ENEMY_HIT_EDGE_DOWN;
						break;
					}
				}
			}
			if (hitdir != ENEMY_HIT_EDGE_NON || restnum > 0)break;	//端に接触しているか、端に接触していなくても残っている敵がいる場合にbreak
		}
		break;

	return hitdir;
}

コメント

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