刚刚的疫情发布会刚刚宣布,这一周我所在的区还是要停课。停课来说对于我们大多数人来说都是痛并快乐着的,快乐的是不用受到学校老师督促,但是痛苦的则是不断下滑的成绩。在这期间甚至还会有很多同学用手机刷机来玩游戏。为了解决这个问题,并且解决学习效率,我决定向早期的金山打字通学习,来制作一个键盘上的小游戏。
让我们的手指在停课浪潮中变得更加灵活 被老师点到再也不害怕
链接: https://caiyun.139.com/m/i?135CdnqkoeLD4 提取码:VW6k
复制内容打开中国移动云盘手机APP,操作更方便哦。点击下面图片直达哦
VW6k
这个程序的想法也是刚刚陈局长宣布又一次停课之后开始的。网课上钉钉当我们的手速不行的时候,再加上网络的延迟丢包率严重,加上家里还有一起在家办公的父母,整个网络会变得很卡顿,你被点起来回答问题很有可能就没有及时回答,这个时候,老师很有可能就在怀疑你在睡觉。尤其是上午的课的时候,这种感觉是很难受的。
所以为了提高我们的学习效率,我决定做一个Pygame小游戏。当出现一个字母在屏幕上的时候,我们就要快速地找到键盘上对应的字母,然后在五秒钟之内要在键盘上响应,如果没有响应的话,那我们的游戏就会判断为失败,自动将我们整个电脑屏幕变成黑屏,作为我们游戏挑战失败的惩罚。那么整个游戏持续的时间也不能太长,不然的话就容易影响到我们下一节课的上课时间。那么让我们按照这个愿景赶紧做起来吧!
本来我是打算用PyQt5实现这一个功能的,但是考虑到PyQt5在打包后整一个文件会变得很大,于是我就准备在网上找一找这种黑屏的代码
果然是有的哈,那么我们立刻把这个代码给复制下来,放到我们的代码中运行下。然后将它改写成函数
版权声明:本文为CSDN博主「肥皂泡FZP」的原创文章,遵循CC 4.0
BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_46222411/article/details/105313489
我们运行了一下也能发现哈,这个代码也是可以破解的,只要将我们任务管理器的任务放在顶层就可以了。然后我们再用快捷键呼出这个任务管理器,删除进程就行了。好了,既然这样,那我们就尽情的测试我们的代码吧!
首先我们要编写出我们Pygame的最小框架,最小框架也是Pygame程序运行最基本的代码,具体代码可以看下面这一篇文章(点击图片即可访问)
接下来,我们在网上找一个键盘的照片,放在我们程序的正中间。(然后我发现我想找的键盘正面的图片实在是没有,只好在淘宝网上找了一个图片)
经过BigJpg2网站放大之后,我们得到了一个画质更高清的图片。(在这里有一个很奇怪的地方,我放了一张网页截图,竟然被说是图片违规…)
然后根据我们图像大概能铺满窗口的尺寸设计窗口的大小
更改一下代码 Width Height 的参数部分(在实际的代码编写过程中,我发现1920的窗口显示出来超出了整个电脑界面。于是,我根据设置600的长度显示出750像素,进行转换,得知Pygame是正常像素的0.8倍,于是才有了1536这个数字)
后边我发现,原来Pygame的图片也是要适配这个大小的,也就是说,我还要得把图片改成1536的大小,我真是有点自作聪明。(这个调整图片大小呢 我们也可以使用pillow库来完成哦)。我们调整过大小后,整个图片将会是这个样子。
很显然这个图片似乎不太好放文字啊,于是我们折腾一番,还是把它改成全屏的页面算了。更改Flags的值为pygame.fullscreen
大概出现的就是这样一个界面,有点丑,大家将就看一下吧
然后我们就可以开始设置文字了,设置中文字体呢我们就必须要用系统支持的汉字字体,这里呢我使用的是我自己电脑当中的字体。由于未获取商用权利,所以这里也就不提供下载链接了。
然后我们增加正确的代码这个东西,让它显示
更改获取响应的方式,由于我们整个程序在实现过程中必须要响应事件,这样子判断我们的正确代码是否在按下的代码中会非常方便
change_color()则是我给大家设置的防止视觉疲劳的更换颜色的代码
按照前面的样子,设置第二个字体,并让它显示在屏幕上
最后再来一个清空键盘的代码,OK,完成
大概呈现的样子是这个样子
我设置了一个连击的模块,然后搞得我百思不得其解的是,按我的逻辑来说是正常运行的地方,为什么它一直显示连击为零呢。我又多次在纸上演示它的过程,很显然,我的逻辑一直是对的。
先来说一下我整一个代码的思路,由于我无法获取其他的错误按键,所以我只能在获取到正确按键的时候,先将错误的次数减一,然后再在检测按键按下的地方加一。这个时候可能就会有人说了,怎么不在keys当中检测呢,我还真有过这样的想法,我打印了keys列表发现当没有按键被按下的时候,它的值全部都是False,当有按键按下时,里面其中一项会变成True。但是由于它在按下一次会检测多次,所以可能会出现下图这样的,按一次加上好多次的情况。
说回上一个问题,我最后实在没招了,只能用最基本的打印的办法来检查是否在哪个地方出现了问题。于是还真让我看出来了。在下面蓝色部分,我们可以清晰地看到这就是一个分界点,那么导致这个状况出现的原因是什么呢
首先它的组合wrong为4 wrong_front为3,而后面则颠倒了过来,并且再也没有变过。结合上面我们所说的,很好的证明了其实KEYDOWN和key.get_pressed()这两个方法之间是有时差的。Get的反应快一些,而keydown的反应慢一些。也就是说,在同样一次循环当中,我们的Down还没有反应过来,这一行就结束运行了。这也就是导致为什么我们的代码会出现这样的原因。
然后知道是时间问题不就好办了,由于我们前面有很多加载图片的代码,加载这些图片的时间一定是能让我们整个程序运行完一次的,所以我们把这个检测的代码放在加载图片的前面,如上图所示
很明显,我前面说的效果实现不了了,我翻看了这么多文档,还是没有找到可以完美双进程运行这个程序的方法。等到寒假去研究研究多进程和线程之后,再把这篇文章给完善一下。
还有一个很奇怪的事情是,我的pygame页面竟然神奇地变了回来,那为了和我的前面设置所相通,我只好又更改来了背景的长宽…
那么不说了,明天还得上课,赶紧地得去睡觉了。GoodBye EveryBody
import pygame
import sys
import random
from multiprocessing import Process
import time
def change_color():
global first_num, second_num, third_num
first_num = random.randint(0,255)
second_num = random.randint(0,255)
third_num = random.randint(0,255)
pygame.init()
width = 1536
height = 864
screen = pygame.display.set_mode((width,height))
pygame.display.set_caption('KeyBoardFlash')
# 加载图片
image = "./images/KeyBoard_small.png"
keyboard_img = pygame.image.load(image)
# 加载字体
font_luxun = pygame.font.Font("./fonts/LUXUN.TTF",50)
font_youyouran = pygame.font.Font("./fonts/YYR.ttf",20)
font_youyouran_40 = pygame.font.Font("./fonts/YYR.ttf",40)
font_shuangqu = pygame.font.Font("./fonts/ShuangQu.TTF",200)
# 设置ASCLL代码
# a-97 z-122
correct_letter = random.randint(97,122)
first_num = random.randint(0,255)
second_num = random.randint(0,255)
third_num = random.randint(0,255)
# 设置参数
wrong = 0
# 点击次数
click = 0
correct = 0
# 连击次数
batter = 0
wrong_front = 0
gaming = True
# 设置时间
play_time = 3
score = 100
# 获取当前时间错
clock_start = time.process_time()
while True:
# 经历了的时间
current = time.process_time() - clock_start
if play_time - current < 0:
gaming = False
# 设置得分数
try:
score = correct/click*100 - wrong + batter/3
except ZeroDivisionError:
score = 0
# 清空界面
screen.fill((0,0,0))
# 渲染游戏键盘
screen.blit(keyboard_img, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
wrong += 1
click += 1
# 按下空格键退出
if event.key == pygame.K_ESCAPE:
sys.exit()
# 设置游戏字体
if gaming:
imgText = font_luxun.render("按下ESC退出 在键盘上按下对应出现的字母 你还有"+str(int(play_time - current))+"秒的时间",True,(255,255,255))
screen.blit(imgText,(0,430.4))
else:
imgText = font_luxun.render("你的得分为(满分一百分):"+str(int(score)),True,(255,255,255))
screen.blit(imgText,(0,430.4))
imgText2 = font_shuangqu.render(chr(correct_letter-32),True,(first_num,second_num,third_num))
screen.blit(imgText2,(673,530))
imgText3 = font_youyouran.render("总点击次数:"+str(click),True,(255,255,255))
screen.blit(imgText3,(0,720))
imgText4 = font_youyouran.render("总错误次数:"+str(wrong),True,(255,255,255))
screen.blit(imgText4,(0,740))
imgText5 = font_youyouran.render("总正确次数:"+str(correct),True,(255,255,255))
screen.blit(imgText5,(0,760))
imgText6 = font_youyouran.render("连击次数 X "+str(batter),True,(255,255,255))
screen.blit(imgText6,(0,800))
# 获得键盘上的灵活响应
keys = pygame.key.get_pressed()
if keys[correct_letter]:
wrong -= 1
batter += 1
correct += 1
change_color()
correct_letter = random.randint(97,122)
if wrong == wrong_front:
wrong_front = wrong
else:
batter = 0
wrong_front = wrong
# 更新屏幕设置
pygame.display.update()