python多媒体应用:从0到1教会你制作中文文字雨

最近浏览了很多关于用Python和Pygame实现代码雨的案例,发现很多都是没有深入讲解代码的整个实现过程,更多的只是分享了代码,作为初学者,这些代码看不懂,作为已经懂的人,这些代码可能用处不大,因此,有了这篇博文。
这篇博文的初衷是:从0到1教会你制作中文文字雨
然后在介绍的过程中,我也将深入介绍Pygame的基础知识,让你从一个小白,学完之后也能对Pygame有一个宏观的认识。
好的,下面正式进入主题。

一、pygame介绍

pygame是一个非常非常火的游戏库,那么作为游戏,我相信大家第一印象就是包括:游戏的主界面、游戏里面酷炫的动态效果。

作为技术人员,应该先关注如下几点准备动作。
(一)pygame库的安装
(二)pygame的初始化和退出
(三)pygame界面的坐标系

(一)pygame库的安装

这个相信大家都懂了,就不深入介绍了。

pip install pygame

(二)pygame的初始化和退出

要使用 pygame 提供的所有功能之前,需要调用 init 方法,在游戏结束前需要调用一下 quit 方法

方法 说明
pygame.init() 导入并初始化所有 pygame 模块,使用其他模块之前,必须先调用 init 方法
pygame.quit() 卸载所有 pygame 模块,在游戏结束之前调用!

(三)pygame界面的坐标系

在游戏中,所有可见的元素 都是以 矩形区域 来描述位置的,要描述一个矩形区域有四个要素:(x, y) (width, height)

原点 在 左上角 (0, 0),其中:
x 轴 水平方向向 右,逐渐增加
y 轴 垂直方向向 下,逐渐增加

pygame 专门提供了一个类 pygame.Rect 用于描述 矩形区域Rect(x, y, width, height) -> Rect

import pygame
pygame.init()
myrect = pygame.Rect(300, 500, 200, 256)
print("myrect坐标原点:%d %d 大小:%d %d" % (myrect.x, myrect.y,myrect.width, myrect.height))

(四)创建游戏主窗口

pygame 专门提供了一个 模块 pygame.display 用于创建、管理 游戏窗口

方法 说明
pygame.display.set_mode() 初始化显示窗口
pygame.display.update() 刷新屏幕内容显示

set_mode 方法

set_mode(resolution=(0,0), flags=0, depth=0) -> Surface
第一个参数为元祖,代表分 辨率(必须);
第二个参数是一个标志位,如果不用什么特性,就指定0;
第三个参数为色深。

参数 说明
resolution 指定屏幕的 宽 和 高,默认创建的窗口大小和屏幕大小一致
flags 参数指定屏幕的附加选项,例如是否全屏等等,默认不需要传递
depth 参数表示颜色的位数,默认自动匹配

返回值:Surface对象(可以理解为:游戏的屏幕),游戏的元素 都需要被绘制到游戏的屏幕上,后续所有的图像绘制都基于这个返回结果

  • 附上flags标识位
flags标识位 功能
FULLSCREEN 创建一个全屏窗口
DOUBLEBUF 创建一个“双缓冲“窗口,建议在HWSURFACE或OPENGL时使用
HWSURFACE 创建一个硬件加速窗口,必须和FULLSCREEN同时使用
OPENGL 创建一个OPENGL渲染的窗口
RESIZABLE 创建一个可以改变大小的窗口
NOFRAME 创建一个没有边框的窗口

备注:convert函数是将图像数据都转化为Surface对象,每次加载完图像以后就应该做这件事件(如果你不写pygame也会帮你做);convert_alpha相比convert,保留了Alpha通道信息。

你可以用如下代码获取你的机器支持的显示模式:

import pygame
pygame.init()
print(pygame.display.list_modes())

输出结果如下:

E:\Python37\python.exe D:/code06.py
pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html
[(1440, 900), (1366, 768), (1360, 768), (1280, 1024), (1280, 960), (1280, 800), (1280, 768), (1280, 720), (1280, 600), (1152, 864), (1024, 768), (800, 600), (640, 480), (640, 400), (512, 384), (400, 300), (320, 240), (320, 200)]

Process finished with exit code 0

(五)图像绘制

在游戏中,能够看到的 游戏元素 大多都是 图像
图像文件 初始是保存在磁盘上的,如果需要使用,第一步 就需要 被加载到内存,要在屏幕上 看到某一个图像的内容,需要按照三个步骤:

使用 pygame.image.load() 加载图像的数据 使用 游戏屏幕 对象,
调用 blit 方法 将图像绘制到指定位置
调用> pygame.display.update() 方法更新整个屏幕的显示

import pygame
from pygame.locals import *

pygame.init()
SCREEN_SIZE = (1024, 768)
screen = pygame.display.set_mode(SCREEN_SIZE, RESIZABLE, 32)

# 绘制背景图像
bg = pygame.image.load("temp.jpg")
screen.blit(bg, (0, 0))
# 绘制背景图像
love = pygame.image.load("timg.jpg")
screen.blit(love, (100, 200))
# 3> 更新显示 - update 方法会把之前所有绘制的结果,一次性更新到屏幕窗口上
pygame.display.update()

可以在 screen 对象完成 所有 blit 方法之后,统一调用一次 display.update 方法,同样可以在屏幕上 看到最终的绘制结果。display.update() 会将 画布 的 最终结果 绘制在屏幕上,这样可以 提高屏幕绘制效率,增加游戏的流畅度。

(六)时钟对象

pygame 专门提供了一个类 pygame.time.Clock 可以非常方便的设置屏幕绘制速度 —— 刷新帧率,要使用 时钟对象 需要两步:

1)在 游戏初始化 创建一个 时钟对象
2)在 游戏循环 中让时钟对象调用 tick(帧率) 方法

tick 方法会根据 上次被调用的时间,自动设置 游戏循环 中的延时:

clock = pygame.time.Clock()
i = 0
# 游戏循环
while True:
    # 设置屏幕刷新帧率
    clock.tick(60)
    print(i)
    i += 1

(七)在游戏循环中 监听 事件

事件 event:
就是游戏启动后,用户针对游戏所做的操作
例如:点击关闭按钮,点击鼠标,按下键盘…

在 游戏循环 中,判断用户 具体的操作,只有 捕获 到用户具体的操作,才能有针对性的做出响应pygame 中通过 pygame.event.get() 可以获得 用户当前所做动作 的 事件列表

#初始化时钟对象
clock = pygame.time.Clock()
#游戏循环
while True:
    # 设置屏幕刷新帧率
    clock.tick(60)
    # 事件监听
    for event in pygame.event.get():
        # 判断用户是否点击了关闭按钮
        if event.type == pygame.QUIT:
            print("退出游戏...")
            pygame.quit()

下表是一个常用事件集:

事件 说明
QUIT 用户按下关闭按钮
KEYDOWN 键盘被按下
KEYUP 键盘被放开
MOUSEMOTION 鼠标移动
MOUSEBUTTONDOWN 鼠标按下
MOUSEBUTTONUP 鼠标放开
VIDEORESIZE 窗口缩放

1、监听鼠标操作

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            # 接收到退出时间后退出程序
            exit()
    # 获得鼠标位置
    x, y = pygame.mouse.get_pos()
    # 将光标画上去
    screen.blit(img, (x, y))
    # 刷新画面
    pygame.display.update()

2、监听键盘操作

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
        if event.type == KEYDOWN:
            if event.key == K_LEFT:
                move_x = -1
            elif event.key == K_RIGHT:
                move_x = 1
            elif event.key == K_UP:
                move_y = -1
            elif event.key == K_DOWN:
                move_y = 1
        elif event.type == KEYUP:
            move_x = 0
            move_y = 0

    x += move_x
    y += move_y

    screen.fill((0, 0, 0))
    screen.blit(img, (x, y))
    # 在新的位置上画图
    pygame.display.update()

KEYDOWN和KEYUP的参数说明:

  • key- 按下或者放开的键值,是一个数字,估计地球上很少有人可以记住,所以Pygame中你可以使用K_xxx来表示,比如字母a就是K_a,还有K_SPACE和K_RETURN等。
  • mod -包含了组合键信息,如果mod & KMOD_CTRL是真值,表示用户同时按下了Ctrl键。类似的还有KMOD_SHIFT,KMOD_ALT。

3、监听窗口缩放

使用VIDEORESIZE进行事件监听。

while True:
    event = pygame.event.wait()
    if event.type == VIDEORESIZE:
         add user code

    pygame.display.update()

(八)一个完整的pygame主程序

import pygame
import sys

pygame.init()

resolution = width,height = 800,600 #设置窗口大小和标题
windowSurface = pygame.display.set_mode(resolution) #设置分辨率并得到全局的【绘图表面】
pygame.display.set_caption("中文字符雨平台")#设置标题

bgSurface = pygame.image.load("temp.jpg").convert()

# 创建时钟对象
clock = pygame.time.Clock()

if __name__ == '__main__':
    while True:
        # 处理用户输入
        for event in pygame.event.get():
            # 处理退出事件
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
        windowSurface.blit(bgSurface, (0, 0))
        # 绘制结束,刷新界面
        pygame.display.flip()

        # 时钟停留一帧的时长
        clock.tick(60)

运行效果如下:
在这里插入图片描述

二、实现中文文字雨

(一)实现主界面

import pygame
import sys

pygame.init()

resolution = width,height = 800,600 #设置窗口大小和标题
windowSurface = pygame.display.set_mode(resolution) #设置分辨率并得到全局的【绘图表面】
pygame.display.set_caption("中文字符雨平台")#设置标题

bgSurface = pygame.Surface((width, height), flags=pygame.SRCALPHA)
pygame.Surface.convert(bgSurface)
bgSurface.fill(pygame.Color(0, 0, 0, 35))

# 创建时钟对象
clock = pygame.time.Clock()

if __name__ == '__main__':
    while True:
        # 处理用户输入
        for event in pygame.event.get():
            # 处理退出事件
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
        windowSurface.blit(bgSurface, (0, 0))
        # 绘制结束,刷新界面
        pygame.display.flip()

        # 时钟停留一帧的时长
        clock.tick(60)

(二)初始化字符,并设置支持中文字体

str1 ="我们希望看到江南水乡的美景。江南水乡,烟雨蒙蒙,雨滴颜色五颜六色,大小不一"
letter = list(str1)
font = pygame.font.Font("c:\windows\Fonts\simhei.ttf", 14)
texts = [
    font.render(str(letter[i]), True, (0, 255, 0)) for i in range(26)
]

(三)初始化行数

    column = int(width/15)
    drops = [0 for i in range(column)]

(四)循环处理

        for i in range(len(drops)):
            text = random.choice(texts)
            windowSurface.blit(text, (i * 15, drops[i] * 15))
            drops[i] += 1
            if drops[i] * 10 > height or random.random() > 0.8:
                drops[i] = 0

(五)完整的代码

import pygame
import sys
import random

pygame.init()

resolution = width,height = 800,600 #设置窗口大小和标题
windowSurface = pygame.display.set_mode(resolution) #设置分辨率并得到全局的【绘图表面】
pygame.display.set_caption("中文字符雨平台")#设置标题

bgSurface = pygame.Surface((width, height), flags=pygame.SRCALPHA)
pygame.Surface.convert(bgSurface)
bgSurface.fill(pygame.Color(0, 0, 0, 35))

# 创建时钟对象
clock = pygame.time.Clock()

if __name__ == '__main__':

    str1 = "01abcdefghijklmnopqurstuvwxyz"
    str1 = "我们希望看到江南水乡的美景。江南水乡,烟雨蒙蒙,雨滴颜色五颜六色,大小不一"
    letter = list(str1)
    font = pygame.font.Font("c:\windows\Fonts\simhei.ttf", 14)
    texts = [
        font.render(str(letter[i]), True, (0, 255, 0)) for i in range(26)
    ]

    column = int(width/15)
    drops = [0 for i in range(column)]

    while True:
        # 处理用户输入
        for event in pygame.event.get():
            # 处理退出事件
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
        windowSurface.blit(bgSurface, (0, 0))
        # 绘制结束,刷新界面

        for i in range(len(drops)):
            text = random.choice(texts)

            windowSurface.blit(text, (i * 15, drops[i] * 15))

            drops[i] += 1
            if drops[i] * 10 > height or random.random() > 0.9:
                drops[i] = 0

        pygame.display.flip()

        # 时钟停留一帧的时长
        clock.tick(20)

(六)运行效果

在这里插入图片描述

OK,介绍完了,感觉挺好玩的,大家也可以自己动手实操一下。

感谢你的关注和阅读。

发布了24 篇原创文章 · 获赞 27 · 访问量 1211

猜你喜欢

转载自blog.csdn.net/dhjabc_1/article/details/105726094