Hasta ahora, cuando intenté programar eso, ponía que cada cierto tiempo los objetos se movían y luego se chequeaba si había colisión:
Sumar 1 a la PosiciónXdeObjeto1
Sumar 1 a la PosiciónXdeObjeto2
¿Hay colisión?El método más sencillo para ver si hay colisión es pedir al programa que mire si los objetos se están tocando. No es la forma ideal, y no recuerdo otro modo de hacerlo.
A altas velocidades, y más aún si los objetos van en direcciones opuestas, una colisión que debería ocurrir podría no detectarse:
AnchoYalturaDeObjeto1 = 1
AnchoYalturaDeObjeto2 = 2
PosiciónXDeObjeto1 = 20
PosiciónXDeObjeto2 = 25
Sumar 10 a la PosiciónXdeObjeto1, queda en 30
Restar 10 a la PosiciónXdeObjeto2, queda en 15
¿Hay colisión?
No.Incluso si se chequea luego de cada movimiento, en ese caso no se detectaría.
El método para detectarla se puede hacer más complejo, no sé bien cómo, creo que tenía relación con ver si 2 funciones tenían un punto en común. Tal vez sea lo más eficiente. Se tienen 2 segmentos de recta, en mi caso ambos horizontales, con cierta posición, y se ve si se están tocando. El planteo es algo así:
AnchoYalturaDeObjeto1 = 1
AnchoYalturaDeObjeto2 = 2
PosiciónXDeObjeto1 = 20
PosiciónXDeObjeto2 = 25
InicioDeSegDeRecta1 = 20
LargoDeSegDeRecta1 = VelocidadXdeObjeto1+AnchoYalturaDeObjeto1/2
InicioDeSegDeRecta2 = 25
LargoDeSegDeRecta2 = VelocidadXdeObjeto2+AnchoYalturaDeObjeto2/2El inicio de la 1 está en su punto más izquierdo, el inicio de 2 en su derecho. Quizá pueda mejorarse.
La posiciónX de los objetos se basa en su centro, por eso al tamaño de los segm. de rectas le agrego la mitad del ancho de los objetos. O se podría poner que los inicios consideren eso.
Luego no sé cómo se sigue. ¿Cómo saber si 2 segmentos de recta colisionan? Además, tal vez deba necesitar saber dónde.
Por otro lado, he pensado que quisiera que el programa intente simular varios movimientos antes de actualizar la pantalla, es decir, en vez de mover los objetos 10 pixeles 1 vez antes de actualizar la pantalla, que los mueva 0.5 píxeles 20 veces antes de actualizar la pantalla. Y en esas 20 veces que vea si hay colisión. Probablemente sea poco eficiente, pero detecta todas las colisiones y bastante bien el lugar donde ocurren ¿no?
¿Conviene que la cantidad de movimiento sea la mitad del ancho de los objeto más corto? ¿o su ancho propio sirve? Creo que no lo último, en el caso de que estuvieran justo a esa distancia y si tuvieran el mismo ancho. No estaban colisionando y luego sería como si hubieran intercambiado posiciones. Ok.
¿Y el resto cómo se hace? Creo que debo poner que se repita algo cierta cantidad de veces. En el ejemplo que puse se movían 10 píxeles en cada momento, y yo quería que se movieran 0.5 así que a 10 lo dividí entre 0.5, que da 20, entonces sería algo como:
Movimientos = VelocidadDelObjetoFaster/(AnchoDelObjetoSmaller/2)
Repetir:
Movimientos--
Objeto = 0
Repetir:
Objeto++
"PosiciónDelObjeto"+Objeto = SuPosición + SuVelocidad/(AnchoDelObjetoSmaller/2)
mienteas Objeto < Objetos
mientras Movimientos > 1¿Está bien?
Luego, si Movimientos es 1 vuelvo a mover los objetos 1 vez. Sino... tengo que moverlos pero menos. O sea, si en vez de que falte 1 movimiento falta 0.2, por ejemplo, en vez de mover el 100% tengo que mover el 20%, o sea:
"PosiciónDelObjeto"+Objeto = SuPosición + SuVelocidad/(AnchoDelObjetoSmaller/2)*Movimiento
¿Correcto?
¿Y si quisiera que la velocidad disminuya por rozamiento? La forma sencilla, creo, es antes de sumarle la velocidad, a ella restarle algo, por ejemplo:
Velocidad-0.001
¿Pero lo que debo restar depende de cuánta sea la velocidad?
Los objetos en cuestión serían barriles en una superficie horizontal. No me interesa tanto realismo en eso, que si no son exactamente cilíndricos o que si el suelo tiene piedritas. Digamos que son cilíndricos y el suelo es, como dije, horizontal, no hay mucho miniobstáculo.
Si resto algo acorde a la velocidad, podría ser que nunca se detenga, siempre disminuiría un porcentaje menor a 100%, pero lo que disminuye debería ser acorde a cuánto recorre ¿no? ¿cómo es la fórmula entonces?