Проблемы с приращением C ++ - PullRequest
       4

Проблемы с приращением C ++

2 голосов
/ 19 сентября 2011

Допустим, у меня есть метод, который управляет движением некоторых персонажей, например:

void Player::moveRight( Uint32 ticks ) 
{ 
    if( speedx < maxspeed ) { speedx += accel; }
    x += speedx * ( ticks / 1000.f );
    //collision
    if( x > (float)( 800 - width ) ) { x = (float)( 800 - width ); }
}

maxspeed = 300 и accel = 2 (также speedx начинается с 0)

Теперь в этом нет ничего плохого, пока я не добавлю в уравнение постоянное замедление / трение. По сути, у меня постоянное замедление 1, которое вычитается из скорости каждого кадра. Это так, если персонаж не движется, он постепенно останавливается.

Проблема заключается в следующем: если speedx = 299 из-за замедления, оператор my if остается верным, и он продолжает прибавлять accel, что повышает скорость до 301, после максимальной скорости.

Какими были бы хорошие решения этой проблемы, которые позволили бы мне иметь любые значения ускорения и замедления, а не приводить в порядок оператор if?

Ответы [ 5 ]

5 голосов
/ 19 сентября 2011

Чтобы перевернуть и закрепить ответ квазеленого, вы можете использовать:

speedx = min(maxspeed, speedx + accel);

Это добавит или ограничит в зависимости от обстоятельств, с очень тривиальным кодом.

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

2 голосов
/ 19 сентября 2011

Измените его на:

if (speedx + accel > maxspeed) { speed = maxspeed; }
else speed += accel;

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

Или вы можете сделать:

speedx = min(speedx + accel, maxspeed);
1 голос
/ 19 сентября 2011

Вариант 1. Обрезать speedx до maxspeed. Код компактный.

speedx += accel;
if (speedx > maxspeed) { speedx = maxspeed; }

Вариант 2: защита от ложного добавления, когда оно вам не нужно.

if (speedx < maxspeed) {
  speedx += accel;
  if (speedx > maxspeed) { speedx = maxspeed; }
}

Первый будет тратить впустую дополнение, когда вы находитесь на maxspeed. Последний тратит впустую сравнение, когда вы ниже maxspeed-accel. Что лучше, зависит от того, какой сценарий более вероятен.

1 голос
/ 19 сентября 2011

Самое простое исправление, вероятно, состоит в том, чтобы обрезать скорость после ее настройки:

void Player::moveRight( Uint32 ticks ) 
{ 
    speedx += accel;
    if( speedx >= maxspeed ) { speedx = maxspeed }
    x += speedx * ( ticks / 1000.f );
    //collision
    if( x > (float)( 800 - width ) ) { x = (float)( 800 - width ); }
}
0 голосов
/ 19 сентября 2011

Простое зажатие спидкса, похоже, будет работать нормально:

if ( speedx < maxspeed ) { speedx = min(speedx+accel,maxspeed); }
...