математика — плавное замедление импульса в C ++ / SFML?

Я делаю игру «астероиды» на C ++ и SFML, и меня интересует плавное замедление и ускорение. В оригинальной игре, когда вы двигались в каком-то направлении, вы набирали «импульс», который увеличивался, пока кнопка удерживалась, и уменьшался при отпускании. Я начал свою собственную версию этого. В настоящее время у меня есть sf::Vector2f содержащий импульс корабля. Это может быть отрицательным или положительным. Проблема в том, что я не могу правильно реализовать замедление (я даже не пытался ускорить его). Я пробовал следующее;

if (plr.momentum.x < 0) {
plr.momentum.x++;
}
if (plr.momentum.x > 0) {
plr.momentum.x--;
}
if (plr.momentum.y < 0) {
plr.momentum.y++;
}
if (plr.momentum.y > 0) {
plr.momentum.y--;
}

При этом после перемещения игрок медленно перетаскивается в верхний левый угол окна (координаты 0,0). Я предполагаю, что это потому, что число с плавающей запятой, например, 0,05, соответствует выражению «больше 0» if. От этого требуется один, что делает его минус. Следующий оператор if добавляет один к нему, и это непрерывно зацикливается. отрицательный x импульс движется влево, а отрицательный y импульс движет вас вверх, и наоборот. Я хотел бы знать методологию плавного замедления и ускорения.

Если вам интересно / интересно, я использую следующий код для перемещения игрока в соответствии с его динамикой;

playerSprite.move(plr.momentum);

Если вы не знакомы с SFML, sf::Vector2f имеет .x а также .y, которые используются в .move из sf::Sprite playerSprite, .move перемещает игрока относительно его текущей позиции; так что если игрок в (5,0), и вы делаете player.move(sf::Vector2f(-1,0))их координаты будут (4,0).

РЕДАКТИРОВАТЬ:
Теперь у меня есть следующий код для замедлений в качестве предложения от друга. Замедление работает отлично, но после замедления оно снова начинает двигаться в верхний левый угол. Чем это вызвано?

if (plr.xSlowdown < 0.f) {
plr.xSlowdown += 0.1f;
}
if (plr.xSlowdown > 0.f) {
plr.xSlowdown -= 0.1f;
}
if (plr.ySlowdown < 0.f) {
plr.ySlowdown += 0.1f;
}
if (plr.ySlowdown > 0.f) {
plr.ySlowdown -= 0.1f;
}

plr.xMomentum = floor(plr.xSlowdown);
plr.yMomentum = floor(plr.ySlowdown);

2

Решение

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

Перетащите силу, основанную на скорости: самый простой способ сделать F = -K v для коэффициента сопротивления K, Итак, если импульс вашего корабля хранится в plr.xMomentum а также plr.yMomentumВаша программа будет:

// note:  "dt" is your timestep;
//   if you don't have one, just choose some small value for "fraction", like 0.005
float fraction = drag_coefficient_K * dt;
plr.xMomentum -= fraction * plr.xMomentum;
plr.yMomentum -= fraction * plr.yMomentum;

Ускорение будет зависеть от ориентации вашего космического корабля:

// note: "orientation" is the angle of your spaceship;
//   the units of orientation are determined by "angle_scale",
//   which should be chosen such that "angle_in_radians" is in radians...
float angle_in_radians = angle_scale * orientation;
float thrust_per_timestep = thrust_value * dt;
plr.xMomentum += thrust_per_timestep * cos(angle_in_radians);
plr.yMomentum += thrust_per_timestep * sin(angle_in_radians);

Комбинация сопротивления и тяги фактически устанавливает верхний предел скорости, которую вы можете достичь (по крайней мере, без помощи гравитации или чего-то еще …).

1

Другие решения

То, что вы хотите, это физика. Очень простая физика: F = ма.

Вам нужно иметь некоторое представление об ускорении, скорости и положении. Пользовательский ввод диктует ускорение. Ускорение меняет скорость, а скорость меняет положение.

В сторону: нет разницы между замедлением и ускорением. Они оба ускорение.

0

По вопросам рекламы [email protected]