/ / Preso em fazer o mecanismo de movimento de jogo 2D - 2d

Preso em fazer o motor de movimento de jogo 2D - 2d

Eu estou fazendo um motor de movimento para o meu jogo 2D top-down, mas eu fiquei preso tentando resolver o seguinte problema:

  • O jogador pode se mover usando as teclas de seta, que aceleram nas respectivas direções. Há fricção, então você para de se mover depois de soltar as teclas, embora não instantaneamente.
  • Quando você segura duas teclas perpendiculares, você acelera nesta direção de 45 ° a mesma velocidade que faria em um eixo
  • Existe uma velocidade máxima que acima de você não pode acelerar caminhandoIsso também limita sua velocidade máxima de caminhada, obviamente. Você pode ser eliminado e, portanto, exceder essa velocidade.
  • Se você se mover mais rápido que o max. velocidade de caminhada, você pode desacelerar mais rápido se você mantiver as teclas na direção oposta (s)

Pseudocódigo para o primeiro ponto, sem atrito:

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

Eu posso resolver o atrito (obtendo o comprimento deo vetor de movimento, reduzindo-o pela fricção, projetando-o de volta com a mesma relação x: y), no entanto, eu não consigo me acostumar a fazer o maxSpeed ​​pronto.

Eu tentei uma solução de não permitir que o jogadorandar em tudo quando acima maxSpeed, mas isso viola o ponto 4. Além disso, teve o efeito colateral desagradável, que quando você se moveu no MaxSpeed ​​para a esquerda, e começou a pressionar para baixo, a direção do movimento não mudou, ou mal mudou.

Então eu comecei a pensar em vários produtos, diferenças e outras coisas com os vetores, mas eu praticamente não conseguia mais seguir ou me deparo com problemas iniciais.

Então, em conclusão, alguém poderia explicar um sistemaque cumpre todos os pontos acima, ou aponta para um artigo que explica como um sistema como este poderia ser implementado? Não se preocupe em sugerir algo complexo, eu posso compreender conceitos difíceis mesmo com algum tempo.

Obrigado pela ajuda!

Respostas:

1 para resposta № 1

Desculpe por não deixar você pensar sobre isso por mais de um dia, mas eu consegui resolvê-lo, e não há duas linhas de código. (Ainda assim, obrigado por todos pelas idéias)

Porque eu sou preguiçoso e cansado, eu não vou mudar isso para pseudocódigo, exceto os dois métodos a seguir:

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

E o código (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;
}

Poderia ser mais curto, poderia ser um pouco mais otimizado, mas funciona. Espero que isso ajude qualquer um que se deparar com esse problema no futuro.


0 para resposta № 2

Adicione ao fundo:

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

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

Onde sinal int (x) { se x <0 return -1; }


0 para resposta № 3

Eu sugeri associar uma velocidade específica com o jogador, além da posição, e apenas verificar essa velocidade contra o maxSpeed ​​quando as teclas de seta são pressionadas.

Se a velocidade exceder maxSpeed, mas as teclas de seta do lado oposto estiverem sendo pressionadas, você manterá a velocidade atual acima de maxSpeed ​​e simplesmente aplicará a aceleração negativa.