pygame网络游戏_4_1:人物行走_地图设计

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39687901/article/details/88527698

1.游戏地图的组成

地图在游戏中是非常重要的一部分,几乎所有的游戏都有地图。比如梦幻西游中的长安城、建邺城、大雁塔等等都是游戏地图。

那么在我们的开发中,地图的组成部分有:

1.地图的背景图:一张完整的地图图片

2.地图的前景图:需要把人物遮挡住的地方

我们按照绘图顺序:画地图背景、画玩家、最后再画地图前景,这样就能将玩家遮挡住。

3.行走层数据:一个二维数组,将地图划分成一个个的小格子,记录着这些小格子是否可以行走。

就比如在我们的游戏开发中,将用32*32做为一个格子的大小。

上图是我很久以前做的地图编辑器,将地图划分成一个个小格子就是这个意思,这应该好理解了吧,黄色格子就是不可行走区域。

2.封装地图类

由于地图行走层就是一个二维数组(二维列表),所以我们先封装一个二维列表,方便以后的操作,core.py中增加:


class Array2D:
    """
        说明:
            1.构造方法需要两个参数,即二维数组的宽和高
            2.成员变量w和h是二维数组的宽和高
            3.使用:‘对象[x][y]’可以直接取到相应的值
            4.数组的默认值都是0
    """

    def __init__(self, w, h, default=0):
        self.w = w
        self.h = h
        self.data = []
        self.data = [[default for y in range(h)] for x in range(w)]

    def show_array2d(self):
        for y in range(self.h):
            for x in range(self.w):
                print(self.data[x][y], end=' ')
            print("")

    def __getitem__(self, item):
        return self.data[item]

创建Array2D对象就是创建一个宽和高为w、h的二维数组,其中show_array2d是在控制台打印二维数组的内容。

因为我们实现了__getitem__方法,所以可以直接用中括号对Array2D对象进行取值,比如

arr2d=Array2D(3,5)

arr2d[2][4]=666

接下来就是编写地图类了,上面我们已经分析过了,地图包括:背景图、前景图、行走数据。

那么构造一个地图对象就需要相应的图片surface和行走数据,core.py中增加:

class GameMap(Array2D):
    """
    游戏地图类
    """

    def __init__(self, bottom, top, x, y):
        # 将地图划分成w*h个小格子,每个格子32*32像素
        w = int(bottom.get_width() / 32) + 1
        h = int(top.get_height() / 32) + 1
        super().__init__(w, h)
        self.bottom = bottom
        self.top = top
        self.x = x
        self.y = y

    def draw_bottom(self, screen_surf):
        screen_surf.blit(self.bottom, (self.x, self.y))

    def draw_top(self, screen_surf):
        screen_surf.blit(self.top, (self.x, self.y))

    def load_walk_file(self, path):
        """
        读取可行走区域文件
        """
        with open(path, 'r') as file:
            for x in range(self.w):
                for y in range(self.h):
                    v = int(file.readline())
                    self[x][y] = v
        self.show_array2d()

GameMap继承自Array2D,因为地图本身就是一个二维数组嘛。

构造方法里有四个参数,bottom和top是相应图片的surface,x,y是地图的绘图坐标。

draw_bottom和draw_top是绘制地图背景和地图前景的方法。

load_walk_file是加载地图行走区域的方法,用双for循环读取文件是因为当初写文件的时候,也是这样写入的,由于继承了Array2D,所以可以直接用self[x][y]。最后在控制台打印一下读取的地图二维数组。

 

3.看看效果

既然封装好了地图类,那我们简单使用一下,看看效果咋样:

在main.py的Game类中,修改一下代码:

    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()
        self.game_map = GameMap(self.map_bottom, self.map_top, 0, 0)
        self.game_map.load_walk_file('./img/map/0.map')

增加了一个game_map属性,也就是游戏地图对象。

再修改一下绘图的代码,看看效果:

    def update(self):
        while True:
            self.clock.tick(self.fps)
            # TODO:逻辑更新
            self.event_handler()
            # TODO:画面更新
            self.game_map.draw_bottom(self.screen_surf)
            Sprite.draw(self.screen_surf, self.hero, 100, 100, 0, 0)
            Sprite.draw(self.screen_surf, self.hero, 210, 120, 1, 1)
            Sprite.draw(self.screen_surf, self.hero, 300, 100, 2, 2)
            pygame.display.update()

我故意改了一下第二个精灵的位置,它竟然跑到房顶去了。

不过,别担心,是因为没有绘制前景图将角色挡住:

我们加一行代码就行了:

    def update(self):
        while True:
            self.clock.tick(self.fps)
            # TODO:逻辑更新
            self.event_handler()
            # TODO:画面更新
            self.game_map.draw_bottom(self.screen_surf)
            Sprite.draw(self.screen_surf, self.hero, 100, 100, 0, 0)
            Sprite.draw(self.screen_surf, self.hero, 210, 120, 1, 1)
            Sprite.draw(self.screen_surf, self.hero, 300, 100, 2, 2)
            self.game_map.draw_top(self.screen_surf)
            pygame.display.update()

本章完~

猜你喜欢

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