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() 复制代码
上述代码基于之前的博客内容实现,运行效果如下:
设置方块
方块目前参考案例给出的是 10 x 7
个,我们需要做的就是生成 70 个不同的形状与颜色的数据。本部分核心用到的代码在图后。
代码中主要的注释部分都已经提供,编写的时候从 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
个小方块,最终实现的效果图如下所示。
逻辑实现
在界面上进行正方形绘制,主要搞定坐标即可,方块颜色白色,宽度设计为 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) 复制代码
用到的全局常量,具体设置参考下述代码,重点理解 XMARGIN
与 YMARGIN
,这两个值为的是将渲染出的整体区域进行居中展示。
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