pygame网络游戏_3:使用精灵图

版权声明:本文为博主原创文章,未经博主允许不得转载。 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()

这样就实现了只绘制精灵图的指定图块的功能,本章完~

猜你喜欢

转载自blog.csdn.net/qq_39687901/article/details/88422493