Devlog - ゲームエンジンを作成しています!

PHPz
リリース: 2024-09-12 18:15:38
オリジナル
287 人が閲覧しました

Devlog - Je créé un moteur de jeu !

ゲームエンジンを作ってます!

この素晴らしい冒険の紹介

ここ数週間、私は、キャンバス に基づいた JavaScript と HTML5 によるビデオ ゲーム エンジンの作成という、話したら面白いかもしれないと思うプロジェクトに定期的に取り組んでいます。

おそらく、ビデオ ゲームを作成するために HTML5 と JavaScript を選択した理由を疑問に思っているのではないでしょうか?答えは質問ほどクールではありません。私の学校 (Zone01 Normandie) に必要なプロジェクトの競争であり、言語にはこのプロジェクトを実行するために必要なものがすべて揃っているという事実が、私がこれらのテクノロジーを選択した理由です。

しかし、実際には、これらは私がベースとして選択したであろう言語ではなく、この言語が完成した後は、別の言語でこの種の別の冒険に乗り出すことになるでしょう。

建築

それで、私はビデオ ゲーム エンジンの設計に取り掛かりました。このエンジンは、少なくとも 2 つの主要なクラスを含むいくつかのクラスで構成されます。Game クラスはゲーム領域全体を管理し、GameObject クラスはオブジェクトを生成できるようにします。私たちのゲームを相互に対話させます。

これらのクラスに、すべてのオブジェクトのコリジョン ボックスを管理できるようにする CollideBox クラスを追加します。

Game クラスには、ゲームの各フレーム (画像) で実行される GameLoop メソッドと、各ゲーム ループ中に呼び出される Draw メソッドがあります。

GameObjectクラスにはStepメソッドとDrawメソッドがあります。
1 つ目はゲーム ループの各ラウンドを実行し、2 つ目は GameLoop クラスの Draw メソッドが呼び出されるたびに実行します。

これにより、理論的にはエンジン モジュールをプロジェクトにインポートすることでゲームを作成できます。
スプライトを表示するために、HTML5 に組み込まれている canva API を使用することにしました (組み込みとは、デフォルトで付属していることを意味します)
これにより、すべてのスプライトを表示したり、画像を再カットしてアニメーションを作成したりできるため、非常に便利です!

数日後、指定された速度でアニメーションを表示し、CollideBox 経由で衝突を検出できるようになりました。
他にもたくさんの素晴らしいものを以下に紹介します:

GameObject クラス

class GameObject{
    constructor(game) { // Initialize the GameObject
        this.x = 0
        this.y = 0 
        this.sprite_img = {file: undefined, col: 1, row: 1, fw: 1, fh: 1, step: 0, anim_speed: 0, scale: 1}
        this.loaded = false
        this.game = game
        this.kill = false
        this.collision = new CollideBox()

        game.gObjects.push(this)

    };
    setSprite(img_path, row=1, col=1, speed=12, scale=1) {
        var img = new Image();
        img.onload = () => {
            console.log("image loaded")
            this.sprite_img = {file: img, col: col, row: row, fw: img.width / col, fh: img.height / row, step: 0, anim_speed: speed, scale: scale}
            this.onSpriteLoaded()
        };
        img.src = img_path


    }
    onSpriteLoaded() {}
    draw(context, frame) { // Draw function of game object
        if (this.sprite_img.file != undefined) {


            let column = this.sprite_img.step % this.sprite_img.col;
            let row = Math.floor(this.sprite_img.step / this.sprite_img.col);

           // context.clearRect(this.x, this.y, this.sprite_img.fw, this.sprite_img.fh);
            context.drawImage(
                this.sprite_img.file,
                this.sprite_img.fw * column,
                this.sprite_img.fh * row,
                this.sprite_img.fw,
                this.sprite_img.fh,
                this.x,
                this.y,
                this.sprite_img.fw * this.sprite_img.scale,
                this.sprite_img.fh * this.sprite_img.scale
            );

            if (frame % Math.floor(60 / this.sprite_img.anim_speed) === 0) {
                // Mise à jour de step seulement à 12 fps
                if (this.sprite_img.step < this.sprite_img.row * this.sprite_img.col - 1) {
                    this.sprite_img.step += 1;
                } else {
                    this.sprite_img.step = 0;
                }
            }
        }
    }
    distance_to(pos) {
        return Math.sqrt((pos.x - this.x) ** 2 + (pos.y - this.y) ** 2)
    }

    collide_with(box) {
        if (box instanceof GameObject) {
            box = box.collision
        }
        return (
            this.collision.x < box.x + box.w &&
            this.collision.x + this.collision.w > box.x &&
            this.collision.y < box.y + box.h &&
            this.collision.y + this.collision.h > box.y
          )
    }
    onStep()   {};
}   
ログイン後にコピー

ゲームクラス

class Game {
    constructor(width = 1400, height = 700) {
        this.gObjects = [];
        this.toLoad = [];
        this.timers = [];
        this.layers = [];
        this.canvas = document.getElementsByTagName("canvas")[0]

        this.canvas.width = width
        this.canvas.height = height
        this.context =  this.canvas.getContext("2d")
        this.context.globalCompositeOperation = 'source-over';
        this.inputs = {};
        this.mouse = {x: 0, y: 0}
        document.addEventListener('keydown', (e) => {
            this.inputs[e.key] = true;
        }, false);
        document.addEventListener('keyup', (e) => {
            this.inputs[e.key] = false;
        }, false);
        document.addEventListener('mousemove', (e) => {
            this.mouse.x = e.x;
            this.mouse.y = e.y;
        })
        document.addEventListener('mouseevent', (e) => {
            switch (e.button) {

            }
        })

    }
    draw(frame) {
        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
        console.log( this.canvas.width, this.canvas.heigh)
        for(let i = 0; i < this.gObjects.length; i ++) {
            this.gObjects[i].draw(this.context, frame)
        }

    }
    gLoop() {
        let fps = Math.floor(1000 / 60)
        console.log(fps)
        let clock = 0
        setInterval(() => {
            clock += 1
            for(let i = 0; i < this.gObjects.length; i ++) {

                if (this.gObjects[i] != undefined) {
                    if (this.gObjects[i].kill) {
                        this.gObjects.splice(i, 1);
                        continue;
                    }
                    this.gObjects[i].onStep();
                }


            }
            this.draw(Math.floor(clock))
               // context.l();

           //     console.log(clock)

           if (fps <= clock) {
            clock = 0
           } 

        }, fps)
    }
    keyboard_check(key) {
        return this.inputs[key] == true
    }
}
ログイン後にコピー

確かに最適化やその他のエラーはたくさんありますが、すべて機能しています。
"完璧!"教えてもらえますか?
それは単純すぎます。

心配事

これを完了し、このエンジンでゲームを作成するためのテストを開始した後、同僚との会話中に恐ろしいニュースを知りました。

テクノロジーの選択は、私の Zone01 学校の要件に対応するために行われたことを覚えていると思います…
確かに、選択された言語は良かったのですが、プロジェクトに重大な支障をきたすような指示があるとは知りませんでした…
Canva ライブラリの使用が禁止されました!

念のため言っておきますが、これは画像を表示するために使用するライブラリです。

次は何でしょうか?

このテキストを書きながら、Canva を使用せずにこのゲーム エンジンを完全に再設計し始めています。

この開発ブログは終了しました。このストーリーの残りの部分はすぐにご覧いただけます。ご心配なく。
次回の開発ブログでは、必ず新しいフォーマットを試してみます。

このコンテンツがあなたを助け、楽しませ、少なくともいくつかの主題について教育することになれば幸いです。一日の終わりとコーディングがうまくいくことを祈っています。

DevLogs 1.1: エンジンは完成しましたが、どのように動作するのでしょうか?

以前

数か月前にビデオ ゲーム エンジンの作成を開始し、完成しました...かなり前に、Zone01 の数人の同僚の協力を得て、スーパー マリオ ブラザーズにインスピレーションを得たゲームを作成することにも成功しました。 itch.io ページ。

この開発ブログに適用する形式を決定するのに多くの時間がかかり、この開発ブログの執筆期限をわずかに遅らせたか、完全に遅らせたことは認めます。
このテーマに取り組めなかった自分の優柔不断の言い訳を辛抱強く受け入れ、今では発売予定日から 2 か月後、電車がキャンセルになったためにさらに 1 時間待たされる中、ルーアンのバス停の休憩所で原稿を書いている自分に気づきました。

因此,讓我們忽略架構的所有細節,自我的開發日誌的第一部分以來,這個架構的變化很小(除了透過避免使用畫布進行的調整之外)。
因此,我們將討論所進行的專案、我們作為團隊的工作方式以及我們遇到的問題。
將此視為對該專案的反饋,我希望您能夠從本文中吸取一些教訓,這將對您的專案之一有所幫助。

專案

這個專案是用 JavaScript 重新創建一個超級瑪利歐兄弟,並從頭開始,至少在程式碼方面是如此。

規格很簡單,我們必須有一個具有多個等級的馬裡奧遊戲,這是一種簡單地創建新等級的方法。
此外,我們還必須建立一個記分板和一個選單來調整選項。

這個項目的困難是:

  • 螢幕上元素的水平捲動
  • 優化螢幕上不存在的元素

捲動,因為它要求所有元素在背景中相對於玩家的位置滾動。
優化螢幕上未顯示的元素有助於減少運行遊戲所需的資源,而不會損失效能。

解決了這些困難後,我們在我的 itch.io 頁面上發布了這個遊戲,您甚至可以去測試它。

本開發日誌就這樣結束了,現在完成了,我將能夠撰寫有關其他項目和/或其他主題的文章。

如果你對我告訴你的內容有一點興趣,你可以在 github 上查看我的不同項目(包括本開發日誌中的項目)。

祝你今天休息愉快!

以上がDevlog - ゲームエンジンを作成しています!の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!