pygame像素地图的实现

实现效果

绘制平面地图
按动键盘可以实现地图位置的移动(图片中的A保存相对不动)
示例1示例2

实现地图类

初始化地图类

同上一篇博文讲过的,增加longwide保存地图块的长宽,和transform2x是否将图片放大两倍,suf_m来保存原始的地图数据,suf_s用来保存绘制地图数据

    def __init__(self, maps=[[0, 0], [0, 0]], long=72, wide=72, transform2X=True):
        # 用键值对保存图片信息
        """
               用字典来保存图片位置
               <1 代表路面、草坪等可以通过的地方
               ≥1且<2 代表墙面、等
               ≥2 代表可以交互的地方
               """
        self.dic = {0: "road", 0.1: "roadv", 0.101: "roadc1", 0.102: "roadc2", 0.103: "roadc3", 0.104: "roadc4"}
        # 放置地图
        self.map = maps

        # 是否放大两倍,图片的长、宽
        self.two_size = transform2X
        self.image_l = long
        self.image_h = wide

        # 计算整体地图的长宽
        length = len(self.map)
        max_long = 1
        for i in range(length):
            if max_long < len(self.map[i]):
                max_long = len(self.map[i])

        # 用来保存原始的地图
        self.suf_m = pygame.Surface([self.image_h * max_long, self.image_l * length])
        self.suf_m.fill([255, 255, 255])

        # 用来显示地图
        self.suf_s = pygame.Surface([1080, 720])
        self.suf_s.set_colorkey([0, 0, 0])

绘制地图并更新

下面这个函数用于从地图中读取数据,根据字典读取图片并根据图片位置绘制地图更新到suf_m,最后将suf_m更新到suf_s

    def print_map(self):
        ci, ri = 0, 0
        for c in self.map:
            for r in c:
                # 根据字典按行绘制
                image = pygame.image.load(r"s\{}.png".format(self.dic[r]))
                # 放大图片
                if self.two_size:
                    image = pygame.transform.scale2x(image)
                self.image_l, self.image_h = image.get_size()
                self.suf_m.blit(image, (ri * self.image_l, ci * self.image_h))
                ri = ri + 1
            ci = ci + 1
            ri = 0  # 初始化行标识
            self.suf_s.blit(self.suf_m.copy(), (0, 0))

设置地图的中心点

确认在地图中的一个不变的点,spirit是用来储存角色信息的对象,获取主角的x坐标和y坐标

    # 根据位置初始化角色位置矢量
    def __move__init__(self, spirit):
        self.x0, self.y0 = spirit.x, spirit.y

位移函数

尽量不要用scroll,不然会有bug(图片移动到边缘有拖影),这里计算移动后的角色与初始化角色的位移,然后用blitsuf_m显示到suf_s上。因为图片与人物的移动位置相反,所以带负号

	# 位移函数
    def center(self, x, y):
        # 清除旧的图片,x, y是移动后角色的位置
        self.suf_s.fill([255, 255, 255])
        # 图片移动的方向与人物相反
        self.suf_s.blit(self.suf_m, (- self.image_l * (x - self.x0), - self.image_h * (y - self.y0)))

开始移动

传入角色当前位置的信息、位移后的信息,判断位移是否能发生:

  1. x不超过地图
  2. y不超过地图
  3. 位移后的不是墙壁

如果可以则返回更新后的角色的位置矢量,否则返回原本角色的位置矢量。

# 向右/下移动一个单位为1,x,y为当前位置
    def move(self, x, y, x_final, y_final):
        if 0 <= y_final < len(self.map):
            if 0 <= x_final < len(self.map[y_final]):
                if self.map[y_final][x_final] < 1:
                    self.center(x_final, y_final)
                    return x_final, y_final
                else:
                    return x, y
            else:
                return x, y
        else:
            return x, y

地图上的其他效果

下雨效果

在地图上随机绘制短线代表下雨

    def print_rain(self):
        for i in range(1000):
            xj, yj, lj = random.randint(0, 2160), random.randint(0, 1030), random.randint(0, 20)
            pygame.draw.line(self.suf_m, [255, 255, 255], (xj, yj), (xj, yj + lj), 1)
        self.suf_s.blit(self.suf_m, (0, 0))

夜晚/日出效果

设置一个透明图层,绘制有颜色的矩形更新到suf_m上,最后将suf_m绘制到suf_s

    def print_time(self, array=[255, 255, 255], alpha=50):
        # 设置一个表现时间的图层
        suf_night = pygame.Surface(self.suf_m.get_size())
        suf_night.set_alpha(alpha)

        # 绘制全屏矩形
        rect = self.suf_m.get_rect()
        pygame.draw.rect(suf_night, array, rect)

        # 绘制到显示图层上
        self.suf_m.blit(suf_night, (0, 0))
        self.suf_s.blit(self.suf_m, (0, 0))

白天和夜晚颜色不同

# 白天
    def print_night(self):
        self.print_time([255, 255, 255])

    # 夜晚
    def print_night(self):
        self.print_time([1, 2, 4])
发布了2 篇原创文章 · 获赞 0 · 访问量 54

猜你喜欢

转载自blog.csdn.net/muronglengjing/article/details/104082613