====== 第3回:クラス・コンストラクタ入門(キャラクターの動きを例に) ======
**テーマ:構造体ベースのキャラ操作 → クラス化で整理しよう!**
----
===== 🎯 学習目標 =====
* 構造体とクラスの違いを、キャラクター制御の例から理解する
* public / private / this の意味を説明できる
* コンストラクタでキャラ初期化を自動化できる
* 自分で「キャラクタークラス」を設計できる
----
===== 🧩 Step 1:構造体でキャラを動かしてみよう(C++構文版) =====
#include
using namespace std;
struct Character {
float x, y; // 位置
float speed; // 速度
bool isJumping; // ジャンプ中かどうか
};
// 関数(キャラを操作)
void Walk(Character& c) {
c.x += c.speed;
}
void Run(Character& c) {
c.x += c.speed * 2;
}
void Jump(Character& c) {
if (!c.isJumping) {
c.y += 5;
c.isJumping = true;
}
}
int main() {
Character player = {0, 0, 1.0f, false};
Walk(player);
Run(player);
Jump(player);
cout << "pos=(" << player.x << ", " << player.y << ")\n";
}
**▶ 特徴**
* データ(構造体)と動作(関数)が別々
* 引数で常に `player` を渡す必要がある
* 「自分の関数」という感じがしない
----
===== 🧭 Step 2:クラスにしてみよう =====
#include
using namespace std;
class Character {
public:
float x, y;
float speed;
bool isJumping;
// コンストラクタ(初期化)
Character(float _x, float _y, float _speed)
: x(_x), y(_y), speed(_speed), isJumping(false) {
}
// メンバ関数(自分自身を操作)
void Walk() {
x += speed;
}
void Run() {
x += speed * 2;
}
void Jump() {
if (!isJumping) {
y += 5;
isJumping = true;
}
}
void Print() {
cout << "pos=(" << x << ", " << y << ")\n";
}
};
int main() {
Character player(0, 0, 1.0f);
player.Walk();
player.Run();
player.Jump();
player.Print();
}
**💡 ポイント**
* `player.Walk()` のようにドットで呼び出せる
* データと動作が一つのかたまりになった
* コンストラクタで初期化が自動化される
----
===== 🧠 Step 3:アクセス制御(public / private) =====
class Character {
private:
float x, y;
float speed;
bool isJumping;
public:
Character(float _x, float _y, float _speed)
: x(_x), y(_y), speed(_speed), isJumping(false) {}
void Walk() { x += speed; }
void Run() { x += speed * 2; }
void Jump() {
if (!isJumping) { y += 5; isJumping = true; }
}
void Print() {
cout << "pos=(" << x << ", " << y << ")\n";
}
};
**▶ 解説**
* `private` は外部から見えない
* `public` は外部から呼び出せる
* クラスの内部構造を守る「カプセル化」
----
===== 🧩 Step 4:thisポインタと初期化の話 =====
class Character {
public:
float x, y;
float speed;
Character(float x, float y, float speed) {
this->x = x;
this->y = y;
this->speed = speed;
}
};
**💬 thisとは?**
* 「自分自身」を指す特別なポインタ
* 同じ名前の変数を区別するために使う
例:
> 「私のx」「私のy」と言いたいときに this->x, this->y を使う
----
===== 🧱 Step 5:ファイル分割(.h / .cpp) =====
**Character.h**
#pragma once
#include
class Character {
private:
float x, y;
float speed;
bool isJumping;
public:
Character(float _x, float _y, float _speed);
void Walk();
void Run();
void Jump();
void Print();
};
**Character.cpp**
#include "Character.h"
using namespace std;
Character::Character(float _x, float _y, float _speed)
: x(_x), y(_y), speed(_speed), isJumping(false) {}
void Character::Walk() { x += speed; }
void Character::Run() { x += speed * 2; }
void Character::Jump() {
if (!isJumping) { y += 5; isJumping = true; }
}
void Character::Print() {
cout << "pos=(" << x << ", " << y << ")\n";
}
**main.cpp**
#include "Character.h"
int main() {
Character hero(0, 0, 1.5f);
hero.Walk();
hero.Run();
hero.Jump();
hero.Print();
}
----
===== 🧩 Step 6:演習 =====
**課題1**
キャラクターに **Dash()** を追加して、スピード3倍で移動するようにせよ。
**課題2**
ジャンプ中にもう一度ジャンプできないようにしてみよう。
**課題3**
`Reset()` 関数を追加し、座標を(0,0)に戻すようにせよ。
**課題4**
`Character` クラスに「名前(std::string name)」を追加し、
`Print()` で `"name : pos=(x,y)"` と表示するようにしてみよう。
----
===== 🧠 Step 7:まとめ =====
| 用語 | 意味 |
|--------|--------|
| class | データ+関数をまとめた型 |
| public/private | アクセス制御(情報隠蔽) |
| this | 自分自身を指すポインタ |
| コンストラクタ | 自動初期化関数 |
| カプセル化 | 内部データを守る仕組み |
----
===== 🎮 応用アイデア =====
* **Playerクラス**にHPや名前を追加して、`TakeDamage(int amount)` を実装
* **Enemyクラス**を派生させ、プレイヤーとの距離を求めて「追いかける」動作へ発展
----