Python100天打卡-Day10-图形用户界面和游戏开发

简介: Python100天打卡-Day10-图形用户界面和游戏开发图形用户界面和游戏开发基于tkinter模块的GUIPython默认的GUI开发模块是tkinter(在Python 3以前的版本中名为Tkinter)使用tkinter来开发GUI应用需要以下5个步骤:导入tkinter模块中我们需要的东西。

Python100天打卡-Day10-图形用户界面和游戏开发
图形用户界面和游戏开发
基于tkinter模块的GUI
Python默认的GUI开发模块是tkinter(在Python 3以前的版本中名为Tkinter)
使用tkinter来开发GUI应用需要以下5个步骤:

导入tkinter模块中我们需要的东西。
创建一个顶层窗口对象并用它来承载整个GUI应用。
在顶层窗口对象上添加GUI组件。
通过代码将这些GUI组件的功能组织起来。
进入主事件循环(main loop)。
GUI应用通常是事件驱动式的,之所以要进入主事件循环就是要监听鼠标、键盘等各种事件的发生并执行对应的代码对事件进行处理,因为事件会持续的发生,所以需要这样的一个循环一直运行着等待下一个事件的发生。
另一方面,Tk为控件的摆放提供了三种布局管理器,通过布局管理器可以对控件进行定位,这三种布局管理器分别是:

Placer(开发者提供控件的大小和摆放位置)
Packer(自动将控件填充到合适的位置)
Grid(基于网格坐标来摆放控件)
使用Pygame进行游戏开发
Pygame是一个开源的Python模块,专门用于多媒体应用(如电子游戏)的开发,其中包含对图像、声音、视频、事件、碰撞等的支持。
下面我们来完成一个简单的小游戏,游戏的名字叫“大球吃小球”

制作游戏窗口
import pygame

def 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 = False

if name == '__main__':

main()

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

def 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 = False

if name == '__main__':

main()

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

def 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 = False

if name == '__main__':

main()

实现动画效果
要实现动画效果,本身的原理也非常简单,就是将不连续的图片连续的播放,只要每秒钟达到了一定的帧数,那么就可以做出比较流畅的动画效果。
import pygame

def main():

# 初始化导入的pygame中的模块
pygame.init()
# 初始化用于显示的窗口并设置窗口尺寸
screen = pygame.display.set_mode((800, 600))
# 设置当前窗口的标题
pygame.display.set_caption('大球吃小球')
# 定义变量来表示小球在屏幕上的位置
x, y = 50, 50
running = True
# 开启一个事件循环处理发生的事件
while running:
    # 从消息队列中获取事件并对事件进行处理
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    screen.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 + 5

if name == '__main__':

main()

碰撞检测
pygame的sprite(动画精灵)模块就提供了对碰撞检测的支持,这里我们暂时不介绍sprite模块提供的功能,因为要检测两个小球有没有碰撞其实非常简单,只需要检查球心的距离有没有小于两个球的半径之和。
from enum import Enum, unique
from math import sqrt
from random import randint

import 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)

@staticmethod
def 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 = x
    self.y = y
    self.radius = radius
    self.sx = sx
    self.sy = sy
    self.color = color
    self.alive = True

def move(self, screen):
    """移动"""
    self.x += self.sx
    self.y += self.sy
    if self.x - self.radius <= 0 or \
            self.x + self.radius >= screen.get_width():
        self.sx = -self.sx
    if self.y - self.radius <= 0 or \
            self.y + self.radius >= screen.get_height():
        self.sy = -self.sy

def eat(self, other):
    """吃其他球"""
    if self.alive and other.alive and self != other:
        dx, dy = self.x - other.x, self.y - other.y
        distance = sqrt(dx ** 2 + dy ** 2)
        if distance < self.radius + other.radius \
                and self.radius > other.radius:
            other.alive = False
            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.pos
            radius = 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模块,我们可以很容易的做到这一点

参考资料:https://github.com/jackfrued/Python-100-Days/blob/master/Day01-15/Day10/图形用户界面和游戏开发.md

作者:wxl1999
来源:CSDN
原文:https://blog.csdn.net/wxl1999/article/details/90300899
版权声明:本文为博主原创文章,转载请附上博文链接!

相关文章
|
2月前
|
设计模式 测试技术 Python
游戏开发的挑战与解决方案:Python 视角
游戏开发是一个复杂且富有挑战性的过程,涉及到多个领域的知识和技术。从 Python 的角度来看,游戏开发面临着一系列的挑战,同时也有许多解决方案可供选择。
|
5天前
|
JavaScript 前端开发 API
游戏开发入门:Python后端与Vue前端的协同工作方式
【4月更文挑战第11天】使用Python后端(Flask或Django)和Vue.js前端开发游戏变得流行,能提高开发效率和可维护性。本文指导如何构建这样的项目,包括设置环境、创建虚拟环境、搭建后端API及前端Vue组件,强调前后端协作和API接口的重要性。这种架构促进团队合作,提升代码质量和游戏体验。
|
27天前
|
Python
Python函数之计算规则图形的面积
Python函数之计算规则图形的面积
14 0
|
1月前
|
数据采集 文字识别 开发者
Python爬虫之图形验证码的识别
python爬虫逆向图形验证码分析,处理和测试实战。
44 0
|
1月前
|
API 开发工具 C++
Python图形用户界面(GUI)编程:大解密
Python图形用户界面(GUI)编程:大解密
55 0
|
1月前
|
开发框架 Linux 开发者
深入了解Python游戏开发模块:pyglet
深入了解Python游戏开发模块:pyglet
27 0
|
1月前
|
UED 开发者 Python
用Python搞图形页面开发
用Python搞图形页面开发
15 2
|
2月前
|
语音技术 Python
Python 游戏开发中的用户交互
在 Python 游戏开发中,用户交互是至关重要的一环。它决定了玩家与游戏之间的互动方式,直接影响着游戏的体验和乐趣。在本文中,我们将探讨 Python 游戏开发中常见的用户交互方式,并提供一些实现这些交互的示例。
|
2月前
|
Python
Python 游戏开发的基本逻辑
游戏开发是一个复杂而富有挑战性的过程,需要综合运用多种技术和知识。在 Python 游戏开发中,理解基本逻辑是至关重要的。本文将介绍 Python 游戏开发的基本逻辑,并提供一些关键概念和示例,帮助你构建一个简单的游戏。
|
2月前
|
Python
Python数学基础二、利用正弦sin求曲边图形的面积
Python数学基础二、利用正弦sin求曲边图形的面积
53 0