python pygame game-physics

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.

  1. mover mosca verticalmente
  2. compruebe la colisión y use if/else con vspeed
  3. mover mosca horizontalmente
  4. verificar colisión y usar if/else con hspeed

-

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