juegos dirtysprite collide python pygame sprite

python - dirtysprite - ¿Cómo hago que los enemigos pierdan dinero después de que mueren?



pygame scale sprite (2)

Estoy buscando hacer que algunos enemigos en mi juego dejen caer "Puntos ARRIBA" (Puntos de actualización en forma de pequeños cuadrados amarillos) cuando los disparo. He intentado algunas cosas diferentes, pero no puedo entender cómo generar estos puntos coleccionables en lugar de dónde acaba de morir un enemigo. ¿Alguien tiene alguna idea sobre cómo podría implementar esto?

Clase UP:

class Up(pygame.sprite.Sprite): def __init__(self, color): super().__init__() self.image = pygame.Surface([5, 5]) self.image.fill(color) self.rect = self.image.get_rect()

Aquí está el ciclo de cuando un enemigo recibe un disparo y muere:

for bullet in bullet_list: #For each bullet: # Whenever a bullet collides with a zombie, block_hit_list = pygame.sprite.spritecollide(bullet, zombie_list, True) for i in block_hit_list: # Destroy the bullet and zombie and add to the score bullet_list.remove(bullet) all_sprites_list.remove(bullet) score += 100

Perdón por no publicar mi código completo, el ciclo principal del juego está en la parte inferior :)

import pygame import math import random BLACK = (0, 0, 0) WHITE = (255, 255, 255) GREEN = (0, 255, 0) RED = (255, 0, 0) BLUE = (0, 0, 255) ORANGE = (255, 119, 0) ZOMBIE_GREEN = (122, 172, 34) YELLOW = (255, 255, 0) cursor_x = 100 cursor_y = 100 class Player(pygame.sprite.Sprite): def __init__(self, color): super().__init__() # pygame.Surface will create a rectangle with the width and height given # and the command below it tells it to fill it in with that color self.image = pygame.Surface([15, 15]) self.image.fill(color) self.rect = self.image.get_rect() # This defines the starting position (x, y) # of whatever sprite is passed through self.rect.x = 600 self.rect.y = 300 # This is the current speed it will move when drawn self.change_x = 0 self.change_y = 0 self.walls = None # Defines how the player will move def movement(self, x, y): self.change_x += x self.change_y += y # Updates the information so the screen shows the player moving def update(self): self.rect.x += self.change_x block_hit_list = pygame.sprite.spritecollide(self, self.walls, False) for block in block_hit_list: if self.change_x > 0: self.rect.right = block.rect.left else: self.rect.left = block.rect.right self.rect.y += self.change_y block_hit_list = pygame.sprite.spritecollide(self, self.walls, False) for block in block_hit_list: if self.change_y > 0: self.rect.bottom = block.rect.top else: self.rect.top = block.rect.bottom class Enemy(pygame.sprite.Sprite): def __init__(self, color): super().__init__() self.image = pygame.Surface([20, 20]) self.image.fill(color) self.rect = self.image.get_rect() self.pos_x = self.rect.x = random.randrange(35, screen_width - 35) self.pos_y = self.rect.y = random.randrange(35, screen_height - 135) # How Zombies move towards player def update(self): zombie_vec_x = self.rect.x - player.rect.x zombie_vec_y = self.rect.y - player.rect.y vec_length = math.sqrt(zombie_vec_x ** 2 + zombie_vec_y ** 2) if self.rect.x != player.rect.x and self.rect.y != player.rect.y: zombie_vec_x = (zombie_vec_x / vec_length) * 1 # These numbers determine zombie_vec_y = (zombie_vec_y / vec_length) * 1 # zombie movement speed self.pos_x -= zombie_vec_x self.pos_y -= zombie_vec_y self.rect.x = self.pos_x self.rect.y = self.pos_y block_hit_list = pygame.sprite.spritecollide(self, sprites_list, False) for block in block_hit_list: if self.rect.x > 0: self.rect.right = block.rect.left elif self.rect.x < 0: self.rect.left = block.rect.right elif self.rect.y > 0: self.rect.bottom = block.rect.top else: self.rect.top = block.rect.bottom class Wall(pygame.sprite.Sprite): def __init__(self, color, x, y, width, height): super().__init__() self.image = pygame.Surface([width, height]) self.image.fill(color) self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y class Cursor(pygame.sprite.Sprite): def __init__(self, width, height): self.groups = all_sprites_list self._layer = 1 pygame.sprite.Sprite.__init__(self) self.image = pygame.Surface([width, height]) self.image.fill(RED) self.rect = self.image.get_rect() self.walls = None # This updates the cursor to move along with your # mouse position (defined in control logic) def update(self): self.rect.x = cursor_x self.rect.y = cursor_y class Bullet(pygame.sprite.Sprite): def __init__(self): super().__init__() self.image = pygame.Surface([8, 8]) self.image.fill(ORANGE) self.rect = self.image.get_rect() # Instead of using the rect. positions, we''ll use pos_ variables # to calculate position. This is because the rect. uses integers # while a variable can have exact float numbers. This will keep # the bullets trajectory exact istead of useing a general # (rounded) whole number <3 self.pos_x = player.rect.x + 4 # Set up pos_x and pos_y here self.pos_y = player.rect.y + 4 # rather than rect.x and rect.y self.walls = None self.change_x = 0 self.change_y = 0 speed = 6 bullet_vec_x = (cursor.rect.x - 4) - player.rect.x bullet_vec_y = (cursor.rect.y - 4) - player.rect.y vec_length = math.sqrt(bullet_vec_x ** 2 + bullet_vec_y ** 2) bullet_vec_x = (bullet_vec_x / vec_length) * speed bullet_vec_y = (bullet_vec_y / vec_length) * speed self.change_x += bullet_vec_x self.change_y += bullet_vec_y def update(self): self.pos_x += self.change_x # Update pos_x and pos_y. They will become floats self.pos_y += self.change_y # which will let them maintain sub-pixel accuracy. self.rect.x = self.pos_x # Copy the pos values into the rect, where they will be self.rect.y = self.pos_y # rounded off. That''s OK since we never read them back. pygame.init() screen_size = pygame.display.Info() size = (1300, 720) screen = pygame.display.set_mode(size) #size = (screen_size.current_w, screen_size.current_h) #screen = pygame.display.set_mode( # ((screen_size.current_w, screen_size.current_h)),pygame.FULLSCREEN # ) screen_width = screen_size.current_w screen_height = screen_size.current_h pygame.display.set_caption("Zombie Shooter") wall_list = pygame.sprite.Group() zombie1_list = pygame.sprite.Group() sprites_list = pygame.sprite.Group() bullet_list = pygame.sprite.Group() all_sprites_list = pygame.sprite.Group() # Walls are made here = (x_coord for where it starts, # y_coord for where it starts, width of wall, height of wall) # These walls are made with fullscreen dimentions, not any set dimentions # Left wall = Wall(BLUE, 0, 0, 10, screen_height) wall_list.add(wall) all_sprites_list.add(wall) # Top wall = Wall(BLUE, 0, 0, screen_width, 10) wall_list.add(wall) all_sprites_list.add(wall) # Bottom wall = Wall(BLUE, 0, screen_height - 10, screen_width, 10) wall_list.add(wall) all_sprites_list.add(wall) # Right wall = Wall(BLUE, screen_width - 10, 0, 10, screen_width) wall_list.add(wall) all_sprites_list.add(wall) # HUD Border wall = Wall(BLUE, 0, screen_height - 100, screen_width, 10) wall_list.add(wall) all_sprites_list.add(wall) # This creates the actual player with the parameters set in ( ). # However, we must add the player to the all_sprites_list # so that it will actually be drawn to the screen with the draw command # placed right after the screen.fill(BLACK) command. player = Player(WHITE) player.walls = wall_list all_sprites_list.add(player) zombie = Enemy(ZOMBIE_GREEN) zombie.walls = wall_list for i in range(5): zombie = Enemy(ZOMBIE_GREEN) all_sprites_list.add(zombie) zombie1_list.add(zombie) sprites_list.add(zombie) cursor = Cursor(7, 7) cursor.walls = wall_list all_sprites_list.add(cursor) bullet = Bullet() font = pygame.font.SysFont("crushed", 30) score = 0 up_score = 0 done = False clock = pygame.time.Clock() pygame.mouse.set_visible(0) # -------- Main Program Loop ----------- while not done: # --- Main event loop --- for event in pygame.event.get(): if event.type == pygame.QUIT: done = True # Press ''P'' to quit the game_____ if event.type == pygame.KEYDOWN: if event.key == pygame.K_p: done = True #________________________________ # Keyboard controls. The numbers inside change the speed of the player if event.type == pygame.KEYDOWN: if event.key == pygame.K_a: player.movement(-4, 0) elif event.key == pygame.K_d: player.movement(4, 0) elif event.key == pygame.K_w: player.movement(0, -4) elif event.key == pygame.K_s: player.movement(0, 4) elif event.type == pygame.KEYUP: if event.key == pygame.K_a: player.movement(4, 0) elif event.key == pygame.K_d: player.movement(-4, 0) elif event.key == pygame.K_w: player.movement(0, 4) elif event.key == pygame.K_s: player.movement(0, -4) # ___________________________________________________________________ # Mouse Controls---------------------------- pos = pygame.mouse.get_pos() cursor_x = pos[0] cursor_y = pos[1] if cursor_x <= 10: cursor_x = 10 if cursor_x >= (screen_width - 17): cursor_x = (screen_width - 17) if cursor_y <= 10: cursor_y = 10 if cursor_y >= (screen_height - 107): cursor_y = (screen_height - 107) elif event.type == pygame.MOUSEBUTTONDOWN: bullet = Bullet() all_sprites_list.add(bullet) bullet_list.add(bullet) #-------------------------------------------- all_sprites_list.update() # How bullets vanish when they hit a sprite or a wall______________________ for bullet in bullet_list: #For each bullet: # Whenever a bullet collides with a zombie, block_hit_list = pygame.sprite.spritecollide(bullet, zombie1_list, True) for i in block_hit_list: # Destroy the bullet and zombie and add to the score bullet_list.remove(bullet) all_sprites_list.remove(bullet) score += 100 for bullet in bullet_list: block_hit_list = pygame.sprite.spritecollide(bullet, wall_list, False) for i in block_hit_list: bullet_list.remove(bullet) all_sprites_list.remove(bullet) #-------------------------------------------------------------------------- cursor.update() bullet_list.update() sprites_list.update() pygame.mouse.set_visible(0) screen.fill(BLACK) all_sprites_list.draw(screen) text = font.render("Score: " + str(score), True, WHITE) screen.blit(text, [30, screen_height - 64]) pygame.display.flip() clock.tick(60) pygame.quit()


Cambie su clase Up para aceptar un argumento pos y úselo para establecer la posición de inicio:

class Up(pygame.sprite.Sprite): def __init__(self, color, pos): super().__init__() self.image = pygame.Surface([5, 5]) self.image.fill(color) self.rect = self.image.get_rect(center=pos)

Ahora, cuando golpeas a un zombi, crea un Up , usando la posición del zombie que acabas de matar.

for bullet in bullet_list: block_hit_list = pygame.sprite.spritecollide(bullet, zombie_list, True) for i in block_hit_list: # just use .kill() to remove a Sprite from all of its Groups # kill() may get called multiple times, but that does not hurt bullet.kill() score += 100 # create an Up for each killed zombie # takes two arguments: color and pos # we call .add() to add the Sprite immediately to # the all_sprites_list and the up_list Up((255, 0, 0), i.rect.center).add(all_sprites_list, up_list)

No mostró el resto del código, pero creo que llama a .draw y .update en su all_sprites_list y crea un Group llamado up_list .


Lo que tendrás que hacer es antes de destruir al zombie sprite agarrar su ubicación y dibujar la moneda UP. Luego asegúrate de que cada vez que el jugador controle el sprite, en este caso la bala, al contacto "recolecte" la moneda. No he trabajado mucho con Python, pero el código principal se vería así:

def drawCoin(): zombieCoords = grabZombieCoords() drawSprite(zombieCoords())

Esto básicamente obtendría las coordenadas del zombi, destrúyalo y luego coloca la moneda en la última ubicación conocida del zombi. Espero que esto ayude.