Я рекомендую немного изменить структуру кода и превратить заклинания в подклассы Spell
(взгляните на шаблон состояния ).Переместите больше кода, связанного со стрельбой, в класс Spell
и задайте ему метод update
, где обновляется таймер, и метод shoot
, в котором создаются маркеры.
Метод shoot
заклинания, которое должно быть нацелено на игрока, может быть переопределено, так что он направлен на положение игрока вместо использования одного из предопределенных направлений.
Вupdate
метод Opponent
, вам просто нужно проверить, выполнено ли текущее заклинание (когда loop
равно 0), затем переключите заклинание, создав новый экземпляр и вызывая его метод update
каждый кадр.
import pygame
class Spell:
def __init__(self, bullet_img, speed, loop, delay):
self.bullet_img = bullet_img
self.pattern = None
self.speed = speed
self.loop = loop
self.delay = delay
self.start_time = pygame.time.get_ticks()
def shoot(self, pos, target_pos):
for pattern in self.pattern:
Bullet(pos, pattern, self.bullet_img, sprites, bullets)
def update(self, pos, target_pos):
time_gone = pygame.time.get_ticks() - self.start_time
if time_gone > self.delay:
self.start_time = pygame.time.get_ticks()
self.shoot(pos, target_pos)
self.loop -= 1
class Spell1(Spell):
def __init__(self):
super().__init__(img, 10, 3, 340)
self.pattern = (pygame.Vector2(-2, 4), pygame.Vector2(0, 4),
pygame.Vector2(2, 4))
class Spell2(Spell):
def __init__(self):
super().__init__(img2, 4, 2, 340)
self.pattern = (pygame.Vector2(4, 4), pygame.Vector2(-4, 4))
class Spell3(Spell):
def __init__(self):
super().__init__(img3, 4, 6, 340)
# Override the shoot method to aim at the player position.
def shoot(self, pos, target_pos):
direction = (pygame.Vector2(target_pos) - pos).normalize() * 4
Bullet(pos, direction, self.bullet_img, sprites, bullets)
class Opponent(pygame.sprite.Sprite):
def __init__(self, pos, sprite, spells, *groups):
super().__init__(*groups)
self.image = sprite
self.rect = self.image.get_rect(topleft=pos)
self.start_time = pygame.time.get_ticks()
self.spells = spells
self.spellno = 0
self.currentspell = spells[self.spellno]() # Create the instance here.
def update(self):
if self.spellno < len(self.spells):
# You can pass the player position instead of the mouse pos here.
self.currentspell.update(self.rect.center, pygame.mouse.get_pos())
# Decrement the loop attribute of the current spell and
# switch to the next spell when it's <= 0. When all spells
# are done, set self.currentspell to None to stop shooting.
if self.currentspell.loop <= 0:
self.spellno += 1
if self.spellno < len(self.spells):
self.currentspell = self.spells[self.spellno]()
class Bullet(pygame.sprite.Sprite):
def __init__(self, pos, direction, image, *groups):
super().__init__(*groups)
self.image = image
self.rect = self.image.get_rect(center=pos)
self.direction = direction
self.pos = pygame.Vector2(self.rect.center)
def update(self):
self.pos += self.direction
self.rect.center = self.pos
if not screen.get_rect().colliderect(self.rect):
self.kill()
sprites = pygame.sprite.Group()
bullets = pygame.sprite.Group()
opponentgroup = pygame.sprite.Group()
img = pygame.Surface((30, 40))
img.fill((0, 100, 200))
img2 = pygame.Surface((30, 30))
img2.fill((110, 0, 220))
img3 = pygame.Surface((30, 50))
img3.fill((255, 170, 0))
minty_spells = [Spell1, Spell2, Spell3]
minty = Opponent((425, 30), img3, minty_spells, opponentgroup)
minty2 = Opponent((225, 30), img3, [Spell2, Spell3, Spell1], opponentgroup)
sprites.add(minty, minty2)
pygame.init()
screen = pygame.display.set_mode([1000, 650])
screen.fill((255, 123, 67))
pygame.draw.rect(screen, (0, 255, 188), (50, 50, 900, 575), 0)
background = screen.copy()
clock = pygame.time.Clock()
def main():
while True:
for events in pygame.event.get():
if events.type == pygame.QUIT:
pygame.quit()
return
sprites.update()
screen.blit(background, (0, 0))
sprites.draw(screen)
pygame.display.update()
clock.tick(100)
if __name__ == '__main__':
main()