【快乐六一】当pygame遇到中文点阵,有趣的code碰撞就此展开,祝各位大朋友、小朋友们节日快乐!

各位好!今天恰逢六一儿童节,一个开心、快乐的节日!

金色的童年、快乐的童年,都是美好的、幸福的回忆!

我的小宝贝一直说想看看我们美丽的文字,所以最近一直在研究中文字符的东东,从技术上可能只是一堆的0和1的数字,但是从整个文学来看,中文是博大精深、源远流长的,能学的东西很多,想精通的东西也不少。

我觉得,学好语文的前提,就是要学好汉字,学好语文的前提,就是要积累足够多的汉字,然后基于我们的汉字,可以组合出丰富的词语、成语,进而可以写出好的句子、好的文章、好的诗词歌赋。

因此,我一直非常关注我的宝贝的学习,也希望可以让我们的文字与技术结合,与代码结合,能产生出一些好玩的东西,在玩的过程中、在娱乐游戏的过程中,健康成长。所以我从昨天开始,转如了一个新的系列:深入研究我们的文字,并在程序的大河里去探索挖掘,希望能做出一些好玩的东西。

恰逢六一,在此祝各位大朋友、小朋友们节日快乐!

那么,有什么好玩的东东呢?

中文点阵,其实顾名思义:就是把我们的汉字打散成点状,然后输出类似点点的效果。

一、先上点效果吧!

跟大家问好!
在这里插入图片描述
继续跟大家打个招呼
在这里插入图片描述
你好,我好,大家好,大家好才是真的好!
在这里插入图片描述
看完了黑白的点阵,那换点有图形界面的看看咯。
在这里插入图片描述
好吧,来点色彩的变化,吸引一下眼球。
在这里插入图片描述
继续把,让里面的点阵变大看看里面的点是什么样子的?
在这里插入图片描述
发现什么了吗?是不是都是一些圆点啊。

那我们在脑洞大开一下,让圆点变成图片看看?

在这里插入图片描述
让图片动起来也许也很好看。那就录制一个GIF动图吧
在这里插入图片描述
还没完,图片可以替换成点,那我们继续用文字来替换圆点,又会是怎么样的体验呢?
在这里插入图片描述
还是搞个动图看看,效果也不错哦。
在这里插入图片描述
好咯,看到这些好看的文字,是不是有点心动了,想自己写写代码,玩玩啊!

那我们就开始教学篇了,都准备好了吗?

二、命令行输出中文字符

(一)输出一个中文字符

import binascii
KEYS = [0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01]

# 初始化16*16的点阵位置,每个汉字需要16*16=256个点来表示,需要32个字节才能显示一个汉字
# 之所以32字节:256个点每个点是0或1,那么总共就是2的256次方,一个字节是2的8次方
rect_list = [] * 16
for i in range(16):
    rect_list.append([] * 16)

#拿“赞”字来演示
text = "好"

#获取中文的gb2312编码,一个汉字是由2个字节编码组成
gb2312 = text.encode('gb2312')

#将二进制编码数据转化为十六进制数据
hex_str = binascii.b2a_hex(gb2312)

#将数据按unicode转化为字符串
result = str(hex_str, encoding='utf-8')

#前两位对应汉字的第一个字节:区码,每一区记录94个字符
area = eval('0x' + result[:2]) - 0xA0

#后两位对应汉字的第二个字节:位码,是汉字在其区的位置
index = eval('0x' + result[2:]) - 0xA0

#汉字在HZK16中的绝对偏移位置,最后乘32是因为字库中的每个汉字字模都需要32字节
offset = (94 * (area-1) + (index-1)) * 32

font_rect = None

#读取HZK16汉字库文件
with open("HZK16", "rb") as f:
    #找到目标汉字的偏移位置
    f.seek(offset)
    #从该字模数据中读取32字节数据
    font_rect = f.read(32)

#font_rect的长度是32,此处相当于for k in range(16)
for k in range(len(font_rect) // 2):
    #每行数据
    row_list = rect_list[k]
    for j in range(2):
        for i in range(8):
            asc = font_rect[k * 2 + j]
            #此处&为Python中的按位与运算符
            flag = asc & KEYS[i]
            #数据规则获取字模中数据添加到16行每行中16个位置处每个位置
            row_list.append(flag)

#根据获取到的16*16点阵信息,打印到控制台
for row in rect_list:
    for i in row:
        if i:
            #前景字符(即用来表示汉字笔画的输出字符)
            print('0', end=' ')
        else:

            # 背景字符(即用来表示背景的输出字符)
            print('.', end=' ')

在这里插入图片描述

(二)封装成函数

def printPlay(textStr,line,background):
    # 初始化16*16的点阵位置,每个汉字需要16*16=256个点来表示,需要32个字节才能显示一个汉字
    # 之所以32字节:256个点每个点是0或1,那么总共就是2的256次方,一个字节是2的8次方
    rect_list = [] * 16
    # print(rect_list)
    for i in range(16):
        rect_list.append([] * 16)

    for text in textStr:
        #获取中文的gb2312编码,一个汉字是由2个字节编码组成
        gb2312 = text.encode('gb2312')
        #将二进制编码数据转化为十六进制数据
        hex_str = binascii.b2a_hex(gb2312)
        #将数据按unicode转化为字符串
        result = str(hex_str, encoding='utf-8')

        #前两位对应汉字的第一个字节:区码,每一区记录94个字符
        area = eval('0x' + result[:2]) - 0xA0
        #后两位对应汉字的第二个字节:位码,是汉字在其区的位置
        index = eval('0x' + result[2:]) - 0xA0
        #汉字在HZK16中的绝对偏移位置,最后乘32是因为字库中的每个汉字字模都需要32字节
        offset = (94 * (area-1) + (index-1)) * 32

        font_rect = None

        #读取HZK16汉字库文件
        with open("HZK16", "rb") as f:
            #找到目标汉字的偏移位置
            f.seek(offset)
            #从该字模数据中读取32字节数据
            font_rect = f.read(32)

        #font_rect的长度是32,此处相当于for k in range(16)
        for k in range(len(font_rect) // 2):
            #每行数据
            row_list = rect_list[k]
            for j in range(2):
                for i in range(8):
                    asc = font_rect[k * 2 + j]
                    #此处&为Python中的按位与运算符
                    flag = asc & KEYS[i]
                    #数据规则获取字模中数据添加到16行每行中16个位置处每个位置
                    row_list.append(flag)

    #根据获取到的16*16点阵信息,打印到控制台
    for row in rect_list:
        # print(row)
        for i in row:
            if i:
                #前景字符(即用来表示汉字笔画的输出字符)
                print(line, end=' ')
            else:

                # 背景字符(即用来表示背景的输出字符)
                print(background, end=' ')
        print()

(三)输出多个中文字符

调用上述函数,输出多个字符

inpt = '你好'
#自定义点阵字中笔画的符号
lineSign = '■'
#自定义点阵字的背景符号
backgroundSign = '○'
#调用之前定义好的函数,打印最终成果
printPlay(inpt,lineSign,backgroundSign)
print()
inpt = '大家好'
printPlay(inpt,lineSign,backgroundSign)

输出:你好!
在这里插入图片描述
输出:大家好!
在这里插入图片描述

三、图形界面输出中文字符

(一)处理逻辑

把上面的函数分成两个函数,其中一个函数实现把中文字符转成16*16的矩阵数据,第二个函数实现矩阵数据的显示,可以分别支持点显示、图片显示、文字显示等多种模式。

(二)printPlay实现把字符转成16*16矩阵

def printPlay(textStr):
    # 初始化16*16的点阵位置,每个汉字需要16*16=256个点来表示,需要32个字节才能显示一个汉字
    # 之所以32字节:256个点每个点是0或1,那么总共就是2的256次方,一个字节是2的8次方
    rect_list = [] * 16
    print(rect_list)
    for i in range(16):
        rect_list.append([] * 16)

    for text in textStr:
        #获取中文的gb2312编码,一个汉字是由2个字节编码组成
        gb2312 = text.encode('gb2312')
        #将二进制编码数据转化为十六进制数据
        hex_str = binascii.b2a_hex(gb2312)
        #将数据按unicode转化为字符串
        result = str(hex_str, encoding='utf-8')

        #前两位对应汉字的第一个字节:区码,每一区记录94个字符
        area = eval('0x' + result[:2]) - 0xA0
        #后两位对应汉字的第二个字节:位码,是汉字在其区的位置
        index = eval('0x' + result[2:]) - 0xA0
        #汉字在HZK16中的绝对偏移位置,最后乘32是因为字库中的每个汉字字模都需要32字节
        offset = (94 * (area-1) + (index-1)) * 32

        font_rect = None

        #读取HZK16汉字库文件
        with open("HZK16", "rb") as f:
            #找到目标汉字的偏移位置
            f.seek(offset)
            #从该字模数据中读取32字节数据
            font_rect = f.read(32)

        #font_rect的长度是32,此处相当于for k in range(16)
        for k in range(len(font_rect) // 2):
            #每行数据
            row_list = rect_list[k]
            for j in range(2):
                for i in range(8):
                    asc = font_rect[k * 2 + j]
                    #此处&为Python中的按位与运算符
                    flag = asc & KEYS[i]
                    #数据规则获取字模中数据添加到16行每行中16个位置处每个位置
                    row_list.append(flag)

    return rect_list

(三)把矩阵显示在界面上。

1、显示文字

# 显示文字字符
text = textlist[index % len(textlist)]
screen.blit(text, (x1+jj*15, x2+ii*15))
# newRect = bg.get_rect(center=(x1+jj*15, x2+ii*15))
# screen.blit(bg,newRect)
index += 1

2、显示白色圆点

pygame.draw.circle(screen, (255, 255, 255), [x1+jj*15, x2+ii*15], 3, 0)

3、显示随机色圆点

pygame.draw.circle(screen,(random.randint(128, 254), random.randint(128, 254), random.randint(128, 254), [x1+jj*15, x2+ii*15], 3, 0)

4、显示图片

bg = random.choice(bglist)
newRect = bg.get_rect(center=(x1 + jj * 15, x2 + ii * 15))
screen.blit(bg, newRect)

5、完整函数

def display(rect_list,screen,textlist,bglist):
    flag = random.randint(0,3)
    ii = 1
    jj = 1
    x2 = 20
    x1 = 20
    index = 0
    for row in rect_list:
        ii += 1
        # print(row)
        jj = 1
        for i in row:
            jj += 1
            if i:
                #前景字符(即用来表示汉字笔画的输出字符)
                if flag==0:
                    # 显示文字字符
                    text = textlist[index % len(textlist)]
                    screen.blit(text, (x1+jj*15, x2+ii*15))
                    # newRect = bg.get_rect(center=(x1+jj*15, x2+ii*15))
                    # screen.blit(bg,newRect)
                    index += 1
                elif flag==1:
                    # 显示圆点字符
                    pygame.draw.circle(screen, (255, 255, 255), [x1+jj*15, x2+ii*15], 3, 0)
                elif flag==3:
                    pygame.draw.circle(screen,(random.randint(128, 254), random.randint(128, 254), random.randint(128, 254), [x1+jj*15, x2+ii*15], 3, 0)
                elif flag==2:
                    # 显示图片字符
                    bg = random.choice(bglist)
                    newRect = bg.get_rect(center=(x1 + jj * 15, x2 + ii * 15))
                    screen.blit(bg, newRect)

(四)加载图片和文字资源

1、加载图片资源

def init_image():
    path = './user1/'
    files = []
    dirs = os.listdir(path)
    for diretion in dirs:
        files.append(path + diretion)

    bglist = []
    for file in files:
        picture = pygame.transform.scale(pygame.image.load(file), (15, 15))
        dSurface = picture.convert()
        bglist.append(dSurface)

    return bglist

2、加载文字资源

def init_info(info):

    bglist = []
    str = '六一儿童节快乐'
    for st in list(str):
        info_fmt = info.render(st, True, (random.randint(128, 254), random.randint(128, 254), random.randint(128, 254)))
        bglist.append(info_fmt)

    return bglist

3、加载资源库

import pygame
import sys
import random
import os

(五)主体函数实现

if __name__ == '__main__':

    pygame.init()

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

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

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

    str1 = '大家好,天天向上,好好学习,艰苦奋斗,节日快乐,家和事兴,六一快乐'
    strlist = str1.split(',')
    print(strlist)
    bglist = init_image()
    info = pygame.font.SysFont("microsoftjhengheimicrosoftjhengheiui", 16)
    textlist = init_info(info)
    while True:
        # 处理用户输入
        for event in pygame.event.get():
            # 处理退出事件
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
        windowSurface.blit(bgSurface, (0, 0))
        rect_list = printPlay(random.choice(strlist))
        display(rect_list,windowSurface,bglist,textlist)

        # 绘制结束,刷新界面
        pygame.display.flip()
        # 时钟停留一帧的时长
        clock.tick(1)

四、完整代码

# encoding UTF-8
import pygame
import sys
import random
import os
import binascii
KEYS = [0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01]

def printPlay(textStr):
    # 初始化16*16的点阵位置,每个汉字需要16*16=256个点来表示,需要32个字节才能显示一个汉字
    # 之所以32字节:256个点每个点是0或1,那么总共就是2的256次方,一个字节是2的8次方
    rect_list = [] * 16
    print(rect_list)
    for i in range(16):
        rect_list.append([] * 16)

    for text in textStr:
        #获取中文的gb2312编码,一个汉字是由2个字节编码组成
        gb2312 = text.encode('gb2312')
        #将二进制编码数据转化为十六进制数据
        hex_str = binascii.b2a_hex(gb2312)
        #将数据按unicode转化为字符串
        result = str(hex_str, encoding='utf-8')

        #前两位对应汉字的第一个字节:区码,每一区记录94个字符
        area = eval('0x' + result[:2]) - 0xA0
        #后两位对应汉字的第二个字节:位码,是汉字在其区的位置
        index = eval('0x' + result[2:]) - 0xA0
        #汉字在HZK16中的绝对偏移位置,最后乘32是因为字库中的每个汉字字模都需要32字节
        offset = (94 * (area-1) + (index-1)) * 32

        font_rect = None

        #读取HZK16汉字库文件
        with open("HZK16", "rb") as f:
            #找到目标汉字的偏移位置
            f.seek(offset)
            #从该字模数据中读取32字节数据
            font_rect = f.read(32)

        #font_rect的长度是32,此处相当于for k in range(16)
        for k in range(len(font_rect) // 2):
            #每行数据
            row_list = rect_list[k]
            for j in range(2):
                for i in range(8):
                    asc = font_rect[k * 2 + j]
                    #此处&为Python中的按位与运算符
                    flag = asc & KEYS[i]
                    #数据规则获取字模中数据添加到16行每行中16个位置处每个位置
                    row_list.append(flag)

    return rect_list


def display(rect_list,screen,textlist,bglist):
    flag = random.randint(0,3)
    ii = 1
    jj = 1
    x2 = 20
    x1 = 20
    index = 0
    for row in rect_list:
        ii += 1
        # print(row)
        jj = 1
        for i in row:
            jj += 1
            if i:
                #前景字符(即用来表示汉字笔画的输出字符)
                if flag==0:
                    # 显示文字字符
                    text = textlist[index % len(textlist)]
                    screen.blit(text, (x1+jj*15, x2+ii*15))
                    # newRect = bg.get_rect(center=(x1+jj*15, x2+ii*15))
                    # screen.blit(bg,newRect)
                    index += 1
                elif flag==1:
                    # 显示圆点字符
                    pygame.draw.circle(screen, (255, 255, 255), [x1+jj*15, x2+ii*15], 3, 0)
                elif flag==3:
                    pygame.draw.circle(screen,(random.randint(128, 254), random.randint(128, 254), random.randint(128, 254)), [x1+jj*15, x2+ii*15], 3, 0)
                elif flag==2:
                    # 显示图片字符
                    bg = random.choice(bglist)
                    newRect = bg.get_rect(center=(x1 + jj * 15, x2 + ii * 15))
                    screen.blit(bg, newRect)


def init_info(info):

    bglist = []
    str = '六一儿童节快乐'
    for st in list(str):
        info_fmt = info.render(st, True, (random.randint(128, 254), random.randint(128, 254), random.randint(128, 254)))
        bglist.append(info_fmt)

    return bglist

def init_image():
    path = './user1/'
    files = []
    dirs = os.listdir(path)
    for diretion in dirs:
        files.append(path + diretion)

    bglist = []
    for file in files:
        picture = pygame.transform.scale(pygame.image.load(file), (15, 15))
        dSurface = picture.convert()
        bglist.append(dSurface)

    return bglist

if __name__ == '__main__':

    pygame.init()

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

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

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

    str1 = '大家好,天天向上,好好学习,艰苦奋斗,节日快乐,家和事兴,六一快乐'
    strlist = str1.split(',')
    print(strlist)
    bglist = init_image()
    info = pygame.font.SysFont("microsoftjhengheimicrosoftjhengheiui", 16)
    textlist = init_info(info)
    while True:
        # 处理用户输入
        for event in pygame.event.get():
            # 处理退出事件
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
        windowSurface.blit(bgSurface, (0, 0))
        rect_list = printPlay(random.choice(strlist))
        display(rect_list,windowSurface,bglist,textlist)

        # 绘制结束,刷新界面
        pygame.display.flip()
        # 时钟停留一帧的时长
        clock.tick(1)

五、完整运行效果

在这里插入图片描述
好玩的代码,写完了!
祖国的文字博大精深,希望我们要好好学习,天天向上!
我的小宝贝健康快乐!
祝各位大朋友、小朋友们节日快乐!

当pygame遇到中文点阵,有趣的code碰撞就此展开!你学会了吗?
感谢,比心!

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值