版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39687901/article/details/88422493
1.什么是精灵图
精灵图:将多张图片合成到一张图片上
精灵图最重要的优点就是加载速度快,为啥呢?如果一个动画有20帧,不用精灵图的话,就得读取20个文件。但如果把20张图片都集成到一张图片上,那么只需要读取一个图片就行了。
那么看看我们需要用的精灵图:
这张图片是8个角色的4方向行走图,这8个角色就是以后玩家注册帐号时可选的角色啦。
2.创建游戏窗口
使用精灵图前,肯定先得把窗口创建出来吧。我们使用面向对象的思想把大家之前都写烂的pygame创建一个空窗口的代码封装一遍。
import sys
import pygame
class Game:
def __init__(self, title, width, height, fps=60):
"""
:param title: 游戏窗口的标题
:param width: 游戏窗口的宽度
:param height: 游戏窗口的高度
:param fps: 游戏每秒刷新次数
"""
self.title = title
self.width = width
self.height = height
self.screen_surf = None
self.fps = fps
self.__init_pygame()
self.__init_game()
self.update()
def __init_pygame(self):
pygame.init()
pygame.display.set_caption(self.title)
self.screen_surf = pygame.display.set_mode([self.width, self.height])
self.clock = pygame.time.Clock()
def __init_game(self):
self.hero = pygame.image.load('./img/character/hero.png').convert_alpha()
self.map_bottom = pygame.image.load('./img/map/0.png').convert_alpha()
self.map_top = pygame.image.load('./img/map/0_top.png').convert_alpha()
def update(self):
while True:
self.clock.tick(self.fps)
# TODO:逻辑更新
self.event_handler()
# TODO:画面更新
def event_handler(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if __name__ == '__main__':
Game("间隙之间", 640, 480)
运行上面代码之后,就能看到我们的窗口啦。
3.封装一个使用精灵图的类
我们的精灵图集成了角色行走的每个动作的图片,那么我们应该如何去绘制精灵图的某一个图块呢?我们给update方法增加两行代码:
def update(self):
while True:
self.clock.tick(self.fps)
# TODO:逻辑更新
self.event_handler()
# TODO:画面更新
self.screen_surf.blit(self.hero, (100, 100))
pygame.display.update()
可以看到,我们把整个精灵图都绘制出来了,位置在窗口的(100,100)。
但是我现在只想绘制图片的某个区域,那么代码可以这样写:
def update(self):
while True:
self.clock.tick(self.fps)
# TODO:逻辑更新
self.event_handler()
# TODO:画面更新
self.screen_surf.blit(self.hero, (100, 100), (0, 0, 96, 128))
self.screen_surf.blit(self.hero, (300, 100), (96, 128, 96, 128))
pygame.display.update()
我们给blit函数多传了一个参数,这个参数是含有4个元素的元组,第1、2个元素代表要在源图中截取区域的左上角坐标,第3、4个元素代表截取区域的宽高。比如第二句的参数(96,128,96,128)的意思就是:
我们理解了blit的截取区域绘制之后,就可以简单的封装一个类,用于绘制指定的单个图块啦。
我们新建一个core.py文件:
class Sprite:
"""
用于绘制精灵图的工具类
"""
@staticmethod
def draw(dest, source, x, y, cell_x, cell_y, cell_w=32, cell_h=32):
"""
绘制精灵图中,指定x,y的图像
:param dest: surface类型,要绘制到的目标surface
:param source: surface类型,来源surface
:param x: 绘制图像在dest中的坐标
:param y: 绘制图像在dest中的坐标
:param cell_x: 在精灵图中的格子坐标
:param cell_y: 在精灵图中的格子坐标
:param cell_w: 单个精灵的宽度
:param cell_h: 单个精灵的高度
:return:
"""
dest.blit(source, (x, y), (cell_x * cell_w, cell_y * cell_h, cell_w, cell_h))
好,我们来看看怎么用:
def update(self):
while True:
self.clock.tick(self.fps)
# TODO:逻辑更新
self.event_handler()
# TODO:画面更新
Sprite.draw(self.screen_surf, self.hero, 100, 100, 0, 0)
Sprite.draw(self.screen_surf, self.hero, 200, 100, 1, 1)
Sprite.draw(self.screen_surf, self.hero, 300, 100, 2, 2)
pygame.display.update()
这样就实现了只绘制精灵图的指定图块的功能,本章完~