Sprite已删除,但Hitbox / rect仍为

时间:2017-02-24 19:53:32

标签: pygame

嘿所有我对编码都比较陌生,只有几个月进入我的游戏开发课程,而我正试图把它全部弄清楚,无论如何我正在为我的课程制作一个小型地狱式太空射击游戏。我遇到了解雇我的老板敌人的问题。玩家子弹与精灵碰撞并且精灵被移除但是老板的命中箱仍然完好无损且玩家可以继续射击以获得积分。

      bulletGroup = pygame.sprite.spritecollide(boss, player.bulletGroup, False)
        count = len(bulletGroup) #Check if any colliding
        #Draw enemy
        if count > 0: # Begin Removal from sprite groups
            player.removeBulletGroup(bulletGroup)
            BaseClass.allSprites.remove(boss)
            #boss.kill()
            bossdead == True
            score += 100
子弹组是球员子弹

下面的图片显示屏幕顶部的老板,然后第二个显示精灵在玩家射击后消失,但老板的命中箱仍然存在

https://s15.postimg.org/e3a6hcf7v/boss.png

https://s10.postimg.org/jz8w4lfu1/bossdead.png

抱歉,如果您需要其他代码,请在此处发布新消息 谢谢你的帮助

发布完整的代码,但仍然是编码的新手,但希望它没问题xD 当发布这个代码时,有些没有进入代码格式,所以我不得不调整类和某些定义的缩进但是一旦粘贴到visual studio中都应该都很好,所以在缩进调整后的注释是真正的一些这是从以前的工作中获得的并且没有去除/调整评论。谢谢你的帮助

主py文件

import pygame, sys, random
from Classes import *
from process import *
from process2 import *

############################### FUNCTIONS ##########################

def main():

############################### VARIABLES ##########################
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600

FPS = 30

BLACK = ( 0, 0, 0)
WHITE = ( 255, 255, 255)
GREEN = ( 0, 255, 0)    

score = 0
playerwins = False
playerloses = False
playerdead = False
playerlives = 3
bossdead = False

timer = Timer()
countdown = 30.0
############################## Initalise ###########################

pygame.init()
size = (SCREEN_WIDTH, SCREEN_HEIGHT)
is_done = False
clock = pygame.time.Clock()

############################# GENERATE WINDOW ######################


screen = pygame.display.set_mode(size)
pygame.display.set_caption("YASS!")
player = Player(0, SCREEN_HEIGHT -50, 32, 32, "spaceship2.png", screen)
boss = Boss(285, SCREEN_HEIGHT -580, 32, 32, "boss2.png", screen)
#enemy = Enemy (0, 50, 32, 32, "drone.png" , screen)
yRow = 150
count = 0
enemies = []
for itr in range (0,50):
    x = random.randint(0, (SCREEN_WIDTH-32))
    enemies.append(Enemies(x, yRow, 32, 32, "drone2.png", screen))
    count+=1
    if count % 9 == 0:
        yRow += 32
timer.setStart(pygame.time.get_ticks())
############################ MAIN GAME LOOP ########################

while not is_done:

    ###################### EVENTS ######################

    process(player)
    process2(boss)
    #process3(enemies)


    ##################### LOGIC ########################

    BaseClass.allSprites.update() # CHANGE  2 - Calls update internally
    if len(enemies) == 0 and bossdead == True:
        is_done = True
        playerwins = True

    currTime = countdown - timer.getElapsed() # Format to 3 Dec. Places
    #Only use for Countdowns, since timers START at 0, this would be an unbreakable loop!
    if currTime <= 0.0:
        currTime = 0.0
        playerloses = True 
        is_done = True
    for enemy in enemies:
        # Delete Bullets that hit enemy
        bulletGroup = pygame.sprite.spritecollide(enemy, player.bulletGroup, False)
        count = len(bulletGroup) #Check if any colliding
        #Draw enemy
        if count > 0: # Begin Removal from sprite groups
            player.removeBulletGroup(bulletGroup)
            enemies.remove(enemy)
            BaseClass.allSprites.remove(enemy)
            score += 1

        bulletGroup = pygame.sprite.spritecollide(boss, player.bulletGroup, False)
        count = len(bulletGroup) #Check if any colliding
        #Draw enemy
        if count > 0: # Begin Removal from sprite groups
            player.removeBulletGroup(bulletGroup)
            BaseClass.allSprites.remove(boss)
            #boss.kill()
            bossdead = True
            score += 100

        bulletGroup2 = pygame.sprite.spritecollide(player, enemy.bulletGroup2, False)
        count = len(bulletGroup2) #Check if any colliding
        #Draw enemy
        if count > 0: # Begin Removal from sprite groups
            enemy.removeBulletGroup2(bulletGroup2)
            #player = None
            BaseClass.allSprites.remove(player)
            playerdead = True
            tempX = player.rect.x
            tempY = player.rect.y

            player = Player(tempX, tempY, 32, 32, "boom2.png", screen)
            is_done = True

        bulletGroup3 = pygame.sprite.spritecollide(player, boss.bulletGroup3, False)
        count = len(bulletGroup3) #Check if any colliding
        #Draw enemy
        if count > 0: # Begin Removal from sprite groups
            boss.removeBulletGroup3(bulletGroup3)
            #player = None
            BaseClass.allSprites.remove(player)
            playerdead = True
            tempX = player.rect.x
            tempY = player.rect.y

            player = Player(tempX, tempY, 32, 32, "boom2.png", screen)
            is_done = True

    ##################### DRAWING CODE GOES HERE #########################

    screen.fill(BLACK) # CHANGE 3  Change background to white instead of black


    pygame.draw.rect(screen,BLACK,(0,0,SCREEN_WIDTH,50))
    drawText(screen, "arial", 24 , WHITE, BLACK, 50, 10, "Bullets: " + str(player.bulletClip))
    drawText(screen, "arial", 24 , WHITE, BLACK, 250, 10, "Score: " + str(score))
    drawText(screen, "arial", 24 , WHITE, BLACK, 450, 10, "Time: " + str('%.3f'%currTime))
    BaseClass.allSprites.draw(screen)
    ##################### CLEAR SCREEN AND SET FPS #######################
    if playerwins == True and is_done == True:
        #name = input("Enter Name: ") #Take input to personally congratulate the winner
        drawText(screen, "arial", 28, GREEN, BLACK, SCREEN_WIDTH/2-100, SCREEN_HEIGHT/2, "You Win!")
        drawText(screen, "arial", 28, GREEN, BLACK, SCREEN_WIDTH/2-100, SCREEN_HEIGHT/2+40, "Score: " +str(score))
        drawText(screen, "arial", 28, GREEN, BLACK, SCREEN_WIDTH/2-100, SCREEN_HEIGHT/2+80, "Time Left: " +str(currTime))

    if playerloses == True:
        drawText(screen, "arial", 28, GREEN, BLACK, SCREEN_WIDTH/2-100, SCREEN_HEIGHT/2, "You Lose!")
        drawText(screen, "arial", 28, GREEN, BLACK, SCREEN_WIDTH/2-100, SCREEN_HEIGHT/2+40, "Score: " +str(score))
        drawText(screen, "arial", 28, GREEN, BLACK, SCREEN_WIDTH/2-100, SCREEN_HEIGHT/2+80, "You Ran Out of Time!")

    if playerdead == True:
        drawText(screen, "arial", 28, GREEN, BLACK, SCREEN_WIDTH/2-100, SCREEN_HEIGHT/2, "You Lose!")
        drawText(screen, "arial", 28, GREEN, BLACK, SCREEN_WIDTH/2-100, SCREEN_HEIGHT/2+40, "Score: " +str(score))
        drawText(screen, "arial", 28, GREEN, BLACK, SCREEN_WIDTH/2-100, SCREEN_HEIGHT/2+80, "You Died =(")

    pygame.display.flip()
    clock.tick(FPS)
    #End Game Loop
    #################### QUIT PROGRAM #############################
pygame.time.wait(3000)
pygame.quit() # exits pygame window
sys.exit() # exits cmd line

main()

类py文件

import pygame, sys, random
from process import Timer

class BaseClass(pygame.sprite.Sprite):                  # Calls the Sprite    Class init function

allSprites = pygame.sprite.Group()      # A group (think list) which will contain every sprite in the game

def __init__(self, x, y, width, height, image_string):

    pygame.sprite.Sprite.__init__(self) # Call Parent Constructor Image
    BaseClass.allSprites.add(self)      # Adds the image to the allsprites group

    self.image = pygame.image.load(image_string)

    # Size and placement
    self.rect = self.image.get_rect()
    self.rect.x = x
    self.rect.y = y
    self.width = width
    self.height = height

    # Change 4 - Motion - Added Motion to Base Class
    # Change 5 - Set Default Velocity to 0
    self.velx = 0
    self.vely = 0

    self.allSprites.add(self) # Adds sprite to the allsprites group

class Player(BaseClass): # Inherits from BaseClass

bulletGroup = pygame.sprite.Group()

def __init__(self, x, y, width, height, image_string, screen):
    BaseClass.__init__(self, x, y, width, height, image_string)
    self.bulletClip = 50
    self.screen_ref = screen 
    #self.velx = 3
    #self.vely = 3     
    #self.collideRect = pygame.rect.Rect((0,0) , (-100, 1))
    #self.collideRect.midbottom = self.rect.midbottom      

def checkScreenBounds(self):
    screen_W = self.screen_ref.get_width() - self.width
    screen_H = self.screen_ref.get_height() - self.height
    if self.rect.x < 0:
        self.rect.x = 0
    elif self.rect.x > screen_W-13:
        self.rect.x = screen_W-13
    if self.rect.y < 0:
        self.rect.y = 0
    elif self.rect.y > screen_H-15:
        self.rect.y = screen_H-15

def update(self):
    self.rect.x += self.velx # we only want x movement
    self.rect.y += self.vely
    self.checkScreenBounds()
    sprites = self.bulletGroup.sprites()
    for sprite in sprites:
        if sprite.hit == True:
            self.bulletGroup.remove(sprite)
            BaseClass.remove(sprite)
            self.bulletClip += 1

def fire(self):
    #Set to player postion
    if self.bulletClip > 1:
        bullet = Bullet(self.rect.x,self.rect.y+20, 16, 16, "laserBig.png", self.screen_ref)
        bullet2 = Bullet(self.rect.x+40,self.rect.y+20, 16, 16, "laserBig.png", self.screen_ref)
        bullet.speed = -8 # we want it to move up so -y in screen co-ords
        bullet2.speed = -8
        self.bulletGroup.add(bullet)
        self.bulletGroup.add(bullet2)
        self.bulletClip -= 2

def removeBulletGroup(self, group):
    count = len(group)
    self.bulletGroup.remove(group)
    BaseClass.allSprites.remove(group)
    self.bulletClip += count


class Bullet(BaseClass): # inherits from BaseClass

def __init__(self, x, y, width, height, image_string, screen): # Constructor
    BaseClass.__init__(self, x, y, width, height, image_string)
    self.screen_ref = screen
    self.hit = False
    self.speed = 0
#check on y axis for boundaries
def checkScreenBounds(self):
    screen_H = self.screen_ref.get_height() - self.height
    if self.rect.y < 50 or self.rect.y > screen_H:
        self.hit = True

def update(self):
    self.rect.y += self.speed # we only want Y movement
    self.checkScreenBounds()

class Enemies(BaseClass):

bulletGroup2 = pygame.sprite.Group()

def __init__(self, x, y, width, height, image_string, screen,):
    BaseClass.__init__(self, x, y, width, height, image_string)
    self.bulletClip2 = 2000

    self.screen_ref = screen
    #Abosulute Respawn start if required
    self.startX = x
    self.startY = y
    # Select Speed of 5 to 10 pixels per frame
    self.velx = random.randint(5,10)
    # Select Left or Right
    dir_choice = random.randint(0,1)
    if dir_choice == 0:
        self.velx *= -1
    self.countdown = random.randint(30,40)
    self.timeInc = self.countdown
    self.timer = Timer()
    self.timer.setStart(pygame.time.get_ticks())

def checkScreenBounds(self):
    screen_W = self.screen_ref.get_width() - self.width
    if self.rect.x < 0:
        self.velx *= -1
    elif self.rect.x > screen_W :
        self.velx *= -1

def update(self):
    self.rect.x += self.velx # We only want X movement
    self.checkScreenBounds()
    sprites = self.bulletGroup2.sprites()
    for sprite in sprites:
        if sprite.hit == True:
            self.bulletGroup2.remove(sprite)
            BaseClass.remove(sprite)
            self.bulletClip2 += 1
    currTime = self.countdown - self.timer.getElapsed() # Format to 3 Dec. Places
    if currTime <= 0:
        self.countdown = self.timer.getElapsed() + self.timeInc
        self.fire()

def fire(self):
    #Set to player postion
    if self.bulletClip2 > 1:
        enemybullet = EnemyBullet(self.rect.x,self.rect.y+20, 16, 16, "enemy bullet1.png", self.screen_ref)
        enemybullet.speed = 4 # we want it to move up so -y in screen co-ords
        self.bulletGroup2.add(enemybullet)
        self.bulletClip2 -= 2


def removeBulletGroup2(self, group):
    count = len(group)
    self.bulletGroup2.remove(group)
    BaseClass.allSprites.remove(group)
    self.bulletClip2 += count

class EnemyBullet(BaseClass): # inherits from BaseClass

def __init__(self, x, y, width, height, image_string, screen): # Constructor
    BaseClass.__init__(self, x, y, width, height, image_string)
    self.screen_ref = screen
    self.hit = False
    self.speed = 0
#check on y axis for boundaries
def checkScreenBounds(self):
    screen_H = self.screen_ref.get_height() - self.height
    if self.rect.y < 50 or self.rect.y > screen_H:
        self.hit = True

def update(self):
    self.rect.y += self.speed # we only want Y movement
    self.checkScreenBounds()


class Boss(BaseClass): # Inherits from BaseClass

bulletGroup3 = pygame.sprite.Group()

def __init__(self, x, y, width, height, image_string, screen):
    BaseClass.__init__(self, x, y, width, height, image_string)
    self.bulletClip3 = 25
    self.screen_ref = screen 
    #self.velx = 3
    #self.vely = 3  
    self.velx = random.randint(5,10)
    dir_choice = random.randint(0,1)
    if dir_choice == 0:
        self.velx *= -1
    self.countdown = random.randint(2,3)
    self.timeInc = self.countdown
    self.timer = Timer()
    self.timer.setStart(pygame.time.get_ticks())         

def checkScreenBounds(self):
    screen_W = self.screen_ref.get_width() - self.width
    if self.rect.x < 5:
        self.velx *= -1
    elif self.rect.x > screen_W-45 :
        self.velx *= -1

def update(self):
    self.rect.x += self.velx # we only want x movement
    self.rect.y += self.vely
    self.checkScreenBounds()
    sprites = self.bulletGroup3.sprites()

    for sprite in sprites:
        if sprite.hit == True:
            self.bulletGroup3.remove(sprite)
            BaseClass.remove(sprite)
            self.bulletClip3 += 1
    currTime = self.countdown - self.timer.getElapsed() # Format to 3 Dec. Places
    if currTime <= 0:
        self.countdown = self.timer.getElapsed() + self.timeInc
        self.fire()

def fire(self):
    #Set to player postion
    if self.bulletClip3 > 1:
        bossbullet = BossBullet(self.rect.x+13,self.rect.y+90, 16, 16, "boss bullet2.png", self.screen_ref)
        #bossbullet2 = BossBullet(self.rect.x+110,self.rect.y+120, 16, 16, "boss bullet.png", self.screen_ref)
        bossbullet.speed = 8 # we want it to move up so -y in screen co-ords
       # bossbullet2.speed = 5
        self.bulletGroup3.add(bossbullet)
        #self.bulletGroup3.add(bossbullet2)
        self.bulletClip3 -= 2

def removeBulletGroup3(self, group):
    count = len(group)
    self.bulletGroup3.remove(group)
    BaseClass.allSprites.remove(group)
    self.bulletClip3 += count

class BossBullet(BaseClass): # inherits from BaseClass

def __init__(self, x, y, width, height, image_string, screen): # Constructor
    BaseClass.__init__(self, x, y, width, height, image_string)
    self.screen_ref = screen
    self.hit = False
    self.speed = 0
#check on y axis for boundaries
def checkScreenBounds(self):
    screen_H = self.screen_ref.get_height() - self.height
    if self.rect.y < 50 or self.rect.y > screen_H:
        self.hit = True

def update(self):
    self.rect.y += self.speed # we only want Y movement
    self.checkScreenBounds()

处理py文件

import pygame, sys

def process(player):
# GLOBAL EVENTS LOOP
for event in pygame.event.get():
    if event.type == pygame.QUIT:
        is_done = True
        sys.exit()
# GLOBAL KEY INPUT
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE]:
    player.fire()
if keys[pygame.K_ESCAPE]:
    is_done = True 
    sys.exit()
if keys[pygame.K_d]:
    player.velx = 12
elif keys[pygame.K_a]:
    player.velx = -12
else:
    player.velx = 0
if keys[pygame.K_s]:
    player.vely = 4
elif keys[pygame.K_w]:
    player.vely = -4
else:
    player.vely = 0

def drawText(screen, fontname, size, forecolour, backcolour, x, y, text):
# Display some text
font = pygame.font.SysFont(fontname,size)
text = font.render(text, True, forecolour, backcolour)
textpos = text.get_rect()
textpos.x = x
textpos.y = y
screen.blit(text, textpos)

class Timer():
def __init__(self):
    self.start_ticks = 0

def setStart(self, val):
    self.start_ticks = val

def getElapsed(self):
    seconds = (pygame.time.get_ticks()- self.start_ticks) / 1000
    return seconds

1 个答案:

答案 0 :(得分:0)

您似乎正在使用

删除精灵
BaseClass.allSprites.remove(boss)

但你实际上并没有删除老板。所以它不会在你的&#34;画所有的精灵&#34;功能,但下次它通过游戏循环,它仍然检查与老板的碰撞。您始终可以使用bossdead变量阻止碰撞检测代码:

if not bossdead    
    bulletGroup = pygame.sprite.spritecollide(boss, player.bulletGroup, False)
    count = len(bulletGroup) #Check if any colliding
    #Draw enemy
    if count > 0: # Begin Removal from sprite groups
        player.removeBulletGroup(bulletGroup)
        BaseClass.allSprites.remove(boss)
        #boss.kill()
        bossdead = True
        score += 100