首页 文章

Sprite已删除,但Hitbox / rect仍然存在

提问于
浏览
0

嘿所有我都是比较新的编码,只有几个月的时间进入我的游戏开发课程,而我正试图把它全部弄清楚,不管怎么说我正在为我的课程制作一个小子弹地狱式太空射击游戏而且我是在解决我的老板敌人问题上 . 玩家子弹与精灵碰撞并且精灵被移除但是老板的命中箱仍然保持完好并且玩家可以继续射击以获得积分 .

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

    看来你正在删除精灵

    BaseClass.allSprites.remove(boss)
    

    但你实际上并没有删除老板 . 因此它不会在你的“绘制所有精灵”功能中绘制它,但是下一次它通过游戏循环时,它仍在检查与老板的碰撞 . 您始终可以使用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
    

相关问题