/ / Застряг у створенні 2D двигуна руху гри - 2d

Застряг у створенні 2D двигуна руху - 2d

Я роблю двигун для моєї зверху вниз 2D-ігри, але я застряг, намагаючись вирішити таку проблему:

  • Гравець може рухатися за допомогою клавіш зі стрілками, що прискорює вас у відповідних напрямках. Існує тертя, тому ви перестаєте рухатися після звільнення ключів, хоча і не миттєво.
  • Коли ви тримаєте два перпендикулярні клавіші, ви прискорюєтеся в цьому напрямку 45 ° на тій же швидкості, що й на одній осі
  • Існує максимальна швидкість, яка вище вас не може прискорити гуляючи, це також обмежує максимальну швидкість руху, очевидно. Ти можеш збитись і, отже, перевищити цю швидкість.
  • Якщо ви рухаєтесь швидше, ніж макс. walkspeed, ви можете сповільнити швидше, якщо ви тримаєте ключі в протилежному напрямку

Псевдокод для першої точки, без тертя:

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

Я можу вирішити тертя (отримати довжинувектор руху, зменшуючи його за рахунок тертя, проектуючи його назад з тією ж х: у відносини), проте, я можу "т обернути мою голову навколо отримання 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) { якщо x <0 повернути -1; }


0 для відповіді № 3

Я пропоную пов'язати певну швидкість з гравцем, крім позиції, і лише перевіряти цю швидкість проти maxSpeed ​​при натисканні клавіш зі стрілками.

Якщо швидкість НЕ перевищує максимальну швидкість, але клавіші зі стрілками з протилежної сторони натискаються, то ви повинні зберегти поточну швидкість вище maxSpeed ​​і просто застосувати негативне прискорення.