/ / Utknąłem w tworzeniu silnika ruchu gry 2D - 2d

Utknął w tworzeniu silnika ruchu gry 2D - 2d

Robię silnik ruchu dla mojej odgórnej gry 2D, ale utknąłem próbując rozwiązać następujący problem:

  • Gracz może poruszać się za pomocą klawiszy strzałek, które przyspieszają Cię w odpowiednich kierunkach. Jest tarcie, więc przestajesz się ruszać po zwolnieniu klawiszy, ale nie od razu.
  • Kiedy trzymasz dwa prostopadłe klawisze, przyspieszasz w tym 45 ° kierunku z taką samą prędkością, jak na jednej osi
  • Istnieje maksymalna prędkość, powyżej której nie można przyspieszyć pieszoOgranicza to także oczywiście maksymalną prędkość chodzenia. Możesz zostać spłukany, a tym samym przekroczyć tę prędkość.
  • Jeśli poruszasz się szybciej niż max. prędkość poruszania się, możesz zwolnić szybciej, jeśli przytrzymasz klawisze w przeciwnym kierunku (s)

Pseudokod dla pierwszego punktu, bez tarcia:

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;
}

Mogę rozwiązać tarcie (uzyskanie długościwektor ruchu, zmniejszając go przez tarcie, wyświetlając go z powrotem z tym samym współczynnikiem x: y), jednak nie mogę objąć głowy, aby uzyskać maxSpeed ​​zrobione.

Próbowałem rozwiązania nie pozwalając graczowichodzić w ogóle, gdy powyżej maxSpeed, ale to narusza punkt 4. Ponadto miał paskudny efekt uboczny, że kiedy przesunąłeś się na MaxSpeed ​​w lewo i zaczął naciskać w dół, kierunek ruchu nie był lub prawie się nie zmienił.

Potem zacząłem myśleć o wielu produktach, różnicach i innych rzeczach z wektorami, ale w większości nie mogłem już tego dłużej przestrzegać lub wpadłem na wczesne problemy.

Podsumowując, czy ktoś mógłby wyjaśnić system?który spełnia wszystkie powyższe punkty, lub wskazuje artykuł, który wyjaśnia, w jaki sposób można wprowadzić taki system? Nie przejmuj się sugerowaniem czegoś skomplikowanego, potrafię uchwycić nawet trudne koncepcje podane w pewnym momencie.

Dzięki za pomoc!

Odpowiedzi:

1 dla odpowiedzi № 1

Przepraszam, że nie pozwoliłem ci myśleć o tym dłużej niż jeden dzień, ale udało mi się go rozwiązać, a to nie dwa wiersze kodu. (Choć wciąż dziękuję za wszystkie pomysły)

Ponieważ jestem leniwy i zmęczony, nie mogę zmienić go na pseudokod, z wyjątkiem dwóch następujących metod:

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

I kod (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;
}

Może być krótszy, może być nieco bardziej zoptymalizowany, ale działa. Mam nadzieję, że pomoże to każdemu, kto natknie się na ten problem w przyszłości.


0 dla odpowiedzi nr 2

Dodaj do dołu:

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

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

Gdzie znak int (x) { jeśli x <0 return -1; }


0 dla odpowiedzi № 3

Sugerowałbym powiązanie określonej prędkości z odtwarzaczem oprócz pozycji i sprawdzanie tej prędkości tylko przy maxSpeed ​​po naciśnięciu klawiszy strzałek.

Jeśli prędkość WYKRACZA przekraczać maxSpeed, ale klawisze strzałek od przeciwnej strony są wciśnięte, wtedy utrzymasz bieżącą prędkość powyżej maxSpeed ​​i po prostu zastosujesz ujemne przyspieszenie.