0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【JS】ゲームのMVCのイベント伝達

Last updated at Posted at 2025-04-10

MVC

Model, View, ControllerでMVC.
Modelはビジネスロジック、Viewは描画、Controllerは操作関連の処理を行う。

参照関係は

  • Controller -> Model
  • Controller -> View
  • View -> Model

Modelは参照先がないのが特徴。

つまりControllerを始点にしてViewを通りModelに終着するのがこのMVCの特徴。
ちなみに参照関係が上述とは違うMVCもあり、それはWebなどでよく使われている。

Model, View, Ctrl

class MyCtrl {
    constructor () {
        this.model = new MyModel()
        this.view = new MyView(this.model)
    }

    update () {
        if (keyboard.isKeyPressed('Enter')) {
            this.model.blabla()
        }
        
        this.model.update()
        this.view.update()
    }

    draw () {
        this.view.draw()
    }
}

こーんな感じでControllerを作る。
Viewはこんな感じ。

class MyView {
    constructor (model) {
        this.model = model
        this.canvas = document.createElement('canvas')
        document.body.appendChild(this.canvas)
        this.ct = this.canvas.getContext('2d')
    }

    update () {
        // nothing todo
    }

    draw () {
        this.ct.fillStyle = 'red'
        this.ct.fillRect(0, 0, 100, 100)
    }
}

Modelはこう。

class MyModel {
    constructor () {
        this.count = 0
    }

    update () {
        // nothing todo
    }

    blabla () {
        this.count++
    }
}

レイヤー間のイベントの伝達

さて、このパターンはModelで行き止まりだが、ModelからControllerへ何かを伝達したい時はあるものである。
つまり子から親に向かって命令を送る。
親から子に流れている処理に逆らってまるで鯉の滝登りのように子から親に命令という名の下剋上をするのである。

じっさいのMVCでどうやるのかは知らんが、とりあえず返り値は使えそうである。

class MyCtrl {
    update () {
        let events = this.model.update()

        for (let event of events) {
            switch (event.kind) {
            case EV_EXIT:
                this.end = true
                break
            case EV_NOTICE:
                this.view.notice(event.message)
                break
            }
        }
    }
}

上みたいにmodelから返り値でイベント列を受け取り、それを処理する。
modelのupdateで色々ビジネスロジックをするわけだが、そのロジックの中でコントローラーに通知したいイベントは上記のように返り値で上層に通知する。うーん、鯉の滝登り!

ModelはCtrlとViewの参照を持っていないので、CtrlとViewを操作することはできない。だが、返り値を使うことで上層レイヤーにイベントを通知、そして上記のthis.view.notice(event.message)のような感じでイベントを通じてViewを呼び出す。

おわりに

うーん、エレガント! すばらしい!
MVCは不滅だ! MVC! MVC!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?