Застрял в создании движка 2D-игры - PullRequest
3 голосов
/ 31 мая 2011

Я делаю движок для своей 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 ​​влево, иначал давить вниз, направление движения не изменилось или почти не изменилось.

Потом я начал думать о многочисленных продуктах, различиях и других вещах с векторами, но я больше не мог следить за ним или столкнулся с раннимпроблемы.

Итак, в заключение, может ли кто-нибудь объяснить систему, которая отвечает всем вышеперечисленным пунктам, или указать на статью, в которой объясняется, как такая система может быть реализована?Не беспокойтесь о том, чтобы предлагать что-то сложное, я могу понять даже сложные концепции, если у вас есть время.

Спасибо за вашу помощь!

Ответы [ 3 ]

1 голос
/ 01 июня 2011

Извините, что не позволил вам думать об этом более одного дня, но мне удалось решить эту проблему, и это не две строки кода.(Хотя все равно спасибо всем за идеи)

Поскольку я ленив и устал, я не буду менять его на псевдокод, кроме следующих двух методов:

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 голосов
/ 31 мая 2011

Я бы посоветовал связать определенную скорость с игроком в дополнение к позиции и проверять эту скорость только по maxSpeed ​​при нажатии клавиш со стрелками.

Если скорость превышает maxSpeed, но нажимаются клавиши со стрелками с противоположной стороны, то вы сохраняете текущую скорость выше maxSpeed ​​и просто применяете отрицательное ускорение.

0 голосов
/ 31 мая 2011

Добавить внизу:

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

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

Где знак int (x) { если х <0 возврат -1; } </p>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...