简体   繁体   中英

sprite collision detection and removing one sprite from group in pygame

so I need to remove one sprite from the group every time I press the - (minus) key. However, I am confused as to how to do it. Another issue I've run into is when I press the + key it is adding more than one sprite at a time. I'm guessing I need to also check for KEYUP ? I also have a bug where some of the sprites will be created on top of each and will stay stuck bouncing off one another. How can I check for existing sprites where the new will be generated? Here is my code

dragon.py

import pygame
from pygame.locals import *

class Dragon(pygame.sprite.Sprite):
    def __init__(self, x,y, vx, vy):
        super().__init__();
        self.image = pygame.image.load("images/dragon.png").convert()
        self.image.set_colorkey(pygame.Color(255,0,255))
        self.rect = self.image.get_rect()

        self.rect.x = x
        self.rect.y = y
        self.vx = vx
        self.vy = vy

    def draw(self, SCREEN):
        SCREEN.blit(self.image, (self.rect.x, self.rect.y))

    def move(self, SCREEN):
        r_collide = self.rect.x + self.image.get_width() + self.vx >= SCREEN.get_width()
        l_collide = self.rect.x + self.vx <= 0
        t_collide = self.rect.y + self.vy <= 0
        b_collide = self.rect.y + self.image.get_height() + self.vy >= SCREEN.get_height()

        # Check collision on right and left sides of screen
        if l_collide or r_collide:
            self.vx *= -1

        # Check collision on top and bottom sides of screen
        if t_collide or b_collide:
            self.vy *= -1

        self.rect.x += self.vx
        self.rect.y += self.vy

    def bounce(self, SCREEN):
        self.vy *= -1
        self.vx *= -1

dragon_animation.py

import pygame
import sys
from random import *
from pygame.locals import *
from flying_dragon.dragon import Dragon


def main():
    pygame.init()

    FPS = 30
    FPS_CLOCK = pygame.time.Clock()

    ''' COLOR LIST '''
    WHITE = pygame.Color(255,255,255)

    ''' create initial window '''
    window_size = (500, 500)
    SCREEN = pygame.display.set_mode(window_size)

    ''' set the title '''
    pygame.display.set_caption("Flying Dragons")

    ''' fill background color in white '''
    SCREEN.fill(WHITE)

    ''' group to store dragons '''
    dragons = pygame.sprite.Group()

    d1 = Dragon(0,0,3,2)
    d1.draw(SCREEN)

    dragons.add(d1)

    ''' main game loop '''
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()

        SCREEN.fill(WHITE)

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_PLUS or pygame.K_KP_PLUS:
                d = Dragon(randint(1, SCREEN.get_width() - dragon.rect.x), randint(1, SCREEN.get_height()- dragon.rect.y), randint(1, 5), randint(1, 5))
                dragons.add(d)

        for dragon in dragons:
            dragons.remove(dragon)
            collisions = pygame.sprite.spritecollide(dragon, dragons, False)
            dragons.add(dragon)

            for dragon in collisions:
                dragon.bounce(SCREEN)

        for dragon in dragons:
            dragon.move(SCREEN)

        dragons.update(SCREEN)
        dragons.draw(SCREEN)

        pygame.display.update()
        FPS_CLOCK.tick(FPS)

if __name__ == "__main__":
    main()
if event.key == pygame.K_MINUS or pygame.K_KP_MINUS:
    dragons.remove(dragons[0])

Should work for removing a sprite. Sprites aren't ordered in the group so will just delete a random one.

As another pointer, you should look at redefining your Dragon.move() function as dragon.update() then the Group.update() call will move all your dragons.

you don't need to draw the dragon immediately after it's creation before the while loop. The draw inside the while loop is sufficient.

When you press a key the event list will hold which key you are holding down and as long as this is down a dragon will be created. As the loop runs pretty fast several dragons will be created before you remove your finger from the keyboard.

also good to do

pygame.event.pump()

before the for event in pygame.event.get(): so that you clear the event list beofre the next run.

read about the pygame event pump here.

Use key = pygame.key.get_pressed() instead of event.get as it will read a key press ONCE.

can't run your code because of this error.

ImportError: No module named flying_dragon.dragon

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM