How to make instances spawn automatically around the player?

 ̄綄美尐妖づ 提交于 2021-02-13 05:29:20

问题


So I want to have the Zombies spawn around the player (the number of Zombies should increase as time passes). Since I don't want the player to die instantly I need the Zombies to spawn away from the player at a certain distance but other than that a random location.

import pygame    
import turtle    
import time    
import math    
import random    
import sys    
import os    
pygame.init()    



WHITE = (255,255,255)    
GREEN = (0,255,0)    
RED = (255,0,0)    
BLUE = (0,0,255)    
BLACK = (0,0,0)    

BGColor = (96,128,56)    
ZColor = (221,194,131)    
PColor = (0,0,255)    

MOVE = 2.5    

size = (1200, 620)    
screen = pygame.display.set_mode(size)    
pygame.display.set_caption("Zombie Game")    

class Char(pygame.sprite.Sprite):    
    def __init__(self, color, pos, radius, width):    
        super().__init__()    
        self.image = pygame.Surface([radius*2, radius*2])    
        self.image.fill(WHITE)    
        self.image.set_colorkey(WHITE)    
        pygame.draw.circle(self.image, color, [radius, radius], radius, width)    
        self.rect = self.image.get_rect()    

    def moveRight(self, pixels):    
        self.rect.x += pixels    
        pass    

    def moveLeft(self, pixels):    
        self.rect.x -= pixels    
        pass    

    def moveUp(self, pixels):    
        self.rect.y -= pixels    
        pass    

    def moveDown(self, pixels):    
        self.rect.y += pixels    
        pass    

class Zombie(pygame.sprite.Sprite):    
    def __init__(self2, color, pos, radius, width):    
        super().__init__()    
        self2.image = pygame.Surface([radius*2, radius*2])    
        self2.image.fill(WHITE)    
        self2.image.set_colorkey(WHITE)    
        pygame.draw.circle(self2.image, color, [radius, radius], radius, width)    
        self2.rect = self2.image.get_rect()    

    def moveRight(self2, pixels):    
        self2.rect.x += pixels    
        pass    

    def moveLeft(self2, pixels):    
        self2.rect.x -= pixels    
        pass    

    def moveUp(self2, pixels):    
        self2.rect.y -= pixels    
        pass    

    def moveDown(self2, pixels):    
        self2.rect.y += pixels    
        pass    


all_sprites_list = pygame.sprite.Group()    

playerChar = Char(PColor, [0, 0], 15, 0)    
playerChar = Char(PColor, [0, 0], 15, 0)    
playerChar.rect.x = 0    
playerChar.rect.y = 0    

all_sprites_list.add(playerChar)    

carryOn = True    
clock = pygame.time.Clock()    

while carryOn:    
    for event in pygame.event.get():    
        if event.type==pygame.QUIT:    
            carryOn=False    
        elif event.type==pygame.KEYDOWN:    
            if event.key==pygame.K_x:    
                carryOn=False    

    keys = pygame.key.get_pressed()    
    if keys[pygame.K_a]:    
        playerChar.moveLeft(MOVE)    
    if keys[pygame.K_d]:    
        playerChar.moveRight(MOVE)    
    if keys[pygame.K_w]:    
        playerChar.moveUp(MOVE)    
    if keys[pygame.K_s]:    
        playerChar.moveDown(MOVE)    

    screen.fill(BGColor)    
    screen.blit(playerChar.image,playerChar.rect)    
    pygame.display.flip()    
    clock.tick(60)    
pygame.quit()    

I couldn't yet try anything because I had no idea how to start.


回答1:


I need the Zombies to spawn away from the player at a certain distance.

In the constructor of the class Zombie the center position of the attribute rect has to be set:

class Zombie(pygame.sprite.Sprite):    
    def __init__(self2, color, pos, radius, width):    
        super().__init__()    
        self2.image = pygame.Surface([radius*2, radius*2])    
        self2.image.fill(WHITE)    
        self2.image.set_colorkey(WHITE)    
        pygame.draw.circle(self2.image, color, [radius, radius], radius, width)    
        self2.rect = self2.image.get_rect()

        self2.rect.center = pos # <-------- add this

Define a list which contains the zombies (zombie_list), a size (radius) zombie_rad of the zombie. Further a range (zombie_dist) for spawn distance of the zombies (minimum and maximum distance) and a time span in milliseconds when the first zombie appears (next_zombie_time).

zombie_list = []
zombie_rad = 10   
zombie_dist = (65, 150)
next_zombie_time = pygame.time.get_ticks() + 3000 # first zombie after 3 seconds

Use pygame.time.get_ticks() to get the number of milliseconds since to program start. If the time exceeds next_zombie_time the span a zombie and set the time for the next zombie to spawn:

current_time = pygame.time.get_ticks()
if current_time > next_zombie_time:
    next_zombie_time = current_time + 1000 # 1 second interval to the next zombie

    # [...] spawn the zombie

Create the outer limit rectangle for the zombie position. This rectangle is the screen rectangle reduced by the radius of a zombie on each side. Each position inside this rectangle is a valid center position of a zombie, so that the zombie is completely on in the bounds of the screen.
Use pygame.Rect.collidepoint to check if a position is inside the rectangle. Repeat creating random position until a position inside the rectangle is found:

on_screen_rect = pygame.Rect(zombie_rad, zombie_rad, size[0]-2*zombie_rad, size[1]-2*zombie_rad)
    zombi_pos = (-1, -1)
    while not on_screen_rect.collidepoint(zombi_pos):

        # [...] create random zombie pos 

To get a random position around the player, get an random distance to the player by random.randint(a,b) and a random angle around the player in radiant by random.random() * math.pi * 2:

dist  = random.randint(*zombie_dist)
angle = random.random() * math.pi * 2

Finally calculate the position by converting the Polar coordinate (dist, angle) to a Cartesian coordinate:

p_pos = (playerChar.rect.centerx, playerChar.rect.centery)
zombi_pos = (p_pos[0] + dist * math.sin(angle), p_pos[1] + dist * math.cos(angle))

See the changes to the main loop of the program:

zombie_list = []
zombie_rad = 10   
zombie_dist = (65, 150)
next_zombie_time = 3000

while carryOn:
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            carryOn=False
        elif event.type==pygame.KEYDOWN:
            if event.key==pygame.K_x:
                carryOn=False

    keys = pygame.key.get_pressed()
    if keys[pygame.K_a]:
        playerChar.moveLeft(MOVE)
    if keys[pygame.K_d]:
        playerChar.moveRight(MOVE)
    if keys[pygame.K_w]:
        playerChar.moveUp(MOVE)
    if keys[pygame.K_s]:
        playerChar.moveDown(MOVE)

    current_time = pygame.time.get_ticks()
    if current_time > next_zombie_time:
        next_zombie_time = current_time + 1000 # 1 second interval to the next zombie

        on_screen_rect = pygame.Rect(zombie_rad, zombie_rad, size[0]-2*zombie_rad, size[1]-2*zombie_rad)
        zombi_pos = (-1, -1)
        while not on_screen_rect.collidepoint(zombi_pos):
            dist  = random.randint(*zombie_dist)
            angle = random.random() * math.pi * 2 
            p_pos = (playerChar.rect.centerx, playerChar.rect.centery)
            zombi_pos = (p_pos[0] + dist * math.sin(angle), p_pos[1] + dist * math.cos(angle))

        new_pos = (random.randrange(0, size[0]), random.randrange(0, size[1]))
        new_zomby = Zombie(RED, zombi_pos, zombie_rad, 0)
        zombie_list.append(new_zomby)

    screen.fill(BGColor)    
    screen.blit(playerChar.image,playerChar.rect)   
    for zombie in zombie_list:
        screen.blit(zombie.image,zombie.rect)      

    pygame.display.flip()    
    clock.tick(60)    


来源:https://stackoverflow.com/questions/54717938/how-to-make-instances-spawn-automatically-around-the-player

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!