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模式相同的操作,进入2模式
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标志位进行判断就可以了。
至此,就完成了对小鸟和管道碰撞的检测并在发生碰撞时进入结束界面。