1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScriptでゲームエンジンを作りたいPart2

Posted at

はじめに

前回の予告通りにFortis.Gameのinit関数について書いていきます。

キャンバス

Fortis.Gameのinit関数内に書くことは描画をするキャンバスについてです。
普通なら

canvas
let canvas = document.createElement("canvas");
let context = canvas.getContext("2d");
document.body.appendChild(canvas);

みたいにしてあげればよいのですが、これだと沢山描画の処理をすると重くなってしまうので、負荷を少しでも抑えるためにOffScreenCanvasというのを使います。
簡単に説明すると、画面には表示させないキャンバスって感じです。

詳しくはこちらから↓
https://developer.mozilla.org/ja/docs/Web/API/OffscreenCanvas

そうすると、コードは以下のようになります。

OffscreenCanvas
//オフスクリーンキャンバス
let offSCanvas = new OffscreenCanvas();
let offSContext = offSCanvas.getContext("2d");

//通常のキャンバス
let canvas = document.createElement("canvas");
let context = canvas.getContext("2d");
document.body.appendChild(canvas);

//描画
function draw(){
    //オフスクリーンキャンバスで描画(例)
    offSContext.fillRect(0,0,100,100);

    //オフスクリーンキャンバスでレンダリングされたものをキャンバスに表示させる
    context.drawImage(offSCanvas.transferToImageBitmap(),0,0);
}

描画のAPIはキャンバスと同じなので、最後のキャンバスに表示させるのだけを忘れなければ大丈夫ですね。

これをFortis.Gameのところに書きます。

engine/core.js
Fortis.Game = {
    //変数系
    canvas: null,//オフスクリーンキャンバス(エンジン外からのアクセスする可能性もあるので、の便宜上この名前とする)
    context: null,//canvasのコンテキスト(名前の理由は同上)
    finalCanvas: null,//最終的に描画されるキャンバス
    finalContext: null,//finalCanvasのコンテキスト
    config: {//設定
        debug: false,//デバッグモード
    },

    //関数
    init() {//初期化
        //オフスクリーンキャンバス
        this.canvas = new OffscreenCanvas();
        this.context = this.canvas.getContext("2d");

        //最終的な描画キャンバス
        this.finalCanvas = document.createElement("canvas");
        this.finalContext = this.finalCanvas.getContext("2d");
        document.body.appendChild(this.finalCanvas);

        //キャンバスのサイズ
        let width = 800;
        let height = 450;
        this.canvas.width = width;
        this.canvas.height = height;
        this.finalCanvas.width = width;
        this.finalCanvas.height = height;

        Fortis.info.SystemInitCompleted();//初期化完了
    },

    //ゲームループ
    loop() {
        this.draw();//描画関数を呼び出す
        requestAnimationFrame(this.loop.bind(this));//アニメーションループ
    },

    //描画
    draw: null,
}
engine/util.js
Fortis.info = {
    //new
    SystemInitCompleted() { Fortis.util.console("Info", "ゲームシステムの初期化が完了しました。") },
    
    StartGameLoop() { Fortis.util.console("Info", "ゲームループを開始します。") },
}

util.jsのinfoにSystemInitCompletedを書いておきます。

描画の処理はdraw.jsというファイルを作ってそこに書きます。(addthis.jsのfilesに追加しておく)

engine/draw.js
Fortis.Game.draw = function(){
    //オフスクリーンキャンバスで描画(例)
    Fortis.Game.context.fillStyle = "#252525";
    Fortis.Game.context.fillRect(0,0,Fortis.Game.canvas.width,Fortis.Game.canvas.height);//キャンバスを塗りつぶし
  
    Fortis.Game.context.fillStyle = "#a0a0a0";
    Fortis.Game.context.fillRect(100,100,50,50);//正方形を描画

    //オフスクリーンキャンバスでレンダリングされたものをキャンバスに表示させる
    Fortis.Game.finalContext.drawImage(Fortis.Game.canvas.transferToImageBitmap(),0,0);
}

適当に書いてみました。必要ないコードを省いで実行させると...

See the Pen Untitled by Rei-Miyakawa (@Rei-Miyakawa) on CodePen.

ちゃんと表示されましたね。

まとめ

以下、今のところのファイル・フォルダの状況(変更されたところだけ)

root/
    ┣index.html
    ┣engine/
    ┃   ┣addthis.js
    ┃   ┣core.js
    ┃   ┣draw.js
    ┃   ┗util.js
    ┗script/
        ┗main.js
engine/addthis.js
let files = [
    "core",
    "draw",//new
    "util",
];
engine/core.js
Fortis.Game = {
    //変数系
    canvas: null,//オフスクリーンキャンバス(エンジン外からのアクセスする可能性もあるので、の便宜上この名前とする)
    context: null,//canvasのコンテキスト(名前の理由は同上)
    finalCanvas: null,//最終的に描画されるキャンバス
    finalContext: null,//finalCanvasのコンテキスト
    config: {//設定
        debug: false,//デバッグモード
    },

    //関数
    init() {//初期化
        //オフスクリーンキャンバス
        this.canvas = new OffscreenCanvas();
        this.context = this.canvas.getContext("2d");

        //最終的な描画キャンバス
        this.finalCanvas = document.createElement("canvas");
        this.finalContext = this.finalCanvas.getContext("2d");
        document.body.appendChild(this.finalCanvas);

        //キャンバスのサイズ
        let width = 800;
        let height = 450;
        this.canvas.width = width;
        this.canvas.height = height;
        this.finalCanvas.width = width;
        this.finalCanvas.height = height;

        Fortis.info.SystemInitCompleted();//初期化完了
    },

    //ゲームループ
    loop() {
        this.draw();//描画関数を呼び出す
        requestAnimationFrame(this.loop.bind(this));//アニメーションループ
    },

    //描画
    draw: null,
}
engine/draw.js
Fortis.Game.draw = function(){
    //オフスクリーンキャンバスで描画(例)
    Fortis.Game.context.fillStyle = "#252525";
    Fortis.Game.context.fillRect(0,0,Fortis.Game.canvas.width,Fortis.Game.canvas.height);//キャンバスを塗りつぶし
  
    Fortis.Game.context.fillStyle = "#a0a0a0";
    Fortis.Game.context.fillRect(100,100,50,50);//正方形を描画

    //オフスクリーンキャンバスでレンダリングされたものをキャンバスに表示させる
    Fortis.Game.finalContext.drawImage(Fortis.Game.canvas.transferToImageBitmap(),0,0);
}
engine/util.js
Fortis.info = {
    //new
    SystemInitCompleted() { Fortis.util.console("Info", "ゲームシステムの初期化が完了しました。") },
    
    StartGameLoop() { Fortis.util.console("Info", "ゲームループを開始します。") },
}

以上です。
前回は少し長かったですが、今回からはこのくらいの分量でやっていこうと思います。
次回からは描画関係について書いていきます。
それではまた次回。

前回:https://qiita.com/Rei-Miyakawa/items/456dd9798d0dffa44c11#%E3%81%BE%E3%81%A8%E3%82%81
次回:

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?