www.devhaven.io www.devhaven.io - 4 months ago 19
Python Question

Python Pygame: Error detecting collision between bullet and enemy (Space Invaders)

I'm trying to create a basic Space Invaders game in Python. The part that I'm struggling on is detecting when a bullet fired by the player hits the enemy target. I have a

Sprite class
for both the bullet and enemy that have attributes specifying the bounding rectangle of the sprite, and I have a
intersect method
that checks whether the bullet hit the enemy using the
colliderect
method. Yet somehow the
intersect method
always returns 1 (not sure what that means) no matter whether the bullet actually hit the enemy or not.

from pygame import *
import random
import sys

class Sprite:
'''
A Sprite class that can initialize a sprite based on an image, and display it.

Parameters:
filename -> the path of the image to be used
xpos -> the x position of the sprite
ypos -> the y position of the sprite
'''
def __init__(self, filename, xpos, ypos):
self.xpos = xpos
self.ypos = ypos
self.sprite_image, self.rect = load_image(filename, (0, 0, 0))
self.sprite_image.set_colorkey((0, 0, 0))

def display(self, screen):
'''
Displays the sprite onto the screen.

Parameters:
screen -> the PyGame display to draw onto.
'''
screen.blit(self.sprite_image, (self.xpos, self.ypos))

def intersect(self, sprite_2):
'''
Returns whether a sprite intersects with another sprite.

Parameters:
sprite_2 -> the sprite to compare intersection with

Returns:
Whether the sprite intersects with sprite_2
'''
return self.rect.colliderect(sprite_2.rect)

def load_image(path, colorkey):
'''
Returns an image and its bounding rectangle based on a filename.

Parameters:
path -> the path of the picture
colorkey -> the color defined to be transparent

Returns:
the loaded image
the bounding rectangle of the image
'''
try:
sprite_image = image.load(path)
except error, message:
print("Cannot load image: {0}".format(path))

sprite_image = sprite_image.convert()

if colorkey is not None:
if colorkey is -1:
colorkey = sprite_image.get_at((0, 0))
sprite_image.set_colorkey(colorkey, RLEACCEL)

return sprite_image, sprite_image.get_rect()

def main():
'''
The main function runs the Space Invader game, implementing all the logic, calculation,
and user interaction.
'''
init()
screen = display.set_mode((800, 600))
display.set_caption("Space Invaders")

fighter = Sprite("spaceship.png", 357, 520)

enemies = []
bullets_good = [] # List of all of the bullets fired by the hero / fighter

for i in range(8): # Add the enemies into the enemies list
new_enemy = Sprite("enemy.png", 55 * i + 10, 50)
enemies.append(new_enemy)

while True:
screen.fill((0, 0, 0)) # Continiously refresh the background of the screen

for enemy in enemies: # Draw the enemies onto the screen
enemy.display(screen)

for bullet in bullets_good: # Draw the bullets onto the screen
bullet.ypos -= 10

for enemy in enemies:
if bullet.intersect(enemy) == 0:
print("MISSILE HIT ENEMY")

bullet.display(screen)

for keyevent in event.get(): # Go through key press events
if keyevent.type == QUIT:
quit()
sys.exit()
if keyevent.type == KEYDOWN:
if keyevent.key == K_LEFT:
fighter.xpos -= 5
if keyevent.key == K_RIGHT:
fighter.xpos += 5
if keyevent.key == K_UP:
# Create a new bullet and add it to the list of bullets fired by the hero
bullet = Sprite("bullet.png", fighter.xpos + 34, fighter.ypos - 20)
bullets_good.append(bullet)

fighter.display(screen)
display.update()
pass

main() # Run the game!

Answer

You have to set your sprites rect attributes for each enemy only then you can call the function colliderect.

Here is what i mean:

enemy.rect.top = some y-value
enemy.rect.left = some x-value
enemy.rect.bottom = some-height
enemy.rect.right = some-width