拖延敌人的时间

2024-09-30 20:28:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在我的pygame代码中延迟一个敌人的射击,那是一个太空入侵者/子弹地狱游戏。不幸的是,我似乎有一个问题延迟射击敌人。在

import pygame
import random
import time
import os
import threading

pygame.time.set_timer ( pygame.USEREVENT , 450 )
event_500ms = pygame.USEREVENT + 1
pygame.time.set_timer(event_500ms, 500)

class Alien2 (pygame.sprite.Sprite):
    def __init__(self):
        # Call the parent class (Sprite) constructor
        super().__init__()

        self.image = pygame.Surface([20, 15])
        self.image = pygame.image.load("alien3.png").convert()
        self.image.set_colorkey(WHITE)


        self.rect = self.image.get_rect()
    def update(self):

        pos = pygame.mouse.get_pos()

        dx = pos[0] - self.rect.x + 18
        dx *= .05
        self.rect.x += dx
def BossPowers():
    bullet3 = Bullet3()
    # Set the bullet so it is where the player is
    bullet3.rect.x = alien2.rect.x + 47
    bullet3.rect.y = alien2.rect.y + 57
    # Add the bullet to the lists
    all_sprites_list.add(bullet3)
    bullet2_list.add(bullet3)

def BossPowers2():
    bullet4 = Bullet4()
    # Set the bullet so it is where the player is
    bullet4.rect.x = alien2.rect.x + 47
    bullet4.rect.y = alien2.rect.y + 57
    # Add the bullet to the lists
    all_sprites_list.add(bullet4)
    bullet2_list.add(bullet4)


def delay():
    #threading.Timer(5.0, delay).start()
    bullet2 = Bullet2()
    # Set the bullet so it is where the player is
    bullet2.rect.x = alien2.rect.x + 47
    bullet2.rect.y = alien2.rect.y + 57
    # Add the bullet to the lists
    all_sprites_list.add(bullet2)
    bullet2_list.add(bullet2)
    BossPowers()
    BossPowers2()

忽略我的意大利面代码,我已经为这个游戏工作了一段时间,有时效率会让我忘记

^{pr2}$

好吧,这是我的问题。 敌舰确实延迟开火。。。sorta,但它只有在飞船移动时才会停止射击。当船停止移动时,它会发射一股水流,而不是我想要它发射的一颗子弹。我需要它来延迟射击,每n秒只发射1颗子弹,而且实际上是在飞船运动的时候发射的。到现在为止,敌人几乎没用,只要稍微移动一下就不会开火,而且很容易被击败。 感谢任何帮助!在


Tags: therectimageimportselfaddisdef
2条回答

我通常使用clock.tick(fps)返回的delta time(自上次tick起经过的时间)并将其传递给sprite的update方法来增加或减少计时器变量。当计时器低于0时,我创建一个Bullet类的实例,将其添加到sprite组并重置计时器。在

import pygame as pg
from pygame.math import Vector2


pg.init()
ALIEN_IMAGE = pg.Surface((20, 15))
ALIEN_IMAGE.fill((40, 200, 90))
BULLET_IMAGE = pg.Surface((5, 5))
BULLET_IMAGE.fill((240, 120, 0))


class Alien(pg.sprite.Sprite):

    def __init__(self, pos, all_sprites, bullets):
        super().__init__()
        self.image = ALIEN_IMAGE
        self.rect = self.image.get_rect(center=pos)
        self.vel = Vector2(1, 0)
        self.pos = Vector2(pos)
        self.bullet_timer = 1  # 1 second.
        self.all_sprites = all_sprites
        self.bullets = bullets

    def update(self, dt):
        self.pos += self.vel
        self.rect.center = self.pos

        # Decrease the countdown timer.
        self.bullet_timer -= dt
        if self.bullet_timer < 0:  # Time is up so create a bullet.
            bullet = Bullet(self.rect.center, Vector2(0, 5))
            # Add the bullet to the sprite groups.
            self.all_sprites.add(bullet)
            self.bullets.add(bullet)
            self.bullet_timer = 1  # Reset timer after firing.


class Bullet(pg.sprite.Sprite):

    def __init__(self, pos, velocity):
        super().__init__()
        self.image = BULLET_IMAGE
        self.rect = self.image.get_rect(center=pos)
        self.vel = velocity
        self.pos = Vector2(pos)

    def update(self, dt):
        self.pos += self.vel
        self.rect.center = self.pos


def main():
    screen = pg.display.set_mode((640, 480))
    clock = pg.time.Clock()

    all_sprites = pg.sprite.Group()
    bullets = pg.sprite.Group()
    alien =  Alien((0, 30), all_sprites, bullets)
    alien2 = Alien((60, 30), all_sprites, bullets)
    all_sprites.add(alien, alien2)

    done = False

    while not done:
        # dt = delta time (passed time since last clock.tick call).
        dt = clock.tick(30) / 1000  # / 1000 to convert to seconds.

        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True

        all_sprites.update(dt)
        screen.fill((30, 30, 30))
        all_sprites.draw(screen)
        pg.display.flip()


if __name__ == '__main__':
    main()
    pg.quit()

问题是意大利面代码就是意大利面。:-)

我自己也搞不清你到底想要什么——如果所有的子弹头函数都创建了相同的子弹头,或者它们实际上是不同的,等等。在

但是,有两个问题导致了你的主要问题——它们可以被修复,保持代码的格式不变,但是我建议对其进行一些重改写,朝着一种更为gnocchi的方法(而不是意大利面)。在

问题的主要来源是注册一个事件在500毫秒后被激发,然后对它做出反应并调用您的delay函数。但是,这个函数同时调用BossPower函数来发射其他子弹,而不会有任何延迟。在

当然,你不能在调用函数发射其他子弹之前,在延迟内调用time.sleep或{},因为那样会暂停整个游戏。在

因此,一种方法是调用delay来注册其他自定义事件以触发下一个项目,然后从函数返回。然后主循环会在找到这些事件后发射下一颗子弹。在

这给我们带来了这段代码中的第二个大问题:在每一帧中获取所有可用的事件,但是对于所有这些事件,您唯一要做的就是检查pygame.QUIT。巧合的是,在每个帧中获取的最后一个事件被event变量引用,并且在您检查自定义事件(if event.type == event_500ms:)的行中可用。到达同一帧的其他事件被简单地丢弃awa。这也意味着您的自定义事件可能会被丢弃。在

因此,重要的是,只有在代码的某一点上获取每个帧的所有事件,并且任何与事件相关的操作或比较都是在同一点进行的。在

现在,Pygame允许使用最少数量的用户定义事件(默认构建中只有8个,因为他们建议只使用两个之间可用的事件)pygame.USEREVENT). 如果你想对每个子弹类使用一个事件类型,那么在你的游戏有3个关卡之前,你已经用完了事件编号。在

因此,由于激发项目符号的代码是完全相同的,并且您只需更改bullet类,就可以创建一系列要激发的项目符号类,并使用itertools.cycle来获取下一个项目符号类型:

...
import itertools


fire_bullet_event = pygame.USEREVENT + 1

...

bullets = itertools.cycle([Bullet2, Bullet3, Bullet4)

def fire_bullet():
    bullet_type = next(bullets)
    bullet2 = bullet_type()

    # Set the bullet so it is where the player is
    bullet2.rect.x = alien2.rect.x + 47
    bullet2.rect.y = alien2.rect.y + 57
    # Add the bullet to the lists
    all_sprites_list.add(bullet2)
    bullet2_list.add(bullet2)

    delay = 500
    # Schedule to call this function again in 500ms. 
    # use an "if" to change the 500 to another number like:
    # if bullet_type == Bullet4:
    #     delay = 2000
    pygame.time.set_timer(fire_bullet_event, delay)


...

# Schedule the first bullet close to entering the loop - 
# it is easier to see than putting it with the game setup code:
pygame.time.set_timer(fire_bullet_event, 500)

while not done:
    #  - Event Processing
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        # all code dealing with events must be inside this `for` loop.
        if event.type == fire_bullet_event:
            fire_bullet()
    if level % 2 == 0:
        all_sprites_list.add(alien2)
        alien2_list.add(alien2)
        for block in block_list:
            block_list.remove(block)
            all_sprites_list.remove(block)

相关问题 更多 >