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.