Что я должен сделать, чтобы создать несколько экземпляров врагов?

#python #pygame

#python #pygame

Вопрос:

Как новичок, я изо всех сил пытаюсь создать несколько врагов в pygame. Что я мог бы добавить или реализовать в своем коде, чтобы сделать это?

Код:

 # WORK IN PROGRESS!
# I followed techwithtim's tutorial
# I do not own the images and sounds used in game
# TODO Create multiple Enemies
import pygame
import random


# Screen parameters
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("SPPACCE")
bg = pygame.image.load("bg.png")
font = pygame.font.SysFont('comicsans', 30, True)
clock = pygame.time.Clock()
score = 0

# Music amp; Sound effects
bulletsound = pygame.mixer.Sound('sounds/bullet_soundeffect.wav') 
explosion = pygame.mixer.Sound('sounds/explosion_effect.wav')
explosion2 = pygame.mixer.Sound('sounds/torpedo_explosion.wav')

# Player parameters
class Player(object):
    def __init__(self, x, y, height, width):
        self.x = x
        self.y = y
        self.height = height
        self.width = width
        self.player_vel = 5

    def draw(self, screen):
        screen.blit(player_char, (self.x, self.y))
       

# Enemy parameters
class Enemy(object):
    def __init__(self, x, y, height, width, end):
        self.x = x
        self.y = y
        self.height = height
        self.width = width
        self.enemy_vel = 1.5
        self.end = end   
        self.path = [self.x, self.end]
        self.hitbox = (self.x   17, self.y   2, 65, 65)
        self.health = 5
        self.visible = True


    def draw(self, screen):
        self.move()
        if self.visible:
            self.hitbox = (self.x   0, self.y, 65, 65)
            pygame.draw.rect(screen, (255, 0, 0), self.hitbox, 2)
            screen.blit(enemy_char, (self.x, self.y))

            # Health bars
            pygame.draw.rect(screen, (0, 0, 0), (self.hitbox[0], self.hitbox[1] - 20, 65, 7))
            pygame.draw.rect(screen, (255, 0, 0), (self.hitbox[0], self.hitbox[1] - 20, 65 - (12 * (5 - self.health)), 7))                

    
    def move(self):
        if self.enemy_vel > 0:
            if self.x < self.path[1]   self.enemy_vel:
                self.x  = self.enemy_vel
            else:
                self.enemy_vel = self.enemy_vel * -1
                self.x  = self.enemy_vel
        else:
            if self.x > self.path[0] - self.enemy_vel:
                self.x  = self.enemy_vel
            else:
                self.enemy_vel = self.enemy_vel * -1
                self.x  = self.enemy_vel

    def hit(self):
        if self.health > 0:
            self.health -= 1
        else: 
            self.visible = False
            explosion.play()
            global score
            score  = 1    
   
# Player Projectile parameters
class Projectile(object):
    def __init__(self, x, y, color, radius):
        self.x = x
        self.y = y
        self.color = color
        self.radius = radius
        self.vel = 12.5
    
    def draw(self, screen):
        pygame.draw.circle(screen, self.color, (self.x, self.y), self.radius)


# Images
player_char = pygame.image.load('sprites/hotdog.png')
enemy_char = pygame.image.load('sprites/hamburger.png')

def blit(): # This draws the sprites
    player.draw(screen)
    enemy.draw(screen)
    for projectile in projectiles:
        projectile.draw(screen)

    score_text = font.render("Score: "   str(score), 1, (0, 109, 255))
    version = font.render("Version 01 ", 1, (51, 153, 255))
    screen.blit(score_text, (0, 0))
    screen.blit(version, (520, 0))


shootloop = 0

if shootloop > 0:
    shootloop  = 1
if shootloop > 2:
    shootloop = 0

player = Player(300, 400, 64, 64) 
enemy = Enemy(random.randint(10, 100), random.randint(20, 100), 64, 64, 480)
enemy_count = random.randint(1, 10)
projectiles = []
run = True


while run:
    clock.tick(60)
    screen.fill((0, 0, 0))
    screen.blit(bg, (0, 0))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    # Movement keys with playeborders
    keys = pygame.key.get_pressed()
    if keys[pygame.K_s] and player.y < 480 - player.height - player.player_vel:
        player.y  = player.player_vel
    if keys[pygame.K_w] and player.y > 280:
        player.y -= player.player_vel
    if keys[pygame.K_d] and player.x < 640 - player.width - player.player_vel:
        player.x  = player.player_vel
    if keys[pygame.K_a] and player.x > player.player_vel:
        player.x -= player.player_vel
    

    for projectile in projectiles:
        if projectile.y - projectile.radius < enemy.hitbox[1]   enemy.hitbox[3] and projectile.y   projectile.radius > enemy.hitbox[1]:
            if enemy.visible == True:
                if projectile.x   projectile.radius > enemy.hitbox[0] and projectile.x - projectile.radius < enemy.hitbox[0]   enemy.hitbox[2]:
                    enemy.hit()
                    explosion2.play()
                    projectiles.pop(projectiles.index(projectile))
                    
        if projectile.y < 640 and projectile.y > 0:
            projectile.y -= projectile.vel
            
        else:
            projectiles.pop(projectiles.index(projectile))
    
    # Player shooting
    if keys[pygame.K_SPACE] and shootloop == 0:
        if len(projectiles) < 1:
            projectiles.append(Projectile(round(player.x   player.width //2), 
            round(player.y   player.height //2), [255, 150, 0], 7))
    
    blit()
    pygame.display.update()
 

Я пытался переработать код из моего последнего игрового проекта, но это не сработало, потому что структуры кода слишком отличаются друг от друга. Этот проект является ООП, в то время как последний имеет разбросанные переменные.

Ответ №1:

Аналогично вашему projectiles составьте список Enemy объектов:

 enemies = []
enemy_count = random.randint(3, 10)
for i in range( enemy_count ):
    new_enemy = Enemy(random.randint(10, 100), random.randint(20, 100), 64, 64, 480)
    enemies.append( new_enemy )
projectiles = []
 

Обновите свой blit(), чтобы нарисовать список врагов:

 def blit(): # This draws the sprites
    player.draw(screen)
    for enemy in enemies:
        enemy.draw(screen)
    for projectile in projectiles:
        projectile.draw(screen)

    score_text = font.render("Score: "   str(score), 1, (0, 109, 255))
    version = font.render("Version 01 ", 1, (51, 153, 255))
    screen.blit(score_text, (0, 0))
    screen.blit(version, (520, 0))
 

И проверьте их все на наличие столкновений:

 for enemy in enemies:
    for projectile in projectiles:
        if projectile.y - projectile.radius < enemy.hitbox[1]   enemy.hitbox[3] and projectile.y   projectile.radius > enemy.hitbox[1]:
            if enemy.visible == True:
                if projectile.x   projectile.radius > enemy.hitbox[0] and projectile.x - projectile.radius < enemy.hitbox[0]   enemy.hitbox[2]:
                    enemy.hit()
                    explosion2.play()
                    projectiles.pop(projectiles.index(projectile))
 

Это должно помочь вам начать.

Изменения относительно просты, потому что у вас уже есть данные, разделенные на объекты. Хорошая работа.

РЕДАКТИРОВАТЬ: повторное создание врага — это просто вопрос добавления другого Enemy объекта в enemies список:

 new_enemy = Enemy(random.randint(10, 100), random.randint(20, 100), 64, 64, 480)
enemies.append( new_enemy )
 

Комментарии:

1. И последний вопрос: есть ли способ возрождать врагов, используя предоставленный вами код?

2. @colappse — это почти то же самое, что и при их первоначальном создании. Пожалуйста, смотрите Редактирование.