我的 pygame 游戏中的子弹不会删除,只会穿过敌人
My bullet in my pygame game won't delete and just pass through the enemy
我正在创建一个简单的游戏,您可以在其中射击 enemy/ufo。每当我射击敌人时它都会 pop/disappear,但是子弹不会(Python 没有给我任何回溯错误)。另外,当我尝试使用碰撞点时,似乎什么也没有发生,但是当我使用碰撞点时,它起作用了。
顺便说一下,这里是完整的代码:
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)
当 ufo 的位置发生变化时,您必须更新属性 UBOX
:
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
当你 blit
ufo 而不是 XUFO
和 YUFO
:
时使用 UBOX
class UFO(pygame.sprite.Sprite):
# [...]
def makeUFO(self, DISPLAYSURF):
self.DISPLAYSURF = DISPLAYSURF
self.DISPLAYSURF.blit(self.UFO, self.UBOX)
此外,您没有正确生成子弹,有时会生成多颗子弹。您必须在事件循环中处理事件 KEYDOW
事件。实际上你在循环外处理事件:
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()
而且运动的计算是错误的。你必须计算每次的方式。这意味着您必须除以 FPS
。例如:
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 # <----
# [...]
在随机位置生成一个不明飞行物,但如果不明飞行物与任何其他不明飞行物相交则跳过它。 UFO 下一帧会自动尝试生成UFO。使用pygame.Rect.colliderect
进行碰撞测试:
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')
我正在创建一个简单的游戏,您可以在其中射击 enemy/ufo。每当我射击敌人时它都会 pop/disappear,但是子弹不会(Python 没有给我任何回溯错误)。另外,当我尝试使用碰撞点时,似乎什么也没有发生,但是当我使用碰撞点时,它起作用了。
顺便说一下,这里是完整的代码:
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)
当 ufo 的位置发生变化时,您必须更新属性 UBOX
:
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
当你 blit
ufo 而不是 XUFO
和 YUFO
:
UBOX
class UFO(pygame.sprite.Sprite):
# [...]
def makeUFO(self, DISPLAYSURF):
self.DISPLAYSURF = DISPLAYSURF
self.DISPLAYSURF.blit(self.UFO, self.UBOX)
此外,您没有正确生成子弹,有时会生成多颗子弹。您必须在事件循环中处理事件 KEYDOW
事件。实际上你在循环外处理事件:
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()
而且运动的计算是错误的。你必须计算每次的方式。这意味着您必须除以 FPS
。例如:
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 # <----
# [...]
在随机位置生成一个不明飞行物,但如果不明飞行物与任何其他不明飞行物相交则跳过它。 UFO 下一帧会自动尝试生成UFO。使用pygame.Rect.colliderect
进行碰撞测试:
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')