ファイル分割(ヘッダーファイル)
定数定義~プロトタイプ宣言(変数宣言を除く)までを main.h に移動。
※C言語では変数をヘッダーファイルに「宣言(extern)」として分離することは可能だが、実体(定義)は1つだけソースファイルに置く必要がある。
C++ではクラスなどの構造にまとめることで、より柔軟に外部ファイル化できる。
//main.h
#pragma once
//-----------------
// 定数定義
//-----------------
const int WINDOW_WID = 800; // ウィンドウの横サイズ
const int WINDOW_HIG = 600; // ウィンドウの縦サイズ
// プレイヤー
const int PLAYER_WID = 32; // プレイヤー画像の横サイズ
const int PLAYER_HIG = 19; // プレイヤー画像の縦サイズ
const int PLAYER_MOVE_SPEED = 6; // プレイヤーの左右の移動速度
// プレイヤー弾
const int PLAYER_BULLET_WID = 6; // プレイヤー弾の画像の横サイズ
const int PLAYER_BULLET_HIG = 30; // プレイヤー弾の画像の縦サイズ
const int PLAYER_BULLET_MOVE = 12; // プレイヤー弾の移動速度
// 敵キャラ
const int ENEMY_WID = 32; // 敵の画像の横サイズ
const int ENEMY_HIG = 23; // 敵の画像の縦サイズ
// 敵キャラの画面表示関連
const int ENEMY_DISP_XNUM = 8; // 敵キャラの横の表示個数
const int ENEMY_DISP_YNUM = 7; // 敵キャラの縦の表示個数
const int ENEMY_DISP_ALL_NUM = ENEMY_DISP_XNUM * ENEMY_DISP_YNUM;
//プロトタイプ宣言
bool Init(void);
void Update(void);
void Draw(void);
main.cppの先頭に下記をinclude。
#include"main.h"
※変数のスコープ
**C言語における変数のスコープ(有効範囲)**について、簡潔に整理します。
✅ 変数のスコープとは?
**「その変数が使える範囲(見える範囲)」**のこと。
🔹 スコープの種類(主に3つ)
スコープ | 説明 | 例 |
---|---|---|
ブロック内スコープ(ローカル変数) | {} で囲まれた範囲内だけで有効 | 関数内の int x = 10; など |
関数スコープ | 関数名 によって識別される範囲。主に goto のラベルに適用 | start: ラベルなど |
ファイルスコープ(グローバル変数) | ファイル全体で有効(関数の外で定義された変数) | int count = 0; (関数の外) |
🔹 補足:リンク可能性による違い(外部から見えるか)
修飾子 | 意味 | 使える範囲 |
---|---|---|
static | ファイル内限定 | 他のファイルから見えない |
extern | 他のファイルにも見せる宣言 | 他の .c から参照可能 |
✅ まとめ一言
スコープ=「どこから見えるか」{}の中=ローカル変数
、関数の外=グローバル変数
static
→ ファイル限定、extern
→ 他ファイルへ開示
(by ChatGPT)
また、基本的に変数は「宣言後」にしか使えないので、使う行以前に必ず宣言しておく。
※pragma once
ヘッダーファイルの多重定義を防ぐための一行。
Player.cpp と Player.h を作成。
プレイヤー関係の変数宣言を main.cpp ⇒ Player.cpp に移動。
初期化用関数の作成とプロトタイプ宣言
//Player.h
#pragma once
//------------------------------------------
//他のファイルでも参照が必要な変数の extern宣言
//------------------------------------------
extern int playerPosX; // 自機のX座標
extern int playerPosY; // 自機のY座標
extern bool playerFlg; // 自機の表示状態管理用フラグ(true:表示、false:非表示)
//-------------------------------------------
//プロトタイプ宣言
//-------------------------------------------
bool PlayerInit(void);
//Player.cpp
//-----------------------------------------------------------------------------
// インベーダーゲーム
// 氏 名:
//-----------------------------------------------------------------------------
#include <DxLib.h>
#include"main.h"
#include"Player.h"
//-----------------
// 変数の宣言
//-----------------
// プレイヤー
int playerImage; // 自機の画像ハンドル番号
int playerPosX; // 自機のX座標
int playerPosY; // 自機のY座標
bool playerFlg; // 自機の表示状態管理用フラグ(true:表示、false:非表示)
bool PlayerInit(void)
{
return true;
}
※extern
✅ 正確な定義(C言語の文法的視点)
extern int count;
→ これは **「変数の宣言(宣言だけ、定義ではない)」**です。int count = 0;
→ これが **定義(実体を与える)**です。
✅ 先生の説明の意図(実務・設計視点)
「他のファイルに変数を公開するもの」
これは要するに:
extern
は **「ここには実体がないけど、どこかにある前提で使いますよ」**という宣言- 他の
.c
ファイルにある変数を 他のソースから見えるように“見せる”ためのラベル - 外部リンク可能にする記号という意味では、「公開する」もOK
✅ つまり両方を整理すると…
観点 | 内容 |
---|---|
文法的に正しい定義 | extern は「宣言」であって「定義」ではない |
実務的にわかりやすい説明 | 他ファイルに「公開する」「参照可能にする」ための仕組み |
最も正確な表現 | 「他ファイルにある実体の宣言を、他の場所でも使うための公開宣言」 |
✅ まとめ一言
extern
は「宣言」であり、
「他ファイルにある変数を見えるようにする(公開する)手段」でもある。
(by ChatGPT)
プレイヤー関係の処理をmain.cpp内のInit()関数からPlayer.cpp内に関数を作成して移動。
代わりに各関数をInit()内に配置。併せてPlayer.hもincludeする。
//Player.cpp
//-----------------------------------------------------------------------------
// インベーダーゲーム
// 氏 名:
//-----------------------------------------------------------------------------
#include <DxLib.h>
#include"main.h"
#include"Player.h"
//-----------------
// 変数の宣言
//-----------------
// プレイヤー
int playerImage; // 自機の画像ハンドル番号
int playerPosX; // 自機のX座標
int playerPosY; // 自機のY座標
bool playerFlg; // 自機の表示状態管理用フラグ(true:表示、false:非表示)
bool PlayerInit(void)
{
// プレイヤー画像の読込み
playerImage = LoadGraph("image/player.png");
if (playerImage == -1)return false;
//-----------------
// 変数の初期化
//-----------------
// プレイヤー
playerPosX = WINDOW_WID / 2 - PLAYER_WID / 2; // ウィンドウの中央X座標
playerPosY = WINDOW_HIG - PLAYER_HIG;
playerFlg = true;
return true;
}
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);
}
}
//Player.h
#pragma once
//------------------------------------------
//他のファイルでも参照が必要な変数の extern宣言
//------------------------------------------
extern int playerPosX; // 自機のX座標
extern int playerPosY; // 自機のY座標
extern bool playerFlg; // 自機の表示状態管理用フラグ(true:表示、false:非表示)
//-------------------------------------------
//プロトタイプ宣言
//-------------------------------------------
bool PlayerInit(void);
void PlayerMove(void);
void PlayerDraw(void);
PlayerBullet.cpp、PlayerBullet.hを作成。自機の弾関連の処理を移行。
//PlayerBullet.cpp
//-----------------------------------------------------------------------------
// インベーダーゲーム
// 氏 名:
//-----------------------------------------------------------------------------
#include <DxLib.h>
#include"main.h"
#include"PlayerBullet.h"
#include"Player.h"
//-----------------
// 変数の宣言
//-----------------
// プレイヤー弾
int playerBulletImage; // プレイヤー弾の画像ハンドル番号
int playerBulletPosX; // プレイヤー弾のX座標
int playerBulletPosY; // プレイヤー弾のY座標
bool playerBulletFlg; // プレイヤー弾の発射状態管理用フラグ(true:表示、false:非表示)
bool PlayerBulletInit(void) {
// プレイヤー弾の画像の読込み
playerBulletImage = LoadGraph("image/playerBullet.png");
if (playerBulletImage == -1)return false;
// プレイヤー弾
playerBulletPosX = playerBulletPosY = 0;
playerBulletFlg = false;
}
void PlayerBulletShot(void) {
if (playerBulletFlg == false) {
//弾が未発射状態なので射撃可能
if (CheckHitKey(KEY_INPUT_SPACE) == 1) {
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;
}
}
//PlayerBullet.h
#pragma once
//----------------------------------------------
//他のファイルでも参照が必要な変数の extern宣言
//----------------------------------------------
extern int playerBulletPosX; // プレイヤー弾のX座標
extern int playerBulletPosY; // プレイヤー弾のY座標
extern bool playerBulletFlg; // プレイヤー弾の発射状態管理用フラグ(true:表示、false:非表示)
bool PlayerBulletInit(void);
void PlayerBulletShot(void);
void PlayerBulletMove(void);
とりあえず続きはまた次回。(現時点では動作しない)
コメント