忆童年!用Python实现愤怒的小鸟游戏

 更新时间:2021年6月7日 00:00  点击:1298

开发工具

Python版本:3.6.4
相关模块:
pygame模块;
以及一些python自带的模块。

环境搭建

安装Python并添加到环境变量,pip安装需要的相关模块即可。

原理介绍

这里简单介绍一下游戏的实现原理呗。首先是游戏的开始界面,大概是长这样的,比较简约:

在这里插入图片描述

主要包括两个部分,即游戏的标题和游戏的开始以及退出按钮,这两部分的代码实现如下:

'''按钮类'''
class Button(pygame.sprite.Sprite):
    def __init__(self, screen, x, y, width, height, action=None, color_not_active=(189, 195, 199), color_active=(189, 195, 199)):
        pygame.sprite.Sprite.__init__(self)
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.action = action
        self.screen = screen
        self.color_active = color_active
        self.color_not_active = color_not_active
    '''添加文字'''
    def addtext(self, text, size=20, font='Times New Roman', color=(0, 0, 0)):
        self.font = pygame.font.Font(font, size)
        self.text = self.font.render(text, True, color)
        self.text_pos = self.text.get_rect()
        self.text_pos.center = (self.x + self.width / 2, self.y + self.height / 2)
    '''是否被鼠标选中'''
    def selected(self):
        pos = pygame.mouse.get_pos()
        if (self.x < pos[0] < self.x + self.width) and (self.y < pos[1] < self.y + self.height):
            return True
        return False
    '''画到屏幕上'''
    def draw(self):
        if self.selected():
            pygame.draw.rect(self.screen, self.color_active, (self.x, self.y, self.width, self.height))
        else:
            pygame.draw.rect(self.screen, self.color_not_active, (self.x, self.y, self.width, self.height))
        if hasattr(self, 'text'):
            self.screen.blit(self.text, self.text_pos)


'''文字标签类'''
class Label(pygame.sprite.Sprite):
    def __init__(self, screen, x, y, width, height):
        pygame.sprite.Sprite.__init__(self)
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.screen = screen
    '''添加文字'''
    def addtext(self, text, size=20, font='Times New Roman', color=(0, 0, 0)):
        self.font = pygame.font.Font(font, size)
        self.text = self.font.render(text, True, color)
        self.text_pos = self.text.get_rect()
        self.text_pos.center = (self.x + self.width / 2, self.y + self.height / 2)
    '''画到屏幕上'''
    def draw(self):
        if hasattr(self, 'text'):
            self.screen.blit(self.text, self.text_pos)

实现起来其实都比较简单,按钮类就是多了一个被鼠标选中之后(也就是鼠标的位置落在按钮的区域范围内时)改变颜色以直观地告诉玩家该按钮已经被选中了的功能。

如果玩家点击退出键(QUIT),则退出游戏:

def quitgame():
    pygame.quit()
    sys.exit()

若点击开始游戏按钮,则开始游戏:

def startgame():
    game_levels = GameLevels(cfg, screen)
    game_levels.start()

游戏界面大概长这样:

在这里插入图片描述

玩家获胜的方法就是操作有限数量的小鸟将所有入侵的猪干掉,换句话说就是利用弹弓发射小鸟,让小鸟击中场上的所有猪。若小鸟全部发射完之后场上仍然有猪没有被击中,则玩家失败。判断游戏胜负关系的代码实现起来其实蛮简单的,大概是这样的:

'''游戏状态'''
def status(self, pigs, birds):
    status_codes = {
        'gaming': 0,
        'failure': 1,
        'victory': 2,
    }
    if len(pigs) == 0: return status_codes['victory']
    elif len(birds) == 0: return status_codes['failure']
    else: return status_codes['gaming']

接着,为了实现游戏,我们先定义一下所有我们需要的游戏精灵类。首先,是我们的主角,愤怒的小鸟:

'''小鸟'''
class Bird(pygame.sprite.Sprite):
    def __init__(self, screen, imagepaths, loc_info, velocity=None, color=(255, 255, 255), **kwargs):
        pygame.sprite.Sprite.__init__(self)
        assert len(loc_info) == 3
        assert len(imagepaths) == 1
        # 设置必要的属性常量
        self.color = color
        self.screen = screen
        self.loc_info = list(loc_info)
        self.imagepaths = imagepaths
        self.velocity = VelocityVector() if velocity is None else velocity
        self.type = 'bird'
        self.fly_path = []
        self.is_dead = False
        self.elasticity = 0.8
        self.is_loaded = False
        self.is_selected = False
        self.inverse_friction = 0.99
        self.gravity = VelocityVector(0.2, math.pi)
        # 屏幕大小
        self.screen_size = screen.get_rect().size
        self.screen_size = (self.screen_size[0], self.screen_size[1] - 50)
        # 导入图像
        self.image = pygame.image.load(imagepaths[0])
    '''画到屏幕上'''
    def draw(self):
        if not self.is_loaded:
            for point in self.fly_path:
                pygame.draw.ellipse(self.screen, self.color, (point[0], point[1], 3, 3), 1)
        position = self.loc_info[0] - self.loc_info[2], self.loc_info[1] - self.loc_info[2]
        self.screen.blit(self.image, position)
    '''判断有没有被鼠标选中'''
    def selected(self):
        pos = pygame.mouse.get_pos()
        dx, dy = pos[0] - self.loc_info[0], pos[1] - self.loc_info[1]
        dist = math.hypot(dy, dx)
        if dist < self.loc_info[2]:
            return True
        return False
    '''加载到弹弓上'''
    def load(self, slingshot):
        self.loc_info[0], self.loc_info[1] = slingshot.x, slingshot.y
        self.is_loaded = True
    '''重新设置位置'''
    def reposition(self, slingshot):
        pos = pygame.mouse.get_pos()
        if self.selected:
            self.loc_info[0], self.loc_info[1] = pos[0], pos[1]
            dx, dy = slingshot.x - self.loc_info[0], slingshot.y - self.loc_info[1]
            self.velocity.magnitude = min(int(math.hypot(dx, dy) / 2), 80)
            self.velocity.angle = math.pi / 2 + math.atan2(dy, dx)
    '''显示发射小鸟的路径'''
    def projectpath(self):
        if self.is_loaded:
            path = []
            bird = Bird(self.screen, self.imagepaths, self.loc_info, velocity=self.velocity)
            for i in range(30):
                bird.move()
                if i % 5 == 0: path.append((bird.loc_info[0], bird.loc_info[1]))
            for point in path:
                pygame.draw.ellipse(self.screen, self.color, (point[0], point[1], 2, 2))
    '''移动小鸟'''
    def move(self):
        # 根据重力改变小鸟的速度向量
        self.velocity = VectorAddition(self.velocity, self.gravity)
        self.loc_info[0] += self.velocity.magnitude * math.sin(self.velocity.angle)
        self.loc_info[1] -= self.velocity.magnitude * math.cos(self.velocity.angle)
        self.velocity.magnitude *= self.inverse_friction
        # 宽度超出屏幕
        if self.loc_info[0] > self.screen_size[0] - self.loc_info[2]:
            self.loc_info[0] = 2 * (self.screen_size[0] - self.loc_info[2]) - self.loc_info[0]
            self.velocity.angle *= -1
            self.velocity.magnitude *= self.elasticity
        elif self.loc_info[0] < self.loc_info[2]:
            self.loc_info[0] = 2 * self.loc_info[2] - self.loc_info[0]
            self.velocity.angle *= -1
            self.velocity.magnitude *= self.elasticity
        # 高度超出屏幕
        if self.loc_info[1] > self.screen_size[1] - self.loc_info[2]:
            self.loc_info[1] = 2 * (self.screen_size[1] - self.loc_info[2]) - self.loc_info[1]
            self.velocity.angle = math.pi - self.velocity.angle
            self.velocity.magnitude *= self.elasticity
        elif self.loc_info[1] < self.loc_info[2]:
            self.loc_info[1] = 2 * self.loc_info[2] - self.loc_info[1]
            self.velocity.angle = math.pi - self.velocity.angle
            self.velocity.magnitude *= self.elasticity

实现它主要需要考虑的是小鸟其实存在五种状态:

  • 排队状态,即在左下角等待进入弹弓时的状态,静止不动即可;
  • 就绪状态,即进入弹弓准备被发射的状态,其需要跟着鼠标不断地移动,使得玩家知道自己目前调整小鸟所到的位置被发射出去之后大概会是 什么样的角度和路径;
  • 飞行状态,即被弹弓发射出去之后的状态,需要根据重力和小鸟的初速度来计算其飞行路径并不断地移动;
  • 碰撞状态,即在飞行过程中撞击到其他物体例如小猪和木桩等时,运动状态发生了改变;
  • 静止状态,即小鸟完成飞行状态之后最终静止时的状态。

接着来实现一下小猪:

'''猪'''
class Pig(pygame.sprite.Sprite):
    def __init__(self, screen, imagepaths, loc_info, velocity=None, **kwargs):
        pygame.sprite.Sprite.__init__(self)
        assert len(loc_info) == 3
        assert len(imagepaths) == 3
        # 设置必要的属性常量
        self.screen = screen
        self.loc_info = list(loc_info)
        self.imagepaths = imagepaths
        self.velocity = VelocityVector() if velocity is None else velocity
        self.type = 'pig'
        self.is_dead = False
        self.elasticity = 0.8
        self.switch_freq = 20
        self.animate_count = 0
        self.inverse_friction = 0.99
        self.gravity = VelocityVector(0.2, math.pi)
        # 屏幕大小
        self.screen_size = screen.get_rect().size
        self.screen_size = (self.screen_size[0], self.screen_size[1] - 50)
        # 导入图像
        self.pig_images = []
        for imagepath in imagepaths: self.pig_images.append(pygame.image.load(imagepath))
        # 设置当前图像
        self.image = random.choice(self.pig_images[:2])
    '''画到屏幕上'''
    def draw(self):
        self.animate_count += 1
        if (self.animate_count % self.switch_freq == 0) and (not self.is_dead):
            self.animate_count = 0
            self.image = random.choice(self.pig_images[:2])
        position = self.loc_info[0] - self.loc_info[2], self.loc_info[1] - self.loc_info[2]
        self.screen.blit(self.image, position)
    '''移动猪'''
    def move(self):
        # 根据重力改变猪的速度向量
        self.velocity = VectorAddition(self.velocity, self.gravity)
        self.loc_info[0] += self.velocity.magnitude * math.sin(self.velocity.angle)
        self.loc_info[1] -= self.velocity.magnitude * math.cos(self.velocity.angle)
        self.velocity.magnitude *= self.inverse_friction
        # 宽度超出屏幕
        if self.loc_info[0] > self.screen_size[0] - self.loc_info[2]:
            self.loc_info[0] = 2 * (self.screen_size[0] - self.loc_info[2]) - self.loc_info[0]
            self.velocity.angle *= -1
            self.velocity.magnitude *= self.elasticity
        elif self.loc_info[0] < self.loc_info[2]:
            self.loc_info[0] = 2 * self.loc_info[2] - self.loc_info[0]
            self.velocity.angle *= -1
            self.velocity.magnitude *= self.elasticity
        # 高度超出屏幕
        if self.loc_info[1] > self.screen_size[1] - self.loc_info[2]:
            self.loc_info[1] = 2 * (self.screen_size[1] - self.loc_info[2]) - self.loc_info[1]
            self.velocity.angle = math.pi - self.velocity.angle
            self.velocity.magnitude *= self.elasticity
        elif self.loc_info[1] < self.loc_info[2]:
            self.loc_info[1] = 2 * self.loc_info[2] - self.loc_info[1]
            self.velocity.angle = math.pi - self.velocity.angle
            self.velocity.magnitude *= self.elasticity
    '''猪死掉了'''
    def setdead(self):
        self.is_dead = True
        self.image = self.pig_images[-1]

猪在游戏中主要包括三种状态:

  • 静止状态,即未被击中时静止在某处的状态;
  • 被击中后的运动状态,即被其他物体击中之后根据动量守恒原理也一起运行时的状态;
  • 被击中后的静止状态,即因为被击中而产生运动之后又恢复静止时的状态、

游戏中的木块实现原理与小猪类似:

''地图里的木块'''
class Block(pygame.sprite.Sprite):
    def __init__(self, screen, imagepaths, loc_info, velocity=None, **kwargs):
        pygame.sprite.Sprite.__init__(self)
        assert len(loc_info) == 3
        assert len(imagepaths) == 2
        # 设置必要的属性常量
        self.type = 'block'
        self.screen = screen
        self.loc_info = list(loc_info)
        self.imagepaths = imagepaths
        self.velocity = VelocityVector() if velocity is None else velocity
        self.elasticity = 0.7
        self.is_destroyed = False
        self.inverse_friction = 0.99
        self.gravity = VelocityVector(0.2, math.pi)
        # 导入图像
        self.block_images = []
        for imagepath in imagepaths: self.block_images.append(pygame.transform.scale(pygame.image.load(imagepath), (100, 100)))
        # 屏幕大小
        self.screen_size = screen.get_rect().size
        self.screen_size = (self.screen_size[0], self.screen_size[1] - 50)
        # 设置当前图像
        self.image = self.block_images[0]
        self.rect = self.image.get_rect()
        self.rotate_angle = math.radians(0)
    '''画到屏幕上'''
    def draw(self):
        pygame.transform.rotate(self.image, self.rotate_angle)
        self.screen.blit(self.image, (self.loc_info[0] - self.rect.width // 2, self.loc_info[1]))
    '''设置为损坏状态'''
    def setdestroy(self):
        self.is_destroyed = True
        self.image = self.block_images[1]
    '''移动木块'''
    def move(self):
        # 根据重力改变木块的速度向量
        self.velocity = VectorAddition(self.velocity, self.gravity)
        self.loc_info[0] += self.velocity.magnitude * math.sin(self.velocity.angle)
        self.loc_info[1] -= self.velocity.magnitude * math.cos(self.velocity.angle)
        self.velocity.magnitude *= self.inverse_friction
        # 宽度超出屏幕
        if self.loc_info[0] > self.screen_size[0] - self.rect.width:
            self.loc_info[0] = 2 * (self.screen_size[0] - self.rect.width) - self.loc_info[0]
            self.velocity.angle *= -1
            self.rotate_angle = -self.velocity.angle
            self.velocity.magnitude *= self.elasticity
        elif self.loc_info[0] < self.rect.width:
            self.loc_info[0] = 2 * self.rect.width - self.loc_info[0]
            self.velocity.angle *= -1
            self.rotate_angle = -self.velocity.angle
            self.velocity.magnitude *= self.elasticity
        # 高度超出屏幕
        if self.loc_info[1] > self.screen_size[1] - self.rect.height:
            self.loc_info[1] = 2 * (self.screen_size[1] - self.rect.height) - self.loc_info[1]
            self.velocity.angle = math.pi - self.velocity.angle
            self.rotate_angle = math.pi - self.velocity.angle
            self.velocity.magnitude *= self.elasticity
        elif self.loc_info[1] < self.rect.height:
            self.loc_info[1] = 2 * self.rect.height - self.loc_info[1]
            self.velocity.angle = math.pi - self.velocity.angle
            self.rotate_angle = math.pi - self.velocity.angle
            self.velocity.magnitude *= self.elasticity

最后,我们来实现一下墙和弹弓就可以啦:

'''弹弓'''
class Slingshot(pygame.sprite.Sprite):
    def __init__(self, screen, x, y, width, height, color=(66, 73, 73), line_color=(100, 30, 22), **kwargs):
        pygame.sprite.Sprite.__init__(self)
        self.x = x
        self.y = y
        self.color = color
        self.width = width
        self.height = height
        self.screen = screen
        self.line_color = line_color
        self.type = 'slingshot'
    '''画到屏幕上'''
    def draw(self, bird=None):
        pygame.draw.rect(self.screen, self.color, (self.x, self.y + self.height * 1 / 3, self.width, self.height * 2 / 3))
        if bird is not None and bird.is_loaded:
            pygame.draw.line(self.screen, self.line_color, (self.x, self.y + self.height / 6), (bird.loc_info[0], bird.loc_info[1] + bird.loc_info[2] / 2), 10)
            pygame.draw.line(self.screen, self.line_color, (self.x + self.width, self.y + self.height / 6), (bird.loc_info[0] + bird.loc_info[2], bird.loc_info[1] + bird.loc_info[2] / 2), 10)
        pygame.draw.rect(self.screen, self.color, (self.x - self.width / 4, self.y, self.width / 2, self.height / 3), 5)
        pygame.draw.rect(self.screen, self.color, (self.x + self.width * 3 / 4, self.y, self.width / 2, self.height / 3), 5)


'''墙'''
class Slab(pygame.sprite.Sprite):
    def __init__(self, screen, imagepaths, x, y, width, height, color=(255, 255, 255)):
        pygame.sprite.Sprite.__init__(self)
        self.x = x
        self.y = y
        self.color = color
        self.width = width
        self.height = height
        self.screen = screen
        self.imagepaths = imagepaths
        if self.width > self.height:
            self.image = pygame.image.load(self.imagepaths[0])
        else:
            self.image = pygame.image.load(self.imagepaths[1])
        self.image = pygame.transform.scale(self.image, (self.width, self.height))
        self.type = 'wall'
    '''画到屏幕上'''
    def draw(self):
        self.screen.blit(self.image, (self.x, self.y))

由此,我们完成了所有游戏精灵的定义,可以开始实现游戏的主循环啦,具体的代码实现如下:

'''开始游戏'''
def start(self):
    # 导入所有游戏精灵
    game_sprites = self.loadlevelmap()
    birds, pigs, blocks, walls = game_sprites['birds'], game_sprites['pigs'], game_sprites['blocks'], game_sprites['walls']
    slingshot = Slingshot(self.screen, 200, self.screen_size[1] - 200, 30, 200)
    birds[0].load(slingshot)
    score_label = Label(self.screen, 50, 10, 100, 50)
    score_label.addtext(f'SCORE: {self.score}', 25, self.cfg.FONTPATH['Comic_Kings'], (236, 240, 241))
    birds_remaining_label = Label(self.screen, 120, 50, 100, 50)
    birds_remaining_label.addtext(f"BIRDS REMAINING: {len(birds)}", 25, self.cfg.FONTPATH['Comic_Kings'], (236, 240, 241))
    pigs_remaining_label = Label(self.screen, 110, 90, 100, 50)
    pigs_remaining_label.addtext(f"PIGS REMAINING: {len(pigs)}", 25, self.cfg.FONTPATH['Comic_Kings'], (236, 240, 241))
    carles_label = Label(self.screen, self.screen_size[0] - 270, self.screen_size[1] - 20, 300, 100)
    carles_label.addtext('CARLES', 60, self.cfg.FONTPATH['arfmoochikncheez'], (113, 125, 126))
    # 游戏主循环
    clock = pygame.time.Clock()
    blocks_to_remove, pigs_to_remove = [], []
    while True:
        # --按键检测
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.quitgame()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_q:
                    self.quitgame()
                elif event.key == pygame.K_r:
                    self.start()
                elif event.key == pygame.K_p or event.key == pygame.K_ESCAPE:
                    self.pauseinterface()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if birds[0].selected():
                    birds[0].is_selected = True
            elif event.type == pygame.MOUSEBUTTONUP:
                if birds[0].is_selected:
                    birds[0].is_selected = False
                    birds[0].start_flying = True
        # --背景颜色填充
        color = self.cfg.BACKGROUND_COLOR
        for i in range(3):
            color = (color[0] + 5, color[1] + 5, color[2] + 5)
            pygame.draw.rect(self.screen, color, (0, i * 300, self.screen_size[0], 300))
        pygame.draw.rect(self.screen, (77, 86, 86), (0, self.screen_size[1], self.screen_size[0], 50))
        # --判断游戏是否结束,若没有则导入新的小鸟
        if (not birds[0].is_loaded) and self.still(pigs + birds + blocks):
            birds.pop(0)
            if self.status(pigs, birds) == 2:
                self.score += len(birds) * 100
                self.switchlevelinterface()
            elif self.status(pigs, birds) == 1:
                self.failureinterface()
            birds[0].load(slingshot)
            birds[0].start_flying = False
        # --重置小鸟的位置
        if birds[0].is_selected:
            birds[0].reposition(slingshot)
        if hasattr(birds[0], 'start_flying') and birds[0].start_flying:
            birds[0].is_loaded = False
        # --弹弓
        slingshot.draw(birds[0])
        # --判断猪是否撞上木桩
        for i in range(len(pigs)):
            for j in range(len(blocks)):
                pig_magnitude_1, block_magnitude_1 = pigs[i].velocity.magnitude, blocks[j].velocity.magnitude
                pigs[i], blocks[j], is_collision = self.collision(pigs[i], blocks[j])
                pig_magnitude_2, block_magnitude_2 = pigs[i].velocity.magnitude, blocks[j].velocity.magnitude
                if is_collision:
                    if abs(pig_magnitude_2 - pig_magnitude_2) > 2:
                        blocks_to_remove.append(blocks[j])
                        blocks[j].setdestroy()
                    if abs(block_magnitude_2 - block_magnitude_1) > 2:
                        pigs_to_remove.append(pigs[i])
                        pigs[i].setdead()
        # --判断鸟是否撞上木桩
        for i in range(len(birds)):
            if not (birds[i].is_loaded or birds[i].velocity.magnitude == 0):
                for j in range(len(blocks)):
                    bird_magnitude_1, block_magnitude_1 = birds[i].velocity.magnitude, blocks[j].velocity.magnitude
                    birds[i], blocks[j], is_collision = self.collision(birds[i], blocks[j])
                    bird_magnitude_2, block_magnitude_2 = birds[i].velocity.magnitude, blocks[j].velocity.magnitude
                    if is_collision:
                        if abs(bird_magnitude_1 - bird_magnitude_2) > 2:
                            if blocks[j] not in blocks_to_remove:
                                blocks_to_remove.append(blocks[j])
                                blocks[j].setdestroy()
        # --判断猪是否撞上猪或者猪撞墙
        for i in range(len(pigs)):
            pigs[i].move()
            for j in range(i+1, len(pigs)):
                pig1_magnitude_1, pig2_magnitude_1 = pigs[i].velocity.magnitude, pigs[j].velocity.magnitude
                pigs[i], pigs[j], is_collision = self.collision(pigs[i], pigs[j])
                pig1_magnitude_2, pig2_magnitude_2 = pigs[i].velocity.magnitude, pigs[j].velocity.magnitude
                if abs(pig1_magnitude_1 - pig1_magnitude_2) > 2:
                    if pigs[j] not in pigs_to_remove:
                        pigs_to_remove.append(pigs[j])
                        pigs[j].setdead()
                if abs(pig2_magnitude_1 - pig2_magnitude_2) > 2:
                    if pigs[i] not in pigs_to_remove:
                        pigs_to_remove.append(pigs[i])
                        pigs[i].setdead()
            for wall in walls: pigs[i] = self.collision(pigs[i], wall)[0]
            pigs[i].draw()
        # --判断鸟是否撞到猪或者鸟是否撞到墙
        for i in range(len(birds)):
            if (not birds[i].is_loaded) and (birds[i].velocity.magnitude):
                birds[i].move()
                for j in range(len(pigs)):
                    bird_magnitude_1, pig_magnitude_1 = birds[i].velocity.magnitude, pigs[j].velocity.magnitude
                    birds[i], pigs[j], is_collision = self.collision(birds[i], pigs[j])
                    bird_magnitude_2, pig_magnitude_2 = birds[i].velocity.magnitude, pigs[j].velocity.magnitude
                    if is_collision:
                        if abs(bird_magnitude_2 - bird_magnitude_1) > 2:
                            if pigs[j] not in pigs_to_remove:
                                pigs_to_remove.append(pigs[j])
                                pigs[j].setdead()
            if birds[i].is_loaded: birds[i].projectpath()
            for wall in walls: birds[i] = self.collision(birds[i], wall)[0]
            birds[i].draw()
        # --判断木桩是否撞到了木桩或者木桩撞到墙
        for i in range(len(blocks)):
            for j in range(i+1, len(blocks)):
                block1_magnitude_1, block2_magnitude_1 = blocks[i].velocity.magnitude, blocks[j].velocity.magnitude
                blocks[i], blocks[j], is_collision = self.collision(blocks[i], blocks[j])
                block1_magnitude_2, block2_magnitude_2 = blocks[i].velocity.magnitude, blocks[j].velocity.magnitude
                if is_collision:
                    if abs(block1_magnitude_2 - block1_magnitude_1) > 2:
                        if blocks[j] not in blocks_to_remove:
                            blocks_to_remove.append(blocks[j])
                            blocks[j].setdestroy()
                    if abs(block2_magnitude_2 - block2_magnitude_1) > 2:
                        if blocks[i] not in blocks_to_remove:
                            blocks_to_remove.append(blocks[i])
                            blocks[i].setdestroy()
            blocks[i].move()
            for wall in walls: blocks[i] = self.collision(blocks[i], wall)[0]
            blocks[i].draw()
        # --墙
        for wall in walls: wall.draw()
        # --显示文字
        score_label.addtext(f'SCORE: {self.score}', 25, self.cfg.FONTPATH['Comic_Kings'], (236, 240, 241))
        score_label.draw()
        birds_remaining_label.addtext(f"BIRDS REMAINING: {len(birds)}", 25, self.cfg.FONTPATH['Comic_Kings'], (236, 240, 241))
        birds_remaining_label.draw()
        pigs_remaining_label.addtext(f"PIGS REMAINING: {len(pigs)}", 25, self.cfg.FONTPATH['Comic_Kings'], (236, 240, 241))
        pigs_remaining_label.draw()
        carles_label.draw()
        # --画面刷新
        pygame.display.update()
        clock.tick(self.cfg.FPS)
        # --删除无效的元素
        if self.still(birds + pigs + blocks):
            for pig in pigs_to_remove:
                if pig in pigs:
                    pigs.remove(pig)
                    self.score += 100
            for block in blocks_to_remove:
                if block in blocks:
                    blocks.remove(block)
                    self.score += 50
            pigs_to_remove = []
            blocks_to_remove = []

其实就是一些按键检测和碰撞检测以及一些分数之类的游戏状态实时更新,感觉没啥好讲的,总之,就这么简单就完事啦~

到此这篇关于忆童年!用Python实现愤怒的小鸟游戏的文章就介绍到这了,更多相关Python愤怒的小鸟内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

[!--infotagslink--]

相关文章

  • python opencv 画外接矩形框的完整代码

    这篇文章主要介绍了python-opencv-画外接矩形框的实例代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-04
  • Python astype(np.float)函数使用方法解析

    这篇文章主要介绍了Python astype(np.float)函数使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-08
  • 最炫Python烟花代码全解析

    2022虎年新年即将来临,小编为大家带来了一个利用Python编写的虎年烟花特效,堪称全网最绚烂,文中的示例代码简洁易懂,感兴趣的同学可以动手试一试...2022-02-14
  • python中numpy.empty()函数实例讲解

    在本篇文章里小编给大家分享的是一篇关于python中numpy.empty()函数实例讲解内容,对此有兴趣的朋友们可以学习下。...2021-02-06
  • python-for x in range的用法(注意要点、细节)

    这篇文章主要介绍了python-for x in range的用法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-05-10
  • Python 图片转数组,二进制互转操作

    这篇文章主要介绍了Python 图片转数组,二进制互转操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-09
  • Python中的imread()函数用法说明

    这篇文章主要介绍了Python中的imread()函数用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
  • python实现b站直播自动发送弹幕功能

    这篇文章主要介绍了python如何实现b站直播自动发送弹幕,帮助大家更好的理解和学习使用python,感兴趣的朋友可以了解下...2021-02-20
  • python Matplotlib基础--如何添加文本和标注

    这篇文章主要介绍了python Matplotlib基础--如何添加文本和标注,帮助大家更好的利用Matplotlib绘制图表,感兴趣的朋友可以了解下...2021-01-26
  • 解决python 使用openpyxl读写大文件的坑

    这篇文章主要介绍了解决python 使用openpyxl读写大文件的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-13
  • python 计算方位角实例(根据两点的坐标计算)

    今天小编就为大家分享一篇python 计算方位角实例(根据两点的坐标计算),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-27
  • python实现双色球随机选号

    这篇文章主要为大家详细介绍了python实现双色球随机选号,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-05-02
  • python中使用np.delete()的实例方法

    在本篇文章里小编给大家整理的是一篇关于python中使用np.delete()的实例方法,对此有兴趣的朋友们可以学习参考下。...2021-02-01
  • 使用Python的pencolor函数实现渐变色功能

    这篇文章主要介绍了使用Python的pencolor函数实现渐变色功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-03-09
  • python自动化办公操作PPT的实现

    这篇文章主要介绍了python自动化办公操作PPT的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-05
  • Python getsizeof()和getsize()区分详解

    这篇文章主要介绍了Python getsizeof()和getsize()区分详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-20
  • python实现学生通讯录管理系统

    这篇文章主要为大家详细介绍了python实现学生通讯录管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-25
  • PyTorch一小时掌握之迁移学习篇

    这篇文章主要介绍了PyTorch一小时掌握之迁移学习篇,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-08
  • 解决python 两个时间戳相减出现结果错误的问题

    这篇文章主要介绍了解决python 两个时间戳相减出现结果错误的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-12
  • Python绘制的爱心树与表白代码(完整代码)

    这篇文章主要介绍了Python绘制的爱心树与表白代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-04-06