第3回:クラス・コンストラクタ入門(キャラクターの動きを例に)

テーマ:構造体ベースのキャラ操作 → クラス化で整理しよう!


  • 構造体とクラスの違いを、キャラクター制御の例から理解する
  • public / private / this の意味を説明できる
  • コンストラクタでキャラ初期化を自動化できる
  • 自分で「キャラクタークラス」を設計できる

#include <iostream>
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` を渡す必要がある
  • 「自分の関数」という感じがしない

#include <iostream>
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()` のようにドットで呼び出せる
  • データと動作が一つのかたまりになった
  • コンストラクタで初期化が自動化される

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` は外部から呼び出せる
  • クラスの内部構造を守る「カプセル化」

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 を使う

Character.h

#pragma once
#include <iostream>
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();
}

課題1 キャラクターに Dash() を追加して、スピード3倍で移動するようにせよ。

課題2 ジャンプ中にもう一度ジャンプできないようにしてみよう。

課題3 `Reset()` 関数を追加し、座標を(0,0)に戻すようにせよ。

課題4 `Character` クラスに「名前(std::string name)」を追加し、 `Print()` で `“name : pos=(x,y)“` と表示するようにしてみよう。


用語 意味
——–——–
class データ+関数をまとめた型
public/private アクセス制御(情報隠蔽)
this 自分自身を指すポインタ
コンストラクタ 自動初期化関数
カプセル化 内部データを守る仕組み

  • PlayerクラスにHPや名前を追加して、`TakeDamage(int amount)` を実装
  • Enemyクラスを派生させ、プレイヤーとの距離を求めて「追いかける」動作へ発展

  • game-engineer/classes/2025/game-development-1/no-07.txt
  • 最終更新: 3カ月前
  • by root