前言:
BOSS系列的日志,建议在看了前面的入门知识后再看,没有一定的基础,这些看起来会很累。精灵组的层管理,确实太强大了。
pygame提供了精灵sprite这个类来管理游戏的各个元素。例如子弹、飞机、爆炸效果(一连串动态图片)……等都可以是一个精灵,所有的精灵默认都在同一个层 0 层里。文档里说明:You can set the default layer through kwargs using 'default_layer' and an integer for the layer. The default layer is 0.
为什么要用层这个概念来编写呢?
1.默认方式下,pygame绘制的顺序是精灵添加的顺序,例如先加载背景,再加载飞机,再加载子弹,那么绘制的顺序就是背景、飞机、子弹。如果先加载飞机、子弹,再加载背景,那么你将只能看到背景图。
很多软件里都有层这个概念,例如photoshop。pygame里的层号用数字表示,1、2、3、4……层,也可以是负数。层号越高,优先级越高,例如把背景层设置为 -1,飞机为 1,子弹为 2,那么不管你什么绘图顺序,子弹拥有在场景的顶层,不会被背景遮挡。
2.单个的精灵只能存在单张image,当向用动态的飞机,动态的子弹时,只能编写不是精灵的单独的类或者函数实现。维护起来很麻烦。而用层来管理就很轻松了。
3.既然pygame提供了层管理的这个概念,何不好好用用。
4.cocos2d 的python版里,也专门用了层来管理,好东西值得借鉴。
下面开始构建游戏的基本框架。
用类来写,可读性、维护性比单个程序好很多,所以大致思路如下:
setting.py :游戏设置的基本文件,屏幕的宽度,高度,尺寸,要加载基本模块,要用到的简化定义,简化的层的定义等
main.py :游戏的框架,包括初始,绘制,更新,碰撞检查,事件检查
bullet.py : 基本的子弹的实现,包括飞行位置的计算,起点位置的设置,飞机的速度和角度,还是子弹图片的设置
animation.py:动态图像的实现类
lifebar.py: 动态生命条的显示
bossbullet: BOSS子弹的实现,BOSS的子弹当然与众不同,动态子弹(用animation实现),不同的图像
boss.py:BOSS的实现,动态的图像,多变的飞行方式,多变的子弹动态图像,多变的发射方式,自带生命条。
先来搭框架:
from setting import *
class MainScene(object):
#初始化
def __init__(self):
pygame.mixer.pre_init()
pygame.init()
pygame.mixer.init()
pygame.font.init()
# pygame.mouse.set_visible(False)
self.scene = pygame.display.set_mode((SCENEWIDTH, SCENEHEIGHT), 1, 32)
pygame.display.set_caption("自学飞机大战--精灵版")
#绘制各个元素
def draw(self):
allgroup.draw(self.scene)
def update(self):
allgroup.update()
def collideEvent(self):
pass
#处理键盘和鼠标相应
def handleEvent(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pass
elif event.key == pygame.K_p: # print layer information in console
print("=========================")
print("-----Spritelist---------")
print("------------------------")
print("toplayer:", allgroup.get_top_layer())
print("bottomlayer:", allgroup.get_bottom_layer())
print("layers;", allgroup.layers())
print("=========================")
def runScene(self):
pygame.mixer.music.load('music/bgm.mp3')
pygame.mixer.music.play(-1)
clock = pygame.time.Clock()
while True:
clock.tick(FPS)
self.draw()
self.update()
self.collideEvent()
self.handleEvent()
pygame.display.flip()
if __name__ == "__main__":
play = MainScene()
play.runScene()
else:
print("i was imported by", __name__)
setting.py的代码如下:
import pygame
from sys import exit
import random
vect = pygame.math.Vector2
FPS = 60
#define sprite groups. Do this before creating sprites
textgroup = pygame.sprite.Group()
backgroundgroup = pygame.sprite.Group()
menugroup =pygame.sprite.Group()
bossgroup = pygame.sprite.Group()
bossbulletgroup = pygame.sprite.LayeredUpdates()
bulletgroup = pygame.sprite.Group()
# only the allgroup draws the sprite, so i use LayeredUpdates() instead Group()
# more sophisticated, can draw sprites in layers
allgroup = pygame.sprite.LayeredUpdates()
SCENEWIDTH = 520
SCENEHEIGHT = 850
SCENERECT = pygame.sprite.Rect(0,0,SCENEWIDTH,SCENEHEIGHT)
用allgroup 来管理所有的精灵。用bossbulletgroup 来管理BOSS的子弹。
运行一下,出现一个游戏界面,因为还没加载背景图,目前屏幕黑色。