python实现外星人入侵——1.类的介绍上

前言

上一篇博客简单介绍了一下游戏的内容和文件构成,这次我们来看一下每一个类文件的内容。

在此之前我们还是需要先提一下生成屏幕(surface)的问题。
首先,我们使用setting(设置类)中设置好了的长宽数据创建了一个屏幕:

	pygame.init() 
    ai_setting = setting()
    screen = pygame.display.set_mode((ai_setting.screen_width, ai_setting.screen_height))#参数是一个元组,宽度&高度
    pygame.display.set_caption("Alien Invasion") 

第一句话:初始化,相当于检查了一下pygame有什么问题。
然后是创建了一个设置类,因为需要使用里面的参数。(我们马上就会详细提到)
pygame.display.set_mode 方法能够创建一个窗口,其中必要参数为元组,(宽度,长度),还有两个非必要的参数这里就没有使用。
pygame.display.set_caption 方法没什么,就是设置了一个窗口的标题,会显示在新生成窗口的上方。
在这里插入图片描述
这里我找到了一个总结了pygame.display一些方法的博客

其他的类

这部分讲的主要是不能实现一个明确对象但又贯穿整体的类。

听着很玄乎,其实就是游戏的设置属性以及统计信息等数据。

setting
class setting():
    def __init__(self):
        #初始化设置
        self.screen_width = 1200
        self.screen_height = 800
        self.bg_color = (230,230,230)   #灰色
            
        """飞船个数限制"""
        self.ship_limit = 2             #应该是“还”有几条命,所以一共是三次机会

        """子弹设置"""
        self.bullet_width = 3
        self.bullet_height = 15
        self.bullet_color = 60,60,60    #深灰色
        self.bullet_allowed = 3         #限制屏幕上最多能显示的子弹个数
        self.bullet_width_big = 300     #大子弹是测试使用的,后续也可能会加入到游戏,“敬请期待”

        """外星人设置"""
        #下落速度
        self.fleet_drop_speed = 10      
        #移动方向,1表示向右,-1向左
        self.fleet_direction = 1

        """游戏进阶"""
        #随着波数增加,各种速度按倍数提高
        self.speedup_scale = 1.1
        #随着波数增加,外星人的点数也要增加
        self.score_scale = 1.5

        """初始设定"""
        #单独把这部分拿出来可能有一点费解,写成方法方便到时候重置游戏难度
        self.initialize_dynamic_settings()          

    def initialize_dynamic_settings(self):
        #外星人左右移动速度
        self.alien_speed_factor = 1
        #飞船速度
        self.ship_speed_factor = 1.5
        #子弹速度
        self.bullet_speed_factor = 1
        #积分
        self.alien_points = 50

    def increase_sp(self):
        # sp = speed + point
        self.ship_speed_factor *= self.speedup_scale
        self.bullet_speed_factor *= self.speedup_scale
        self.alien_speed_factor *= self.speedup_scale

        self.alien_points = int(self.alien_points*self.score_scale)

设置类,没有传入参数。
在主函数中我们创建的设置类叫做ai_setting

ai_setting = setting()

存储了一些对象的属性,比如:

  1. 外星人的下落速度,移动方向(移动方向是正负还是有一点讲究的,先放着以后会讲)
  2. 子弹的长宽,颜色和屏幕上允许的最多子弹个数(还有一个大子弹,是以后的添加项)
  3. 屏幕的长宽,以及背景颜色(这里我们采取的是灰色)
  4. 左上角的飞船个数(其实也就是你有几条命,这里注意有两个飞船但一共三条命)
  5. 游戏初始设定(为什么采用的是方法,后面提到)
  6. 游戏的进阶,也就是各种速度的提高以及外星人个体得分的提高率

这里面有两个方法。
第一个方法居然是一些变量,同时我们可以看到在__init__中我们也将该方法作为一个属性。
这样我们就能在创建变量的同时调用方法,进行初始化,同时也方便我们在游戏进行一半的时候进行初始化
(比如再来一局)
另一个方法实现的是在升阶的同时将飞船速度、子弹速度和外星人的左右移动速度加快,并且提高了外星人的分数

统计信息类
class GameStats():
    """跟踪游戏的统计信息"""
    def __init__(self,ai_settings):
        self.ai_settings = ai_settings
        self.reset_stats()
        #游戏是否开始
        self.game_active = False
        #游戏最高分
        self.high_score = 0
    def reset_stats(self):
        """初始化在游戏运行期间可能变化的统计信息"""
        self.ships_left = self.ai_settings.ship_limit
        self.score = 0
        self.level = 1

在这里我们对游戏的状态进行控制,通过boolean型判断是否开始游戏。
同时我们还存储了得分、等级、最高分和剩下几条命(需要setting)。
和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

        #加载外星人图像,并设置rect属性
        self.image = pygame.image.load('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)

    def update(self):
        """向右移动外星人"""
        self.x += self.ai_settings.alien_speed_factor * self.ai_settings.fleet_direction
        self.rect.x = self.x

    def check_edge(self):
        """如果碰到边界,返回true"""
        screen_rect = self.screen.get_rect()
        if self.rect.right >= screen_rect.right:
            return True
        elif self.rect.left <= 0:
            return True

对于外星人,我们是采用贴图的方式来实现的,所以我们需要先导入图片,然后在屏幕上找到一个位置来贴图。
在贴图的时候,py是将图片处理成一个矩形:

self.image = pygame.image.load('image/alien.bmp')
self.rect = self.image.get_rect()

这个rect有x、y坐标属性,center、centerx、centery居中属性,以及top、bottom、left、right对齐属性,
另外对于矩形来说,还有width和height。
由于我们的外星人有很多个,所以我们将外星人放置在了屏幕的左上角,后期再进行调整。

self.rect.x = self.rect.width
self.rect.y = self.rect.height

x、y坐标问题
我画一个图就懂了:
在这里插入图片描述

外星人的移动轨迹是左右移动,每当碰到左右边界就相反方向移动,同时向飞船靠近,对于单个飞船,我们给出了两个方法:

  1. 向右移动外星人
  2. 检测外星人是否碰到左右边界

不过随着波数的增加,外星人移动速度会变快(一级快1.1倍),此时我们原来的rect.x(只能存储int型)很明显就不够用了,
这时我们给出了self.x,用他来存储float型的x坐标,最终交给rect.x,实现功能。

另外外星人左右移动的过程中速度暂时是不变的,改变的只有方向,所以我们只需要改变x对速度的加减即可,
这也是当时将方向定义为int型的理由。

很明显外星人相关的事件是有很多的,为什么我只定义了一部分?
个人理解中,类中的方法一定是对于单个对象实现的,比如飞船和外星人的碰撞、外星人被子弹打中,都是一个交互的事件,所以不适合放在外星人类中的;
对于外星人撞到了底端,其实我们也可以使用同样的方法,但是这里选择了另外一个结构。

我记得我说过外星人是有很多个的,但是类一次只能创建一个外星人,所以我们需要另外一个结构保存这些外星人,这里我们采取了pygame自带的精灵类:sprite,精灵模块中有一个Group结构,非常适合一个类创建多个对象的情况。

总结一下

这篇博客主要是对一部分的类进行讲解。
首先是两个不用来生成明确对象的类,设置类和统计数据类;
对于生成实际对象的类,这次只讲了一个alien类,剩下几个类也差不了太多。

python实现外星人入侵——2

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值