Bomberman-Klon, wie macht man Bomben?

8

Ich spiele mit einem Bomberman-Klon herum, um die Entwicklung von Spielen zu lernen.

Bisher habe ich Kacheln, Bewegung, Kollisionserkennung und Gegenstandsaufnahme durchgeführt. Ich habe auch Pseudo-Bombplacing (nur Grafik und Kollision, keine echte Funktionalität).

Ich habe eine jsFiddle des Spiels mit der Funktionalität gemacht, die ich derzeit habe. Der Code in der Geige ist allerdings sehr hässlich. Scrollen Sie an der Karte vorbei und Sie finden, wie ich Bomben platziere.

Was ich jedenfalls tun möchte, ist ein Objekt, das allgemeine Informationen über Bomben enthält wie:

function Bomb(){
  this.radius = player.bombRadius;
  this.placeBomb = function (){
    if(player.bombs != 0){
      // place bomb
    }
  }
  this.explosion = function (){
  // Explosion
  }
}

Ich weiß allerdings nicht wirklich, wie ich es in den Code einfügen soll. Jedes Mal, wenn ich eine Bombe platziere, muss var bomb = new Bomb();oder muss ich diese ständig im Skript haben, um darauf zugreifen zu können.

Wie fügt die Bombe Schaden zu? Ist es so einfach wie X, Y in alle Richtungen zu machen, bis der Radius abläuft oder das Objekt ihn stoppt? Kann ich so etwas wie setTimeout (bomb.explosion, 3000) als Timer verwenden?

Jede Hilfe wird geschätzt, sei es eine einfache Erklärung der Theorie oder Codebeispiele basierend auf der Geige. Als ich das Objekt so ausprobierte, brach es den Code.

Update: Ich platziere jetzt Bomben und lösche sie nach einer gewissen Zeit, abhängig von der Position, an der ich sie platziert habe. Aber wenn ich eine Bombe platziere, bevor die erste Bombe explodiert, wird nur eine davon gelöscht (offensichtlich, da sich bombX und bombY geändert haben, seit die erste platziert wurde).

Jetzt muss ich wissen, wie ich dieses Problem beheben kann, vielleicht ein neues Array mit allen Bombenpositionen erstellen? Was ist der beste Weg, dies zu tun?

Aktueller Code:

function placeBomb(){
    if(placebomb && player.bombs != 0){
        map[player.Y][player.X].object = 2;
        bombX = player.X; bombY = player.Y;
        placebomb = false;
        player.bombs--;
        setTimeout(explode, 3000);
    }
}
function explode(){
    alert('BOOM!');
    delete map[bombY][bombX].object;
    player.bombs++;
}
Justanotherhobbyist
quelle
1
jsFiddle + Firebug -> Prototyping-Tool für Spiele? Hatte noch nie daran gedacht. +1 für das angenehme Blasen! :)
Anko

Antworten:

6

Es sieht nicht so schlecht aus, aber Sie brauchen eine bessere Kontrolle über Timing und Eingabe. Da die Bewegungsgeschwindigkeit von der Einstellung der Tastenanschlagwiederholung auf dem Computer des Benutzers abhängt, ist dies nicht genau optimal.

Stattdessen sollten Sie verfolgen, welche Tasten gerade gedrückt gehalten werden. Sie können dies wie folgt tun (im Pseudocode):

keyisdown=false
keydown event{
    if(!keyisdown){
        //This is the 'real' keydown event, the one that only happens the moment the
        //key is pressed down. You may not need it, but this is how you construct it.
    }
    keyisdown=true
}

keyup event{
    keyisdown=false
}

Und dann bewegen Sie in Ihrer Update-Funktion den Player, wenn keyisdownund möglicherweise wenden Sie einige andere Bedingungen an, z. B. kann sich der Player nicht bewegen, wenn er sich vor weniger als einer Anzahl von Updates bewegt hat.

Halten Sie einen aktualisierten Zähler oder eine andere Methode, um die Zeit im Auge zu behalten, damit Ihr Code immer genau weiß, wie weit er fortgeschritten sein sollte.

Da bomb
Persönlich würde ich es einfach halten, du brauchst es eigentlich nicht zu benutzen this,new und all die anderen ausgefallenen Dinge in JavaScript, um nützliche Objekte zu erstellen.

Sie könnten so etwas tun wie:

bombobject = {} //That is all it takes to make an object.
bombobject.blowtime = currenttime + delay
bombobject.position = mapobject
mapobject.bomb = bombobject

Dann können Sie bei jedem Update durch die Karte radeln, prüfen, ob eine Bombe vorhanden ist und ob es Zeit zum Blasen ist. Wenn ja, blasen Sie das Bombenobjekt und entfernen Sie es.

Bugtracking
Ihr Code leckt Fehler, sie sind ziemlich einfach, aber wenn Sie nichts über sie lernen und damit umgehen, werden Sie später Probleme haben. Jeder moderne Browser verfügt über eine Firebug-Klon-Entwicklerkonsole. Öffnen Sie es, sehen Sie sich die Registerkarte der Skriptkonsole an, sehen Sie den bösen roten Text und korrigieren Sie ihn.

Bearbeiten: Bedenken hinsichtlich der Zeitmessung
Nur für den Datensatz möchten Sie wahrscheinlich etwas Fortgeschritteneres als setIntervalfür das Timing. Wenn Sie es ernst meinen, müssen Sie Ihren Code wirklich an den Zeitschlupf anpassen. Eine ungefähre Beschreibung des Problems finden Sie in meiner allerersten Antwort zum Stapelüberlauf: https://stackoverflow.com/a/2549426/305545

Bearbeiten: setTimeOut-Version behoben
Da Sie dieselben Variablen für verschiedene Bomben verwenden, werden Sie diese überschreiben, wenn eine neue Bombe platziert wird. Sie können einen Verschluss verwenden, um individuelle Variablen für jede Bombe zu erstellen, wie folgt:

function placeBomb(){
    if(placebomb && player.bombs != 0){
        map[player.Y][player.X].object = 2;
        var bombX = player.X;
        var bombY = player.Y;
        placebomb = false;
        player.bombs--;
        setTimeout(explode, 3000);
    }
    function explode(){
        alert('BOOM!');
        delete map[bombY][bombX].object;
        player.bombs++;
    }
}

Nun sind die bombXund bombYVariablen und die explodeFunktion sind Einheimische zur Schließung von placeBombs erstellt, so ist es die lokale Instanz , explodedass auf dem Timeout angebracht, und es liest die lokalen Variablen. Jedes Mal, wenn Sie anrufenplaceBomb einen neuen Abschluss ein neuer Abschluss erstellt.

Ich hätte setTimeout dafür nicht verwendet, ich hätte Updates gezählt und somit eine feste Anzahl von Updates sichergestellt, bevor die Bombe explodiert, aber ich denke, das wird in Ordnung funktionieren.

aaaaaaaaaaaa
quelle
Ja, die Geige ist nicht der gleiche Code wie meine game.js, einige kopieren, einfügen und nur zufällig einfügen. Der echte Code enthält keine Fehler in Firebug- oder Chromes-Entwicklertools. Ich werde versuchen, deine Bombe zum Laufen zu bringen. Vielen Dank. :)
justanotherhobbyist
Wirklich keine Fehler? Weder wenn Sie versuchen, sich von der Karte zu entfernen?
aaaaaaaaaaaa
Jetzt, wo Sie es erwähnen, habe ich das bekommen, aber das ist kein Problem, da die ersten Fliesen ein Rahmen aus Beton sind. :) Nur die Geigenkarte, die vereinfacht wurde.
Justanotherhobbyist
Ja, ich habe das Problem mit setTimeout bemerkt. Ich habe jetzt eine Reihe von Bomben, die mit 2 Bomben gut funktionieren. Bei mehr Bomben wird die mittlere nicht gelöscht. Ich denke, ich muss ein bisschen Timing machen, wenn (timer> = timeplaced) oder etwas ähnliches. Ich lerne viel, indem ich Fehler mache und sie im Laufe der Zeit aussortieren muss: D, vor ein paar Tagen konnte ich nicht einmal Pong machen.
Justanotherhobbyist
Bitte schön. Und es ist schön zu hören, dass Sie lernen. Manchmal ist es schwer zu glauben, dass die Lösung der unmittelbaren Probleme der Menschen wirklich irgendwohin führen wird.
aaaaaaaaaaaa
0

Scheint, als hättest du eine ziemlich nette Markise, die nur einen praktischen Code für die Explosionen hinzufügen wollte.

            for (int i = 0; i < actor.blasradius; ++i)
        {
            tiles[actor.tileX - i][actor.tileY].explode(); //left
            tiles[actor.tileX + i][actor.tileY].explode(); //right
            tiles[actor.tileX][actor.tileY -i].explode(); //up
            tiles[actor.tileX][actor.tileY + i].explode(); //down
        }
Omgnoseat
quelle
Ja, ich habe etwas Ähnliches, aber mit Bedingungen wie Kisten, Beton usw. und Zerstörung oder Anhalten, je nachdem. Der Code kann hier nachgelesen werden: gamedev.stackexchange.com/questions/26065/...
justanotherhobbyist