George Cleaver
George Cleaver

Reputation: 1

Spawning of multiple enemies randomly in Pygame

Basically I am coding a programming project for my school at the moment, I was originally using a modular form of coding however it became apparent that OOP would be a more efficient way to code. I've been following some youtube tutorials as I am not that confident with OOP and seem to have hit a brick wall. I am currently struggling with spawning multiple enemies from my enemy class and also in random locations on the screen. I thought maybe ill have to create a list to append the enemies to and go from there but everything I have tried over the past few days has not worked! Thanks in advance for helping me with this issue and I will paste the code below.

    import tkinter as tk
    import pygame
    import time
    import random


    def shutdown():
      root.destroy()
    #Beginning of the game code for mainmenu link    
    def Begin():

pygame.init()
#display size
display_width = 640
display_height = 750

gameDisplay = pygame.display.set_mode((display_width,display_height))

pygame.display.set_caption ("Spellmaster")
#Images for wizard sprite
wizard_right = [pygame.image.load('right_1.png'), pygame.image.load('right_3.png'), pygame.image.load('right_2.png'), pygame.image.load('right_4.png'), pygame.image.load('right_5.png')]
wizard_left = [pygame.image.load('left_1.png'), pygame.image.load('left_3.png'), pygame.image.load('left_2.png'), pygame.image.load('left_4.png'), pygame.image.load('left_5.png')]
still = pygame.image.load("wizardsprite.png")
background = pygame.image.load("background.png")
clock = pygame.time.Clock()

score = 0

class player(object):
    def __init__ (self,x,y,width,height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.vel = 4
        self.steps= 0
        self.left = False
        self.right = False
        self.hitbox = (self.x + 20, self.y, 50, 60)

    #blit the character on screen
    def draw(self,gameDisplay):
        if self.steps + 1 >=27:
            self.steps = 0

        if self.left:
            gameDisplay.blit(wizard_left [self.steps//20], (self.x,self.y))
            self.steps +=1

        elif self.right:
            gameDisplay.blit(wizard_right [self.steps//20], (self.x,self.y))
            self.steps +=1

        else:
            gameDisplay.blit(still, (self.x,self.y))
            self.steps=0
        self.hitbox = (self.x + 20, self.y, 50, 60)
        #pygame.draw.rect(gameDisplay, (255,0,0),self.hitbox,2)

#FIRESPELL

class projectile(object):
    def __init__(self,x,y,radius,color,facing):
        self.x = x
        self.y = 662
        self.radius = radius
        self.color = color

        self.facing = 0
        self.vel = 10


    def draw(self,gameDisplay):
        pygame.draw.circle(gameDisplay, self.color, (self.x,self.y), self.radius)

#ENEMY CLASS
class enemy(object):
        redspider= [pygame.image.load('redspider_right.png'), pygame.image.load('redspider_left.png'), pygame.image.load('redspider_right.png'), pygame.image.load('redspider_left.png')]

        def __init__(self,x,y,width,height,end):
                self.x=x
                self.y=y
                self.width = width
                self.height = height
                self.end= end
                self.vel = 1.4
                self.walkCount = 0
                self.path = [self.y, self.end]
                self.hitbox = (self.x + 20, self.y, 70, 60)
                self.health = 0.2
                self.visible = True


        def draw(self,gameDisplay):
            self.move()
            if self.visible:
                if self.walkCount + 1 >= 27:
                    self.walkCount = 0
                else:
                    gameDisplay.blit(self.redspider[self.walkCount //2], (self.x, self.y))
                    self.walkCount += 0
                self.hitbox = (self.x + 2, self.y, 70, 60)
                #pygame.draw.rect(gameDisplay, (255,0,0), self.hitbox,2)


        def move(self):
            if self.vel > 0:
                if self.y + self.vel < self.path[1]:
                    self.y += self.vel


        def collision(self):
            if self.health > 0:
                self.health-= 1
            else:
                self.visible= False
            print("HIT")





def redraw():
    gameDisplay.blit(background, (0,0))
    text = font.render('SCORE: ' + str(score), 1,(255,0,0))
    gameDisplay.blit(text, (500,13))
    wizard.draw(gameDisplay)
    redspider.draw(gameDisplay)
    for bullet in bullets:
        bullet.draw(gameDisplay)


    pygame.display.update()


#MAIN LOOP

pygame.font.init()
font = pygame.font.SysFont('Engravers MT', 30)
wizard=player(300, 662, 80, 84)
redspider=enemy(360,80,80,84,650)
spides = []
shootControl = 0
bullets =[]
crashed = False
while not crashed:
    clock.tick(120)


    if shootControl >0:
        shootControl+=1
    if shootControl > 3:
        shootControl=0

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            crashed = True


    for bullet in bullets:
        if bullet.y - bullet.radius < redspider.hitbox[1] + redspider.hitbox[3] and bullet.y + bullet.radius > redspider.hitbox[1]:
            if bullet.x + bullet.radius > redspider.hitbox[0] and bullet.x - bullet.radius < redspider.hitbox[0] + redspider.hitbox[2]:
                redspider.collision()
                score += 1
                bullets.pop(bullets.index(bullet))

        if bullet.x < 500 and bullet.x > 0:
            bullet.y -= bullet.vel
        else:
            bullets.pop(bullets.index(bullet))

    keys = pygame.key.get_pressed()

    if keys[pygame.K_a] and wizard.x > wizard.vel:
            #if event.key == pygame.K_a and wizard.x > wizard.vel:
                wizard.x -= wizard.vel
                wizard.left= True
                wizard.right= False

    elif keys [pygame.K_d] and wizard.x < 560:
                wizard.x += wizard.vel
                wizard.right= True
                wizard.left=False

    if keys [pygame.K_SPACE] and shootControl ==0:
            if wizard.left:
                facing = 0
            else:
                facing = 0

            if len(bullets) < 500:
               bullets.append(projectile(round(wizard.x + wizard.width //2), round(wizard.y + wizard.height//2), 5, (255,0,0), facing))

            shootControl=1



    if event.type == pygame.KEYUP:
            if event.key == pygame.K_a or event.key == pygame.K_d:
                wizard.left= False
                wizard.right=False




    redraw()

pygame.quit()
shutdown

Upvotes: 0

Views: 4474

Answers (1)

Ethanol
Ethanol

Reputation: 370

To spawn your enemies at random locations around your screen, it is very simple. There are two possible ways:

First, you could modify the enemy init() to have self.x and self.y be randint, as shown below.

self.x = random.randint(0, display_width)
self.y = random.randint(0, display_height)

This method works, but limits your ability to place enemies in specific locations, and will be anywhere, and can place enemies where you don't want them. The second way is basically the first way, but it is written when defining a new enemy

redspider = enemy(random.randint(0, screen_width), random.randint(0, screen_height), 80, 84, 650)

This also works but when defining each new enemy manually it will take more time. But, this allow you to still place enemies in certain locations when used later. Both of these have flaws because they are placed randomly, but you can create functions to limit where thee are placed.

As for your with appending enemies in a list, you can do this:

enemies = []
maxenemies = 10
for i in range(maxenemies):
    enemies.append(enemy(random.randint(0, screen_width), random.randint(0, screen_height), 80, 84, 650))

This pushes maxenemies amount of enemies into the enemies list, which can be drawn and used later. maxenemies is just optional, but would be something I would suggest to do for readability. Tell me if these suggestions work for you.

Upvotes: 2

Related Questions