„Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen.“ – Konfuzius, „Die Gespräche des Konfuzius. Lu Linggong“
Titelseite > Programmierung > Devlog – Ich erstelle eine Spiel-Engine!

Devlog – Ich erstelle eine Spiel-Engine!

Veröffentlicht am 02.11.2024
Durchsuche:672

Devlog - Je créé un moteur de jeu !

Ich erstelle eine Spiel-Engine!

Einführung in dieses großartige Abenteuer

Seit einigen Wochen arbeite ich regelmäßig an einem Projekt, über das ich meiner Meinung nach interessant sprechen könnte: der Erstellung meiner Videospiel-Engine in JavaScript und HTML5 basierend auf dem Canvas.

Sie fragen sich wahrscheinlich, warum Sie sich für HTML5 und JavaScript entschieden haben, um Videospiele zu erstellen? Die Antwort ist weniger cool als die Frage, es ist der Wettbewerb der für meine Schule (Zone01 Normandie) notwendigen Projekte und die Tatsache, dass die Sprachen über alles Notwendige verfügen, um dieses Projekt durchzuführen, die mich dazu veranlasst haben, diese Technologien zu wählen.

Aber eigentlich sind das nicht die Sprachen, die ich als Basis gewählt hätte, und ich werde mich nach der Fertigstellung dieses Abenteuers sicherlich auf andere Abenteuer dieser Art mit anderen Sprachen einlassen.

Architektur

Also habe ich mich daran gemacht, meine Videospiel-Engine zu entwerfen. Sie wird aus mehreren Klassen bestehen, darunter mindestens zwei Hauptklassen: Die Game-Klasse, die den gesamten Spielbereich verwaltet, und die GameObject-Klasse, mit der Sie die Objekte generieren können in unseren Spielen und sorgen dafür, dass sie miteinander interagieren.

Zu diesen Klassen werde ich die CollideBox-Klasse hinzufügen, mit der ich die Kollisionsboxen aller Objekte verwalten kann.

Die Game-Klasse verfügt über eine GameLoop-Methode, die bei jedem Frame (Bild) des Spiels ausgeführt wird, und eine Draw-Methode, die während jeder Spielschleife aufgerufen wird.

Die GameObject-Klasse verfügt über eine Step-Methode und eine Draw-Methode.

Der erste führt jede Runde der Spielschleife aus und der zweite jedes Mal, wenn die Draw-Methode der GameLoop-Klasse aufgerufen wird.

Dadurch können Sie theoretisch Spiele erstellen, indem Sie das Engine-Modul in ein Projekt importieren.

Für die Anzeige der Sprites habe ich mich für die Verwendung der Canva-API entschieden, die in HTML5 integriert ist (integriert bedeutet, dass sie standardmäßig mitgeliefert wird)
Dadurch kann ich alle Sprites anzeigen und die Bilder neu schneiden, um Animationen zu erstellen, die für mich äußerst nützlich sein werden!

Nach einigen Tagen bin ich in der Lage, Animationen bei einer bestimmten Geschwindigkeit anzuzeigen und Kollisionen über meine CollideBoxes zu erkennen.

Und viele andere schöne Dinge, die ich Ihnen unten zeigen werde:

Die GameObject-Klasse

Klasse GameObject{ Konstruktor(Spiel) { // GameObject initialisieren this.x = 0 this.y = 0 this.sprite_img = {Datei: undefiniert, Spalte: 1, Zeile: 1, fw: 1, fh: 1, Schritt: 0, anim_speed: 0, Maßstab: 1} this.loaded = false this.game = Spiel this.kill = false this.collision = new CollideBox() game.gObjects.push(this) }; setSprite(img_path, row=1, col=1, speed=12, scale=1) { var img = neues Bild(); img.onload = () => { console.log("Bild geladen") 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) { // Zeichenfunktion des Spielobjekts if (this.sprite_img.file != undefiniert) { 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 * Spalte, this.sprite_img.fh * Zeile, 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) { // Schrittweise Aktualisierung nur bei 12 fps if (this.sprite_img.step box.x && this.collision.y box.y ) } onStep() {}; }
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  box.x &&
            this.collision.y  box.y
          )
    }
    onStep()   {};
}   

Die Spielklasse

Klassenspiel { Konstruktor(Breite = 1400, Höhe = 700) { this.gObjects = []; this.toLoad = []; this.timers = []; this.layers = []; this.canvas = document.getElementsByTagName("canvas")[0] this.canvas.width = Breite this.canvas.height = Höhe 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; }, FALSCH); document.addEventListener('keyup', (e) => { this.inputs[e.key] = false; }, FALSCH); document.addEventListener('mousemove', (e) => { this.mouse.x = e.x; this.mouse.y = e.y; }) document.addEventListener('mouseevent', (e) => { Schalter (e.Taste) { } }) } draw(frame) { this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); console.log(this.canvas.width, this.canvas.height) for(let i = 0; i { Uhr = 1 for(let i = 0; i 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 box.x && this.collision.y box.y ) } onStep() {}; } Es gibt sicherlich viele Optimierungen oder andere Fehler, aber alles funktioniert,

"Perfekt!" verrätst du es mir?
Das wäre viel zu einfach.

Die Sorgen

Nachdem ich damit fertig war und begonnen hatte, die Voraussetzungen für die Entwicklung eines Spiels mit dieser Engine zu testen, erfuhr ich während eines Gesprächs mit einem Kollegen schreckliche Neuigkeiten.

Ich kann mir vorstellen, dass Sie sich daran erinnern, dass die Technologieentscheidungen getroffen wurden, um den Anforderungen meiner Zone01-Schule zu entsprechen…

Nun ja, die gewählten Sprachen waren zwar gut, aber mir war keine Anweisung bekannt, die das Projekt ernsthaft behindern würde…
Uns wurde die Nutzung der Canva-Bibliothek untersagt!

Zur Erinnerung: Dies ist die Bibliothek, die wir zum Anzeigen unserer Bilder verwenden.

Was kommt als nächstes?

Während ich diesen Text schreibe, fange ich auch an, diese Spiel-Engine komplett neu zu gestalten, ohne die Verwendung von Canva.

Dieses Devlog ist fertig und Sie werden den Rest dieser Geschichte bald lesen, keine Sorge.

Für den nächsten Devlog werde ich auf jeden Fall ein neues Format ausprobieren.

Hoffentlich hat Ihnen dieser Inhalt geholfen, Sie unterhalten oder Sie zumindest über einige Themen aufgeklärt. Ich wünsche Ihnen einen schönen Feierabend und gute Codierung.

DevLogs 1.1: Die Engine ist fertig, wie funktioniert sie?

Vorher

Vor ein paar Monaten habe ich mit der Entwicklung meiner Videospiel-Engine begonnen, ich habe sie fertiggestellt ... Vor einiger Zeit und mit der Hilfe mehrerer Kollegen von Zone01 ist es uns sogar gelungen, ein von Super Mario Bros. inspiriertes Spiel zu entwickeln, das auf meinem verfügbar ist Itch.io-Seite.

Die Entscheidung über das Format für die Bewerbung für dieses Devlog hat viel Zeit in Anspruch genommen, und ich gebe zu, dass ich die Frist für das Schreiben dieses Devlogs etwas verzögert oder sogar ganz verschoben habe.

Indem ich geduldig die Entschuldigung meiner Unentschlossenheit entgegennehme, nicht an diesem Thema zu arbeiten, befinde ich mich nun zwei Monate nach dem geplanten Veröffentlichungstermin wieder und schreibe auf dem Rastplatz des Busbahnhofs von Rouen, während mein ausgefallener Zug mich dazu zwingt, eine zusätzliche Stunde zu warten.

Lassen Sie uns also alle Details der Architektur behandeln, die sich seit dem ersten Teil meines Devlogs kaum verändert hat (abgesehen von der Anpassung durch den Verzicht auf Leinwände).

Wir werden daher über das durchgeführte Projekt, die Art und Weise, wie wir als Team gearbeitet haben, und die Probleme sprechen, auf die wir gestoßen sind.
Sehen Sie dies als Feedback zu diesem Projekt und ich hoffe, dass Sie aus diesem Schreiben einige Lehren ziehen können, die Ihnen bei einem Ihrer Projekte helfen werden.

Das Projekt

Das Projekt bestand darin, einen Super Mario Bros. in JavaScript nachzubilden und von Grund auf neu zu beginnen, zumindest was den Code angeht.

Die Spezifikationen waren einfach, wir mussten ein Mario-Spiel mit mehreren Levels haben, eine Möglichkeit, einfach neue zu erstellen.

Außerdem mussten wir eine Anzeigetafel und ein Menü erstellen, um die Optionen anzupassen.

Die Schwierigkeiten dieses Projekts waren:

    Horizontales Scrollen von Elementen auf dem Bildschirm
  • Optimierung von Elementen, die nicht auf dem Bildschirm vorhanden sind
Scrollen, da alle Elemente relativ zur Position des Spielers im Hintergrund scrollen müssen.

Und durch die Optimierung von Elementen, die nicht auf dem Bildschirm angezeigt werden, werden die Ressourcen reduziert, die zum Ausführen des Spiels ohne Leistungsverlust erforderlich sind.

Nachdem wir diese Schwierigkeiten gelöst haben, haben wir dieses Spiel auf meiner itch.io-Seite veröffentlicht, wo Sie es sogar testen können.

So endet dieses Devlog. Jetzt, da ich fertig bin, kann ich über andere Projekte und/oder andere Themen schreiben.

Wenn Sie auch nur ein bisschen daran interessiert sind, was ich Ihnen erzähle, können Sie sich meine verschiedenen Projekte (einschließlich der in diesem Devlog) auf Github ansehen.

Einen schönen Rest des Tages!

Freigabeerklärung Dieser Artikel ist reproduziert unter: https://dev.to/roys122/devlog-1-je-cree-un-moteur-jeu--
Neuestes Tutorial Mehr>

Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.

Copyright© 2022 湘ICP备2022001581号-3