阅读 67

pygame 小游戏准备工作要做足&pygame 游戏开场动画渲染学习

这篇博客的目的

本文继续为你补充 pygame 中的一些小知识点,后面开始写一个知名案例,较于其他博客,本篇博客拆解及其细致。

导入 pygame 中常用的常量 使用下述代码,可以导入 pygame 中常用的常量。

from pygame.locals import * 复制代码

locals 中内置了如下常量。

['ACTIVEEVENT', 'ANYFORMAT', 'APPACTIVE', 'APPFOCUSMOUSE', 'APPINPUTFOCUS', 'ASYNCBLIT', 'AUDIODEVICEADDED', 'AUDIODEVICEREMOVED', 'AUDIO_ALLOW_ANY_CHANGE', ...] 复制代码

总数可以通过下述代码获取,达到了 551 个。

import pygame from pygame.locals import * print(len(dir(pygame.locals))) 复制代码

所以通过代码导入之后,此 551 个常量,不需要在通过 pygame.x 方式进行调用了,可以直接使用常量名称。

下面三种方式调用的数据是一致的。

print(pygame.BLEND_MAX) print(pygame.locals.BLEND_MAX) print(BLEND_MAX) 复制代码

多应用自定义常量 pygame 进行游戏编写时,经常会遇到需要数字变量的时候,此时可以设置为下述内容:

WIDTH = 400 HEIGHT = 300 FPS = 30 复制代码

熟练使用该形式代码,可以大幅度的增加代码的可读性。 对于部分字符串,也可以声明成常量,便于后续的使用。

SQUARE = 'square' LINES = 'lines' 复制代码

Memory Puzzle 记忆拼图 该案例来源自书籍中的案例,互联网已经有相关的完整代码,本阶段学习将对该案例进行拆解,重新梳理实现逻辑。

游戏主框架部分代码 本部分决定了游戏的一个主体结构,也是编写过程中最简单的点。

import pygame import random import sys from pygame.locals import * FPS = 30 WIDTH = 600 HEIGHT = 400 # 颜色常量 WHITE = (255, 255, 255) TURQUOISE = (64, 224, 208) # 场景颜色 BGCOLOR = TURQUOISE # 游戏运行入口函数 def main():     # pygame 模块初始化     pygame.init()     # pygame 时钟初始化     FPSCLOCK = pygame.time.Clock()     # 设置游戏窗口     SCREEN = pygame.display.set_mode((WIDTH, HEIGHT))     # 游戏窗口标题     pygame.display.set_caption("记忆拼图")     # 背景填充     SCREEN.fill(BGCOLOR)     # 游戏主循环     while True:         # 事件处理         for event in pygame.event.get():             # 按下 ESC 键或者点击关闭,退出程序             if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):                 pygame.quit()                 sys.exit()         # 更新屏幕         pygame.display.update()         # 设置帧率         FPSCLOCK.tick(FPS) if __name__ == '__main__':     main() 复制代码

上述代码基于之前的博客内容实现,运行效果如下:

pygame 小游戏前的准备工作要做足

设置方块

方块目前参考案例给出的是 10 x 7 个,我们需要做的就是生成 70 个不同的形状与颜色的数据。本部分核心用到的代码在图后。

pygame 小游戏前的准备工作要做足

代码中主要的注释部分都已经提供,编写的时候从 main_board = get_random_board() 函数调用开始进行编写。

import pygame import random import sys from pygame.locals import * FPS = 30 WIDTH = 600 HEIGHT = 400 # 设置横向盒子的数量 BOARDWIDTH = 10 # 设置纵向盒子的数量 BOARDHEIGHT = 7 # 颜色常量 WHITE = (255, 255, 255) TURQUOISE = (64, 224, 208) RED = (255, 0, 0) GREEN = (0, 255, 0) BLUE = (0, 0, 255) YELLOW = (255, 255, 0) ORANGE = (255, 128, 0) PURPLE = (255, 0, 255) CYAN = (0, 255, 255) # 场景颜色 BGCOLOR = TURQUOISE # 定义形状 DONUT = 'donut'  # 甜甜圈 SQUARE = 'square'  # 方形 DIAMOND = 'diamond'  # 钻石 LINES = 'lines'  # 多条线 OVAL = 'oval'  # 椭圆 ALLCOLORS = (RED, GREEN, BLUE, YELLOW, ORANGE, PURPLE, CYAN) ALLSHAPES = (DONUT, SQUARE, DIAMOND, LINES, OVAL) # 游戏运行入口函数 def main():     # pygame 模块初始化     pygame.init()     # pygame 时钟初始化     FPSCLOCK = pygame.time.Clock()     # 设置游戏窗口     SCREEN = pygame.display.set_mode((WIDTH, HEIGHT))     # 游戏窗口标题     pygame.display.set_caption("记忆拼图")     # ********************     # 游戏中的 board 数据生成     main_board = get_random_board()     # ********************     # 背景填充     SCREEN.fill(BGCOLOR)     # 游戏主循环     while True:         # 事件处理         for event in pygame.event.get():             # 按下 ESC 键或者点击关闭,退出程序             if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):                 pygame.quit()                 sys.exit()         # 更新屏幕         pygame.display.update()         # 设置帧率         FPSCLOCK.tick(FPS) # 游戏中的拼图数据生成函数主体 def get_random_board():     # 全列举所有的颜色和形状,进行组合之后的结果存在 icons 中     icons = []     for color in ALLCOLORS:         for shape in ALLSHAPES:             icons.append((shape, color))     # 列表乱序     random.shuffle(icons)     # 计算需要多少种的元素(也就是整个 BORDER 里所有 box(目前有 70 个) 的一半)     num_icons_used = int(BOARDWIDTH * BOARDHEIGHT / 2)     # 将上面得到的元素复制一份(得到的结果就可以两两配对)     icons = icons[:num_icons_used] * 2     # 再次打乱 icons 里的元素的顺序     random.shuffle(icons)     # 创建用来存放 board 数据的结构,将上面处理好的 icons 分组放入 board 中     board = []     for x in range(BOARDWIDTH):         # 列集合         column = []         for y in range(BOARDHEIGHT):             # 每次都添加第一个元素             # print(icons[0])             column.append(icons[0])             # 删除已经复制的元素             del icons[0]         board.append(column)     # print(board)     return board if __name__ == '__main__':     main() 复制代码

代码运行之后,生成的结构体如下,10 行 7 列,好像和一开始的设置有些出入,后面如果碰到问题,在进行修改。

[[('lines', (0, 255, 0)), ('square', (255, 255, 0)), ('donut', (0, 255, 0)), ('donut', (0, 255, 255)), ('square', (255, 128, 0)), ('diamond', (255, 128, 0)), ('square', (255, 255, 0))], [('diamond', (0, 255, 255)), ('oval', (255, 0, 0)), ('donut', (255, 128, 0)), ('diamond', (255, 255, 0)), ('square', (0, 0, 255)), ('oval', (255, 128, 0)), ('oval', (255, 0, 0))], [('oval', (255, 0, 255)), ('donut', (0, 255, 255)), ('donut', (255, 255, 0)), ('donut', (0, 0, 255)), ('square', (255, 0, 0)), ('square', (0, 255, 255)), ('diamond', (0, 255, 0))], [('square', (255, 0, 255)), ('oval', (255, 128, 0)), ('oval', (255, 255, 0)), ('oval', (255, 255, 0)), ('oval', (0, 255, 255)), ('lines', (0, 255, 0)), ('lines', (255, 0, 0))], [('lines', (255, 255, 0)), ('lines', (255, 255, 0)), ('lines', (0, 255, 255)), ('donut', (255, 0, 0)), ('donut', (0, 255, 0)), ('oval', (255, 0, 255)), ('lines', (255, 128, 0))], [('diamond', (255, 0, 0)), ('donut', (255, 255, 0)), ('diamond', (0, 0, 255)), ('diamond', (255, 0, 255)), ('square', (0, 255, 255)), ('oval', (0, 0, 255)), ('diamond', (0, 255, 0))], [('diamond', (0, 0, 255)), ('donut', (255, 0, 255)), ('oval', (0, 255, 0)), ('lines', (0, 255, 255)), ('square', (0, 0, 255)), ('square', (0, 255, 0)), ('oval', (0, 255, 255))], [('donut', (0, 0, 255)), ('lines', (255, 0, 255)), ('diamond', (255, 255, 0)), ('square', (255, 0, 0)), ('oval', (0, 0, 255)), ('lines', (255, 0, 255)), ('square', (255, 0, 255))], [('diamond', (255, 128, 0)), ('lines', (0, 0, 255)), ('lines', (0, 0, 255)), ('donut', (255, 0, 255)), ('donut', (255, 128, 0)), ('lines', (255, 0, 0)), ('lines', (255, 128, 0))], [('oval', (0, 255, 0)), ('donut', (255, 0, 0)), ('square', (0, 255, 0)), ('square', (255, 128, 0)), ('diamond', (0, 255, 255)), ('diamond', (255, 0, 0)), ('diamond', (255, 0, 255))]] 复制代码

本篇代码先到此为止,下篇继续完善。

本系列专栏将通过不断编写游戏的方式,带你夯实 Python 知识。

这篇博客的目的

今天的主要目标就是绘制 10*7 个小方块,最终实现的效果图如下所示。

pygame 游戏开场动画渲染学习,绘制 10*7=70 个小方块

逻辑实现

在界面上进行正方形绘制,主要搞定坐标即可,方块颜色白色,宽度设计为 40 像素。

核心函数调用为:

# 游戏开场动画 start_game_animation(main_board) 复制代码

函数主体内容

# 游戏入场动画函数 def start_game_animation(board):     # 默认获取到的都是 False     covered_boxes = generate_revealed_boxes(False)     draw_board(board, covered_boxes) 复制代码

该函数内部调用了 generate_revealed_boxes()draw_board() 两个函数。

generate_revealed_boxes()

# 生成一个 10*7 的数组,用来存放 box 的状态 def generate_revealed_boxes(val):     revealed_boxes = []     for i in range(BOARDWIDTH):         revealed_boxes.append([val] * BOARDHEIGHT)     return revealed_boxes 复制代码

该函数会返回一个 7x10 结构,值都为 False 的二维列表。

[[False, False, False, False, False, False, False],  [False, False, False, False, False, False, False],  …… 复制代码

draw_board() 该函数用于绘制白色方块。

# 绘制默认 box def draw_board(board, revealed):     for boxx in range(BOARDWIDTH):         for boxy in range(BOARDHEIGHT):             left, top = lefttop_coords_box(boxx, boxy)             if not revealed[boxx][boxy]:                 # 绘制一个被覆盖的box                 pygame.draw.rect(SCREEN, BOXCOLOR, (left, top, BOXSIZE, BOXSIZE))             else:                 pass 复制代码

这里又出现了一个新的函数 lefttop_coords_box(boxx, boxy),函数用途是传入方块的 x 坐标和 y 坐标,绘制一个矩形。

坐标转换函数内容如下:

# 计算出 box 的左上角的像素坐标 def lefttop_coords_box(boxx, boxy):     # 将数字坐标转化成像素坐标     left = boxx * (BOXSIZE + GAPSIZE) + XMARGIN     top = boxy * (BOXSIZE + GAPSIZE) + YMARGIN     return (left, top) 复制代码

用到的全局常量,具体设置参考下述代码,重点理解 XMARGINYMARGIN ,这两个值为的是将渲染出的整体区域进行居中展示。

FPS = 30 WIDTH = 640 HEIGHT = 480 # 设置横向盒子的数量 BOARDWIDTH = 10 # 设置纵向盒子的数量 BOARDHEIGHT = 7 # 设置box的大小 BOXSIZE = 40 # 设置box间的间隔 GAPSIZE = 10 # 计算距离 x 轴边缘的距离 XMARGIN = int((WIDTH - (BOARDWIDTH * (BOXSIZE + GAPSIZE))) / 2) # 计算距离 y 轴边缘的距离 YMARGIN = int((HEIGHT - (BOARDHEIGHT * (BOXSIZE + GAPSIZE))) / 2)


作者:梦想橡皮擦
链接:https://juejin.cn/post/7028372314446102565

文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐