Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

27.08.2017, 19:40

Wie kann ich in SFML (C++) meinen Sprite schrittweise fortbewegen?

Hallo!

Ich programmiere gerade ein Spiel, für das es essentiell ist, dass sich der Spieler Schrittweise, also bei mir in 33 Pixel Schritten fortbewegt.
Hat jemand eine Idee, wie man das realisieren kann? Ich habe schon die Bewegung gemacht, allerdings kann sich der Spieler noch frei Bewegen.

Ich saß da jetzt schon entspannte 2 Stunden dran, und habe bis jetzt gewartet, dass ich freigeschaltet werde :dash: :rolleyes:

Hier ein Auszug aus meiner Klasse für Bewegung in eine Richtung (den Rest habe ich herausgeschnitten):

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
//Verändert MoveMent - verhindert das Laufen in 2 Richtungen gleichzeitig
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left) && MoveMent != 1)
    MoveMent = 1;

//Bewegt den Spieler je nach Wert in MoveMent
if (MoveMent == 1)
    {
        psPlayer->move(-200 * frametime, 0);        //ermöglicht bis jetzt das freie Laufen, muss ersetzt werden
        psPlayer->setTexture(*ptPlayerLeft);        //Verändert die Textur je nach Richtung - vorher definiert
    }


Weil man später durch schmale "Gänge" laufen muss, wäre es zu umständlich und unmöglich die Bewegung frei zu lassen - zumal ich ein altes Spiel für Windows 10 nachbaue, dass so funktioniert hat. Ich möchte also, dass wenn der Spieler von Koordinate 99 nur zu Feld 50 geht, die Figur sich automatisch bis Koordinate 33 bewegt.

LG und vielen Dank im Voraus :thumbup: , BleenPaper

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »BleenPaper« (27.08.2017, 19:59) aus folgendem Grund: unklar, verwirrend


Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

2

27.08.2017, 20:08

Du misst die vergangene Zeit und sobald diese einen bestimmten Wert überschreitet bewegst du deine Sprite um deine gewünschten 33 Pixel weiter. Zusätzlich kannst du zwischen den beiden Werten jetzt noch interpolieren. Das bedeutet dass du die Position nicht direkt um die 33 Pixel verschiebst, sondern das ganze Schrittweise über mehrere Frames machst. Fang erst mal vorne an. Speichere dir die vergangene Zeit und bewege dann wenn genug Zeit vergangen ist um die 33 Pixel.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

3

27.08.2017, 20:44

Danke!

Okay, erstmal danke für die Tipps! 8) :)

Zitat

Du misst die vergangene Zeit und sobald diese einen bestimmten Wert überschreitet bewegst du deine Sprite um deine gewünschten 33 Pixel weiter.

Die Theorie habe ich soweit verstanden, aber wenn die Zeit noch nicht verstrichen ist, bewegt sich der Spieler ja nicht oder? ?( Ich will vor allem, dass sich der Spieler zuende Bewegt (durch "MoveMent" bewegt sich der Spieler solange, bis eine Andere Richtung gewählt wird oder die Leertaste gedrückt wird)

Ich hoffe du verstehst, dass ich die Theorie erstmal verstehen möchte oder? :search:

Danke, ich probiere das jetzt auf jeden Fall einmal aus!

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

4

27.08.2017, 20:58

Die Theorie habe ich soweit verstanden, aber wenn die Zeit noch nicht verstrichen ist, bewegt sich der Spieler ja nicht oder? Ich will vor allem, dass sich der Spieler zuende Bewegt (durch "MoveMent" bewegt sich der Spieler solange, bis eine Andere Richtung gewählt wird oder die Leertaste gedrückt wird)

Lass den Spieler für den Anfang erst mal von Position zu Position springen. Als Pseudocode ist das in etwa so:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
current_time = 0.0
time_for_move = 0.8
movement = 33

update(delta_time) {
  if(should_move and current_time == 0) {
    position += movement
  }
  current_time += delta_time
  if(current_time >= time_for_move) {
    current_time = 0
  }
}


Damit hast du vielleicht eine Vorstellung davon wie das aussehen kann. An sich ganz simpel. Wenn das soweit läuft kannst du dafür sorgen dass die Bewegung Schrittweise stattfindet, solange der Zähler nach oben gezählt wird.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

5

27.08.2017, 21:19

BleenPaper

Wird MoveMent nach der Bewegung auch irgendwo wieder zurückgesetzt?


Willkommen im Forum übrings!
Freischaltung geschieht manuell, daher kann es durchaus mal etwas dauern. ;)
fka tm

6

27.08.2017, 21:41

@Schorsch Super, Danke! Damit lässt sich doch schon einmal viel mit Anfangen :D Danke! Ich gucke mir das einmal in Ruhe durch :D :)

@Michael Nein, das Ziel ist es, dass sich der Player so lange bewegt, bis man ihm eine andere Richtung gibt. Vielleicht kann man das Später noch an/aus stellen, aber erstmal soll das so bleiben :D :) :P
-> Man kann Leertaste drücken, um den Spieler zum stehen zu bringen 8o

An alle: Danke für die schnelle Hilfe! :D hier findet man mehr als bei stackoverflow, die sich ja eher um Probleme und nicht Anfänger kümmern ^^ :D

TGGC

1x Rätselkönig

Beiträge: 1 799

Beruf: Software Entwickler

  • Private Nachricht senden

7

28.08.2017, 07:09

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
current_time = 0.0
time_for_move = 0.8
movement = 33

update(delta_time) {
  if(should_move and current_time == 0) {
    position += movement
  }
  current_time += delta_time
  if(current_time >= time_for_move) {
    current_time = 0
  }
}
Reicht sicher für den Anfang, ist aber mathematisch nur korrekt wenn delta_time konstant und time_for_move ein Vielfaches davon ist. Ansonsten dauert die Bewegung länger oder wird evtl. auch mal komplett vergessen.

Genauer wäre, wenn du dir die Richtung der aktuellen Bewegung in einem Vektor ablegst, bzw. (0;0) fuer stehen bleiben und dann das hier:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
update(delta_time)
{
    current_time += delta_time;
    while (current_time >= should_move)
    {
        current_time -= should_move;
        position += movement * direction;
    }
}

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

8

28.08.2017, 07:13

Wenn die Bewegung immer nur in 33-Pixel-Schritten erfolgen soll, dann solltest du die Position intern einfach als zwei int-Werte speichern und diese zur Darstellung des Sprites mit 33 multiplizieren.

9

29.08.2017, 09:05

@David Scherfgen Mhhh habe ich das falsch verstanden oder meinst du, dass dass ich den Sprite einfach um 33 verschieben soll? :huh: ^^

Also der soll sich flüssig bewegen, aber automatisch nach 33 Pixeln stoppen und nicht erst z.B. bei 50 oder so.

@TGGC Danke, das gucke ich mir auch noch einmal in Ruhe an :)

Zitat

Wenn das soweit läuft kannst du dafür sorgen dass die Bewegung Schrittweise stattfindet, solange der Zähler nach oben gezählt wird.


Und das bekomme ich gerade nicht hin... :wacko:
Ich bin dann wieder da gelandet, wo ich am Anfang war.... xD

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

10

29.08.2017, 10:11

@David Scherfgen Mhhh habe ich das falsch verstanden oder meinst du, dass dass ich den Sprite einfach um 33 verschieben soll?

Also der soll sich flüssig bewegen, aber automatisch nach 33 Pixeln stoppen und nicht erst z.B. bei 50 oder so.

Das hat damit erst mal nichts zutun. An sich besteht dein Raster aus 33x33 Pixel Quadraten. Deine Spielfigur kann sich von Quadrat zu Quadrat bewegen und muss sich dabei auch immer für ein ganzes Quadrat bewegen anstatt zwischendurch anzuhalten. Für deine Spielwelt sind also nur die einzelnen Quadrate wichtig und die kannst du wie David schon richtig sagt einfach als int Werte abbilden. Deine Spielfigur ist jetzt entweder genau auf einer Zelle, oder bewegt sich von Zelle zu Zelle. Vereinfache dir das ganze mal. Die Figur läuft die ganze Zeit nach rechts und kann dabei nie stehen bleiben. Dabei benötigt sie eine Sekunde um sich eine Zelle weit zu bewegen. Jetzt kannst du dir die Zeit merken und die Figur nach einer Sekunde um ein Feld nach rechts schieben. Wenn du deine Figur jetzt zeichnest, dann zeichnest du sie nicht auf das Feld auf dem sie sich grad befindet sondern ein Stück davor. Das ganze nennt sich Interpolation. Wenn 0.1 Sekunden verganzen sind dann zeichnest du die Figur um 10% zwischen dem Start und dem Ziel verschoben, bei 0.5 Sekunden genau mittig zwischen Start und Ziel und bei einer Sekunde direkt auf das Ziel.
Noch mal vereinfacht, du merkst dir das letzte Feld der Figur, du merkst dir das aktuelle Feld der Figur ( das Feld auf dem sie landen soll ) und in Abhängigkeit der vergangenen Zeit schiebst du die Figur in diese Richtung.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Werbeanzeige