Python编写微信打飞机小游戏(九)

Python编写Wechat手淫小游戏(九)

  在头里的博文中大家为玩乐增多了随分数累计的难度依次增加机制,那就带来二个标题:当达到前边的难度等级后,敌方飞机漫天掩地而来,笔者方小飞机根本应付不回复,因而在这里篇博文中我们为笔者方飞机付与秘招——随机补给全屏炸弹和最好子弹。

  首先来简单描述那三个秘招,全屏炸弹是指在打闹进度中,当客户按下空格键时,就接触意气风发枚全屏炸弹(假使当前部分话),那时候显示屏上的装有敌机顿时销毁。一级子弹是指游戏的使用者在选拔到钦赐补给包之后,小编方飞机可以叁次发射两发子弹,攻击力加倍。ok,早先专门的工作。

  1、定义supply模块

  定义叁个名称为supply.py的模块用以保存一级军械的有关属性,包括全屏炸弹补给类和一流子弹补给类。对于全屏炸弹补给类,这里先付给完整代码:

# ====================定义超级炸弹补给包====================
class BombSupply(pygame.sprite.Sprite):
    def __init__(self, bg_size):
        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.image.load(image/ufo2.png)
        self.rect = self.image.get_rect()
        self.width, self.height = bg_size[0], bg_size[1]
        self.rect.left, self.rect.bottom = randint(0, self.width - self.rect.width), -100
        self.speed = 5
        self.active = False
        self.mask = pygame.mask.from_surface(self.image)

    def move(self):
        if self.rect.top < self.height:
            self.rect.top += self.speed
        else:
            self.active = False

    def reset(self):
        self.active = True
        self.rect.left, self.rect.bottom = randint(0, self.width - self.rect.width), -100

  可以预知BombSupply类布局与事前敌方飞机的类组织非常相通,其实补给包本身就和敌机械和工具备雷同的性子:随飞机地方置起始化,以一定速度向下活动,必要开展掩膜碰撞检查测验(只可是碰撞之后不会招致小编方敌机械损坏毁)等等。相似的,一级子弹补给类的代码如下,两个在布局上完全近似,不再赘言。

# ====================定义超级子弹补给包====================
class BulletSupply(pygame.sprite.Sprite):
    def __init__(self, bg_size):
        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.image.load(image/ufo1.png)
        self.rect = self.image.get_rect()
        self.width, self.height = bg_size[0], bg_size[1]
        self.rect.left, self.rect.bottom = randint(0, self.width - self.rect.width), -100
        self.speed = 5
        self.active = False
        self.mask = pygame.mask.from_surface(self.image)

    def move(self):
        if self.rect.top < self.height:
            self.rect.top += self.speed
        else:
            self.active = False

    def reset(self):
        self.active = True
        self.rect.left, self.rect.bottom = randint(0, self.width - self.rect.width), -100

  2、实例化一级炸弹

  值得注意的一些是,在娱乐发轫是自带3个全屏炸弹的,由此大家先不运营补给发放机制,先把那三发一级炸弹使用好。

  首先在娱乐运营时要求将全屏炸弹的Logo和多余数量显示在画面左下角的职位,由于炸弹数量是可变的(笔者方飞机大概吃到补给包),由此在main函数中初叶化一个全局变量用来保存当前全屏炸弹的数额:

bomb_num = 3  # 初始为三个炸弹

  然后加载全屏炸弹的小Logo并获得其地点属性,注意早先supply.py模块中加载的图样是补给包的Logo(带小降落伞的),实际不是全屏炸弹的Logo:

    bomb_image = pygame.image.load(image/bomb.png)  # 加载全屏炸弹图标
    bomb_rect = bomb_image.get_rect()
    bomb_front = score_font

  注意既然接下去既然要求展现字符(全屏炸弹数量),大家就一向选用从前创设好的用来打字与印刷分数的字体对象就可以(详见上篇博文)。接下来的劳作正是在main()函数的while循环准将图片以至炸弹数量实时的绘图到显示器上:

            # ====================绘制全屏炸弹数量和剩余生命数量====================
            bomb_text = bomb_front.render(× %d % bomb_num, True, color_black)
            bomb_text_rect = bomb_text.get_rect()
            screen.blit(bomb_image, (10, height - 10 - bomb_rect.height))
            screen.blit(bomb_text, (20 + bomb_rect.width, height - 10 - bomb_text_rect.height))

  注意这里由于供给炸弹Logo的乘号以致炸弹数量并列排在一条线彰显,由此需求得到图片与字体的尺寸,至于什么布置,相信大家稍加推敲就会明了的。此时运作程序,显示器左下角平时展现Logo。

  3、触发全屏炸弹

  既然已经把全屏炸弹展现出来了,仅仅放在这里震慑是相当不足的,每当顾客按下二次空格键,就接触少年老成枚全屏炸弹,显示器上独具敌机立时损毁。当然,我们首先供给了然客商哪一天按下了空格键:

        # ====================检测用户的退出及暂停操作====================
        for event in pygame.event.get():  # 响应用户的偶然操作
            if event.type == QUIT:  
                # 如果用户按下屏幕上的关闭按钮,触发QUIT事件,程序退出elif event.type == KEYDOWN:
                if event.key == K_SPACE:  # 如果检测到用户按下空格键
                    if bomb_num:  # 如果炸弹数量大于零,则引爆一颗超级炸弹
                        bomb_num -= 1
                        bomb_sound.play()
                        for each in enemies:
                            if each.rect.bottom > 0:  # 屏幕上的所有敌机均销毁
                                each.active = False

  由于空格键的按下归属不时操作,由此接收“pygame.event.get(卡塔尔(قطر‎”的事件响应机制,代码构造轻易,即当检查实验到客户键盘按下同期对应键值为“K_SPACE”时,炸弹数量减风华正茂(如若炸弹数量超过零),播放全屏炸弹音响效果、显示屏上存有敌机械损坏毁,在这也能呈现出当下我们在实例化敌机对象时将敌机统生龙活虎放在了“enemies”这么些Smart组构造中的优势了,操作十三分方便。

  4、开启补给编写制定

  全屏炸弹顺利施放,接下去开启补给编写制定。设定为每10秒发放三遍补充,咱们经过接触时间机制来成功那些功效,将在补给发放定义为二个客户时间,每间距30秒触发叁次,在响合时间的进度中开首化补给包,首先在main()函数中定义事件:

    supply_timer = USEREVENT  # 补给包发放定时器
    pygame.time.set_timer(supply_timer, 10 * 1000)  # 定义每10秒发放一次补给包

  注意Pygame模块中为每种事件经过宏定义的措施定义了三个标号,用以区分种种时间。大家在概念本身的顾客事件的时候也要人工的为其赋值三个事件标号,为了确认保障顾客定义的平地风波标号与系统事件标号不冲突,Pygame特意提供了“USEREVENT”那几个宏,标号在(0,USEREVENT-1)的风浪为系统时间,因而这里大家将定义的客户事件钦点为“USEREVENT”是不会和种类事件发生冲突的。事件定义完之后调用time类中的set_timer()函数设定事件触发的事件间隔,注意这里的时间是以飞秒为单位的,由此需求倍加1000调换来秒。

  当然要想顺遂的打字与印刷补给包,首先须要对其展开实例化(和对手飞机的实例话相同):

    # ====================实例化补给包====================
    bullet_supply = supply.BulletSupply(bg_size)
    bomb_supply = supply.BombSupply(bg_size)

  接下去在whlie()循环之中编写补给停车计时器“supply_timer”的事件响应函数:

        # ====================检测用户的退出及暂停操作====================
        for event in pygame.event.get():  # 响应用户的偶然操作
            if event.type == QUIT:  
                # 如果用户按下屏幕上的关闭按钮,触发QUIT事件,程序退出elif event.type == supply_timer:  # 响应补给发放的事件消息
                if choice([True, False]):
                    bomb_supply.reset()
                else:
                    bullet_supply.reset()

 

  事件响应函数的机要职分是规定当前应该实例化何种补给包,是全屏炸弹补给包仍旧一流子弹补给包,这种选取应该是私自的,由此可以用“choice()”完成自由挑选机制,然后再依据随意结果将相应的补给包举办重新设置操作(reset会将相应的互补对象的active变量激活),进而指点接下去的抵补发放机制。

  5、检查实验顾客是或不是得到补给包

  在通过事件响应函数鲜明当前发给的补给类型之后,接下里就须要检查实验小编方飞机是否通畅拾获了补给包,主旨是经过碰撞检查实验机制来达成,首先判定是或不是收获了全屏炸弹补给包:

            # ====================绘制补给并检测玩家是否获得====================
            if bomb_supply.active:  # 如果是超级炸弹补给包
                bomb_supply.move()
                screen.blit(bomb_supply.image, bomb_supply.rect)
                if pygame.sprite.collide_mask(bomb_supply, me):  # 如果玩家获得超级炸弹补给包
                    get_bomb_sound.play()
                    if bomb_num < 3:
                        bomb_num += 1
                    bomb_supply.active = False

  程序思路很清楚,假使当前全屏炸弹补给包被激活,则打字与印刷其图标并开首自行移动,在移动进程中若与小编方飞机产生了磕碰(碰撞检查测验重返true),则感到游戏的使用者顺遂获得了全屏炸弹补给包,那个时候再判别游戏者剩余全屏炸弹的数量,假使低于四个,则加少年老成,之后再将补给包对象的active变量置为false,关闭补给目的。

  接下去剖断客商是不是收获一级子弹补给包,这里有几许急需专心,正是在获取全屏炸弹之后,小编方飞机将以此发射两发子弹,因而供给设置一个标识位“is_double_bullet”来代表方今的子弹状态,“is_double_bullet
= false”表示最近发射的是普通子弹,“is_double_bullet =
true”表示方今发射的是顶尖子弹,首先在main函数中宣示变量并伊始化:

is_double_bullet = False   # 是否使用超级子弹标志位

  然后早先开展一流子弹补给包的碰撞检查实验:

           if bullet_supply.active:  # 如果是超级子弹补给包
                bullet_supply.move()
                screen.blit(bullet_supply.image, bullet_supply.rect)
                if pygame.sprite.collide_mask(bullet_supply, me):
                    get_bullet_sound.play()
                    is_double_bullet = True
                    bullet_supply.active = False

  既然添加了二种子弹属性,因而有不可缺乏在绘制子弹从前行行生机勃勃把判别了,不过到前不久了却大家日常还一直不定义一流子弹类,以前在定义bullet.py模块的时候已经提到过,Bullet1意味普通子弹,Bullet2表示最好子弹,在此边大家将bullet模块中的Bullet2的类定义代码补上,和Bullet1的结构完全相近:

# ====================定义超级子弹====================
class Bullet2(pygame.sprite.Sprite):
    def __init__(self, position):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(image/bullet2.png)
        self.rect = self.image.get_rect()
        self.rect.left, self.rect.top = position
        self.speed = 14
        self.active = True
        self.mask = pygame.mask.from_surface(self.image)

    def move(self):
        if self.rect.top < 0:
            self.active = False
        else:
            self.rect.top -= self.speed

    def reset(self, position):
        self.rect.left, self.rect.top = position
        self.active = True

  在概念好Bullet2之后,须要在主程序中实例化一级子弹。和事情发生前普通子弹的实例化情势左近(参见以前博文),只是这里在子弹实例话的逐一个人置配置上有一些小技艺,先上代码:

    # ====================生成超级子弹====================
    bullet2 = []
    bullet2_index = 0
    bullet2_num = 10  # 定义子弹实例化个数
    for i in range(bullet2_num//2):
        bullet2.append(bullet.Bullet2((me.rect.centerx - 33, me.rect.centery)))
        bullet2.append(bullet.Bullet2((me.rect.centerx + 30, me.rect.centery)))

  可以看到,这里的一级子弹是成对实例化的(10发子弹,分为5次周而复始),即敌机左侧一发左边一发,这样只要在今日打字与印刷的进度中二次打字与印刷相邻的多个子弹对象,就能够发生“二遍射两发”的成效了,形似的,怎样促成三次射三发、四发,我们应该也都能明白了。

  接下去须求做的正是对原本的枪弹展现程序进行改变,扩大生龙活虎项剖断分支,代码如下:

            if not (delay % 10):  
                # 播放子弹音效if not is_double_bullet:  
                    # 发射普通子弹else:  # 如果当前是超级子弹状态
                    bullets = bullet2
                    bullets[bullet2_index].reset((me.rect.centerx - 33, me.rect.centery))
                    bullets[bullet2_index + 1].reset((me.rect.centerx + 30, me.rect.centery))
                    bullet2_index = (bullet2_index + 2) % bullet2_num

  果如其言,这里在打字与印刷一流子弹的时候贰次激活子弹组中的隔壁两发子弹,即达成左右两侧各发射一发子弹的功效。这里之具有应用bullets那么些个中变量,是为着简化接下去的子弹与敌机的碰撞检查测量检验(不必再分别普通子弹和特等子弹)。至于(me.rect.centerx

  • 33, me.rect.centery)、(me.rect.centerx – 33,
    me.rect.centery)那七个坐标地点也是经验值,适逢其时代表我方飞机的多少个斯特林发动机的职责。

  6、设置一级子弹时间机械漏刻

  运路程序,上边的享有预期功效都例行事项,不过存在三个主题材料,正是大器晚成旦我们得到了一级子弹补给包,则作者方飞机就能够无终止的发射一流子弹,那显著是不创立的,究竟一级兵戈照旧精品军械,一直都能用就不可能显示其高昂了,由此大家加多几个机制,即获取顶级子弹补给包之后,拔尖子弹转态只可以不断一准期期,规准期间之后自动变成普通子弹。

  相似大家因而事件触发机制产生那么些效应,首先在main()函数中定义那么些事件:

    double_bullet_timer = USEREVENT + 1  # 超级子弹持续时间定时器

  在成功收获超级子弹补给包之后,开启这么些电火花计时器:

            if bullet_supply.active:  # 如果是超级子弹补给包
                pass
                if pygame.sprite.collide_mask(bullet_supply, me):
                    pass
                    pygame.time.set_timer(double_bullet_timer, 18 * 1000)

  可以看到这里大家将超级子弹的持续时间设置为18秒。然后编写对应的事件响应函数,在响应进程中关闭一流子弹状态就可以:

        # ====================检测用户的退出及暂停操作====================
        for event in pygame.event.get():  # 响应用户的偶然操作
            if event.type == QUIT:  
                # 如果用户按下屏幕上的关闭按钮,触发QUIT事件,程序退出elif event.type == double_bullet_timer:
                is_double_bullet = False
                pygame.time.set_timer(double_bullet_timer, 0)

  注意这里将时直接触时间设置为零象征关闭了那几个事件,等待下叁回拿走最棒子弹之后再另行展开。明日的博文就到此处,内容有一些多,大家慢慢看吗。

 

在事情发生前的博文中大家为游乐增添了随分数累积的难度依次增加机制,那就带动三个标题:当达到前边的难度等…

发表评论

电子邮件地址不会被公开。 必填项已用*标注

相关文章