Por exemplo, no método update do seu código, para fazer um delocamento em mru:
public void update() {
x = x + vx;
y = y + vy;
}
Agora, se você quer que exista gravidade. Lembre-mos que a gravidade é uma força constante, que força um mruv, ou seja a velocidade varia a cada instante de tempo t. Quer dizer, a cada chamada de nosso update.
public void update() {
vy = vy - g;
x = x + vx;
y = y + vy;
}
Não tem muito segredo. Veja o que diz o algoritmo da física a cada instante t, tente adaptar isso para o método update do seu móvel em questão.
No caso da bola quicar, existe outra força envolvida. A mesmo que deu um impulso inicial para baixo (que pode ter sido criada através do momento da bola e da gravidade). Nesse caso, essa força deve ser invertida.
Acho que não preciso dizer que vy e vx são atributos de sua classe que definem a velocidade em x e y do seu objeto móvel.
Agora… como fazer isso em java…
Bem, os algoritmos acima assumem que você tem uma taxa de updates por segundo constante, como proposto no livro Killer Programming in Java.
Se você estiver trabalhando com updates variáveis, seu método update vai ter que receber também um delta T, e você terá que ajustar o tamanho do deslocamento de acordo com esse delta, o que levaria a fórmulas ligeiramente diferentes.
Como eu disse, melhor mesmo é pegar um livro de física, entender o que acontece a cada instante de tempo e implementar. Tem que lembrar que a física do jogo também não precisa ser tão rigorosa quanto a real. Mesmo porque, se ficar rigorosa demais, pode perder a graça… já pensou se o Mario só pulasse bem baxinho?
Você pode ler o livro Killer Game Programming in Java no site do próprio autor:
http://fivedots.coe.psu.ac.th/~ad/jg/
Talvez encontre algoritmos prontos por lá.