Python pygame-在团队中杀死一个精灵的问题

Python pygame-在团队中杀死一个精灵的问题,python,pygame,Python,Pygame,我正在尝试使用pygame为学校项目创建一个游戏。我想要的障碍(在这种情况下的盒子)的方式得到的球员。玩家可以摧毁盒子,这将导致在相同高度的随机位置产生另一个盒子 我已经将代码分为3个独立的模块,分别是精灵、主代码和设置(游戏变量) 主要内容: import pygame as pg import random from sprites import * from settings import * import os import sys import time class Game

我正在尝试使用pygame为学校项目创建一个游戏。我想要的障碍(在这种情况下的盒子)的方式得到的球员。玩家可以摧毁盒子,这将导致在相同高度的随机位置产生另一个盒子

我已经将代码分为3个独立的模块,分别是精灵、主代码和设置(游戏变量)

主要内容:

import pygame as pg 
import random 
from sprites import *
from settings import * 
import os 
import sys
import time

class Game:
    def __init__(init):#initialising the games properties(window,sound,speed,etc).
        pg.init()
        pg.mixer.init()
        init.clock = pg.time.Clock()
        init.screen = pg.display.set_mode((WIDTH,HEIGHT))
        pg.display.set_caption(TITLE)
        init.clock = pg.time.Clock()
        init.running = True
        init.font_name = pg.font.match_font(FONT_NAME)
        init.data()
    def data(load):
        load.dir = os.path.dirname(__file__)

    def new(new):#starts the game again.
        new.score = 0 
        new.obstacles = pg.sprite.Group()
        new.platforms = pg.sprite.Group()
        new.bullets = pg.sprite.Group()
        new.all_sprites = pg.sprite.Group()
        new.player = Player(new)
        new.all_sprites.add(new.player)
        for plat in PLATFORM_LIST:
            p = Platform(*plat) 
            new.all_sprites.add(p)
            new.platforms.add(p)
        for obs in OBSTACLE_LIST:
            new.obstacle = Obstacle(*obs)
            new.all_sprites.add(new.obstacle)
            new.obstacles.add(new.obstacle)

        new.run()
    def run(run):
        run.playing = True
        while run.playing:
            run.cooldown = 0
            run.clock.tick(FPS)
            run.events()
            run.update()
            run.draw()

    def update(update):
        bullet = Bullet
        #game update.
        update.all_sprites.update()
        #spawning obstacles lower half
        while len(update.obstacles) < 3:
            width = random.randrange(50, 100)
            update.obstacle = Obstacle(random.randrange(0, WIDTH - width),HEIGHT-100,100,50)
            update.obstacles.add(update.obstacle)
            update.all_sprites.add(update.obstacle)
        #spawning obstacles randomly throughout the middle half
        #spawning obstacles randomly throughout the map upper half
        #check if bullet collides with an obstacles.
        collide = pg.sprite.groupcollide(update.bullets,update.obstacles,True,False)
        if collide:

            update.obstacle.obs_health = update.obstacle.obs_health - bullet.damage
            if update.obstacle.obs_health == 0:
                update.obstacle.kill()  

        #check if player hits the sides of an obstacle.
        if update.player.velocity.x >0:#when moving right.
            collide = pg.sprite.spritecollide(update.player,update.obstacles,False)
            if collide:
                if update.player.pos.y >= collide[0].rect.centery+20:#if the player is above the platform.
                    update.player.pos.x = collide[0].rect.left - (PLAYER_WIDTH/2)
                    update.player.velocity.x = 0
                    update.player.acceleration.y = 0

        if update.player.velocity.x <0:#when moving left.
            collide = pg.sprite.spritecollide(update.player,update.obstacles,False)
            if collide:
                if update.player.pos.y >= collide[0].rect.centery:
                    update.player.pos.x = collide[0].rect.right + (PLAYER_WIDTH/2)
                    update.player.velocity.x = 0


        #check if player hits side of platforms            
        if update.player.velocity.x >0 and (update.player.velocity.y < 0):#when moving right.
            collide = pg.sprite.spritecollide(update.player,update.platforms,False)
            if collide:
                if update.player.pos.y < collide[0].rect.centery+50:#if the player is below the obstacle.
                    update.player.pos.x = collide[0].rect.left - (PLAYER_WIDTH/2)
                    update.player.velocity.x = 0

        if update.player.velocity.x <0:#when moving left.
            collide = pg.sprite.spritecollide(update.player,update.obstacles,False)
            if collide:
                if update.player.pos.y > collide[0].rect.centery:
                    update.player.pos.x = collide[0].rect.right + (PLAYER_WIDTH/2)
                    update.player.velocity.x = 0
        #check if player hits a platform while ascending:
        if update.player.velocity.y <0:#only when moving up.
            collide = pg.sprite.spritecollide(update.player,update.platforms,False)
            if collide:
                if update.player.pos.y > collide[0].rect.bottom:
                    update.player.pos.y = collide[0].rect.bottom + (PLAYER_HEIGHT/2) + PLAYER_JUMP 
                    update.player.velocity.y = 0 

        #check if a player hits a platform while falling.
        if update.player.velocity.y >0:#only while falling will this apply.
            collide = pg.sprite.spritecollide(update.player,update.platforms,False)#false allows you to avoid deleting the object you jump into.    
            if collide:
                if update.player.pos.y < collide[0].rect.centery:#if the player is above the center of the platform.
                    update.player.pos.y = collide[0].rect.top +1
                    update.player.velocity.y = 0
            collide = pg.sprite.spritecollide(update.player,update.obstacles,False) 
            if collide:
                if update.player.pos.y < collide[0].rect.centery:
                    update.player.pos.y = collide[0].rect.top +1
                    update.player.velocity.y = 0
    #spawning obstacles randomly throughout the map upper half

    #spawning obstacles randomly throughout the middle half



    def events(events):
        events.cooldown += events.clock.get_time()
        #processes inputs.
        for event in pg.event.get():
            #check for window closing.
            if event.type == pg.QUIT:#if the 'x' button is clicked
                if events.playing:    
                    events.playing = False#stop the game loop.
                events.running = False#stop the main loop.
            if event.type == pg.KEYDOWN:
                if event.key == pg.K_UP:
                    events.player.jump()
                if event.key == pg.K_SPACE:
                        events.player.bullet_list.append(events.player.shoot())
                        #print(len(events.player.bullet_list))
    def draw(draw):
        draw.screen.fill(GREY)# creates a black screen.
        draw.draw_text(str(draw.player.PLAYER_HEALTH),24,BLACK,WIDTH/32,HEIGHT /32)
        draw.all_sprites.draw(draw.screen)#draws the sprites in the group all_sprites.

        #after drawing the screen is flipped.
        pg.display.flip()
    def start_screen(start):#screen displayed when the game is started.
        start.screen.fill(BGCOLOR)
        start.draw_text(TITLE,48,WHITE,WIDTH/2,HEIGHT /4)
        start.draw_text("Arrows to move,UP to jump", 22,WHITE,WIDTH/2,HEIGHT/2)
        start.draw_text("Press a key to play",22,WHITE,WIDTH/2,HEIGHT*3/4)    
        pg.display.flip()
        start.any_key()#temporary key to start system.


    def any_key(wait):
        waiting = True
        while waiting:#a loop is used for the start screen until an action is done.
            wait.clock.tick(FPS)#allows animations to 
            for event in pg.event.get():
                if event.type == pg.QUIT:#if the 'x' button is pressed during the start screen.
                    waiting = False
                    wait.running = False#stops the main loop.
                if event.type == pg.KEYUP:#if any key is released.
                    waiting = False
    def over_screen(over):#displayed when the game ends.
        if not over.running:
            return#skips the over screen when 'x' button is pressed.
        over.screen.fill(BGCOLOR)
        over.draw_text('GAME OVER',48,WHITE,WIDTH/2,HEIGHT /4)
    def draw_text(self, text, size, color, x, y):

        font = pg.font.Font(self.font_name, size)#selects the chosen font.
        text_surface = font.render(text, True, color)#creates the text with anti aliasing and the color chosen.
        text_rect = text_surface.get_rect()
        text_rect.midtop = (x, y)#position of text.
        self.screen.blit(text_surface, text_rect)#renders text on screen.

g = Game()
g.start_screen()
while g.running:#the main loop.
    g.new()
    g.over_screen()
pg.quit()#closes the window.
我遇到的问题是在销毁多个盒子中的一个之后生成一个新的盒子。一个盒子可以通过射击来消耗它的生命而被摧毁

假设我有3个盒子:A、B和C。当我试图摧毁B或C时,盒子A是被摧毁和重生的

我觉得这是一个显而易见的答案

与障碍物有关的代码:

while len(update.obstacles) < 3:
        width = random.randrange(50, 100)
        update.obstacle = Obstacle(random.randrange(0, WIDTH - width),HEIGHT-100,100,50)
        update.obstacles.add(update.obstacle)
        update.all_sprites.add(update.obstacle)
创建类:

class Obstacle(pg.sprite.Sprite):
    def __init__(self,x,y,w,h):
        pg.sprite.Sprite.__init__(self)
        self.image = pg.Surface((w,h))
        self.image.fill(BLUE)
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.obs_health = 100
将其添加到精灵组:

for obs in OBSTACLE_LIST:
            new.obstacle = Obstacle(*obs)
            new.all_sprites.add(new.obstacle)
            new.obstacles.add(new.obstacle)
碰撞:

collide = pg.sprite.groupcollide(update.bullets,update.obstacles,True,False)
        if collide:

            update.obstacle.obs_health = update.obstacle.obs_health - bullet.damage
            if update.obstacle.obs_health == 0:
                update.obstacle.kill()
产生新的障碍:

while len(update.obstacles) < 3:
        width = random.randrange(50, 100)
        update.obstacle = Obstacle(random.randrange(0, WIDTH - width),HEIGHT-100,100,50)
        update.obstacles.add(update.obstacle)
        update.all_sprites.add(update.obstacle)
而len(更新障碍物)<3:
宽度=随机。随机范围(50100)
update.barrier=障碍物(random.randrange(0,宽度-宽度),高度-100100,50)
更新.障碍物.添加(更新.障碍物)
更新。所有精灵。添加(更新。障碍)

首先,对于所有实例方法,如果您使用名称
self
而不是第一个参数使用的所有自定义名称,例如
new
update
,这将对读者有所帮助

重写之后,您的代码将如下所示:

collide=pg.sprite.groupcollide(self.bullets,self.barriends,True,False)
如果发生碰撞:
self.barrier.obs_health=self.barrier.obs_health-bullet.damage
如果self.disabler.obs_health==0:
self.disabler.kill()
现在问问你自己,为什么程序知道碰撞的是
self.barrier
自我障碍是否应该存在?看起来,
self.barriends
只是在创建游戏类时用作临时局部变量,用于将
barriends
添加到
self.barriends

如果是这样,只需使用一个局部变量,如下所示:

障碍物列表中的obs的
:
障碍物=障碍物(*obs)
self.all_精灵添加(障碍)
自我。障碍。添加(障碍)

在这一点上,希望错误消息能够清楚地表明引用
self.barrier
是不起作用的
pg.sprite.groupcollide
返回一个
sprite_dict
,因此您需要从
collide
中提取障碍物,以找出发生碰撞的原因。

@KentShikama感谢您指出这一点

我用字典解决了这个问题

for obstacles, bullets in collide.items():
            obstacles.obs_health = obstacles.obs_health - bullet.damage
            if obstacles.obs_health == 0:
                obstacles.kill() 

也许其他人能帮上忙,但至少我在第一次阅读时没能理解你的问题。也许用特定的名字来识别盒子会有助于解释你的问题,比如:“当盒子A被摧毁时,我想让不同的盒子B在不同的位置繁殖,而不是相同的盒子A繁殖。”@KentShikama感谢你的反馈!再读一遍,我并没有真正澄清这个问题。
for obstacles, bullets in collide.items():
            obstacles.obs_health = obstacles.obs_health - bullet.damage
            if obstacles.obs_health == 0:
                obstacles.kill()