「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

相关文章
|
1月前
|
IDE 开发工具 Python
Python扑克游戏编程---摸大点
Python扑克游戏编程---摸大点
|
2月前
|
Python
python编写下象棋游戏|4-14
python编写下象棋游戏|4-14
|
2月前
|
人工智能 算法 图形学
总有一个是你想要的分享40个Python游戏源代码
这是一系列基于Python开发的游戏项目集合,包括中国象棋、麻将、足球、坦克大战、扑克等多种类型游戏,运用了Pygame等库实现图形界面与AI算法。此外还包含迷宫、数独、推箱子等益智游戏及经典游戏如《仙剑奇侠传二战棋版》和《星露谷物语》的Python版本,适合编程学习与娱乐。
107 11
|
1月前
|
数据采集 前端开发 Python
Python pygame 实现游戏 彩色 五子棋 详细注释 附源码 单机版
Python pygame 实现游戏 彩色 五子棋 详细注释 附源码 单机版
70 0
|
2月前
|
消息中间件 数据采集 数据库
庆祝吧!Python IPC让进程间的合作,比团队游戏还默契
【9月更文挑战第7天】在这个数字化时代,软件系统日益复杂,单进程已难以高效处理海量数据。Python IPC(进程间通信)技术应运而生,使多进程协作如同训练有素的电竞战队般默契。通过`multiprocessing`模块中的Pipe等功能,进程间可以直接传递数据,无需依赖低效的文件共享或数据库读写。此外,Python IPC还提供了消息队列、共享内存和套接字等多种机制,适用于不同场景,使进程间的合作更加高效、精准。这一技术革新让开发者能轻松应对复杂挑战,构建更健壮的软件系统。
36 1
|
3月前
|
机器学习/深度学习 存储 定位技术
强化学习Agent系列(一)——PyGame游戏编程,Python 贪吃蛇制作实战教学
本文是关于使用Pygame库开发Python贪吃蛇游戏的实战教学,介绍了Pygame的基本使用、窗口初始化、事件处理、键盘控制移动、以及实现游戏逻辑和对象交互的方法。
|
4月前
|
机器学习/深度学习 人工智能 开发者
Python适合做游戏吗?
【7月更文挑战第2天】Python适合做游戏吗?
111 56
|
3月前
|
机器学习/深度学习 人工智能 自然语言处理
【机器学习】python之人工智能应用篇--游戏生成技术
游戏生成技术,特别是生成式人工智能(Generative Artificial Intelligence, 简称Generative AI),正逐步革新游戏开发的多个层面,从内容创作到体验设计。这些技术主要利用机器学习、深度学习以及程序化内容生成(Procedural Content Generation, PCG)来自动创造游戏内的各种元素,显著提高了开发效率、丰富了游戏内容并增强了玩家体验。以下是生成式AI在游戏开发中的几个关键应用场景概述
66 2
|
3月前
|
Python
【python】Python成语接龙游戏[1-3难度均有](源码+数据)【独一无二】
【python】Python成语接龙游戏[1-3难度均有](源码+数据)【独一无二】
|
3月前
|
Python
【Leetcode刷题Python】174. 地下城游戏
LeetCode 174题 "地下城游戏" 的Python解决方案,使用动态规划算法计算骑士从左上角到右下角拯救公主所需的最低初始健康点数。
51 3