Как управлять «скоростью» в простой гоночной игре? - PullRequest
1 голос
/ 19 октября 2010

Я пытаюсь разработать простую гоночную 2D-игру (смотрите сверху вниз) на C #, sdl.net. Теперь я пытаюсь управлять скоростью, ускорением и тормозами моей машины. Моя проблема в алгоритме. У меня есть цикл (Events_Tick) выполняется 50 раз в секунду, где позиция моей машины обрабатывается следующим образом:

private void Events_Tick(object sender, TickEventArgs e)
{
    car.ProcessPosition();
}

и ProcessPosition это что-то вроде:

if (throttle)
{
    speed += 1;
    x += 1;                        
}

и, наконец, я рисую свой спрайт на новом X.

Проблема в том, что это слишком быстро!

Поэтому я спрашиваю вас, как поддерживать 50 кадров в секунду (кадров в секунду) и перемещать мой спрайт (автомобиль) только на N пикселей в секунду (в зависимости от его скорости).

Заранее спасибо! Привет!

Ответы [ 5 ]

4 голосов
/ 19 октября 2010

Прежде всего, поскольку у вас есть 2d, а не 1d игра, вам нужно, чтобы ваша скорость составляла

class Vector
{
     double x;
     double y;
}

в этом классе, вам следует поддерживать положение и скорость.

Так какВы 2d сверху вниз, вам нужно будет реализовать некоторые .RotateLeft() и .RotateRight() для вектора скорости.

Вращение будет реализовано следующим образом:

x' = cos(a) * x - sin(a) * y
y' = sin(a) * x + cos(a) * y

И вы 'Вам придется реализовать ваш метод .Move() следующим образом:

void Move(Vector v)
{
    x+=v.x;
    y+=v.y;
}

РЕДАКТИРОВАТЬ: пожалуйста, спросите, требуется ли разъяснение, или более подробное обсуждение.

Также вы можете использоватьтаймер здесь, но попробуйте рассчитать время, потраченное с момента последнего события таймера, а затем умножить скорость на это значение при добавлении к текущей позиции, таким образом вы получите более точную позицию.

a в sin() и cos() будет углом в радианах, и вам, вероятно, здесь понадобятся градусы.

Вот что-то , чтобы вы могли ориентироваться в градусах и радианах.

2 голосов
/ 19 октября 2010

Используйте двойное значение для скорости и x, затем вы можете использовать Math.Round (x) для рисования.

  if (throttle == true) {
        speed+=0.05;                    
  }
  x+=speed; //move car even without acceleration

Следуйте советам Хенка, чтобы сделать вашу программу более гибкой и иметь возможность показыватьпользователь что-то вроде 50 миль в час вместо 0,05 пикселей за 0,02 с:

double speedInMph = 50;
double screenSizeInMiles = .1;
double screenSizeInPx = 500;

if(throttle)
{
    speedInMph += 1;
}
double speedInMpms = 50/(60*60*1000);//Miles per millisecond
double xInMiles = speedInMpms * 50;
double pxPerMile = screenSizeInPx/screenSizeInMiles;
x+= xInMiles * pxPerMile;
1 голос
/ 19 октября 2010

Вы должны добавить скорость в соответствии с текущим ускорением и обрабатывать только ускорение с помощью элементов управления, ограничивая скорость с помощью ограничения и увеличивая ее в соответствии с временем, прошедшим между двумя итерациями игрового цикла.

float accel = 10.0f; // units per squared second
float maxSpeed = 50.0f // units per second
float curSpeed = 0.0f;

//game init

while (1) {
  long timeBefore = time();
  // game loop
  long timeElapsed = time() - timeBefore;

  if (throttle) {
    curSpeed += accel*(timeElapsed / 1000.0);
    if (curSpeed > maxSpeed)
      curSpeed = maxSpeed;
  }
}

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

Эта модель подразумевает постоянное ускорение, в то время как вы можете гипотетически хотеть динамическое, в этом случае вы просто перемещаете обновление в ускорение (с учетом длительности кадра по скорости) и ограничиваете его, чтобы не превышать фиксированный порог .

1 голос
/ 19 октября 2010

Ускорение будет постоянным, в зависимости от пользовательского ввода (на простом уровне автомобиль ускоряется, замедляется или поддерживает скорость).

Скорость будет меняться в каждом кадре в зависимости от этого ускорения.В каждом кадре обновляйте скорость автомобиля на основе ускорения и доли секунды, которую охватывает кадр (т. Е. 1/50-ую секунды в вашем случае).

Итак, если ваша машина ускоряется на 10 единицрасстояние в секунду, в вашем примере скорость будет увеличиваться на 1/5 от единицы расстояния на кадр.

Просто подумал, что стоит немного поработать над другими ответами, вместо того, чтобы просто публиковать больше кода :-)

0 голосов
/ 19 октября 2010

Хенк прав.Вы захотите создать

Thread

и вызывать его метод

Sleep(Int32)

каждый раз в цикле, чтобы замедлить анимацию, где параметр int - это время паузы в миллисекундах.

В вашем случае вы захотите перемещать автомобиль на N / 50 пикселей каждый раз, когда зацикливаетесь, и каждый раз спите в течение 20 миллисекунд.

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