2Dゲーム制作㉙(2025/10/22)

アニメーションカウンターとArrayの修正。
(Enemy.cpp)

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

	eAnimCounter++;
	if (eAnimCouter >= ENEMY_PATTERNS)eAnimCounter = 0;

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

				}
			}
		}
	}

Draw関数を、敵キャラの種類・アニメーションパターンに対応させていく。
(Enemy.cpp)

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

Release関数を配列対応にして、破棄失敗の場合に値を戻すように変更する。
(Enemy.cpp)

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

CheckHitEdgeProcの変数表記を変更。
(Enemy.cpp)

//エリアの端にぶつかっていないかのチェック処理
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 (eArray[yy][xx].flag == true) {
					restnum++;
					if (eArray[yy][xx].pos.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 (eArray[yy][xx].flag == true) {
					restnum++;
					if (eArray[yy][xx].pos.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 (eArray[yy][xx].flag == true) {
					restnum++;
					if (eArray[yy][xx].pos.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;
}



インライン関数の要素名を修正。
敵の残数で移動が加速するための変数定義を追加。
(Enemy.h)

#pragma once
#include "StDefine.h"

class Enemy
{

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);
	int GetEnemyRestNum(void);				//敵の残機数を取得

	bool GetAlive(int x, int y){ return eArray[y][x].flag; }
	void SetAliveOff(int x, int y) { eArray[y][x].flag = false; }
	POSITION GetPos(int x, int y) { return eArray[y][x].pos; }
        void SetPos(int x, int y, POSITION pos) { eArray[y][x].pos = pos; }	
	eEnemyMoveDirection GetNextMoveDir(void) { return eNextMoveDirection; }
	void SetMoveDir(eEnemyMoveDirection dir) { eMoveDirection = dir; }
	void SetNextMoveDir(eEnemyMoveDirection dir) {eNextMoveDirection = dir;	}


	// 敵キャラ
	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_MOVE_X_SPEED = 4;		//敵の横方向の移動量
	static constexpr int ENEMY_MOVE_Y_SPEED = (ENEMY_HIG + ENEMY_DISP_Y_DISTANCE);//敵の縦方向移動量
	static constexpr int ENEMY_MOVE_INTERVAL_COUNT = 32;	//敵移動のインターバル
	static constexpr int ENEMY_MOVE_CUT_INTERVAL = 2;	//短縮する移動間隔
	static constexpr int ENEMY_REST_PER_MINIMUM = 10;//敵キャラ残機数の割合%
	static constexpr int ENEMY_REST_PER_MINI_2 = 20;//敵キャラ残機数の割合(%)
	static constexpr int ENEMY_REST_PER_MINI_3 = 40;//敵キャラ残機数の割合(%)
	static constexpr int ENEMY_REST_PER_MINI_4 = 60;//敵キャラ残機数の割合(%)
	static constexpr int ENEMY_REST_PER_MINI_5 = 80;//敵キャラ残機数の割合(%)



private:
	//敵キャラの表示関連
	static constexpr int ENEMY_DISP_ALL_NUM = ENEMY_DISP_XNUM * ENEMY_DISP_YNUM;

	// 敵キャラ
	int imageArray[ENEMY_KIND_MAX][ENEMY_PATTERNS];	// 敵の画像ハンドル番号
	charaData eArray[ENEMY_DISP_YNUM][ENEMY_DISP_XNUM];// 敵のX座標表示位置と生存フラグと種類のテーブル
	bool flgArray[ENEMY_DISP_YNUM][ENEMY_DISP_XNUM];// 敵の存在フラグテーブル

	eEnemyMoveDirection eMoveDirection;	//敵キャラの現在の移動方向
	eEnemyMoveDirection eNextMoveDirection;	//敵キャラの下移動後の移動方向
	int eMoveIntervalCounter;		//敵キャラ移動の間隔調整用カウンタ
	int eAnimCounter;			//敵キャラのアニメーションカウンタ
};

敵残数によって移動速度が速くなるように変更。
まずは残機数の割合(%)をintで計算。※端数は切り捨て
次に、IntervalCounterの更新部分を修正する。
(Enemy.cpp)


void Enemy::Update(void)
{
	int rnum = GetEnemyRestNum();
	int per = (rnum * 100) / ENEMY_DISP_ALL_NUM;
	if (per > ENEMY_REST_PER_MINIMUM) {
		eMoveIntervalCounter++;
		if (eMoveIntervalCounter > 0) {
			int cutCount = 0;
			if (per < ENEMY_REST_PER_MINI_5) {
				if (per < ENEMY_REST_PER_MINI_2) {
					cutCount = 16;
				}
				else if (per < ENEMY_REST_PER_MINI_3) {
					cutCount = 14;
				}
				else if (per < ENEMY_REST_PER_MINI_4) {
					cutCount = 10;
				}
				else {
					cutCount = 8;
				}
			}
			if (eMoveIntervalCounter >= (ENEMY_MOVE_INTERVAL_COUNT-ENEMY_MOVE_CUT_INTERVAL*cutCount)) {
				eMoveIntervalCounter = -1;
			}
			return;
		}
	}

	eAnimCounter++;
	if (eAnimCounter >= ENEMY_PATTERNS)eAnimCounter = 0;

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

				}
			}
		}
	}

今日はここまで。

コメント

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