【问题标题】:Randomly spawning an enemy随机生成一个敌人
【发布时间】:2020-02-14 15:51:33
【问题描述】:

我正在制作一个小型 2d 游戏,其目标是尽可能多地吃便便,但我在随机生成便便时遇到了麻烦。我希望便便在敌人的 y 位置生成,然后像 rpg 一样向前射击。

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

【问题讨论】:

  • 到目前为止你尝试过什么?有什么工作吗?看来您在随机帧期间调用了 poop(po_x, po_y) 函数,这个 poop() 函数有什么作用?你如何在屏幕上移动便便?如果您更详细地解释您现在的工作以及您遇到的下一步问题,我们可以更轻松地帮助您解决这个问题!
  • 我已经尝试了几种方法,例如,如果随机生成的数字低于某个阈值,它会生成一个 show_poop 变量。我有 true 并且 poop 函数只是另一个失败的尝试,我试图创建一个包含关于 poop 的所有信息的函数,然后如果随机生成的数字低于阈值,我就会调用该函数。跨度>

标签: python random pygame


【解决方案1】:

如果您想管理多个“便便”,则必须创建一个列表。每个“便便”都是一个对象(class 的一个实例)。

创建一个类Poop,它可以update位置和draw便便:

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 中可以定义客户事件。每个事件都需要一个唯一的 ID。用户事件的 ID 必须从 pygame.USEREVENT 开始。在这种情况下,pygame.USEREVENT+1 是计时器事件的事件 ID,它会产生便便。

在事件循环中发生事件时创建一个新的便便并设置一个新的随机时间:

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

在循环中更改便便的位置并将它们从列表中删除,如果它们离开左侧的窗口:

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

在循环中绘制它们

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

【讨论】:

    【解决方案2】:

    您可以使用 pygame 的时间模块随机生成敌人。我假设您为此使用 OOP。首先,在初始化你的敌人类时,记录它第一次产生的时间。

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

    然后,您可以计算自您的敌人上次生成以来经过的时间。您可以在主游戏循环中执行类似now = time.time() 的操作并获得不同。

    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)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-22
      • 1970-01-01
      • 1970-01-01
      • 2016-12-16
      • 1970-01-01
      • 1970-01-01
      • 2011-10-26
      • 1970-01-01
      相关资源
      最近更新 更多