Фон:
У меня проблема с получением правильной кривой скачка для моего проекта римейка ретро-платформера. Оригинальная игра для NES, а скорость игрока хранится в двух отдельных частях: один байт для целого числа и другой для дробной части.
Гравитация добавляется к скорости игрока Y со скоростью 0,25 за кадр.
Когда игрок прыгает, его скорость Y устанавливается на -4.64453125. Остальная часть кривой скачка оставлена гравитации.
Когда игрок поднимается, его вертикальная скорость приближается к 0 со скоростью 0,25 за кадр. Однако, когда скорость игрока достигает значения меньше нуля, скорость изменяется по другому шаблону. Вместо того, чтобы постепенно уменьшаться на 0,25 каждый кадр, он следует этой схеме:
[1.75, -0.25, -0.25, -0.25, 1.75, -0.25, -0.25, -0.25, 1.75, ...]
Похоже, что-то связано с целочисленным переполнением.
Данные:
Вот дамп данных из оригинала. Это таблица скорости.
Jump Curve
Y-Hi Y-Lo Decimal Change/Frame
4 165 4.64453125 ?
4 101 4.39453125 -0.25
4 37 4.14453125 -0.25
3 229 3.89453125 -0.25
3 165 3.64453125 -0.25
3 101 3.39453125 -0.25
3 37 3.14453125 -0.25
2 229 2.89453125 -0.25
2 165 2.64453125 -0.25
2 101 2.39453125 -0.25
2 37 2.14453125 -0.25
1 229 1.89453125 -0.25
1 165 1.64453125 -0.25
1 101 1.39453125 -0.25
1 37 1.14453125 -0.25
0 229 0.89453125 -0.25
0 165 0.64453125 -0.25
0 101 0.39453125 -0.25
0 37 0.14453125 -0.25
-1 229 -1.89453125 1.75
-1 165 -1.64453125 -0.25
-1 101 -1.39453125 -0.25
-1 37 -1.14453125 -0.25
-2 229 -2.89453125 1.75
-2 165 -2.64453125 -0.25
-2 101 -2.39453125 -0.25
-2 37 -2.14453125 -0.25
-3 229 -3.89453125 1.75
-3 165 -3.64453125 -0.25
-3 101 -3.39453125 -0.25
-3 37 -3.14453125 -0.25
-4 229 -4.89453125 1.75
-4 165 -4.64453125 -0.25
-4 101 -4.39453125 -0.25
-4 37 -4.14453125 -0.25
-5 229 -5.89453125 1.75
-5 165 -5.64453125 -0.25
-5 101 -5.39453125 -0.25
-5 37 -5.14453125 -0.25
-6 229 -6.89453125 1.75
Проблема:
В моей игре я не смог добиться этого эффекта. Когда скорость меньше нуля, она продолжает регулярно уменьшаться на 0,25, а не по схеме, описанной выше. Вместо того, чтобы хранить целые и дробные части отдельно, я храню их вместе в одной поплавке.
Как достичь этого эффекта?
источник
Ответы:
По сути, вам просто нужно вычесть 64 из
low
, чтобы вычесть 0,25, потому что 8-битное значение может иметь 256 значений, поэтому 256 * 0,25 = 64 При наличии недостаточного значенияlow
также вычитайте 1 изhigh
.Отказ от ответственности: этот код намеренно неверен, когда речь идет о отрицательных числах, предполагается, что он моделирует числовые аномалии, описанные в вопросе. Для сравнения в нижней части этого ответа можно найти реализацию правильной обработки отрицательных чисел класса с фиксированной точкой.
РЕДАКТИРОВАТЬ : я также добавил преобразование в float и из float и вывод
Сгенерированный вывод такой же, как в вашей таблице:
В отличие от этого, класс с фиксированной точкой правильно обрабатывает отрицательные числа:
источник