MadCoderErrr
MadCoderErrr

Reputation: 53

My bullet in my pygame game won't delete and just pass through the enemy

I am creating a simple game where you would shoot an enemy/ufo. Whenever I shoot the enemy it would pop/disappear, however the bullet won't (Python didn't give me any traceback error). Also when I tried to use the colliderect, nothing seems happening but when I used the collidepoint, it worked.

By the way, here is the full code:

import pygame, sys, random
from pygame.locals import *
from pygame import mixer

pygame.init()

WINDOWWIDTH  = 800 # Width of the screen
WINDOWHEIGHT = 550 # Height of the screen
FPS          = 20
WHITE        = (255, 255, 255)


class Player(pygame.sprite.Sprite):
    """
    This is the class for the player and the other functions for the program.
    """
    def __init__(self, DISPLAYSURF):
        pygame.sprite.Sprite.__init__(self)
        self.PLAYER      = pygame.image.load('SpaceRocket.png').convert_alpha() #SpaceShip by dawnydawny from Pixabay
        self.XPLAYER     = WINDOWWIDTH / 2
        self.YPLAYER     = WINDOWHEIGHT - 75
        self.FONT        = pygame.font.Font('freesansbold.ttf', 15)
        self.PBOX        = self.PLAYER.get_rect()
        self.PBOX.center = (self.XPLAYER, self.YPLAYER)
        self.DISPLAYSURF = DISPLAYSURF
        self.color       = WHITE
    
    def makePLAYER(self):
        self.DISPLAYSURF.blit(self.PLAYER, self.PBOX)
    
    def spaceMessage(self, message):
        self.message = message
        self.mesg    = self.FONT.render(self.message, True, self.color)
        self.MBOX    = self.mesg.get_rect()
        self.MBOX.x  = (50)
        self.MBOX.y  = (WINDOWHEIGHT - 500)
        self.DISPLAYSURF.blit(self.mesg, self.MBOX )
    
    def showScore(self, score):
        self.score = score
        self.spaceMessage("SCORE: %s" % score)
    
    def terminate(self):
        pygame.quit()
        sys.exit()
    
    
class UFO(pygame.sprite.Sprite):
    """
    This is the class for the UFO.
    """
    def __init__(self, XUFO, YUFO):
        pygame.sprite.Sprite.__init__(self)
        self.XUFO        = XUFO
        self.YUFO        = WINDOWHEIGHT - 570
        self.UFO         = pygame.image.load('SpaceUFO.png').convert_alpha() #Image by Mostafa Elturkey from Pixabay
        self.UBOX        = self.UFO.get_rect()
        self.UBOX.center = (self.XUFO, self.YUFO)
    
    def makeUFO(self, DISPLAYSURF):
        self.DISPLAYSURF = DISPLAYSURF
        self.DISPLAYSURF.blit(self.UFO, [self.XUFO, self.YUFO])
    
    
class Bullet(pygame.sprite.Sprite):
    """
    This is the class for bullets.
    """
    def __init__(self, bulletx, bullety):
        pygame.sprite.Sprite.__init__(self)
        self.bulletx        = bulletx
        self.bullety        = bullety
        self.SpaceBulletIMG = pygame.image.load("SpaceBulletIMG.png").convert_alpha() #Image by Clker-Free-Vector-Images from Pixabay
        self.BBOX           = self.SpaceBulletIMG.get_rect()
        self.BBOX.center    = (self.bulletx, self.bullety)
    
    def makeBullet(self, DISPLAYSURF):
        self.DISPLAYSURF = DISPLAYSURF
        self.DISPLAYSURF.blit(self.SpaceBulletIMG, self.BBOX)
    
SpaceUFO    = []
SpaceBullet = []
def runGame(Player):
    global FPSCLOCK, BACKGROUNDIMG, DISPLAYSURF, SpaceUFO

    DISPLAYSURF   = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
    BACKGROUNDIMG = pygame.image.load('SpaceBackground.jpg') # Image by Free-Photos from Pixabay 
    FPSCLOCK      = pygame.time.Clock()
    Player        = Player(DISPLAYSURF)
    SpaceKill     = 0
    SCORE         = 0
    BulletSound   = mixer.Sound('BulletSound.wav') # From https://www.freesoundeffects.com/
    pygame.display.set_caption('Space Fight by MadCoderErrr')
    mixer.music.load('SpaceSound.mp3') # Music: https://www.bensound.com
    mixer.music.play(-1)

    if SpaceKill > 0:
        SpaceKill += 1
    if SpaceKill > 10:
        SpaceKill = 0

    while True:
        DISPLAYSURF.blit(BACKGROUNDIMG, [0, 0])
    
        for event in pygame.event.get():
            if event.type == QUIT:
                Player.terminate()
            
        if len(SpaceUFO) < 5:
            SpaceUFO.append(UFO(round(random.randrange(0, WINDOWWIDTH - 20.0 ** 2) * 20.0) / 20.0, WINDOWHEIGHT - 570))
            print('making new aliens')
            continue
        
        for ufo in SpaceUFO.copy():
            ufo.makeUFO(DISPLAYSURF)
            ufo.YUFO += FPS / 4
            continue
        
        for ufo in SpaceUFO:
            if ufo.YUFO >= WINDOWHEIGHT:
                SpaceUFO.pop(SpaceUFO.index(ufo))
                print('Alien is gone')
            
        for bullet in SpaceBullet.copy():
            DISPLAYSURF.blit(bullet.SpaceBulletIMG, [bullet.bulletx, bullet.bullety])
            if bullet.bullety > 0:
                bullet.bullety -= FPS
            if bullet.bullety < 0:
                SpaceBullet.pop()
                print('Bullet is now gone!')
            continue
            
        if SpaceBullet:
            for bullet in SpaceBullet.copy():
                for ufo in SpaceUFO.copy():
                    if ufo.UBOX.colliderect(bullet.BBOX):
                        SpaceBullet.pop(SpaceBullet.index(bullet))
                        SpaceUFO.pop(SpaceUFO.index(ufo))
                        print('hit')
                        SCORE += 1
                        break
    

        if SpaceBullet:
            for bullet in SpaceBullet.copy():
                for ufo in SpaceUFO.copy():
                    if ufo.UBOX.collidepoint(bullet.bulletx, bullet.bullety):
                        SpaceBullet.pop(SpaceBullet.index(bullet))
                        SpaceUFO.pop(SpaceUFO.index(ufo))
                        print('hit')
                        SCORE += 1
                        break
                    if ufo.UBOX.collidepoint(bullet.bulletx - 10, bullet.bullety):
                        SpaceBullet.pop(SpaceBullet.index(bullet))
                        SpaceUFO.pop(SpaceUFO.index(ufo))
                        print('hit')
                        SCORE += 1
                        break
                    
        if event.type == KEYDOWN:
            if event.key == K_LEFT and not Player.XPLAYER <= 0:
                Player.XPLAYER -= FPS
            if event.key == K_RIGHT and Player.XPLAYER < WINDOWWIDTH - (FPS * 3):
                Player.XPLAYER += FPS
            if event.key == K_SPACE and SpaceKill < 10:
                if len(SpaceBullet) < 10:
                    SpaceBullet.append(Bullet(Player.XPLAYER, Player.YPLAYER))
                SpaceKill = 1
                BulletSound.play()
            
        Player.showScore(SCORE)
        DISPLAYSURF.blit(Player.PLAYER, [Player.XPLAYER, Player.YPLAYER])
        FPSCLOCK.tick(FPS)
        pygame.display.flip()
        pygame.display.update()
    
    if __name__ == '__main__':
    runGame(Player)

Upvotes: 2

Views: 161

Answers (1)

Rabbid76
Rabbid76

Reputation: 211146

You have to update the attribute UBOX, when the position of the ufo is changed:

def runGame(Player):
    # [...]

    while True:
        # [...]

        for ufo in SpaceUFO.copy():
            ufo.makeUFO(DISPLAYSURF)
            ufo.YUFO += FPS / 4
            ufo.UBOX.center = (ufo.XUFO, ufo.YUFO) # <---- ADD

Use UBOX when you blit the ufo rather then XUFO and YUFO:

class UFO(pygame.sprite.Sprite):
    # [...]

    def makeUFO(self, DISPLAYSURF):
        self.DISPLAYSURF = DISPLAYSURF
        self.DISPLAYSURF.blit(self.UFO, self.UBOX)

Furthermore you don't spawn the bullets correctly, sometimes multiple bullets are generated. You have to handle the event KEYDOW event in the event loop. Actually you handle the event outside the loop:

def runGame(Player):
    # [...]

    while True:
        # [...]

        DISPLAYSURF.blit(BACKGROUNDIMG, [0, 0])
    
        for event in pygame.event.get():
            if event.type == QUIT:
                Player.terminate()
            if event.type == KEYDOWN:
                if event.key == K_LEFT and not Player.XPLAYER <= 0:
                    Player.XPLAYER -= FPS
                if event.key == K_RIGHT and Player.XPLAYER < WINDOWWIDTH - (FPS * 3):
                    Player.XPLAYER += FPS
                if event.key == K_SPACE and SpaceKill < 10:
                    if len(SpaceBullet) < 10:
                        SpaceBullet.append(Bullet(Player.XPLAYER, Player.YPLAYER))
                    SpaceKill = 1
                    BulletSound.play()  

Furthermore the computation of the movement is wrong. You have to compute the way per time. This means you have to divide by FPS. For instance:

FPS          = 60

# [...]

def runGame(Player):
    # [...]

    while True:
        # [...]

        for ufo in SpaceUFO.copy():
            ufo.makeUFO(DISPLAYSURF)

            ufo.YUFO += 60 / FPS # <----
           
            ufo.UBOX.center = (ufo.XUFO, ufo.YUFO)
  
        # [...]

        for bullet in SpaceBullet.copy():
            DISPLAYSURF.blit(bullet.SpaceBulletIMG, [bullet.bulletx, bullet.bullety])
            if bullet.bullety > 0:

                bullet.bullety -= 240 / FPS # <----
  
            # [...]

Generate a UFO at a random position, but skip it if the UFO intersects with any other UFO. The UFO It will automatically be tried to generate the UFO in the next frame. Use pygame.Rect.colliderect for the collision test:

def runGame(Player):
    # [...]

    while True: 
        # [...]

        for i in range(len(SpaceUFO), 5):
            
            x, y = round(random.randrange(0, WINDOWWIDTH - 20.0 ** 2) * 20.0) / 20.0, WINDOWHEIGHT - 570
            new_ufo = UFO(x, y)
            if not any(ufo for ufo in SpaceUFO if ufo.UBOX.colliderect(new_ufo.UBOX)):
                SpaceUFO.append(new_ufo)
                print('making new aliens')

Upvotes: 2

Related Questions