py实现外星人入侵(二次开发)——4.特殊外星人(高得分、大子弹和盾牌外星人)

前言

之前的游戏都是正常的外星人,这次我们添加了不一样的种类:

  • 击中得分*10的高得分外星人
  • 击中获得一个大子弹的外星人,大子弹的宽度更大,并且击中敌人不会消失,不计入总子弹数
  • 获得了一个盾牌的外星人,能抵御一次子弹攻击

当然了,为了提高可玩性,特殊外星人的左右移动速度是正常的1.5倍,下落距离是正常的2倍,并且另外特殊外星人出现的概率较低。

尝试贴图——失败

最开始是准备直接在外星人的图片上贴一个单词上去,因为实在是懒得自己做图片,还需要重新拆出来几个分组,但是在我往上贴图的过程中,却变成了这样:
在这里插入图片描述
直接把之前的图片挡住了。
经过测试,单词的效果和之前的外星人相同,能触发事件,所以结案了:
孩子的外星人图片被单词图片顶掉了
单词部分:

def write(self):
	#设置字号颜色
	self.text_color = (0x49,0xa7,0xda)
	self.font = pygame.font.SysFont(None,48)
	#设置文字
	if self.if_bullet:
		self.msg = "buttle"
	elif self.if_more:
		self.msg = "more"
	#制作文字并做成方框
	self.image =self.font.render(self.msg,True,self.text_color,(0x23,0xd7,0x31))
	self.image_rect = self.image.get_rect()
	#只是实现了暂时的对齐,后面还需要调整
	self.image_rect.centerx = self.rect.centerx
	self.image_rect.centery = self.rect.centery

可以看到我根本没写blit,但是就能显示,最后找到了aliens.draw()方法
aliens是存放了我所有外星人精灵(sprite)的编组(group),这个方法相当于是对每一个对象都调用了一次blit方法,那么就是说明我的alien图片被替换掉了……

无语子。

特殊外星人事件处理——失败

本来想着文字就文字吧,因为网上的文本显示都是这样的,使用render做成一个图片,然后贴上去。
所以我想的是在check_bullet_alien_collisions函数中处理,因为该函数本身就是处理外星人和子弹碰撞的事件。
在这里插入图片描述
然后,运行直接报错,说list对象没有if_more属性,然后我尝试打印了一下collisions:
在这里插入图片描述
完犊子。
这里再提一下pygame.sprite.groupcollide函数:
输入两个精灵的编组,判断元素是否相交,并对相交的一对进行处理,并返回一个字典。
我之前以为字典的内容其实就是相交的精灵对象,然后一打印,居然是这玩意,心态炸了。

定稿

我的思路是这样的,我们已知的冲突函数是没法把删除调的内容找出来,然后判断是哪种外星人,所以我们就干脆对每一种外星人都创建一个编组,缺点就是需要将之前的处理外星人事件函数任务几乎翻了四倍。
对于每一种,我都给出了一个专门的图像,放个图给大家乐一乐:
(不过还是要注意一点,外星人图片的大小是相同的,所以不影响后期的计算行数列数)
在这里插入图片描述
有植物大战僵尸文字版那味了(狗头
在这里插入图片描述
首先是在setting.py中添加了这样的设置:

self.special_speed_factor = 1.5 #特殊外星人的左右移动速度为正常1.5倍
self.special_score_facteor = 10 #特殊外星人得分为十倍

然后我们在alien_invasion.py中创建了一万个编组:
在这里插入图片描述
添加了特殊外星人,就需要记录我们拥有了多少颗大子弹,这里我将记录变量添加到stats中,和得分等数据一起:
在这里插入图片描述
(因为游戏开始大子弹数量也需要清零,所以将其放在方法中,方便以后调用)
因为还需要我们在屏幕上显示我们当前拥有的大子弹数目,所以我选择在显示飞船(声明)个数的下方、和等级齐平的位置显示,这就需要修改我们的记分牌:
学着等级的样子,我添加了更新大子弹个数的函数:

def prep_big_bullet(self):
	"""渲染大子弹的个数,数字形式"""
	self.bullet_img = self.font.render(str(self.stats.big_bullet),True,self.text_color,self.ai_settings.bg_color)
	# 将个数放在飞船下面
	self.bullet_rect = self.bullet_img.get_rect()
	self.bullet_rect.left = self.screen_rect.left
	self.bullet_rect.bottom = self.level_rect.bottom

同时在渲染和初始化函数中进行了添加:
在这里插入图片描述
最后记得在修改了stats.big_bullet之后,调一下prep_big_bullet进行刷新就好了,不然是不会改变的。

上述部分都是边角,或者是可以直接copy魔改的部分,下面的事件处理和外星人类修改才是大头。

外星人类的修改

之前本来想创建子类的,但是后面想了一下,我们只需要创建一个通用外星人,然后放在不同的编组中,就能对应不同的外星人
说干就干。
首先我们添加了三个特殊外星人标识:
在这里插入图片描述
因为不同的外星人对应着不同的图像,所以我们还不能直接加载,我选择创建了一个方法:
(只需要记得给完标识符就调用方法即可,不给标识符就会出错)

    def loading(self):    
        # 加载外星人图像,并设置rect属性
        if self.if_bullet:
            self.image = pygame.image.load('./alien/image/alien_bullet.bmp')
        elif self.if_more:
            self.image = pygame.image.load('./alien/image/alien_more.bmp')
        elif self.if_shield:
            self.image = pygame.image.load('./alien/image/alien_shield.bmp')
        else:
            self.image = pygame.image.load('./alien/image/alien.bmp')

        self.rect = self.image.get_rect()
        
        # 开始每一个外星人都在屏幕的左上角
        self.rect.x = self.rect.width
        self.rect.y = self.rect.height
        # 用来存储准确的位置,用其更新rect.x
        self.x = float(self.rect.x)

随后,在update方法中,添加了对不同种类的外星人有不同的左右移动速度(调用ai_setting)

成果长这样:

import pygame
from pygame.sprite import Sprite

class Alien(Sprite):
    """单个外星人的类"""
    def __init__(self, ai_settings, screen):
        """初始化外星人并设置起始位置"""
        super(Alien, self).__init__()
        self.screen = screen
        self.ai_settings = ai_settings
        
        # 移动方向,1表示向右,-1向左
        self.fleet_direction = 1

        # 特殊外星人
        self.if_bullet = False
        self.if_more = False
        self.if_shield = False

    def loading(self):    
        # 加载外星人图像,并设置rect属性
        if self.if_bullet:
            self.image = pygame.image.load('./alien/image/alien_bullet.bmp')
        elif self.if_more:
            self.image = pygame.image.load('./alien/image/alien_more.bmp')
        elif self.if_shield:
            self.image = pygame.image.load('./alien/image/alien_shield.bmp')
        else:
            self.image = pygame.image.load('./alien/image/alien.bmp')

        self.rect 
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值