python - pygame-¿El enemigo sale volando de la pantalla cuando choca contra tierra?
game-physics (2)
primer póster aquí.
Trataré de mantener esto lo más simple posible. Intento hacer un juego en pygame, pero parece que mi detección de colisiones está actuando. Tengo una clase de jugador que detecta si el jugador colisiona con el suelo o con otros objetos en la lista de entornos, y tengo una clase enemiga que colisiona con cualquier cosa en la misma lista. Los enemigos calculan en qué dirección deben viajar para intentar golpear al jugador. Existe la gravedad que es muy probable que desempeñe un papel importante en el problema.
El problema es que cuando las "moscas" se colocan y caen al suelo, inmediatamente saltan de la pantalla, a pesar de que sus valores X e Y parecen (según los registros de los elementos en la pantalla) no moverse en absoluto.
Como aclaración, las dos "moscas" se colocan en una lista secundaria para permitir la detección de colisiones. Además, como nota al margen, el ''fallo'' no ocurre si no hay detección de colisión a la izquierda y a la derecha ... Gracias a cualquiera que pueda brindar ayuda :)
def collisions():
#Detection Working as intended
for fly in Fly.List:
fly_proj = pygame.sprite.spritecollide(fly, Projectile.List, True)
if len(fly_proj) > 0:
for hit in fly_proj:
fly.health -= 100
X = pygame.sprite.spritecollide(fly, current_level.object_list, False)
if len(X) == 0: #Gravity here:
if (fly.vspeed == 0):
fly.vspeed = 1
print("Gravity")
else:
fly.vspeed += 0.35
if len(X) > 1:
for hit in X:
if fly.vspeed > 0:
fly.rect.bottom = hit.rect.top +1
fly.vspeed = 0
elif fly.vspeed < 0:
fly.rect.top = hit.rect.bottom -1
elif fly.hspeed > 0:
fly.rect.right = hit.rect.left
fly.hspeed = 0
elif fly.hspeed < 0:
fly.rect.left = hit.rect.right
fly.hspeed = 0
print(len(X),framecounter, fly.vspeed, fly.hspeed)
#Kill fly if health reaches 0
if fly.health <= 0:
fly.destroy(Fly)
#Detect where the player is
if window_rect.contains(fly.rect):
fly.playersnapshot = player.rect.x
if fly.rect.x - player.rect.x >= -10:
#print("LEFTING")
fly.hspeed = -2
if fly.rect.x - player.rect.x <= 10:
fly.hspeed = 2
fly.truefalse = True
event = None
fly.rect.y += fly.vspeed
fly.rect.x += fly.hspeed
Creo que tu if/else
es incorrecto.
Probablemente cuando vuele toque tierra, establezca vspeed
a cero y luego if/else
comprueba hspeed
y usa tierra hacia la left/right
para cambiar de left/right
.
Conozco un método.
- mover mosca verticalmente
- compruebe la colisión y use
if/else
convspeed
- mover mosca horizontalmente
- verificar colisión y usar
if/else
conhspeed
-
EDITAR:
# move horizontally only
fly.rect.x += fly.hspeed
X = pygame.sprite.spritecollide( ... )
for hit in X:
if fly.hspeed > 0:
fly.rect.right = hit.rect.left
else:
fly.rect.left = hit.rect.right
# move vertically only
fly.rect.y += fly.vspeed
X = pygame.sprite.spritecollide( ... )
for hit in X:
if fly.vspeed > 0:
fly.rect.bottom = hit.rect.top
else:
fly.rect.top = hit.rect.bottom
# on_ground = True
Encontré este método en el código fuente de "Platform Jumper" en ProgramArcadeGames.com
ver página con: platform_jumper.py
Gracias a las furas por proporcionarme algo para estallar, he descubierto cuál era el problema. Para aquellos que están interesados, el código reemplazado:
if fly.vspeed > 0:
fly.rect.bottom = hit.rect.top +1
fly.vspeed = 0
elif fly.vspeed < 0:
fly.rect.top = hit.rect.bottom -1
elif fly.hspeed > 0:
fly.rect.right = hit.rect.left
fly.hspeed = 0
elif fly.hspeed < 0:
fly.rect.left = hit.rect.right
fly.hspeed = 0
con:
fly.rect.y += fly.hspeed
if fly.vspeed > 0:
fly.rect.bottom = hit.rect.top
else:
fly.rect.top = hit.rect.bottom
if fly.rect.bottom == hit.rect.top:
fly.vspeed = 0
if fly.vspeed == 0:
fly.rect.x += fly.vspeed
if fly.hspeed > 0:
fly.rect.right = hit.rect.left
else:
fly.rect.left = hit.rect.right
pero, ahora tengo un problema donde el objeto volador está cayendo incontrolablemente (vspeed sigue aumentando) y el culpable es esta pequeña cantidad de código:
if self.vspeed == 0:
self.vspeed = 1
else:
self.vspeed += 0.35 #Rate of gravity
Si alguien tiene alguna pista de lo que está sucediendo aquí, no dude en responder con una respuesta :)
ACTUALIZAR
Gracias a Furas que básicamente hicieron todo el trabajo por mí: D Gracias por enseñarme algo nuevo :)
Para aquellos que están interesados, el código de trabajo final es el siguiente: (on_ground) se llama cuando se llama a la función colllisions ().
fly.rect.y += fly.vspeed
X = pygame.sprite.spritecollide(fly, current_level.object_list, False)
for hit in X:
if fly.vspeed > 0:
fly.rect.bottom = hit.rect.top
on_ground = True
else:
fly.rect.top = hit.rect.bottom
# move horizontally only
fly.rect.x += fly.hspeed
X = pygame.sprite.spritecollide(fly, current_level.object_list, False)
for hit in X:
if fly.hspeed > 0:
fly.rect.right = hit.rect.left
else:
fly.rect.left = hit.rect.right
if on_ground == True:
fly.vspeed = 0
#print("WAT2")
else:
fly.vspeed += 0.35