/ / Stuck при създаването на 2D двигател за движение - 2d

Забит в създаването на 2D двигател за движение на игра - 2d

Аз правя движещ двигател за моята 2D игра отгоре-надолу, но се забих, опитвайки се да решим следния проблем:

  • Играчът може да се движи с помощта на клавишите със стрелки, които ви ускоряват в съответните посоки. Има триене, така че да спрете да се движите, след като ги освободите, макар и не незабавно.
  • Когато задържите два перпендикулярни клавиша, ускорявате в тази посока на 45 ° със същата скорост, каквато бихте направили на една ос
  • Има максимална скорост, която над вас не може да се ускори с ходене, това също очевидно ограничава максималната ви скорост на ходене. Може да се отървеш и по този начин да надвишиш тази скорост.
  • Ако се движите по-бързо от макс. може да забавите скоростта, ако държите клавиши в обратната (ите) посока (и)

Псевдокод за първата точка, без триене:

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

Мога да разреша триенето (получаване на дължината надвижението на вектора, което го намалява от триенето, прожектира го обратно със същото съотношение x: y), обаче, не мога да обгърна главата си около получаване на maxSpeed ​​направено.

Опитах се да не разреша на играча да решикогато се движите над MaxSpeed, но това нарушава точка 4. Също така имаше и неприятния страничен ефект, че когато се преместихте в MaxSpeed ​​вляво и започнахте да натискате надолу, посоката на движение не се промени или едва се промени.

Тогава започнах да мисля за многобройни продукти, различия и други неща с векторите, но най-вече не можах да го последвам или да се сблъсках с ранни проблеми.

Така че, в заключение, някой може да обясни системакойто отговаря на всички точки по-горе или посочва статия, която обяснява как може да се приложи такава система? Не се безпокойте да предполагате нещо сложно, мога да разбера дори трудни понятия, дадени известно време.

Благодаря за вашата помощ!

Отговори:

1 за отговор № 1

Съжалявам, че не ви оставях да мислите за това повече от един ден, но успях да го разреша и няма два реда код (Въпреки че все още благодаря на всички за идеите)

Тъй като съм мързелива и уморена, няма да я променя на псевдокод, освен следните два метода:

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

И кодът (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;
}

Може да бъде по-кратък, може да бъде малко по-оптимизиран, но работи. Надявам се, че това ще помогне на всеки, който се сблъсква с този проблем в бъдеще.


0 за отговор № 2

Добави в дъното:

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

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

Където знак int (x) { ако х <0 връщане -1; }


0 за отговор № 3

Предлагам да се свърже определена скорост с плейъра в допълнение към позицията и само да се провери тази скорост срещу maxSpeed, когато се натиснат клавишите със стрелки.

Ако скоростта надвишава maxSpeed, но се натискат клавишите със стрелки от другата страна, тогава запазвате скоростта над maxSpeed ​​и просто прилагате отрицателното ускорение.