/ / Stuck bei der 2D-Spiel Bewegung Motor - 2D

Stuck bei der 2D-Spiel Bewegung Motor - 2D

Ich mache eine Bewegungsmaschine für mein Top-Down-2D-Spiel, aber ich blieb stecken und versuchte, das folgende Problem zu lösen:

  • Der Spieler kann sich mit den Pfeiltasten bewegen, die Sie in die entsprechenden Richtungen beschleunigen. Es gibt Reibung, also hörst du auf, dich zu bewegen, nachdem du die Schlüssel losgelassen hast, aber nicht sofort.
  • Wenn Sie zwei senkrechte Tasten halten, beschleunigen Sie in dieser 45 ° -Richtung die gleiche Geschwindigkeit wie auf einer Achse
  • Es gibt eine Höchstgeschwindigkeit, die über Ihnen nicht beschleunigen kann zu FußDies begrenzt natürlich auch Ihre maximale Gehgeschwindigkeit. Sie können jedoch davonkommen und so diese Geschwindigkeit überschreiten.
  • Wenn Sie schneller als max. Schrittgeschwindigkeit, Sie können schneller langsamer werden, wenn Sie die Tasten in die entgegengesetzte Richtung halten

Pseudocode für den ersten Punkt, ohne Reibung:

gameTick(){

tempX += LeftKeyHeld ? -1 : 0;
tempX += RightKeyHeld ? 1 : 0;
tempY += UpKeyHeld ? -1 : 0;
tempY += DownKeyHeld ? 1 : 0;
ratio = 0.71;

if( |tempX| == |tempY| ) {
tempX =tempX* ratio;
tempY =tempY* ratio;
}
player.x += tempX;
player.y += tempY;
}

Ich kann die Reibung lösen (bekommen die Länge vonder Bewegungsvektor reduziert ihn durch die Reibung, projiziert ihn mit dem gleichen x: y-Verhältnis zurück), aber ich kann meinen Kopf nicht umdrehen, um die maxSpeed-Funktion auszuführen.

Ich habe versucht, dem Spieler das nicht zu erlaubengehen Sie überhaupt über MaxSpeed, aber dies verletzt Punkt 4. Außerdem hatte es die unangenehme Nebenwirkung, dass, wenn Sie mit MaxSpeed ​​nach links bewegt und zu drücken, die Bewegungsrichtung nicht oder kaum geändert wurde.

Dann begann ich über zahlreiche Produkte, Unterschiede und andere Dinge mit den Vektoren nachzudenken, aber ich konnte es meistens nicht mehr nachvollziehen oder stieß auf frühe Probleme.

Abschließend könnte jemand ein System erklärenwas erfüllt alle oben genannten Punkte oder verweist auf einen Artikel, der erklärt, wie ein solches System implementiert werden könnte? Machen Sie sich keine Sorgen, wenn Sie etwas Kompliziertes vorschlagen, ich kann selbst schwierige Konzepte für eine gewisse Zeit erfassen.

Danke für Ihre Hilfe!

Antworten:

1 für die Antwort № 1

Tut mir leid, dass ich dich nicht länger als einen Tag darüber nachdenken ließ, aber es gelang mir, es zu lösen, und es gab zwei Zeilen Code. (Trotzdem danke für die Ideen)

Weil ich faul und müde bin, ändere ich es nicht in Pseudocode, außer die folgenden zwei Methoden:

updateGame(){
player.walk();
player.move();
}
player.move(){
player.x += player.speedX
player.y += player.speedY
}

Und der Code (Java):

public void walk() {
float tempX = 0;
float tempY = 0;
float accelX;
float accelY;
float nextSpeedX;
float nextSpeedY;
float nextSpeed;
float speed;
tempX += walkLeft ? -1 : 0;
tempX += walkRight ? 1 : 0;
tempY += walkUp ? -1 : 0;
tempY += walkDown ? 1 : 0;

if (Math.abs(tempX) == Math.abs(tempY)) {
tempX = (float) tempX * rat;
tempY = (float) tempY * rat;
}

accelX = tempX * (float) runSpeed;
accelY = tempY * (float) runSpeed;
speed = (float) Math.sqrt(speedX * speedX + speedY * speedY);
nextSpeedX = speedX + accelX;
nextSpeedY = speedY + accelY;
nextSpeed = (float) Math.sqrt(nextSpeedX * nextSpeedX + nextSpeedY * nextSpeedY);

if (nextSpeed > maxSpeed) { //can"t accelerate by running
if (nextSpeed > speed) {  //wants to accelerate
if (speed > maxSpeed) {  //the current speed is larger than maximum.
float diff = (float)(speed / nextSpeed);
float greenX = nextSpeedX*diff;
float greenY = nextSpeedY*diff;
accelX = greenX-speedX;
accelY = greenY-speedY;
} else { //speed <= maxspeed
float diff = (float)(maxSpeed / nextSpeed);
float greenX = nextSpeedX*diff;
float greenY = nextSpeedY*diff;
accelX = greenX-speedX;
accelY = greenY-speedY;
}
} else { //wants to slow! allow it!
//acceleration doesn"t need to be changed
}
} else { //no problem, allow it!
//acceleration doesn"t need to be changed
}
speedX += accelX;
speedY += accelY;
}

Könnte kürzer sein, könnte ein bisschen mehr optimiert sein, aber es funktioniert. Ich hoffe, dass dies jedem helfen wird, der in Zukunft auf dieses Problem stößt.


0 für die Antwort № 2

Zum Ende hinzufügen:

 If (|tempX|>maxSpeed)
tempX=maxSpeed*sign(tempX);

If (|tempY|>maxSpeed)
tempY=maxSpeed*sign(tempX);

Woher int Zeichen (x) { wenn x <0 ist Rückgabe -1; }


0 für die Antwort № 3

Ich würde vorschlagen, eine bestimmte Geschwindigkeit dem Spieler zusätzlich zur Position zuzuordnen und diese Geschwindigkeit nur gegen maxSpeed ​​zu prüfen, wenn die Pfeiltasten gedrückt werden.

Wenn die Geschwindigkeit die maxSpeed ​​überschreitet, aber die Pfeiltasten von der gegenüberliegenden Seite gedrückt werden, dann behalten Sie die aktuelle Geschwindigkeit oberhalb von maxSpeed ​​und wenden einfach die negative Beschleunigung an.