如何使实例在播放器周围自动生成?

时间:2019-02-15 22:35:28

标签: python class pygame

所以我想让僵尸在玩家周围产生(随着时间的流逝,僵尸的数量应该增加)。因为我不想让玩家立即死亡,所以我需要让僵尸在一定距离之外从玩家处生成,而不是随机位置。

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()    

我无法尝试任何事情,因为我不知道如何开始。

1 个答案:

答案 0 :(得分:2)

  

我需要僵尸在玩家一定距离之外生成。

在类Zombie的构造函数中,必须设置属性rect的中心位置:

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

定义一个列表,其中包含僵尸(zombie_list),僵尸的大小(半径)zombie_rad。还有一个范围(zombie_dist)用于僵尸的生成距离(最小和最大距离)以及第一个僵尸出现时的时间跨度(毫秒)(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

使用pygame.time.get_ticks()获取自编程开始以来的毫秒数。如果时间超过next_zombie_time,则跨度为僵尸,并设置下一个僵尸产生的时间:

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

为僵尸位置创建外部限制矩形。此矩形是屏幕矩形,每边均减小了僵尸的半径。此矩形内的每个位置都是僵尸的有效中心位置,因此僵尸完全位于屏幕的边界内。
使用pygame.Rect.collidepoint检查位置是否在矩形内。重复创建随机位置,直到找到矩形内的位置:

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 

要在玩家周围获得随机位置,请以random.randint(a,b)到玩家随机距离,并以random.random() * math.pi * 2放射出玩家周围的随机角度:

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

最后通过将Polar coordinatedistangle)转换为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))

查看对程序主循环的更改:

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)