---
# System prepended metadata

title: インゲーム設計
tags: [2024春みんげ～アクションチーム]

---

[HOME](https://hackmd.io/2BHmUlxZRy-eNbUEF2Mc-A?view)
# インゲーム設計
## クラス
### ボツ案

```cpp=
class StageManager {
private:
    NoteManager noteManager;
    Player player;
    MusicData musicData;
public:
    void loadFromFile(filePath) {
        // 譜面、メタデータファイルから情報取得
        noteManager.loadNotesFromCSV(CSV文字列)
    }
    void update() {
        noteManager.update();
        player.update();
    }
    void draw() const {
        noteManager.draw();
        player.sraw();
    }
}

class NoteManager {
private:
    Array<Note*> notes;
public:
    void loadNotesFromCSV(String rawCSV) {
        // csv文字列からノーツ読み込み
    }
    
    void update() {
        for (auto note : notes) {
            note->update();
        }
    }
    
    
    
    void draw() const {
        for (auto note : notes) {
            note->draw();
        }
    }
}


class Player {
public:
    void animate(PlayerAnimation);
    void update();
    void drawAt(Vec2 pos);
}

class MusicData {
public:
    double bpm;
    int beatPerMeasure;
    Duration firstBeatTimePos
}
```

## 設計（決定）
```mermaid
classDiagram
InGame "1" --> "1" Notes
Notes "1" --> "0..n" Note
Note <|-- それぞれのNote

class InGame {
    -Array<Note*> notes
    -Audio music
    
    +update()
    +draw()
    -judge(now): Judgment
}

class Notes {
    -Array<Note*> notes
    
    +notesInsideScreen(now): Array
}

class Note {
    +draw()
}
    
```
    
```cpp

class Notes {
    Array <std::shared_ptr<Note>> notes;
    
    Init() {
        // 譜面読み込み
        while() {
            notes << std::make_shared<Node>(args...);
        }
    }
    
    notesInsideScreen(now) {
        return notes.filter([](Note *n){ return !n->isOutOfRange(now); });
    }
}

class InGame {
    Notes notes = {...};
    Audio music;

    InGame::update() {
        inputType = ...
        now = music.posSec();

        player.update();
        effectManager.update();
        for (auto note : notes.notesInsideScreen(now)) {
            note.update(); // animation
            judge.judge(now, note, inputType);
        }
    }

    InGame::draw() {
        now = 今の時間
        for (auto note : notes.notesInsideScreen(now)) {
            note.draw();
        }
    }

    const double margin = 0.1;

    Judgment judge(now, note, inputType) {
        // 画面に入ってきてすぐのノーツに反応してしまう
        // ジャッジはプレイヤーの一定範囲内でのみ行う
        if (!note->isActive())
            return Judgment::None;
        if (note->type != inputType)
            return Judgment::None;
        if (abs(now - note->time) < margin) {
            return Judgment::Success;
        } else {
            return Judgment::failure;
        }
    }
}

class Note {
protected:
    Note(Duration timePos, double intervalBeat)
        : timePos(timePos), intervalBeat(intervalBeat) {}
    virtual ~Note() {} // 仮想デストラクタ
        
    const Duration timePos; // ノーツの配置位置(s)
    const double intervalBeat; // ノーツが出現してからプレイヤーに衝突するまでの拍数
    NoteState state; // ノーツの状態（回避に成功したかどうか）
    AvoidType avoidType; // 回避の仕方

public:
    virtual void update(Duration now, Player player) = 0;
    virtual void draw(Duration now, Player player) const = 0;
    virtual bool isActive() const = 0;
    
    void setState(NoteState nextState) {
        this->state = nextState;
    }
    
    bool isOutOfRange(double now) {
        
    }
}


```

Note::update()で何をするか？

InGameシーンがすべてのノーツと曲をもち、画面内ノーツを対象に処理・判定を行う。
シーンがJudgeしてもいいよね？

### Animation
AnimationTexture.h
```cpp
class AnimationTexture {
private:
    Texture texture; // 元となる画像
    Point frameSize; // 1フレームのサイズ(ピクセル)
    int numFrame; // フレーム数

public:
    AnimationTexture(Texture texture, Point frameSize);
    // 指定したフレーム番号のテクスチャを返す
    Texture frame(int frame);
    // switchSpanの期間ごとにフレームを切り替えたテクスチャを返す
    // timePosの剰余を取ってアニメーションさせる
    // (timePos / switchSpan) mod numFrame
    Texture animateByTime(Duration timePos, Duration switchSpan);
}
```
AnimationTexture.cpp
```cpp
AnimationTexture::AnimationTexture(Texture texture, Point frameSize, int numFrame)
    : texture(texture), frameSize(frameSize), numFrame(numFrame) {}

Texture AnimationTexture::draw(int frame) {
    // 実装
}

Texture AnimationTexture::animateByTime(Duration timePos, Duration switchSpan) {
    // 実装
}

```

### UV管理（仮）
`playerJump.png`
画像。
`playerJump.json`
UVをずらすために1フレームの横と縦の長さを指定する。
```json
{
    "widthPerFrame": 10,
    "heightPerFrame": 20
}
```
CSVでもいいかもー
`playerJump.csv`
```csv
10,20
```

### アセット管理
Asset.h
```cpp=
namespace Asset {
    namespace Texture {
        String playerRun{U"playerRun.png"};
        String playerJump{U"playerJump.png"};
    }
}
```

Asset.cpp
```cpp=
void RegisterAsset() {
    
}
```
