/ / Coincé à créer un moteur de mouvement de jeu en 2D - 2d

Coincé à créer un moteur de mouvement de jeu en 2D - 2d

Je fais un moteur de mouvement pour mon jeu en 2D, mais je suis resté bloqué en essayant de résoudre le problème suivant:

  • Le joueur peut bouger en utilisant les touches fléchées, ce qui vous accélère dans les directions respectives. Il y a des frictions, donc vous arrêtez de bouger après avoir relâché les touches, mais pas instantanément.
  • Lorsque vous tenez deux touches perpendiculaires, vous accélérez dans cette direction de 45 ° à la même vitesse que sur un axe
  • Il y a une vitesse maximale que vous ne pouvez pas accélérer au-dessus en marchant, cela limite aussi votre vitesse de marche maximale, évidemment. Vous pouvez vous faire renverser et donc dépasser cette vitesse.
  • Si vous vous déplacez plus vite que max. vitesse de marche, vous pouvez ralentir plus rapidement si vous maintenez les touches dans la direction opposée

Pseudocode pour le premier point, sans frottement:

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

Je peux résoudre le frottement (obtenir la longueur dele vecteur de mouvement, en le réduisant par le frottement, le projetant avec le même rapport x: y), cependant, je ne peux pas m'empêcher de faire le maxSpeed.

J'ai essayé une solution de ne pas permettre au joueur demarcher quand au dessus de maxSpeed, mais cela viole le point 4. En outre, cela a eu un effet secondaire désagréable, lorsque vous vous êtes déplacé de MaxSpeed ​​vers la gauche et que vous avez commencé à appuyer, la direction du mouvement n'a pas changé.

Ensuite, j'ai commencé à penser à de nombreux produits, différences et autres choses avec les vecteurs, mais je ne pouvais surtout pas le suivre ou rencontrer des problèmes au début.

Donc, en conclusion, quelqu'un pourrait-il expliquer un systèmequi remplit tous les points ci-dessus, ou pointez sur un article qui explique comment un tel système pourrait être mis en œuvre? Ne vous souciez pas de suggérer quelque chose de complexe, je peux même saisir des concepts difficiles avec du temps.

Merci de votre aide!

Réponses:

1 pour la réponse № 1

Désolé de ne pas vous avoir laissé penser à cela pendant plus d’une journée, mais j’ai réussi à le résoudre, et c’est en deux lignes de code.

Parce que je suis "paresseux et fatigué, je ne devrais pas" changer en pseudo-code, sauf les deux méthodes suivantes:

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

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

Pourrait être plus court, pourrait être un peu plus optimisé, mais cela fonctionne. J'espère que cela aidera quiconque trébuche sur ce problème à l'avenir.


0 pour la réponse № 2

Ajouter au bas:

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

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

Où signe int (x) { si x <0 renvoyer -1; }


0 pour la réponse № 3

Je suggérerais d'associer une vitesse spécifique au lecteur en plus de la position, et de ne vérifier que cette vitesse contre maxSpeed ​​lorsque les touches fléchées sont enfoncées.

Si la vélocité dépasse la vitesse maximale, mais que les touches fléchées du côté opposé sont enfoncées, vous pouvez conserver la vitesse actuelle au-dessus de maxSpeed ​​et appliquer simplement l'accélération négative.