En este articulo se explican levemente conceptos básicos de física para luego entender el código (en Python + Pygame) del lanzamiento de un proyectil simple (piedra, bala redonda de cañón...).
CONCEPTOS BÁSICOS
0 Conceptos básicos en python:
Esta sección da información de Python que es útil para programar lo que se explica en este documento.
X**Y = X elevado a Y. Por ejemplo: 2 ** 3 = 2*2*2
sqrt(X) = raíz cuadrada de X. Por ejemplo: sqrt(9) = 3 (ya que 3**2 = 9)
radians(A) Devuelve el ángulo A pasado de grados a radianes
degrees(A) Devuelve el ángulo A pasado de radianes a grados
La tangente, el seno, el coseno... trabaja con el ángulo en radianes.
sin(A) = seno de A
cos(A) = coseno de A
tan(A) = tangente de A
atan(A) = arcotangente de A
Para utilizar estas funciones hace falta importarlas del modulo math. Por ejemplo:
from math import sqrt, radians, cos
1 La velocidad:
Es el desplazamiento en un cierto incremento de tiempo. Por ejemplo: km/h, m/s (Sistema internacional)... Pero para programar utilizaremos las unidades de píxeles / tiempo que tarda un ciclo del bucle.
Por lo tanto, si la velocidad es 0, el cuerpo estará quieto.
2 Aceleración:
Es el incremento de velocidad en un cierto incremento de tiempo. Por ejemplo: m/s^2 (S.I.). Pero para programar utilizaremos las unidades de píxeles / tiempo que tarda un ciclo del bucle^2.
Por lo tanto, si la aceleración es 0, la velocidad se mantiene constante, pudiendo ser o no 0.
3 Vectores:
Para hacer cálculos con la velocidad, la aceleración... es conveniente utilizar los vectores que son segmentos orientados que determinan la intensidad(modulo) y la dirección. Pueden dar la información del punto de aplicación (donde empieza), aunque puede no darse este dato y considerar el punto 0 sin importar su ubicación en el plano (vector libre).
Los datos del vector se pueden dar de dos maneras: en coordenadas polares o en coordenadas cartesianas.
3.1 En coordenadas polares:
Para ello es necesario el modulo (intensidad) y el ángulo que va al contrario de las agujas del reloj empezando desde donde se situaría la aguja cuando son las 3h.

El ángulo puede darse en radianes o grados. Dependiendo del caso ara falta uno o otro. La relación que tienen es: una circunferencia tiene 360 grados o 2*pi radianes.
3.2 En coordenadas cartesianas:
Para ello es necesario dos ejes (ya que estamos en 2 dimensiones) de coordenadas. Un eje esta en posición horizontal (x) y el otro en vertical (y). El vector se descompone en la suma de dos vectores que tienen la misma dirección que los ejes de coordenadas y empiezan en un punto 0. Por ejemplo, si tenemos un “vector x” de modulo 3 unidades y un “vector y” de 2 unidades el vector se representaría:

Para dar estos datos de una forma mas simple se pueden dar dentro de un paréntesis con dos valores en el que, por convenio, el primer dato es el modulo del “vector x” y el segundo el del “vector y”. Por ejemplo, con los mismos datos de antes: V = (3, 2)
3.3 De coordenadas polares a cartesianas:
Si se representa un vector dadas las coordenadas polares y luego los ejes horizontal y vertical, utilizando rectas paralelas obtenemos un triangulo rectángulo (Con un ángulo recto (90º) ).

Una vez tenemos esto, el “lado y” es la componente “vector y” del vector. Y el “lado x”, “vector x”. Para obtener la longitud de estos lados se utiliza el seno y el coseno. En Python:
cos(a) = x / M --> x = cos(a) * M
sin(a) = y / M --> y = sin(a) * M
3.4 De coordenadas cartesianas a polares:
Una vez representada la suma de las dos componentes del vector, utilizando rectas paralelas obtenemos el triangulo rectángulo (imagen anterior).
Para obtener el ángulo se utiliza la tangente. En Python:
tan(a) = y / x --> a = atan( y / x)
Para obtener el módulo se utiliza el teorema de Pitágoras. En Python:
M**2 = x**2 + y**2 --> M = sqrt(x**2 + y**2)
4 Elegir el punto de referencia y convenio de signos:
Para hacer los calculo con los componentes de los vectores (velocidad x, gravedad...) hay que ponerles signos dependiendo del sentido que tengan. Por ejemplo: si tiramos una piedra hacia arriba, la gravedad y la “velocidad y” (inicial) están en el mismo eje (el “y”) pero tienen sentidos contrario por lo tanto uno será positivo y otro negativo.
En las pantallas, el punto 0 se toma en la esquina superior izquierda. El “eje x” es positivo hacia la derecha. El “eje y” es positivo hacia abajo. Si tomamos esto como referencia, una velocidad o aceleración hacia arriba es negativa, hacia abajo es positiva, hacia la izquierda es negativa y hacia la derecha, positiva.
6 Tiro parabólico:
Es el lanzamiento de un proyectil(por ejemplo una piedra, una pelota... ya que si fuera algo como un misil autopropulsado, la cosa se complica mas). El movimiento se puede descomponer en dos movimientos rectilíneos, uno horizontal y otro vertical (por esa razón se trabaja con las componentes del vector). Si se considera nula la fricción con el aire, el movimiento horizontal no tiene aceleración, por lo tanto es un movimiento rectilíneo uniforme. En el movimiento vertical actúa la fuerza de la gravedad que crea una aceleración constante, por lo tanto es un movimiento rectilíneo uniformemente acelerado.
En el tiro parabólico la velocidad tiene un cierto ángulo sobre la recta horizontal, si el ángulo fuese 0 se le llama tiro horizontal y si fuese de 90º se le llama tiro vertical.
CÓDIGO:
(Proyectil utilizado:

- Código: Seleccionar todo
import pygame
from pygame.locals import *
from math import sin, cos, radians
# Aceleracion que produce la fuerza de la gravedad
gravedad = 0.2
# Vector velocidad en coordenadas polares
velocidad_inicial = 12.5 # Modulo (unos 63 m/s)
angulo_inicial = 45 # Direccion
# El punto donde comienza el movimiento el proyectil
posicion_inicial = [50, 550]
def main():
pygame.init()
screen = pygame.display.set_mode ((800,600)) # Define una pantalla con resolucion de 800x600
proyectil = pygame.image.load("bolap.png").convert_alpha() # Carga la imagen
proyectil_rect = proyectil.get_rect() # Crea una superficie a partir de la imagen
proyectil_rect.center = posicion_inicial # Situa el proyectil en su posicion inicial
# Pasa de coordenadas polares a coordenadas cartesianas
velocidad_inicial_x = cos(radians(angulo_inicial)) * velocidad_inicial
velocidad_inicial_y = sin(radians(angulo_inicial)) * velocidad_inicial
# Pone signo a las velocidades dependiendo de su direccion
velocidad_x = +velocidad_inicial_x
velocidad_y = -velocidad_inicial_y
velocidad = [velocidad_x, velocidad_y] # Crea una lista con las dos componentes del vector
clock = pygame.time.Clock() # Se utiliza para limitar los fotogramas por segundos
while True:
clock.tick(10) # Limita la ejecucion a 10 fotogramas por segundo
velocidad[1] += gravedad # Incrementa la velocidad con el valor de la gravedad,
# que solo actua en la componente "y" (acelera el cuerpo)
# Incrementa la posicion del cuerpo sumandole las componentes de la velocidad
# Funciana igual utilizando un metodo o otro
#proyectil_rect.move_ip(velocidad[0], velocidad[1])
proyectil_rect.center = [proyectil_rect.center[0] + velocidad[0], proyectil_rect.center[1] + velocidad[1]]
# Descomentado imprime un fondo negro pero sin imprimirlo se puede apreciar mejor el movimiento
#screen.fill((0,0,0))
screen.blit (proyectil, proyectil_rect) # Imprime la imagen del proyectil en su posicion
pygame.display.update() # Actualiza la pantalla
if __name__ == '__main__': main() # Ejecuta la funcion
David Ramírez
Se que este articulo no es perfecto así que espero vuestras críticas para poder mejorarlo entre todos. Por ejemplo: si alguna parte no quedó clara, no les pareció bien la estructura del articulo...
Y si tienen alguna duda les invito a postearla. Yo intentaré responderles pero si no puedo, también lo leerán otras personas que a lo mejor si pueden hacerlo.
Espero que les haya resultado interesante y/o útil.
Saludos.