Verschieben eines Sprites in XNA / C # mithilfe von Vektoren

9

Ich beschäftige mich derzeit mit der Entwicklung von XNA-Spielen in der Sprache C #.

Ich habe zwei Klassen: den Hauptspielhandler und eine "Sprite" -Klasse. Es folgt ein grundlegender Pseudocode, der das Problem hoffentlich angemessen beschreibt.

Game.cs

class game {
  sprite the_sprite;
  void update(time) {
    var mouse = mouse.state
    if(mouse.clicked) { this.the_sprite.moveTo(mouse.x, mouse.y) }
    this.the_sprite.update(time)
    base.update(time)
  }
}

Sprite.cs

class sprite {
  vector2 location;
  vector2 move_to;
  void moveTo(x, y) { this.move_to = new vector2(x, y) }
  void update(time) {
    if(this.location.x > this.move_to.x /* (or less than) */) {
      // adjust location.x
    }
    if(this.location.y > this.move_to.y /* (or greater than) */) {
      // adjust location.y
    }
  }
}

Grundsätzlich gilt: Wenn der Benutzer irgendwo im Spielfenster klickt, werden die x- und y-Koordinaten der Maus erfasst, und das Spielobjekt bewegt sich über einen bestimmten Zeitraum zu diesem Ort.

Nun ... der Code funktioniert, ist aber hässlich und Objekte bewegen sich nicht direkt auf das Objekt zu (stattdessen ist es eine diagonale Bewegung, gefolgt von einer einachsigen Bewegung). Ich vermute, es gibt einige mathematische Funktionen, die ich verwenden kann, aber ich habe ehrlich gesagt keine Ahnung, wo ich anfangen soll. Irgendwelche Vorschläge?

Matt
quelle
3
Hallo Gast. Was Sie suchen, ist Normalisierung. Bitte lesen Sie die Antworten auf diese Frage: gamedev.stackexchange.com/questions/7540/… . Einer bietet Code, den Sie benötigen, der zweite erklärt, wie er sehr gut funktioniert.
Notabene
Hallo, ich habe mir den Link angesehen und es war genau das, was ich brauchte. Danke!
Matt

Antworten:

12

Wenn ich Ihr Problem richtig verstehe, sollten Sie nur eine Richtung Vector2 haben, die die Richtung darstellt, in die Sie sich innerhalb Ihrer Sprite-Klasse bewegen möchten. So was:

public Vector2 Direction { get; set; }

Dies ist der normalisierte Vektor (dh er hat eine Länge von 1), der anzeigt, wohin Sie möchten.

Fügen Sie dann eine Speed ​​float-Eigenschaft hinzu, die angibt, wie schnell das Sprite sein soll.

public float Speed { get; set; }

Sie müssen auch eine UpdateSprite-Funktion hinzufügen. Warum also nicht in Ihre Sprite-Klasse einfügen?

public Update(GameTime gameTime)
{
   Position += Direction * Speed * gameTime.ElapsedGameTime.TotalSeconds;
}

Dadurch wird die Position des Sprites aktualisiert, damit es sich bewegt (Sie multiplizieren mit den Delta-Sekunden, damit sich das Sprite auch auf langsamen Computern ordnungsgemäß bewegt).

Schließlich legen Sie einfach Ihre Richtungseigenschaft wie folgt fest:

sprite.Direction = location - sprite.Position;
sprite.Direction.Normalize();
Jesse Emond
quelle
Beachten Sie auch, dass Ihr Sprite angekommen ist, wenn die Länge des Sprites.Direction (vor der Normalisierung) unter einem bestimmten Schwellenwert liegt.
TreDubZedd
Genau, ich wollte gerade meinen Beitrag bearbeiten, aber ich denke, ich werde es nicht tun. Wenn Sie nicht möchten, dass Ihr Sprite ständig nach dem Ziel sucht, setzen Sie die Richtung einfach auf Vector2.Zero, wenn es nahe genug am Ziel liegt.
Jesse Emond
Sehr gute Antwort ... und Sie haben mir auch die Verwendung von gameTime beigebracht (um Sprites auf langsameren Computern mit einer angemessenen Geschwindigkeit zu bewegen), also zwei Fliegen mit einer Klappe. Ich werde diese Antwort als akzeptiert markieren.
Matt
:) Übrigens möchte ich persönlich die Normalisierung in meine Sprite-Klasse (innerhalb meiner Update-Funktion) einfügen, um zu verhindern, dass ich sie außerhalb der Klasse ständig normalisieren muss. Sie sollten auch sicherstellen, dass die Länge des Vektors nicht gleich 0 ist, da Sie sonst eine Ausnahme durch 0 erhalten. Überprüfen Sie einfach, ob Direction.LengthSquared ()> 0 ist, bevor Sie es aus Sicherheitsgründen normalisieren (Länge im Quadrat, damit Sie diese teure Quadratfunktion nicht berechnen müssen;)).
Jesse Emond
Nehmen wir an, wir verwenden eine andere IDE ohne Normalisierungsfunktion. Wie lautet die Normalisierungsgleichung?
Spooks
1

Google-Normalisierung ... Ich bin auch ein wenig verloren, aber ich bin mir ziemlich sicher, dass dies zur Lösung Ihres Problems beitragen wird. Jemand anderes kann meine Antwort ausarbeiten oder widerlegen, da bin ich mir sicher

Edit: Ich könnte das besser beantworten, entschuldige

Ich persönlich schaue immer auf diesen Blog-Beitrag, um bei solchen Problemen zu helfen: http://blog.wolfire.com/2009/07/linear-algebra-for-game-developers-part-1/

Es beginnt bei Null und ist für die Spieleentwicklung relevant.

Douglas Rae
quelle
3
Sie haben Recht, es ist Normalisierung. Es ist jedoch immer besser, in früheren Fragen eine gute Antwort zu finden. Und wenn Sie antworten, ist es immer besser, wenig zu erklären oder Code zu teilen oder was auch immer Sie für nützlich halten, und nicht nur auf Google zu verweisen.
Notabene
Ich hätte kommentieren sollen, du hast recht.
Douglas Rae