(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時点。
コメント