【Python】使用Pygame做一个Flappy bird小游戏(四)

时间:2022-07-23
本文章向大家介绍【Python】使用Pygame做一个Flappy bird小游戏(四),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

0. 最终效果

1. 小鸟与管道之间的碰撞检测

最近比较忙,好久没更新这个系列,今天更新一下。上一节添加了游戏管道,整个游戏可以说已经具备了一个雏形,但是缺少小鸟和管道之间的互动,也就是无法判断小鸟是否撞到了管道。今天来实现一下这个功能。

碰撞检测的实现方法大致有两种,一种是利用pygame的sprite类来实现,另一种就是检测两个图像的是否有重合。但在这个游戏的整个制作过程中,我都没有使用sprite类,所以肯定采取第二种方法了。

第二种方法非常易于理解,本质上就是检测两个物体是否重合,如果重合,则判断为碰撞。但是怎么判断两个物体是否重合呢?也非常简单,只需要判断两个图像的坐标关系。

1.1 程序实现

既然已经有了思路,实现这个程序其实并不复杂。

首先我们需要判断小鸟是否正在经过管道区域,这一区域的范围是pipe_x~pipe_x+52;如果小鸟在这一范围中那么我们需要判断小鸟是否正常通过上下管道间隙,也就是判断小鸟是否位于管道之间的间隙中,这一区域的范围是pipe_dy+320~pipe_dy+396。将这一过程写为函数check()。为了进入结束模式,我设置了一个变量end_flag用来作为进入结束界面的标志位.

def check(pipe_dy,pipe_x,base_y,end_flag):	#小鸟的x坐标值恒定,一直是52,小鸟图像的宽度是34
    pipe_dy  = pipe_dy+320
    if (52+34)>pipe_x>0:
        #print("pipe_dy,pipe_x,base_y",pipe_dy,pipe_x,base_y)
        if (pipe_dy+76) > base_y > pipe_dy:
            pass
        else:
            end_flag = 1			#如果发生碰撞,进入2模式(结束游戏)
            #print(end_flag)
    return end_flag

1.2 游戏结束界面

在上面的程序中,如果发生碰撞,则会将结束标志位end_flag设置为1,就会进入一个新的界面,这个界面我称之为结束界面。结束界面基本与开始界面相同,只是在碰撞后,小鸟将直接下坠到绿砖上,且出现gameover的图案。制作起来也很简单。

一样的导入操作。

game_over = 'K:/bird/gameover.png'
over = pygame.image.load(game_over)

添加一个绘制结束游戏的界面。

def end():
    screen.blit(background,(0,0))
    screen.blit(green_base,(base_x,400))
    screen.blit(over,(52,200))

然后需要对之前的更新图像函数做一波修改,主要是修改小鸟的动作,如果不在绿砖上,那么小鸟需要向下飞(dirx = 1),直到到达绿砖上。

def updatexy_end(time_passed_seconds,base_x,base_y,dirx):
    distance_moved = time_passed_seconds * speed
    bird_distance = time_passed_seconds * bird_speed
    base_y = base_y + dirx*bird_distance
    base_x -= distance_moved
    if base_x<-40:
        base_x += 40
    if base_y <380:#base_y-10:
        dirx = 1
    elif base_y >380:
        dirx = 0
    return base_x,base_y,dirx

与之前进入0、1模式相同的操作,进入结束模式

if end_flag==1:
        time_passed = clock.tick()
        time_passed_seconds = time_passed / 1000 
        end()
        count = drawbird(count)
        base_x,base_y,dirx = updatexy_end(time_passed_seconds,base_x,base_y,dirx)

还需要对进入模式0、1的条件进行一下微调,防止同时进入两个模式。

if start_flag == 1 and end_flag==0:#进入游戏界面
elif start_flag == 0 and end_flag==0:#欢迎界面

实现的结束界面如下(小鸟依旧在扇动翅膀):

1.3 在碰撞时进入结束界面

进行完上两步,我们已经完成了小鸟结束界面的准备工作,最后一步就是在发生碰撞时,进入结束界面就可以了。

由于最初初始化了两个管道,所以对应的有两组管道坐标,我们需要在游戏模式下对两组坐标都进行检测。

end_flag = check(pipe_y,pipe_x,base_y,end_flag)
end_flag = check(pipe_y1,pipe_x1,base_y,end_flag)

最后只需要检测结束标志位end_flag的状态来确定是否需要进入结束模式。

至此,就完成了对小鸟和管道碰撞的检测和在发生碰撞时进入结束界面这一功能的实现。

下一节将为本游戏加入计分系统和音乐,最后一节会将本游戏打包为exe格式。