「Python」数字推盘游戏

简介: 前面知识只是简单的对pygame进行参数的介绍,后面还需要用到MVC设计模式,在这里不多做说明,建议直接观察源代码

「Python」数字推盘游戏


🎮数字推盘游戏


前面知识只是简单的对pygame进行参数的介绍,后面还需要用到MVC设计模式,在这里不多做说明,建议直接观察源代码😅


前期知识储备pygame是为了开发2D游戏而设计的Python跨平台模块,使用前需要导入


pip install pygame


然后出现


Installing collected packages: pygameSuccessfully installed pygame-2.0.1

即安装成功此游戏需要用到以下7个模块

pygame的初始化和退出
创建游戏窗口
游戏循环与游戏时钟
图形和文本绘制
元素位置控制
动态效果
时间与事件处理

1.pygame初始化


init()函数


init()函数可以一次性初始化pygame所有模块


quit()函数


quit()函数可以卸载所有之前被初始化的pygame模块。python在退出之前解释器会释放所有的模块,quit()函数并非必须调用。开发人员应当在需要时主动调用quit()函数卸载模块资源

"""数字推盘"""
import pygame  # 导入制作游戏的模块
def main():
    pygame.init()  # 初始化所有模块
    pygame.quit()  # 卸载所有模块
if __name__ == '__main__':
    main()

2.创建游戏窗口


pygame通过display子模块创建图形界面窗口 相关函数说明如下

set_mode() 初始化游戏窗口


set_caption() 设置窗口标题

update() 更新屏幕显示内容


set_mode()函数声明:set_mode(resolution=(0,0), flags=0, depth=0) -> Surface


①resolution 图形窗口分辨率。参数resolution本质上是一个元祖,该元祖的两个元素分别指定图形窗口的宽和高,单位为像素。默认情况下与屏幕大小一致。

②flags 标志位,用于设置窗口特性,默认0

③depth 色深,该参数只取整数,取值范围为【8,32】


set_mode()函数的额返回值为Surface对象,Surface可以被视为画布,图形在画布上才能展现。画布默认背景黑色,fill()方法可以填充画布


**set_caption() **用于设置窗口标题,函数声明如下:set_caption(title, icontitle=None) -> None


icontitle设置显示在任务栏上的程序标题,默认与title一致


窗口一闪而过:因为程序在设置完标题后就结束了


**update() ** 用于刷新窗口,在使用fill()方法填充后背景颜色却未变,是因为程序中未调用该函数对窗口进行刷新。在pygame.quit()之前调用update()函数


3.游戏循环与游戏时钟


要使得游戏保持运行需要在程序中天健一个无限循环,循环代码如下:

while True:
    pass

动态的效果实际上无数静态的组合起来快速播放形成的 在计算机上一秒绘制60(桢)Frame便可以达到连续、高品质的动画效果。换言之,窗口中刷新图像的频率只要不低于每秒60Frame,即可以达到动画的效果。 修改后的代码如下:

i = 0
while True:
    Print(i)
    i += 1

过高的帧率意味着超高的负荷,所以需要设置游戏时钟 可以调用pygame的time模块里面的clock类,通过该类的tick()方法就可设置游戏循环的执行频率

FPS = 60    # 预设频率
def main():
    ...
    FPSCLOCK= pygame.time.Clock()       # 创建clock模块
    ...
    while True:
        print(i)
        i += 1
        FPSCLOCK.tick(FPS)      # 控制帧率

4.图形和文本绘制


pygame中的图形窗口是一个surface对象,在窗口上进行绘制实质上就是surface对象上进行绘制。


①图形绘制

加载图片load(filename) -> Surface

从当前路径加载图片imgSurf = pygame.image.load('bg.jpg')

绘制图片


绘制图像就是将surface对象叠加在另一个surface对象之上。通过blit()方法可以实现图像绘制,具体语法如下:blit(source, dest, area=None, special_flags = 0) -> Rect


  • source接收被绘制的surface对象
  • dest接收一个表示位置的元组,该元祖指定left和top两个值,left和top分别表示图片距离窗口左边和顶部的距离。该参数也可接收一个表示矩形的元组(left,top,width,height)
  • area可选参数,通过该参数可设置矩形区域。若设置的矩形区域小于source所设置的surface对象的区域,那么仅绘制surface对象的部分内容
  • special_flags是标志位


WINSET.blit(imgSurf, (0, 0))   # 将imgSurf加载到窗口WINSET中(0,0)代表的是位置


②文本绘制

使用font类

Font(filename,size) -> Font   # 创建字体对象
"""filename用于设置字体对象的字体,size用于设置字体大小
具体用法如下:"""
BASICFONT = pygame.font.Font('STKAITI.TTF', 25)
"""
SysFont()函数常见一个系统字体对象。SysFont()函数的声明如下
SysFont(name, size, bold=False, italic=False) -> Font
name 系统字体的名字,可以通过pygame.font.get_fonts()函数获得当前系统的所有可用字体列表
size 大小
bold 粗体,默认不加粗
italic 斜体
Font()1函数更加灵活
"""
# 渲染文本内容 render()
render(text, antialias, color, background=None) -> Surface
"""
text:文字内容
antialias:是否抗锯齿(抗锯齿让绘制的文字更平滑)
render方法返回surface对象---即一张内容为文字的图片
"""
msgSurf = BASICFONT.render('初始化...', True, MSGCOLOR, MSGBGCOLOR) # 渲染
""""
使用save方法将图片保存到本地
"""
pygame.image.save(msgSurf,'msg.png')
"""
渲染之后仍然需要绘制渲染结果,用blit
"""

到此,所有的代码如下:


把while循环删了,电脑可以的话你可以不删~hahahah

"""set_mode模块"""
import pygame
WINWIDTH = 640  # 窗口宽度
WINHEIGHT = 480  # 窗口高度
# -----颜色预设-----
DARKTURQUOISE = (3, 54, 73)
YELLOW = (255, 255, 193)
# -----颜色变量-----
BGCOLOR = DARKTURQUOISE  # 预设背景颜色
MSGCOLOR = DARKTURQUOISE  # 设置字体颜色
MSGBGCOLOR = YELLOW  # 按钮背景颜色
FPS = 60  # 预设频率
def main():
    pygame.init()  # 初始化所有模块
    FPSCLOCK = pygame.time.Clock()  # 创建clock模块
    # 创建窗体,即创建爱你surface对象
    WINSET = pygame.display.set_mode((WINWIDTH, WINHEIGHT))
    WINSET.fill(BGCOLOR)  # 填充背景颜色
    pygame.display.set_caption('数字推盘')  # 设置窗口标题
    image = pygame.image.load('bg.jpg')  # 加载背景图片
    WINSET.blit(image, (0, 0))  # 绘制背景图片
    BASICFONT = pygame.font.Font('hua_wen_xing_kai.ttf', 25)  # 创建字体对象
    msgSurf = BASICFONT.render('初始化...', True, MSGCOLOR, MSGBGCOLOR)  # 渲染
    WINSET.blit(msgSurf, (0, 0))
    WINSET.blit(image, (0, 0))  # 绘制图片
    pygame.display.update()  # 刷新窗口
    pygame.quit()  # 卸载所有模块
if __name__ == '__main__':
    main()

5.元素位置控制


Rect()类,放置图片and文本


x轴水平向右为正

y轴水平向下为正

"""
Rect(x, y, width, height) -> Rect
创建矩形对象 
rect = pygame.Rect(80, 160, 160, 120) # 坐标为(80,160) 160 × 120 像素
可以通过rect.()
来查看它的方法
"""
"""
surface对象在窗口的位置通过blit()方法的参数dest确定
"""
# 渲染字体
    autoSurf = BASICFONT.render('自 动', True, BTTEXTCOLOR, BTCOLOR)
    autoRect = autoSurf.get_rect()  # 获取矩阵属性
    autoRect.x = WINWIDTH - autoRect.width - 10  # 重设横坐标
    autoRect.y = WINHEIGHT - autoRect.height - 10  # 重设纵坐标
    WINSET.blit(autoSurf, autoRect)  # 绘制字体

6.动态效果


本游戏的方块由矩形和文本组成,其中文本用的是font模块的Font()函数、render()方法以及Surface类的blit()方法绘制,矩形使用pygame中draw模块的rect()函数绘制。 So,实现方块的移动需要实现:


①绘制矩形方块


rect(Surface,color,Rect,width=0) -> Rect

Rect接收一个矩形对象

# 创建矩形
    blockRect = pygame.Rect(0.5 * (WINWIDTH - BLOCKSIZE),
                            0.5 * (WINHEIGHT - BLOCKSIZE),
                            BLOCKSIZE,
                            BLOCKSIZE)
    pygame.draw.rect(WINSET, BTCOLOR, blockRect)  # 绘制矩形

②绘制数字


数字应该位于矩形中心,矩形对象的左上角坐标代表矩形的位置,目前上面绘制的矩形在屏幕的中心,假设数字的矩形对象为numRect,则其在屏幕中的x,y坐标分别如下:


numRect.x = blockRect.x + 0.5 * (BLOCKSIZE-numRect.width)

numRect.y = blockRect.y + 0.5 * (BLOCKSIZE-numRect.height)


③移动方块

移动通过在不同但连续的位置绘制同一个surface对象。 推盘中的方块由方块图像blockSurf和numSurf组成。移动过程在for循环中实现

 # 在背景的不同位置绘制方块,制造移动效果。方块向右移动 BLOCKSIZE+2
    for i in range(0, BLOCKSIZE, 2):
        FPSCLOCK.tick(FPS)  # 循环帧率控制
        # ----绘制----
        pygame.draw.rect(WINSET, BTCOLOR, blockRect)
        WINSET.blit(numSurf, numRect)
        pygame.display.update()
        # ----位置更改,实现向右移动----
        blockRect.x += 10  # 修改方块横坐标
        numRect.x += 10  # 修改数字横坐标

以上方块只是简单的做了一个平移的操作,很显然不符合游戏的设定。于是改用surface类中的copy方法

# 准备背景
    baseSurf = WINSET.copy()
    # 创建矩形
    ...
    # ----位置更改,实现向右移动----
        blockRect.x += 10  # 修改方块横坐标
        numRect.x += 10  # 修改数字横坐标
        WINSET.blit(baseSurf, (0, 0))  # 使用备份baseSurf覆盖WINSET

7.时间与事件处理


pygame常见事件列表:

"""
KEYDOWN   键盘被按下   unicode,key,mod
KEYUP   键盘被放开   key,mod
参数
unicode:记录按键的unicode值
key:按下或放开的键的键值
mod:包含组合键信息
"""
"""
MOUSEMOTION     鼠标移动  pos,rel,button
MOUSEBUTTONDOWN   鼠标按下  pos,button
MOUSEBUTTONUP   鼠标松开  pos,button
pos:鼠标操作的位置,包含x和y是一个元祖
rel:当前位置与上次产生鼠标事件时鼠标指针位置间的距离
buttons:一个含有3个数字的元祖,(1,0,0)--三个数字分别对应左键、滚轮、右键
button: 整形数值, 1-->单击鼠标左键  2-->单击滚轮  3-->单击右键  4-->向上滑动滚轮  5-->向下滑动滚轮
"""
 # 创建窗体,即创建爱你surface对象
    WINSET = pygame.display.set_mode((WINWIDTH, WINHEIGHT))
    WINSET.fill()  # 填充背景颜色
    pygame.display.set_caption('数字推盘')  # 设置窗口标题
    image = pygame.image.load('bg.jpg')  # 加载背景图片
    WINSET.blit(image, (0, 0))  # 绘制背景图片
    msgSurf = BASICFONT.render('初始化...', True, MSGCOLOR, MSGBGCOLOR)  # 渲染
    # 渲染字体
    autoSurf = BASICFONT.render('自 动', True, BTTEXTCOLOR, BTCOLOR)
    autoRect = autoSurf.get_rect()  # 获取矩阵属性
    autoRect.x = WINWIDTH - autoRect.width - 10  # 重设横坐标
    autoRect.y = WINHEIGHT - autoRect.height - 10  # 重设纵坐标
    WINSET.blit(autoSurf, autoRect)  # 绘制字体
    WINSET.blit(msgSurf, (0, 0))
    WINSET.blit(image, (0, 0))  # 绘制图片
    # 准备背景
    baseSurf = WINSET.copy()
    # 创建矩形
    blockRect = pygame.Rect(0.5 * (WINWIDTH - BLOCKSIZE),
                            0.5 * (WINHEIGHT - BLOCKSIZE),
                            BLOCKSIZE,
                            BLOCKSIZE)
    pygame.draw.rect(WINSET, BTCOLOR, blockRect)  # 绘制矩形
    # 绘制数字
    numSurf = BASICFONT.render('5', True, BTTEXTCOLOR, BTCOLOR)
    numRect = numSurf.get_rect()
    numRect.x = blockRect.x + 0.5 * (BLOCKSIZE - numRect.width)
    numRect.y = blockRect.y + 0.5 * (BLOCKSIZE - numRect.height)
    # 获取点击事件,rect.collodepoint(),判断点击位置
    while True:
        FPSCLOCK.tick(FPS)  # 循环帧率控制
        for event in pygame.event.get():
            if event.type == MOUSEBUTTONUP:  # 鼠标放开事件
                if blockRect.collidepoint(event.pos):  # 点击的是方块
                    print('点击方块')
    # 在背景的不同位置绘制方块,制造移动效果。方块向右移动 BLOCKSIZE+2
    for i in range(0, BLOCKSIZE, 2):
        FPSCLOCK.tick(FPS)  # 循环帧率控制
        # ----绘制----
        pygame.draw.rect(WINSET, BTCOLOR, blockRect)
        WINSET.blit(numSurf, numRect)
        pygame.display.update()
        # ----位置更改,实现向右移动----
        blockRect.x += 10  # 修改方块横坐标
        numRect.x += 10  # 修改数字横坐标
        WINSET.blit(baseSurf, (0, 0))  # 使用备份baseSurf覆盖WINSET
    # pygame.display.update()  # 刷新窗口
    pygame.quit()  # 卸载所有模块

上面只是简单的介绍了一下pygame的一些简单的使用,后面具体的设计需要用到MVC设计模式(即模型-视图-控制器)


大致流程为:

绘制静态页面->生成推盘序列->打乱推盘->在循环中绘制动态页面并更新,判断程序是否退出,最后接收用户输入并进行处理

主程序如下:

def main():
    global FPSCLOCK, WINSET, STATICSURF, BASICFONT
    global NEW_SURF, NEW_RECT
    global SOLVEDBOARD
    '''游戏流程,游戏的框架先放进去,然后填充'''
    pygame.init()  # 初始化所有模块
    FPSCLOCK = pygame.time.Clock()  # 创建clock模块
    BASICFONT = pygame.font.Font('hua_wen_xing_kai.ttf', 25)  # 创建字体对象
    # 初始化
    initBorad = getStartingBoard()
    print(initBorad)
    WINSET, NEW_SURF, NEW_RECT = drawStaticWin()
    STATICSURF = WINSET.copy()
    mainBoard = generateNewPuzzle(AUTOMOVE)
    msg = None
    while True:
        FPSCLOCK.tick(FPS)
        drawBoard(mainBoard, msg)  # 根据初始拼图信息与提示信息,绘制游戏界面
        pygame.display.update()
        # 判断是否结束游戏
        checkForQuit()  # 判断是否接收到终止信息
        userInput = getInput(mainBoard)  # 获取用户输入
        mainBoard, msg = processing(userInput, mainBoard, msg)

具体模块见源代码

1.png

需要准备的就是背景图片以及字体 游戏界面如下:

1.png

8.源代码


推盘.py


9.打包游戏


先安装工具pyinstaller

pip install pyinstaller
# 查看已安装工具
pip list
# 打包 game.py是主程序的名称
# 注意需要到游戏的主目录下执行以下命令
pyinstaller -F -w game.py

1.png

1.png

1.png

打包安装成功

1.png

执行完上述~~三个命令 ~~ (实际只需要两个)后,会新增build和dist文件夹

1.png

.exe可执行文件存放在dist文件夹中,需要将引用的背景'bg.png'和字体放在.exe目录之下

1.png

相关文章
|
2天前
|
存储 Java C语言
【python】——使用嵌套列表实现游戏角色管理
【python】——使用嵌套列表实现游戏角色管理
38 0
|
2天前
|
人工智能 数据可视化 机器人
【Python】Python实现五子棋游戏(带可视化界面)【独一无二】
【Python】Python实现五子棋游戏(带可视化界面)【独一无二】
|
2天前
|
存储 人工智能 算法
【Python】Yahtzee(掷骰子游戏)模拟程序【独一无二】
【Python】Yahtzee(掷骰子游戏)模拟程序【独一无二】
|
2天前
|
存储 Python
Python 一步一步教你用pyglet制作“彩色方块连连看”游戏
Python 一步一步教你用pyglet制作“彩色方块连连看”游戏
39 0
|
2天前
|
算法 Python
Python 一步一步教你用pyglet制作汉诺塔游戏
Python 一步一步教你用pyglet制作汉诺塔游戏
30 0
|
2天前
|
存储 Python
如何使用Python实现“猜数字”游戏
本文介绍了使用Python实现“猜数字”游戏的过程。游戏规则是玩家在给定范围内猜一个由计算机随机生成的整数,猜对则获胜。代码中,首先导入random模块生成随机数,然后在循环中获取玩家输入并判断大小,提供猜小、猜大提示。通过增加猜测次数限制、难度选择、优化输入提示和图形化界面等方式可优化游戏。这篇文章旨在帮助初学者通过实际操作学习Python编程。
42 2
|
2天前
|
存储 Python Windows
10分钟学会用python写游戏,实例教程
10分钟学会用python写游戏,实例教程
43 0
|
2天前
|
Python
Python猜字游戏是一种常见的编程练习
Python猜字游戏是一种常见的编程练习
27 2
|
2天前
|
Python
用 Python 写一个猜数字游戏并运行它
用 Python 写一个猜数字游戏并运行它
15 0
|
2天前
|
UED 开发者 Python
制作你的第一个 Python 游戏
想要制作一个 Python 游戏?这是一个令人兴奋的项目!在这篇文章中,我将引导你完成制作第一个 Python 游戏的步骤。即使你没有编程经验,也不用担心,我们将从基础开始,一起探索游戏开发的乐趣。