zoukankan      html  css  js  c++  java
  • 2015/11/7用Python写游戏,pygame入门(7):碰撞检测

    我们已经完成了飞机大战的大部分东西,但是游戏还是没有办法正式开玩,因为子弹并不能打掉飞机。只有完成了这一个工作,游戏才算基本成型。

    今天的内容就非常简单了,就是做到这个碰撞检测,以及控制好子弹和飞机的消失。pygame里的sprite模块里有碰撞检测部分,但是,我们这里自己动手实现一个碰撞检测的函数。


    检测碰撞的方法很简单,就是子弹的位置在飞机图片的内部。由于子弹和飞机的速度比较快,所以不需要非常精确地判别。

    我们认为,如果子弹的坐标(b.x, b.y)在飞机的图片范围内,也就是(e.x, e,y)到(e.x + e.width, e.y + e.height)这个矩形范围内就行。(这里需要回忆一下,我们的子弹的坐标是子弹图片的中心,敌机的坐标是它图片左上角的坐标)

    所以,碰撞就是检测:

    e.x < b.x < e.x + e.width

    e.y < b.y < b.y + b.height

    如果子弹确定已经达到了敌机,要做的事就是让子弹重置,也让飞机重置。

    代码实现就是这样一个函数:

    def checkHit(enemy,bullet):
        if enemy.x < bullet.x < enemy.x + enemy.image.get_width() 
           and enemy.y < bullet.y < enemy.y + enemy.image.get_height():
            enemy.active = False
            bullet.active = False
            return True
        else:
            return False

    这个函数可以用来检测碰撞,然后我们在原来的主循环里的代码段更改成这样:

    for b in bullet:
            if b.active:
                b.move(time_passed_second)#移动子弹
                for e in enemy:
                    if e.active:
                        checkHit(e,b)
                screen.blit(b.image, (b.x, b.y))#显示子弹

    然后运行你的代码,你就可以看到。子弹能够打掉飞机了。当然,你们都发现了。这个效果很突兀。之后,我会在上面加上动画显示效果,整个图像会不那么突兀。


    现在子弹能够打掉敌机了,但是敌机没办法碰撞掉自己的飞机,我们可以再写一个敌机和自己飞机的碰撞检测。

    这里的碰撞检测,我们用另外一种方法来检测:

    我们通过两点之间的距离小于一定值以后,就认为是碰撞了。求距离用了两点间距离公式,这里不用复习了吧。

    def checkCrash(enemy):
        plane_x, plane_y = pygame.mouse.get_pos()
        enemy_x, enemy_y = enemy.x, enemy.y
        enemy_x += enemy.image.get_width()/2
        enemy_y += enemy.image.get_height()/2
        distance = sqrt(float(plane_x - enemy_x)**2 + float(plane_y - enemy_y)**2)
        if distance < 75:
            return True
        else:
            return False

    这里用了sqrt()开平方,所以要在前面加一句from math import sqrt

    这种方法,对于连个圆形的对象比较碰撞,相当好用,但是对于我们的飞机形状还是表现稍差,具体用什么方法,大家自己可以考虑。


    现在我们完成的大部分的东西,既可以打飞机又可以被飞机撞毁。然后我们应该加一些内容让它显得更丰富。比如说一个记分的模块,比如说游戏结束后显示结束,选择再来一次的模块。

    这些东西,今天就暂不往下讲了,大家可以自己实现,明天我给大概的框架。

    由于程序已经比较长了,就不发上来了。等差不多写完功能再发吧。

  • 相关阅读:
    【luogu3768】简单的数学题【杜教筛】【欧拉函数】
    【bzoj3589】动态树【树链剖分】【线段树】
    【bzoj4386】[POI2015]Wycieczki【矩阵快速幂】【倍增】
    【bzoj2186】[Sdoi2008]沙拉公主的困惑 【线性筛】【容斥原理】
    【bzoj3884】上帝与集合的正确用法 【欧拉函数】
    【bzoj4417】[Shoi2013]超级跳马 【矩阵快速幂】
    【bzoj3435】【uoj#55】[WC2014]紫荆花之恋 【动态树分治】【平衡树】
    【bzoj3681】Arietta 【网络流】【主席树】【启发式合并】
    【bzoj1532】[POI2005]Kos-Dicing 【网络流】【二分】
    【bzoj1565】[NOI2009]植物大战僵尸 【网络流】【最大权闭合子图】
  • 原文地址:https://www.cnblogs.com/SRL-Southern/p/4945090.html
Copyright © 2011-2022 走看看