I just started learning pygame today and am running into some issues with collision. When the ship hits the asteroid most time it will not do anything, but something 19 collisions and a lot of sound effects happen all at once.
from pygame import *
import random as rand
from colors import *
import os
pygame.mixer.pre_init(44100, 16, 2, 4096) #frequency, size, channels, buffersize
pygame.init() #turn all of pygame on.
fps = 60
window_size = window_width, window_height = 800, 600
pygame.mixer.music.load('music.wav')
pygame.mixer.music.play(-1)
explode = pygame.mixer.Sound("explode.wav")
class Player(pygame.sprite.Sprite):
#sprite for player
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("plane.png")
self.rect = self.image.get_rect()
self.setprop()
self.xspeed = 0
def setprop( self ):
self.rect = self.image.get_rect()
self.orgin_x = self.rect.centerx
self.orgin_y = self.rect.centery
def set_position(self, x, y):
self.rect.x = x - self.orgin_x
self.rect.y = y - self.orgin_y
def update(self):
self.xspeed = 0
keystate = pygame.key.get_pressed()
if keystate[pygame.K_LEFT]:
self.xspeed = -8
if keystate[pygame.K_RIGHT]:
self.xspeed = 8
self.rect.x += self.xspeed
if self.rect.right > window_width:
self.rect.right = window_width
if self.rect.left < 0:
self.rect.left = 0
class Mob(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("boulder.png")
#self.image.fill(red)
self.rect = self.image.get_rect()
self.rect.x = rand.randrange(window_width - self.rect.width)
self.rect.y = rand.randrange( -100, -40 )
self.speed = rand.randrange(6, 8)
self.sound = pygame.mixer.Sound("swoosh.wav")
def play_sound(self):
self.sound.play()
def update(self):
self.rect.y += self.speed
if self.rect.top > window_height + 10:
self.rect.x = rand.randrange(window_width - self.rect.width)
self.rect.y = rand.randrange( -100, -40 )
self.speed = rand.randrange(6, 8)
sprites = pygame.sprite.Group()
mobs = pygame.sprite.Group()
player = Player()
sprites.add(player)
for i in range(12):
m = Mob()
mobs.add(m)
player.set_position( window_width/2, window_height/2 +215 )
pygame.init()
pygame.mixer.init()
window = pygame.display.set_mode( window_size, pygame.RESIZABLE )
pygame.display.set_caption('Dodge the Boulders!')
clock = pygame.time.Clock()
explode = pygame.mixer.Sound("explode.wav")
running = True
while ( running ):
for event in pygame.event.get():
if( event.type == pygame.QUIT ):
running = False
if ( pygame.sprite.collide_rect(m, player) ):
explode.play()
print('collide')
clock.tick( fps )
window.fill(black)
sprites.update()
sprites.draw(window)
mobs.update()
mobs.draw(window)
pygame.display.update()
pygame.display.quit()
pygame.quit()
Here is the part I'm using for collision (in my game loop)
if ( pygame.sprite.collide_rect(m, player) ):
explode.play()
print('collide')
I've use this method of collision in other files and it seemed to have worked, I'm not sure what the issue is here. The only thing I could think of is that I'm not updating it somewhere but I couldn't find anything. I don't want anything else to happen other than playing a sound (and print collision)
Your game loop sees a collision -> plays the sound . The loop is fast .
Understand the problem?
You can try making a global variable and set it to True
when collision happened to avoid multiple sounds.
Example:
crash = False // at global scope
if (pygame.sprite.collide_rect(m, player) and not crash):
explode.play()
print('collide')
crash = True
Just make sure to reset it to False
when needed if your game continues after crash.
Figured it out a bit ago but decided to post here.
so this
hits = pygame.sprite.spritecollide(player, mobs, False)
if hits:
running = False
will take a sprite first, and then a group. (boolean is dokill). It basically can only test in this way.
This however can test group against group:
hits = pygame.sprite.groupcollide(mobs, bullets, True, True)
if hits:
pygame.mixer.Sound.play(zap)
You could just use spritecollide
and kill the collided mob. Then play the sound and add a new mob for every collided mob.
# A list of mobs that have collided with the player.
# Set dokill to True to remove the collided sprites.
collided_mobs = pygame.sprite.spritecollide(player, mobs, True)
# Do something for every collided mob.
for mob_sprite in collided_mobs:
sound.play()
mobs.add(Mob()) # Add a new mob to replace the collided.
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.