Reputation: 53
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
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