2015-05-27 5 views
1

У меня есть класс мяч со следующими переменными:сделать отскок мяча до остановки

int x,y,width,height; 
double velX,velY; 

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

//Gravity & movement for the ball 
ball.setVelY(ball.getVelY() + 0.2); 

ball.setY((int)(ball.getY() + ball.getVelY())); 

//Make the ball bounce. 
if(ball.getBounds().intersects(block.getBounds()){ 
    ball.setVelY(ball.getVelY() * -0.7);   
} 

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

ответ

7

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

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

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

+0

Я согласен с этой оценкой. Лучше применять силы в непрерывном режиме, а затем проверять пороговые значения (например, 0 или меньше). Таким образом, вы можете избежать периодического обновления и просто использовать его в постоянном движении до тех пор, пока другие силы/etc не повлияют на него. – Sh4d0wsPlyr

1

Проблема может быть цифровой. Что вы делаете, когда сочинительство

ball.setVelY(ball.getVelY() + 0.2); 
ball.setY(ball.getY() + ball.getVelY()); 

интегрируется дифференциальное уравнение с помощью Euler method. На самом деле, это упрощение:

ball.setVelY(ball.getVelY() + g * DeltaTime); // g = 9.8m/s² for earth gravity 
ball.setY(ball.getY() + ball.getVelY() * DeltaTime); 

где DeltaTime ваша времени интегрирования шаг, который вы принимаете равным единице, для простоты.

К сожалению, метод Эйлера только условно стабилен, что означает, что вы можете оказаться в ситуациях, когда скорость расходится (или этот тип нескончаемых колебаний). Чтобы восстановить стабильность, лучший способ - уменьшить временной шаг, что в вашем случае означает уменьшение скорости или, скорее, уменьшение силы тяжести. Попробуйте установить g от 0,2 до 0,05 и увеличить частоту вашего таймера на 4, чтобы проверить это.

Если вы участвуете в математике, вы также можете взглянуть на безусловные стабильные методы, такие как backward Euler method.

Смежные вопросы