简体   繁体   中英

Group Collision Detection Not Working Properly

I am having problems with group collision. I am making a game with a gun and the mouse is the crosshair. When I touch the enemy(group) , the collision is not detected until I touch the only enemy in the corner(0,0) . I want to be able to collide with all of the enemies moving across the screen. I am using pygame.sprite.spritecollideany() for the collision code and I'm using sys.exit() for the output.

import pygame
import random
import sys
import os
from pygame.locals import *

#Initialize pygame
pygame.init()

#Window properties
window_width = 1366
window_height = 768
window = pygame.display.set_mode((window_width,window_height),pygame.FULLSCREEN)
pygame.display.set_caption("Sniper")

#Clock
clock = pygame.time.Clock()

#Movement
moveX = 1
moveY = 0

#Colors
black = (0,0,0)
white = (255,255,255)
blue = (0,0,64)

#Sprite groups
enemies = pygame.sprite.Group()
cursors = pygame.sprite.Group()

#Enemy
class Enemy(pygame.sprite.Sprite):
    def __init__(self,x,y):
        pygame.sprite.Sprite.__init__(self)
        self.x = x
        self.y = y
        self.width = 25
        self.height = 100
        self.image = pygame.image.load('graphic\\sprite\\spr_enemy.png').convert()
        self.rect = self.image.get_rect()
    def update(self):
        window.blit(self.image,(self.x,self.y))

#Player
class Player(pygame.sprite.Sprite):
    def __init__(self,x,y):
        pygame.sprite.Sprite.__init__(self)
        self.x = x
        self.y = y
        self.width = 100
        self.height = 25
        self.image = pygame.image.load('graphic\\sprite\\spr_player.png').convert()
        self.rect = self.image.get_rect()
    def update(self):
        window.blit(self.image,(self.x,self.y))

#Cursor
class Cursor(pygame.sprite.Sprite):
    def __init__(self):
        pygame.mouse.set_visible(False)
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('graphic\\cursor\\crosshair.png').convert()
        self.rect = self.image.get_rect()
    def update(self,enemies):
        self.rect.center = pygame.mouse.get_pos()
        if (pygame.sprite.spritecollideany(self,enemies)):
            sys.exit()

#Define sprites
player = Player(500,100)
cursor = Cursor()
cursors.add(cursor)
enemy = Enemy(0,0)

#Gameloop
gameLoop = True
while gameLoop:
    for event in pygame.event.get():
        if (event.type == pygame.QUIT):
            gameLoop = False
        #Keydown
        if (event.type == pygame.KEYDOWN):
            #Space key
            if (event.key == pygame.K_SPACE):
                x = random.randint(0,0)
                y = random.randint(0,668)                
                enemies.add(Enemy(x,y))
            #Escape key
            if (event.key == pygame.K_ESCAPE):
                sys.exit()            

    #Window color
    window.fill(blue)

    #Updating player
    player.update()

    #Updating enemy
    for enemy in enemies:
        enemy.x += moveX
    enemy.update()
    enemies.update()
    enemies.draw(window)

    #Updating cursor
    cursors.update(enemies)
    cursors.draw(window)

    #FPS
    clock.tick(60)

    pygame.display.flip()
pygame.quit()

You would need to change the position of the pygame.sprite.spritecollideany() command from your update function to your while loop, remove the parantheses around the command, and change the command to pygame.sprite.spriteCollide() so it looks like this:

import pygame
import random
import sys
import os
from pygame.locals import *

#Initialize pygame
pygame.init()

#Window properties
window_width = 1366
window_height = 768
window = pygame.display.set_mode((window_width,window_height),pygame.FULLSCREEN)
pygame.display.set_caption("Sniper")

#Clock
clock = pygame.time.Clock()

#Movement
moveX = 1
moveY = 0

#Colors
black = (0,0,0)
white = (255,255,255)
blue = (0,0,64)

#Sprite groups
enemies = pygame.sprite.Group()
cursors = pygame.sprite.Group()

#Enemy
class Enemy(pygame.sprite.Sprite):
    def __init__(self,x,y):
        pygame.sprite.Sprite.__init__(self)
        self.x = x
        self.y = y
        self.width = 25
        self.height = 100
        self.image = pygame.image.load('graphic\\sprite\\spr_enemy.png').convert()
        self.rect = self.image.get_rect()
    def update(self):
        window.blit(self.image,(self.x,self.y))

#Player
class Player(pygame.sprite.Sprite):
    def __init__(self,x,y):
        pygame.sprite.Sprite.__init__(self)
        self.x = x
        self.y = y
        self.width = 100
        self.height = 25
        self.image = pygame.image.load('graphic\\sprite\\spr_player.png').convert()
        self.rect = self.image.get_rect()
    def update(self):
        window.blit(self.image,(self.x,self.y))

#Cursor
class Cursor(pygame.sprite.Sprite):
    def __init__(self):
        pygame.mouse.set_visible(False)
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('graphic\\cursor\\crosshair.png').convert()
        self.rect = self.image.get_rect()
    def update(self):
        self.rect.center = pygame.mouse.get_pos()

#Define sprites
player = Player(500,100)
cursor = Cursor()
cursors.add(cursor)
enemy = Enemy(0,0)

#Gameloop
gameLoop = True
while 1:
    for event in pygame.event.get():
        if (event.type == pygame.QUIT):
            gameLoop = False
        #Keydown
        if (event.type == pygame.KEYDOWN):
            #Space key
            if (event.key == pygame.K_SPACE):
                x = random.randint(0,0)
                y = random.randint(0,668)
                enemies.add(Enemy(x,y))
            #Escape key
            if (event.key == pygame.K_ESCAPE):
                sys.exit()

        if pygame.sprite.spritecollide(cursor, enemies, True):
            sys.exit()

    #Window color
    window.fill(blue)

    #Updating player
    player.update()

    #Updating enemy
    for enemy in enemies:
        enemy.x += moveX
    enemy.update()
    enemies.update()
    enemies.draw(window)

    #Updating cursor
    cursors.update(enemies)
    cursors.draw(window)

    #FPS
    clock.tick(60)

    pygame.display.flip()
pygame.quit()

The explanation for these changes are that by moving the pygame.sprite.spritecollide() command into the while loop, you can make contact with any enemy in any position and still activate your sys.exit(). The pygame.sprite.spritecollide() needs three things in its parantheses: the variable you put your function in ( cursor = Cursor() ), the sprite group you are colliding with ( enemies = pygame.sprite.Group() ), and the True/False in the third (since your statement is that as long gameloop = True the game still runs, so True will be put in the third part.) This should fix your problem and if not then I hope you find an answer soon! Also, I recommend using while 1: or while True: !

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