Python开发系列课程(12) - 图形用户界面和游戏开发

article/2025/9/7 2:03:35

图形用户界面和游戏开发

基于tkinter模块的GUI

GUI是图形用户界面的缩写,图形化的用户界面对使用过计算机的人来说应该都不陌生,在此也无需进行赘述。Python默认的GUI开发模块是tkinter(在Python 3以前的版本中名为Tkinter),从这个名字就可以看出它是基于Tk的,Tk是一个工具包,最初是为Tcl设计的,后来被移植到很多其他的脚本语言中,它提供了跨平台的GUI控件。当然Tk并不是最新和最好的选择,也没有功能特别强大的GUI控件,事实上,开发GUI应用并不是Python最擅长的工作,如果真的需要使用Python开发GUI应用,wxPython、PyQt、PyGTK等模块都是不错的选择。

基本上使用tkinter来开发GUI应用需要以下5个步骤:

  1. 导入tkinter模块中我们需要的东西。
  2. 创建一个顶层窗口对象并用它来承载整个GUI应用。
  3. 在顶层窗口对象上添加GUI组件。
  4. 通过代码将这些GUI组件的功能组织起来。
  5. 进入主事件循环(main loop)。

下面的代码演示了如何使用tkinter做一个简单的GUI应用。

import tkinter
import tkinter.messageboxdef main():flag = True# 修改标签上的文字def change_label_text():nonlocal flagflag = not flagcolor, msg = ('red', 'Hello, world!')\if flag else ('blue', 'Goodbye, world!')label.config(text=msg, fg=color)# 确认退出def confirm_to_quit():if tkinter.messagebox.askokcancel('温馨提示', '确定要退出吗?'):top.quit()# 创建顶层窗口top = tkinter.Tk()# 设置窗口大小top.geometry('240x160')# 设置窗口标题top.title('小游戏')# 创建标签对象并添加到顶层窗口label = tkinter.Label(top, text='Hello, world!', font='Arial -32', fg='red')label.pack(expand=1)# 创建一个装按钮的容器panel = tkinter.Frame(top)# 创建按钮对象 指定添加到哪个容器中 通过command参数绑定事件回调函数button1 = tkinter.Button(panel, text='修改', command=change_label_text)button1.pack(side='left')button2 = tkinter.Button(panel, text='退出', command=confirm_to_quit)button2.pack(side='right')panel.pack(side='bottom')# 开启主事件循环tkinter.mainloop()if __name__ == '__main__':main()

需要说明的是,GUI应用通常是事件驱动式的,之所以要进入主事件循环就是要监听鼠标、键盘等各种事件的发生并执行对应的代码对事件进行处理,因为事件会持续的发生,所以需要这样的一个循环一直运行着等待下一个事件的发生。另一方面,Tk为控件的摆放提供了三种布局管理器,通过布局管理器可以对控件进行定位,这三种布局管理器分别是:Placer(开发者提供控件的大小和摆放位置)、Packer(自动将控件填充到合适的位置)和Grid(基于网格坐标来摆放控件),此处不进行赘述。

使用Pygame进行游戏开发

Pygame是一个开源的Python模块,专门用于多媒体应用(如电子游戏)的开发,其中包含对图像、声音、视频、事件、碰撞等的支持。Pygame建立在SDL的基础上,SDL是一套跨平台的多媒体开发库,用C语言实现,被广泛的应用于游戏、模拟器、播放器等的开发。而Pygame让游戏开发者不再被底层语言束缚,可以更多的关注游戏的功能和逻辑。

下面我们来完成一个简单的小游戏,游戏的名字叫“大球吃小球”,当然完成这个游戏并不是重点,学会使用Pygame也不是重点,最重要的我们要在这个过程中体会如何使用前面讲解的面向对象程序设计,学会用这种编程思想去解决现实中的问题。

制作游戏窗口

import pygamedef main():# 初始化导入的pygame中的模块pygame.init()# 初始化用于显示的窗口并设置窗口尺寸screen = pygame.display.set_mode((800, 600))# 设置当前窗口的标题pygame.display.set_caption('大球吃小球')running = True# 开启一个事件循环处理发生的事件while running:# 从消息队列中获取事件并对事件进行处理for event in pygame.event.get():if event.type == pygame.QUIT:running = Falseif __name__ == '__main__':main()

在窗口中绘图

可以通过pygame中draw模块的函数在窗口上绘图,可以绘制的图形包括:线条、矩形、多边形、圆、椭圆、圆弧等。需要说明的是,屏幕坐标系是将屏幕左上角设置为坐标原点(0, 0),向右是x轴的正向,向下是y轴的正向,在表示位置或者设置尺寸的时候,我们默认的单位都是像素。所谓像素就是屏幕上的一个点,你可以用浏览图片的软件试着将一张图片放大若干倍,就可以看到这些点。pygame中表示颜色用的是色光三原色表示法,即通过一个元组或列表来指定颜色的RGB值,每个值都在0~255之间,因为是每种原色都用一个8位(bit)的值来表示,三种颜色相当于一共由24位构成,这也就是常说的“24位颜色表示法”。

import pygamedef main():# 初始化导入的pygame中的模块pygame.init()# 初始化用于显示的窗口并设置窗口尺寸screen = pygame.display.set_mode((800, 600))# 设置当前窗口的标题pygame.display.set_caption('大球吃小球')# 设置窗口的背景色(颜色是由红绿蓝三原色构成的元组)screen.fill((242, 242, 242))# 绘制一个圆(参数分别是: 屏幕, 颜色, 圆心位置, 半径, 0表示填充圆)pygame.draw.circle(screen, (255, 0, 0,), (100, 100), 30, 0)# 刷新当前窗口(渲染窗口将绘制的图像呈现出来)pygame.display.flip()running = True# 开启一个事件循环处理发生的事件while running:# 从消息队列中获取事件并对事件进行处理for event in pygame.event.get():if event.type == pygame.QUIT:running = Falseif __name__ == '__main__':main()

加载图像

如果需要直接加载图像到窗口上,可以使用pygame中image模块的函数来加载图像,再通过之前获得的窗口对象的blit方法渲染图像,代码如下所示。

import pygamedef main():# 初始化导入的pygame中的模块pygame.init()# 初始化用于显示的窗口并设置窗口尺寸screen = pygame.display.set_mode((800, 600))# 设置当前窗口的标题pygame.display.set_caption('大球吃小球')# 设置窗口的背景色(颜色是由红绿蓝三原色构成的元组)screen.fill((255, 255, 255))# 通过指定的文件名加载图像ball_image = pygame.image.load('./res/ball.png')# 在窗口上渲染图像screen.blit(ball_image, (50, 50))# 刷新当前窗口(渲染窗口将绘制的图像呈现出来)pygame.display.flip()running = True# 开启一个事件循环处理发生的事件while running:# 从消息队列中获取事件并对事件进行处理for event in pygame.event.get():if event.type == pygame.QUIT:running = Falseif __name__ == '__main__':main()

实现动画效果

说到动画这个词大家都不会陌生,事实上要实现动画效果,本身的原理也非常简单,就是将不连续的图片连续的播放,只要每秒钟达到了一定的帧数,那么就可以做出比较流畅的动画效果。如果要让上面代码中的小球动起来,可以将小球的位置用变量来表示,并在循环中修改小球的位置再刷新整个窗口即可。

import pygamedef main():# 初始化导入的pygame中的模块pygame.init()# 初始化用于显示的窗口并设置窗口尺寸screen = pygame.display.set_mode((800, 600))# 设置当前窗口的标题pygame.display.set_caption('大球吃小球')# 定义变量来表示小球在屏幕上的位置x, y = 50, 50running = True# 开启一个事件循环处理发生的事件while running:# 从消息队列中获取事件并对事件进行处理for event in pygame.event.get():if event.type == pygame.QUIT:running = Falsescreen.fill((255, 255, 255))pygame.draw.circle(screen, (255, 0, 0,), (x, y), 30, 0)pygame.display.flip()# 每隔50毫秒就改变小球的位置再刷新窗口pygame.time.delay(50)x, y = x + 5, y + 5if __name__ == '__main__':main()

碰撞检测

通常一个游戏中会有很多对象出现,而这些对象之间的“碰撞”在所难免,比如炮弹击中了飞机、箱子撞到了地面等。碰撞检测在绝大多数的游戏中都是一个必须得处理的至关重要的问题,pygame的sprite(动画精灵)模块就提供了对碰撞检测的支持,这里我们暂时不介绍sprite模块提供的功能,因为要检测两个小球有没有碰撞其实非常简单,只需要检查球心的距离有没有小于两个球的半径之和。为了制造出更多的小球,我们可以通过对鼠标事件的处理,在点击鼠标的位置创建颜色、大小和移动速度都随机的小球,当然要做到这一点,我们可以把之前学习到的面向对象的知识应用起来。

from enum import Enum, unique
from math import sqrt
from random import randintimport pygame@unique
class Color(Enum):"""颜色"""RED = (255, 0, 0)GREEN = (0, 255, 0)BLUE = (0, 0, 255)BLACK = (0, 0, 0)WHITE = (255, 255, 255)GRAY = (242, 242, 242)@staticmethoddef random_color():"""获得随机颜色"""r = randint(0, 255)g = randint(0, 255)b = randint(0, 255)return (r, g, b)class Ball(object):"""球"""def __init__(self, x, y, radius, sx, sy, color=Color.RED):"""初始化方法"""self.x = xself.y = yself.radius = radiusself.sx = sxself.sy = syself.color = colorself.alive = Truedef move(self, screen):"""移动"""self.x += self.sxself.y += self.syif self.x - self.radius <= 0 or \self.x + self.radius >= screen.get_width():self.sx = -self.sxif self.y - self.radius <= 0 or \self.y + self.radius >= screen.get_height():self.sy = -self.sydef eat(self, other):"""吃其他球"""if self.alive and other.alive and self != other:dx, dy = self.x - other.x, self.y - other.ydistance = sqrt(dx ** 2 + dy ** 2)if distance < self.radius + other.radius \and self.radius > other.radius:other.alive = Falsea self.radius = self.radius + int(other.radius * 0.146)def draw(self, screen):"""在窗口上绘制球"""pygame.draw.circle(screen, self.color,(self.x, self.y), self.radius, 0)

事件处理

可以在事件循环中对鼠标事件进行处理,通过事件对象的type属性可以判定事件类型,再通过pos属性就可以获得鼠标点击的位置。如果要处理键盘事件也是在这个地方,做法与处理鼠标事件类似。

def main():# 定义用来装所有球的容器balls = []# 初始化导入的pygame中的模块pygame.init()# 初始化用于显示的窗口并设置窗口尺寸screen = pygame.display.set_mode((800, 600))# 设置当前窗口的标题pygame.display.set_caption('大球吃小球')running = True# 开启一个事件循环处理发生的事件while running:# 从消息队列中获取事件并对事件进行处理for event in pygame.event.get():if event.type == pygame.QUIT:running = False# 处理鼠标事件的代码if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:# 获得点击鼠标的位置x, y = event.posradius = randint(10, 100)sx, sy = randint(-10, 10), randint(-10, 10)color = Color.random_color()# 在点击鼠标的位置创建一个球(大小、速度和颜色随机)ball = Ball(x, y, radius, sx, sy, color)# 将球添加到列表容器中balls.append(ball)screen.fill((255, 255, 255))# 取出容器中的球 如果没被吃掉就绘制 被吃掉了就移除for ball in balls:if ball.alive:ball.draw(screen)else:balls.remove(ball)pygame.display.flip()# 每隔50毫秒就改变球的位置再刷新窗口pygame.time.delay(50)for ball in balls:ball.move(screen)# 检查球有没有吃到其他的球for other in balls:ball.eat(other)if __name__ == '__main__':main()

上面的两段代码合在一起,我们就完成了“大球吃小球”的游戏(如下图所示),准确的说它算不上一个游戏,但是做一个小游戏的基本知识我们已经通过这个例子告诉大家了,有了这些知识已经可以开始你的小游戏开发之旅了。其实上面的代码中还有很多值得改进的地方,比如刷新窗口以及让球移动起来的代码并不应该放在事件循环中,等学习了多线程的知识后,用一个后台线程来处理这些事可能是更好的选择。如果希望获得更好的用户体验,我们还可以在游戏中加入背景音乐以及在球与球发生碰撞时播放音效,利用pygame的mixer和music模块,我们可以很容易的做到这一点,大家可以自行了解这方面的知识。事实上,想了解更多的关于pygame的知识,最好的教程是pygame的官方网站,如果英语没毛病就可以赶紧去看看啦。 如果想开发3D游戏,pygame就显得力不从心了,对3D游戏开发如果有兴趣的读者不妨看看Panda3D。

这里写图片描述


http://chatgpt.dhexx.cn/article/vp8F2IAl.shtml

相关文章

【python游戏开发】:那些由python开发的知名网站和游戏你知道多少

前言 众所周知&#xff0c;Python不仅在数据分析和人工智能方面有着广泛的应用&#xff0c;而且在网站开发和游戏开发方面也是独一无二的。今天&#xff0c;大美将带你去看看哪些知名的大公司和网站是用Python开发的&#xff0c;还有一些用Python开发的超级游戏。列出一些著名…

python游戏开发的五个案例分享

本文给大家分享了作者整理的五个python游戏开发的案例,通过具体设计思路,代码等方面详细了解python游戏开发的过程,非常的详细,希望大家能够喜欢 一、序列应用——猜单词游戏 1. 游戏介绍 猜单词游戏就是计筧机随机产生一个单词&#xff0c;打乱字母顺序&#xff0c;供玩家去…

pgzero:用 Python 进行游戏开发

1. pgzero python在各个领域都有着丰富的第三方库&#xff0c;pygame是python在游戏领域的应用库&#xff0c;可以用来开发各种不同的游戏。但是对于初学者来说&#xff0c;还是存在一定的门槛。 而今天要和大家分享的pgzero&#xff08;pygame zero&#xff09;是在pygame基础…

Python3爬虫、数据清洗与可视化实战之写一个简单的爬虫

文章目录 关于爬虫的合法性了解网页认识网页结构写一个简单的HTML 使用requests库请求网站安装requests库爬虫的基本原理使用GET方式抓取数据使用POST方式抓取数据 使用Beautiful Soup解析网页清洗和组织数据爬虫攻防战 关于爬虫的合法性 几乎每一个网站都有一个名为robots.tx…

Python3.X 爬虫实战(并发爬取)

【工匠若水 http://blog.csdn.net/yanbober 未经允许严禁转载&#xff0c;请尊重作者劳动成果。私信联系我】 1 背景 在这一系列开始前我们就说过&#xff0c;简单的爬虫很容易&#xff0c;但是要完成一个高效健壮的爬虫不是一个简单的事情&#xff0c;这一系列我们已经明白了爬…

Python爬虫(三)

Python爬虫&#xff08;三&#xff09; 一、ajax请求豆瓣电影第一页 # get请求 # 获取豆瓣电影的第一页数据并保存 import urllib.request url https://movie.douban.com/j/chart/top_list?type5&interval_id100%3A90&action&start0&limit20 headers {use…

Python3爬虫(一)抓取网页的html

因为代码只有几行&#xff0c;所以可以先贴代码&#xff1a; import urllib.request url rhttp://douban.com res urllib.request.urlopen(url) html res.read().decode(utf-8) print(html) 第一行&#xff0c;导入 urllib库的request模块 第二行&#xff0c;指定要抓取的网…

python3爬虫-Python3网络爬虫入门实战解析

网络爬虫简介 网络爬虫&#xff0c;也叫网络蜘蛛(Web?Spider)。它根据网页地址(URL)爬取网页内容&#xff0c;而网页地址(URL)就是我们在浏览器中输入的网站链接。 在浏览器的地址栏输入URL地址&#xff0c;在网页处右键单击&#xff0c;找到检查。(不同浏览器的叫法不同&am…

Python3爬虫概述

爬虫基础 文章目录 爬虫基础爬虫概述Session和Cookie简述1. Session2. Cookie3.关于Session 参考资料 爬虫概述 简单来说&#xff0c;爬虫就是从网页上提取信息并保存的自动化程序。 爬虫程序的工作: 获取网页: 爬虫需要先获取网页信息&#xff0c;即网页源代码进行后续分析。…

python爬虫之

使用BeaufulSoup获取指定class时&#xff0c;结果是将我们所输入的字符串去做模糊匹配&#xff0c;因此会将所有包含的class结果输出&#xff0c;如下图&#xff1a; 但我们所需要的可能是精确匹配的那一条&#xff0c;这个时候更换一下代码即可&#xff1a; web_url http://…

Python3 网络爬虫 <教程全集>

1.1 最简单的爬虫 我的老师&#xff1a;Jack Cui PS&#xff1a;我是通过 看 Jack Cui 老师的文章 学习的爬虫&#xff0c;也为我之后的 爬虫打开了大门。 1.1.1 URL 是什么&#xff1f; 在学习 爬虫之前&#xff0c;我们必须知道 我们 平常 所说的网址&#xff0c;实际上 叫…

爬虫python

一、Urllib 1.什么是互联网爬虫&#xff1f; 如果我们把互联网比作一张大的蜘蛛网&#xff0c;那一台计算机上的数据便是蜘蛛网上的一个猎物&#xff0c;而爬虫程序就是一只小蜘蛛&#xff0c;沿着蜘蛛网抓取自己想要的数据 解释1&#xff1a;通过一个程序&#xff0c;根据Ur…

手把手教你如何入门Python3 网络爬虫

很多朋友学习Python都是先从爬虫开始&#xff0c;其原因不外两方面&#xff1a; 其一Python对爬虫支持度较好&#xff0c;类库众多&#xff0c;其二语法简单&#xff0c;入门容易&#xff0c;所以两者形影相随&#xff0c;不离不弃。 要使用python语言做爬虫&#xff0c;首先需…

python3 爬虫

一.网络爬虫&#xff08;Web Crawler&#xff09; 1.网络爬虫&#xff1a;是一种按照一定的规则&#xff0c;自动地抓取网上信息的程序或者脚本。 2.爬虫&#xff1a;为了获取网上大量的我们能看的到或看不到的数据 3.基本步骤&#xff1a;&#xff08;1&#xff09;定位要爬的…

python 爬虫

Python 爬虫教程(更新中) 目录 1. 简介 2. 注意 3. xpathselenium 4. xpathscarpy&#xff08;更新中&#xff09; 5. icrawler 【借助更加便捷操作的pip包】 1. 简介 爬虫主要有2种方式&#xff1a;API(报文)-静态、模拟鼠标点击形式-动态&#xff1b; Xpath Scrapy(…

【python】python爬虫

爬虫基础 HTTP协议 HTTP是Hyper Text Transfer Protocol&#xff08;超文本传输协议&#xff09;的缩写&#xff0c;是用于从万维网&#xff08;WWW:World Wide Web &#xff09;服务器传输超文本到本地浏览器的传送协议。 HTTP是基于TCP/IP通信协议来传递数据&#xff08;HT…

Python3 网络爬虫(一):初识网络爬虫之夜探老王家(2020年最新版)

一、前言 3年前&#xff0c;我在 csdn 写过 Python3 网络爬虫系列教程&#xff0c;经过三年的积累&#xff0c;累计阅读量近 90W。 同时&#xff0c;我也在 Github 开源了所有 Python3 网络爬虫代码&#xff0c;累积获得 10.3k 的 star&#xff0c;4.1k 的 fork。 可以说&…

Python3 爬虫快速入门攻略

一、什么是网络爬虫&#xff1f; 1、定义&#xff1a;网络爬虫&#xff08;Web Spider&#xff09;&#xff0c;又被称为网页蜘蛛&#xff0c;是一种按照一定的规则&#xff0c;自动地抓取网站信息的程序或者脚本。 2、简介&#xff1a;网络蜘蛛是一个很形象的名字。如果把互…

Python3爬虫(一):Python的入门学习以及Python网络爬虫的初步认识

Author&#xff1a;baiyucraft BLog&#xff1a; baiyucraft’s Home IDE&#xff1a;PyCharm 其实对于Python&#xff0c;一直想去学习&#xff0c;但一直没有足够的的时候去研究&#xff0c;这次趁疫情在家的时间&#xff0c;对于Python好好的研究研究。算是作为自己对于Py…

Python3网络爬虫(一):利用urllib进行简单的网页抓取

运行平台&#xff1a;Windows Python版本&#xff1a;Python3.x IDE&#xff1a;Sublime text3 转载请注明作者和出处&#xff1a;http://blog.csdn.net/c406495762/article/details/58716886 一直想学习Python爬虫的知识&#xff0c;在网上搜索了一下&#xff0c;大部分都是…