Случайно порождает врага - PullRequest
1 голос
/ 14 февраля 2020

Я нахожусь в процессе создания небольшой 2d игры, цель которой - съесть как можно больше p oop, но у меня возникают проблемы с порождением p oop в случайные моменты времени. Я хочу, чтобы р oop появлялся у противника, но затем стрелял вперёд как рпг.

import pygame
from pygame.locals import *
from numpy.random import rand

pygame.init()
pygame.display.set_caption('STINKY BEETLE')

screen_width = 800
screen_height = 600
game_running = True
pl_x = int(screen_width/10)
pl_y = int(screen_height/2)
pl_width = 80
pl_height = 40
pl_vel = 30
en_width = 80
en_height = 40
en_x = screen_width - screen_width/10 - en_width
en_y = int(screen_height/2)
en_yvel = -10
po_width = 50
po_height = 30
po_x = 720
po_y = en_y
po_xvel = 15

screen = pygame.display.set_mode((screen_width, screen_height))
clock = pygame.time.Clock()

while game_running:
    clock.tick(10)

    po_delay = rand(1)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            game_running = False

        if event.type == MOUSEBUTTONDOWN:
            if event.button == 4 and pl_y > pl_vel:
                pl_y -= pl_vel

            elif event.button == 5 and pl_y < screen_height - pl_width:
                pl_y += pl_vel

    if po_delay < 0.01:
        poop(po_x, po_y)

    en_y += en_yvel
    if en_y <= 0 or en_y >= screen_height - en_height:
        en_yvel =- en_yvel

    screen.fill((0, 0, 0))
    pygame.draw.rect(screen, (105, 255, 125), (pl_x, pl_y, pl_width, pl_height))
    pygame.display.update()

    pygame.draw.rect(screen, (255, 125, 115), (en_x, en_y, en_width, en_height))
    pygame.display.update()

pygame.quit()

Ответы [ 2 ]

3 голосов
/ 17 февраля 2020

Если вы хотите управлять несколькими «poops», то вы должны создать список. И каждый «p oop» является объектом (экземпляром класса ).

Ящик класса Poop, который может update положение и draw p oop:

class Poop:
    def __init__(self, x, y, w, h):
        self.rect = pygame.Rect(x, y-h//2, w, h)
        self.vel = -15
    def update(self):
        self.rect.x += self.vel
    def draw(self, surf):
        pygame.draw.rect(surf, (255, 200, 125), self.rect)

poops = []

Используйте событие таймера, чтобы порождать колоды. Используйте pygame.time.set_timer(), чтобы повторно создать USEREVENT. Время устанавливается в миллисекундах. Установите случайное время с помощью random.randint(a, b), например, установите время от 0,5 до 4 секунд (конечно, вы можете выбрать свой собственный временной интервал):

min_time, max_time = 500, 4000 # 0.5 seconds to to 4 seconds
spawn_event = pygame.USEREVENT + 1
pygame.time.set_timer(spawn_event, random.randint(min_time, max_time))

Примечание, в событиях клиента Pygame можно определить. Каждому событию нужен уникальный идентификатор. Идентификаторы пользовательских событий должны начинаться с pygame.USEREVENT. В этом случае pygame.USEREVENT+1 - это идентификатор события для таймера, который порождает циклы.

Создайте новый p oop, когда событие происходит в событии l oop, и установите новое случайное время :

for event in pygame.event.get():
    # [...]
    if event.type == spawn_event:
        pygame.time.set_timer(spawn_event, random.randint(min_time, max_time))
        poops.append(Poop(en_x, en_y+en_yvel+en_height//2, 50, 30))

Измените расположение элементов в al oop и удалите их из списка, если они выходят из окна слева:

for poop in poops[:]:
    poop.update()
    if poop.rect.right <= 0:
        poops.remove(poop)

Нарисуйте их в л oop

for poop in poops:
    poop.draw(screen)

См. Пример:

import pygame
from pygame.locals import *
import random

pygame.init()
pygame.display.set_caption('STINKY BEETLE')

class Poop:
    def __init__(self, x, y, w, h):
        self.rect = pygame.Rect(x, y-h//2, w, h)
        self.vel = -15
    def update(self):
        self.rect.x += self.vel
    def draw(self, surf):
        pygame.draw.rect(surf, (255, 200, 125), self.rect)

screen_width = 800
screen_height = 600
game_running = True
pl_x, pl_y = screen_width//10, screen_height//2
pl_width, pl_height, pl_vel = 80, 40, 30
en_width, en_height, en_yvel = 80, 40, -10
en_x, en_y,  = screen_width - screen_width//10 - en_width, screen_height//2

screen = pygame.display.set_mode((screen_width, screen_height))
clock = pygame.time.Clock()

min_time, max_time = 500, 4000 # 0.5 seconds up to 4 seconds 
spawn_event = pygame.USEREVENT + 1
pygame.time.set_timer(spawn_event, random.randint(min_time, max_time))
poops = []

while game_running:
    clock.tick(10)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            game_running = False

        if event.type == MOUSEBUTTONDOWN:
            if event.button == 4 and pl_y > pl_vel:
                pl_y -= pl_vel
            elif event.button == 5 and pl_y < screen_height - pl_width:
                pl_y += pl_vel

        if event.type == spawn_event:
            pygame.time.set_timer(spawn_event, random.randint(min_time, max_time))
            poops.append(Poop(en_x, en_y+en_yvel+en_height//2, 50, 30))

    en_y += en_yvel
    if en_y <= 0 or en_y >= screen_height - en_height:
        en_yvel =- en_yvel

    for poop in poops[:]:
        poop.update()
        if poop.rect.right <= 0:
            poops.remove(poop)

    screen.fill((0, 0, 0))
    for poop in poops:
        poop.draw(screen)
    pygame.draw.rect(screen, (105, 255, 125), (pl_x, pl_y, pl_width, pl_height))
    pygame.draw.rect(screen, (255, 125, 115), (en_x, en_y, en_width, en_height))
    pygame.display.update()

pygame.quit()
1 голос
/ 17 февраля 2020

Вы можете использовать модуль времени Pygame для случайного появления врагов. Я предполагаю, что вы используете OOP для этого. Во-первых, при инициализации класса противника запишите время его первого появления.

class Enemy:
    def __init__(self):
        self.start = time.time()
        # other code

Затем вы можете рассчитать количество времени, прошедшее с момента последнего появления вашего врага. Вы можете сделать что-то вроде now = time.time() в своей основной игре l oop и получить разницу.

enemy = Enemy()
while True:
    now = time.time()
    time_passed = now - enemy.start()

Теперь вы можете использовать это time_passed в качестве аргумента для вашей spawn_enemy() функции, которую вы можете создать, которая может выглядеть примерно так:

def spawn(self, t):
   counter = t % random.randint(1, 10)
   if counter >= 0 and counter <=  0.2:
       #spawn enemy

Вызовите эту функцию как spawn(time_passed)

...