«Пули», снятые из двух пигейских спрайтов, объединяются в одну длинную линию - PullRequest
0 голосов
/ 17 февраля 2019

У меня есть спрайт, который стреляет пулями.Иногда пули также стреляют из невидимых стрелков.

Переключение с середины программы противника на стрелок работает, но когда я хочу, чтобы пули стреляли определенным образом, с задержками между выстрелами, пули, кажется, становятсяодиночная линия (фиолетовая вещь на изображении - маркеры):

Screenshot with long purple line starting from circle

Механика работает, когда стреляет противник, но не когда это невидимый квадрат.

Почему это происходит?Есть небольшая ошибка, которую мне нужно исправить?

Вот мой код:

import pygame
import time
import itertools
import os

pygame.init()
SCREENWIDTH = 1000
SCREENHEIGHT = 650
screen = pygame.display.set_mode([SCREENWIDTH, SCREENHEIGHT])
screen.fill((255, 123, 67))
pygame.draw.rect(screen, (230, 179, 204), (0, 50, 1000, 650), 0)

background = screen.copy()
clock = pygame.time.Clock()
stageon = True

class Spell:

    def __init__(self, bullet, pattern, speed, loop, tick_delay):
        self.bullet = bullet
        self.pattern = pattern
        self.speed = speed
        self.loop = loop
        self.tick_delay = tick_delay

class Shooter(pygame.sprite.Sprite):

    def __init__(self, spell, pos, *groups):
        super().__init__(*groups)
        self.image = pygame.image.load("Sprites/transparent.jpg")
        self.rect = self.image.get_rect(topleft=(pos))
        self.pos = pygame.Vector2(pos)
        self.start_time = pygame.time.get_ticks()
        self.currentspell = spell
        self.speed = 3
        self.ticks = 1000

    def update(self):
        time_gone = pygame.time.get_ticks() - self.start_time
        if self.currentspell is not None and time_gone > self.currentspell.tick_delay:
            self.start_time = pygame.time.get_ticks()
            for bullet in self.currentspell.pattern:
                if bullet[0] <= time_gone:
                    Bullet(self.rect.center, bullet[1], self.currentspell.bullet, sprites, bullets)

            self.currentspell.loop -= 1
            if self.currentspell.loop <= 0:
                    self.currentspell = None
                    self.kill()

class Opponent(pygame.sprite.Sprite):

    def __init__(self, sprite, sequence, *groups):
        super().__init__(*groups)
        self.image = sprite
        self.rect = self.image.get_rect(topleft=(425, 30))
        self.pos = pygame.Vector2(self.rect.topleft)
        self.start_time = pygame.time.get_ticks()
        self.sequence = sequence
        self.spellno = 0
        self.currentspell = sequence[self.spellno]
        self.speed = 3
        self.ticks = 1000
        self.shooters = 0
    def update(self):
        time_gone = pygame.time.get_ticks() - self.start_time
        if type(self.currentspell) != Spell:
           Shooter(self.currentspell[0], self.currentspell[1], sprites) 
           self.shooters += 1
        if self.shooters != 0:
           return
        else:
            if self.currentspell is not None and time_gone > self.currentspell.tick_delay:
                self.start_time = pygame.time.get_ticks()
                for bullet in self.currentspell.pattern:
                    if bullet[0] <= time_gone:
                        Bullet(self.rect.center, bullet[1], self.currentspell.bullet, sprites, bullets)

                self.currentspell.loop -= 1
                if self.currentspell.loop <= 0:
                    self.spellno += 1
                    if self.spellno >= len(self.sequence):
                        self.currentspell = None
                    else:
                        self.currentspell = self.sequence[self.spellno]

sprites = pygame.sprite.Group()

class Bullet(pygame.sprite.Sprite):

    def __init__(self, pos, direction, image, *groups):
        super().__init__(*groups)
        self.image = image
        self.rect = self.image.get_rect(topleft=pos)
        self.direction = direction
        self.pos = pygame.Vector2(self.rect.topleft)


    def update(self):
        self.pos += self.direction
        self.rect.topleft = (self.pos.x, self.pos.y)
        if not screen.get_rect().colliderect(self.rect):
            self.kill()

bullets = pygame.sprite.Group()

opponentgroup = pygame.sprite.Group()

img4 = pygame.image.load("Sprites/utd.png")

ut1 = Spell(pygame.image.load("Sprites/purple-glowey.png"),((0, pygame.Vector2(-1, 1) * 4),
                                                            (0, pygame.Vector2(-0.5, 1) * 4.5),
                                                            (0, pygame.Vector2(0, 1) * 5),
                                                            (0, pygame.Vector2(0.5, 1) * 4.5),
                                                            (0, pygame.Vector2(1, 1) * 4),),4, 1, 400)

ut2 = Spell(pygame.image.load("Sprites/purple-glowey.png"),((0, pygame.Vector2(1, 0) * 5),),4, 8, 400)

op_spells = [ut1, (ut2, (10, 395))]

OP = Opponent(img4, op_spells, opponentgroup)
sprites.add(OP)



def main():
    while stageon:
        for events in pygame.event.get():
            if events.type == pygame.QUIT or stageon == False:
                time.sleep(1)
                pygame.quit()
                return        
        sprites.update()
        screen.blit(background, (0, 0))
        sprites.draw(screen)
        pygame.display.update()

        clock.tick(100)
        if stageon == False:
            return
if __name__ == '__main__':
    main()

1 Ответ

0 голосов
/ 20 февраля 2019

Ваша проблема в том, что это функция update класса Opponent:

def update(self):
    time_gone = pygame.time.get_ticks() - self.start_time
    if type(self.currentspell) != Spell:
       Shooter(self.currentspell[0], self.currentspell[1], sprites) 
       self.shooters += 1
    ...

Вы используете список op_spells = [ut1, (ut2, (10, 395))], и, как вы можете видеть, второй элемент не является экземпляромSpell.Таким образом, условие if if type(self.currentspell) != Spell будет True, и будет создан новый экземпляр Shooter.

Но создание Shooter instace происходит каждый кадр, поэтому вы создаете бесконечное количество Shooter экземпляров, которые, в свою очередь, создают бесконечное число Bullet экземпляров.

Вы можете изменить свою update функцию следующим образом:

def update(self):
    time_gone = pygame.time.get_ticks() - self.start_time

    if self.currentspell is not None:
        spell = self.currentspell if type(self.currentspell) == Spell else self.currentspell[0]
        shooterpos = None if type(self.currentspell) == Spell else self.currentspell[1]
        if time_gone > spell.tick_delay:
            if shooterpos:
                # we have a position, so create a shooter
                Shooter(spell, shooterpos, sprites) 
            else:
                # we don't have a position, so create the Bullets ourself
                self.start_time = pygame.time.get_ticks()
                for bullet in spell.pattern:
                    if bullet[0] <= time_gone:
                        Bullet(self.rect.center, bullet[1], spell.bullet, sprites, bullets)
                spell.loop -= 1

            # if we have a position or the spell loop is done, go to the next spell
            if shooterpos or spell.loop <= 0:
                self.spellno += 1
                if self.spellno >= len(self.sequence):
                    self.currentspell = None
                else:
                    self.currentspell = self.sequence[self.spellno]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...