Estoy haciendo un juego en el que las bolas rebotan alrededor del dentro de de un círculo mucho más grande. El círculo más grande no se mueve.Python y Pygame: colisión de bolas con el interior del círculo
Aquí está el código que estoy utilizando actualmente para estas colisiones:
def collideCircle(circle, ball):
"""Check for collision between a ball and a circle"""
dx = circle.x - ball.x
dy = circle.y - ball.y
distance = math.hypot(dx, dy)
if distance >= circle.size + ball.size:
# We don't need to change anything about the circle, just the ball
tangent = math.atan2(dy, dx)
ball.angle = 2 * tangent - ball.angle
ball.speed *= elasticity + 0.251
angle = 0.5 * math.pi + tangent
ball.x -= math.sin(angle)
ball.y += math.cos(angle)
Se basa en el maravilloso tutorial por Peter Collingridge over here.
Los objetos de círculo y bola son ambas clases, con (x, y), radio, ángulo y velocidad.
Estoy teniendo dos problemas con este método, sin embargo:
- el balón salta de (lo que sospecho) es su "punto de anclaje", que parece estar en la esquina superior derecha del círculo.
- Al colisionar con el 5% inferior del círculo, no rebota lo suficiente y, por lo tanto, se "hunde" fuera de la pantalla. Supongo que esto se debe a que el rebote no es lo suficientemente alto como para mover la pelota sobre su "punto de anclaje" (incorrectamente colocado).
Después de haber analizado las posibles soluciones, "Detección rápida de colisiones de círculo" [Enlace eliminado debido al límite de correo no deseado], que aunque en Java utiliza el mismo método, todas se relacionan con colisiones externas, mientras que miro rebotar una pelota en el interior de un círculo.
Aquí es también las definiciones de clase de la bola() y el círculo():
class Ball():
def __init__(self, (x,y), size):
"""Setting up the new instance"""
self.x = x
self.y = y
self.size = size
self.colour = (0,128,255)
self.thickness = 0
self.speed = 0.01
self.angle = math.pi/2
def display(self):
"""Draw the ball"""
pygame.draw.circle(screen, self.colour, (int(self.x), int(self.y)), self.size, self.thickness)
def move(self):
"""Move the ball according to angle and speed"""
self.x += math.sin(self.angle) * self.speed
self.y -= math.cos(self.angle) * self.speed
(self.angle, self.speed) = addVectors((self.angle, self.speed), gravity)
self.speed *= drag
class Circle():
def __init__(self, (x,y), size):
"""Set up the new instance of the Circle class"""
self.x = x
self.y = y
self.size = size
self.colour = (236, 236, 236)
self.thickness = 0
self.angle = 0 # Needed for collision...
self.speed = 0 # detection against balls
def display(self):
"""Draw the circle"""
pygame.draw.circle(screen, self.colour, (int(self.x), int(self.y)), self.size, self.thickness
Gracias de antemano, Nathan
¿El eje X no estaría definido por el coseno del ángulo y el eje Y por el seno? ¿O aprendí mal? : X – JCM
Creo que tienes razón en que esa es la manera estándar de definir las cosas, pero mientras seas consecuente en realidad no hace ninguna diferencia. Claramente, si gira todo 90 grados, eso no debería afectar la forma en que las cosas rebotan (suponiendo que la gravedad también cambie). –
@PeterCollingridge, ¡sus artículos son * increíbles *!Soluciones elegantes, estilo python, felicidades ... ¡y gracias! – MestreLion