200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > Python 打字小游戏开发 来体验不一样的打字游戏乐趣(完结篇)

Python 打字小游戏开发 来体验不一样的打字游戏乐趣(完结篇)

时间:2021-11-20 22:48:40

相关推荐

Python 打字小游戏开发 来体验不一样的打字游戏乐趣(完结篇)

Python 打字小游戏开发,来体验不一样的打字游戏乐趣(完结篇)

资源下载完整代码

Python 打字小游戏开发,来体验不一样的打字游戏乐趣(第一篇)

Python 打字小游戏开发,来体验不一样的打字游戏乐趣(第二篇)

资源下载

/download/qq_59142194/85969323

完整代码

在前面第二篇文章中已简要地对类里面的功能有所说明,现在主要就剩下

configuration_project()函数和monitoring_data()函数了。

configuration_project()函数就是依次进行实例化、调用功能、创建玩家(自己)和电脑玩家对象,开启线程调用死循环的方法;

而monitoring_data()函数里面就是实时进行监测小车移动时的数据变化,在这里面time.sleep(2.5) # 休眠2.5秒后才开始,这里就是小车真正在窗口上停止而赛道和小树开始往后面移动,两者的移动速度都等于玩家自己的打字速度(player.car.speed = dt.typspeed #使小车速度 = 打字速度)。

player_car_s += player.car.speed #让小车此时已移动的路程加上小车速度

timesleep3_posx_s_list[player.username] = player_car_s

for i, caroop in enumerate(caroop_list[1:]):

caroop.car.posx += caroop.car.speed - player.car.speed

timesleep3_posx_s_list[caroop.username] = timesleep3_posx_s_list[caroop.username] + caroop.car.speed这段代码是实时记录每一辆小车移动了的路程。

if max(timesleep3_posx_s_list.values()) > gw.road.road_length:这里面就是将timesleep3_posx_s_list中最大的路程大于我们在开始时初始化的路程就结束游戏(FLAG = False)。最后就是整个代码里面的time.sleep()休眠的时间都是在测试中,我自己调试到的一个不错值。

import tkinter as tkimport threading,random,time,datetimeimport inspectimport ctypesfrom tkinter import ttkfrom pygame import mixerFLAG = True # 定义一个信号量,用于判断最前面的小车是否到达终点,游戏结束变为FalseCARFLAG = True # 定义小车真正在窗口上移动时的信号量,当小车在窗口上静止不动时变为FalseROAD = '' # 赛道(Python,Java,MySql赛道)# 玩家类class Player:def __init__(self,username):self.username = '[玩家]'+username# 创建小车def car_create(self,c,carposy_list):self.car = Car('./sucai/car1.png', carposy_list, 'img1', self.username)self.car_img = tk.PhotoImage(file=self.car.filepath)c.create_image(self.car.posx, self.car.posy, image=self.car_img, tag=self.car.cartag)c.create_text(self.car.posx-30, self.car.posy, text=self.car.username, font=("Purisa", 16), fill='white', tag=self.car.username)# 电脑类class Computer:def __init__(self,username='[电脑]'):self.username = username# 创建小车def car_create(self,c,filepath, posy, cartag, username):self.car = Car(filepath, posy, cartag, username)self.car_img = tk.PhotoImage(file=self.car.filepath)c.create_image(self.car.posx, self.car.posy, image=self.car_img, tag=self.car.cartag)c.create_text(self.car.posx-30, self.car.posy, text=self.car.username, font=("Purisa", 16), fill='white',tag=self.car.username)# 赛道类class Road:def __init__(self,roadtype):self.text = []with open(f'./sucai/{roadtype}关键字.txt', mode='r', encoding='utf-8') as f:for line in f:self.text.append(line.strip().split('\t')[0])self.road_number = int(len(self.text)*1.2) if ROAD == 'Python' else int(len(self.text)*1.5) # 赛道的数量self.road_length = (self.road_number - 3) * 1000 # 需要跑完赛道的长度self.road_s = 0.0# 起点线def begin(self,c):c.create_rectangle(100, 50, 150, 352, fill='#FFF6EE', tag='begin')c.create_text(135, 200, text='R\ne\na\nd\ny\ni\nn\ng\n \nG\nO', font=("Purisa", 20), fill='black', tag='begin')# 终点线def destination(self,c):self.c_end = c.create_text(self.road_length - 120, 200, text='终\n点', font=("Purisa", 52), fill='white',tag='end')# 路相对于车移动def roadmove(self,c,tag_road):global FLAG,playerself.tag_road = tag_roadif FLAG:self.road_s += player.car.speedif self.road_s > 1000:self.road_s = 0.0if self.tag_road:c.delete(self.tag_road.pop(0))for i in range(1, self.road_number + 1):c.move(i, -player.car.speed, 0)c.move(self.c_end, -player.car.speed, 0)# 小树类class Tree:speed = 0def __init__(self, posx,posy,filepath,treetag='tree'):self.posx = posxself.posy = posyself.filepath = filepathself.treetag = treetag# 创建树def tree_create(self,c):self.tree_img = tk.PhotoImage(file=self.filepath)c.create_image(self.posx, self.posy, image=self.tree_img, tag=self.treetag)# 树相对于车移动def treemove(self, c):global FLAG,playerif FLAG:if self.posx >10:self.speed = player.car.speedself.posx -= self.speedc.delete(self.treetag)c.create_image(self.posx, self.posy, image=self.tree_img, tag=self.treetag)else:self.posx = random.randint(550,950)self.speed = player.car.speedself.posx -= self.speedc.create_image(self.posx, self.posy, image=self.tree_img, tag=self.treetag)# 小车类class Car:speed = 2.0 # 初始化小车的移动速度posx = 70 # 初始化小车的初始位置,x轴方向car_move_distance = [] # 记录小车,以初始化速度speed = 2.0开始移动的路程def __init__(self, filepath, posy, cartag, username):self.filepath = filepathself.posy = posyself.cartag = cartagself.username = username# 小车移动方法def car_move(self,c,car_img):global FLAGprint(self.username,'准备就绪...')self.car_img = car_imgdef run():if FLAG:if CARFLAG:self.posx += self.speedself.car_move_distance = []self.car_move_distance.append((self.cartag, self.posx))c.delete(self.cartag)c.create_image(self.posx, self.posy, image=self.car_img, tag=self.cartag)c.delete(self.username)c.create_text(self.posx, self.posy, text=self.username, font=("Purisa", 13), fill='white',tag=self.username)else:c.delete(self.cartag)c.create_image(self.posx, self.posy, image=self.car_img, tag=self.cartag)c.delete(self.username)c.create_text(self.posx, self.posy, text=self.username, font=("Purisa", 13), fill='white',tag=self.username)c.after(10, run)else: print(f'{self.username} 小车停止')run()# 小车移动速度随时变化def car_speed_change(self):global FLAG,playertime.sleep(2.3)while FLAG:if player.car.speed < 14: self.speed = random.uniform(player.car.speed - 0.3, player.car.speed + 0.7)elif 14 < player.car.speed < 18: self.speed = random.uniform(player.car.speed - 0.8, player.car.speed + 0.5)else: self.speed = random.uniform(19 - 1.1, 19 + 0.3)time.sleep(1)# 打字类class display_text:def __init__(self, gw):self.gw = gwself.l1_oop = [] # 存储提示标签对象self.l2_oop = [] # 存储玩家打字时的标签对象self.cpm_list = [] #用正确的总输入字符次数除以总花费的时间(以分钟为单位)self.typspeed = 0.0 # 记录打字的速度self.anwser = '' # 拼接答案self.text = self.gw.road.text # 单词内容self.text2 = self.text.copy()self.text.extend(self.text2) # 单词内容翻倍 x 2self.text_number = len(self.text) / 2 # 单词个数self.loading_text()# 加载打字内容def loading_text(self):col = 1 # 列数number = 20 # 每页展示20个字for i, text in enumerate(self.text[:number]):l1 = tk.Label(gw.text_frame, text=text, bg='white', font=('微软雅黑', 15))l2 = tk.Label(gw.text_frame, text='', bg='white', font=('微软雅黑', 15))if i < int(number / 2):l1.grid(row=1, column=col, )l2.grid(row=2, column=col, )elif int(number / 2) <= i < number:l1.grid(row=3, column=col - int(number / 2), )l2.grid(row=4, column=col - int(number / 2), )col += 1l1.focus_set()l1.bind("<Key>", self.l_bind)self.l1_oop.append(l1)self.l2_oop.append(l2)# 标签绑定键盘事件def l_bind(self, event):# print(f"事件触发键盘输入:{event.char},对应的ASCII码:{event.keycode}")global FLAGif not FLAG: returnif not self.text: returnif event.keycode == 8:self.anwser = ''self.l2_oop[0].configure(text='')returnif not 65 <= event.keycode <= 90: returnself.anwser += event.charself.l2_oop[0].configure(text=self.anwser, bg='#FFFAE3')result = self.text[0]if self.anwser.strip() == result:self.cpm_list.append(result)self.l1_oop[0].configure(fg='red')self.text.remove(result)self.l1_oop.pop(0)self.l2_oop.pop(0)self.anwser = ''if not self.l1_oop and len(self.text) != 0:gw.text_frame.destroy()gw.display_text_frame()self.loading_text()returnif len(self.anwser) >= len(result):self.anwser = ''# 检测打字速度, 每分钟输入了多少字符def typing_speed(self):global FLAGtime_ = 0while FLAG:time_ += 1try:self.cpm = round(len(''.join(self.cpm_list)) / time_ * 60)self.wpm = round(len(self.cpm_list) / (time_ / 60))# 用来表示打字速度,即每分钟打多少个字(或单词)gw.cpm_label.configure(text=f'cpm:{self.cpm}')gw.wpm_label.configure(text=f'wpm:{self.wpm}')except:self.cpm = 0self.wpm = 0self.typspeed = self.cpm / 12time.sleep(1)# 游戏窗口类class GameWindow:bgcolor = '#68696E' # 画布颜色root = tk.Tk()root.title('打字小游戏开发')screenwidth = root.winfo_screenwidth()screenheight = root.winfo_screenheight()def __init__(self):pass# 窗口页面的大小def window_page_size(self,windowsize):rootwidth, rootheight = windowsizerootposx = int((self.screenwidth - rootwidth) / 2)rootposy = int((self.screenheight - rootheight) / 2) - 100self.root.geometry('{}x{}+{}+{}'.format(rootwidth, rootheight, rootposx, rootposy))time.sleep(0.1)# 选择赛道def select_road(self):def func(event):global FLAG,CARFLAG,ROADFLAG = TrueCARFLAG = Trueroad = event.widget["text"]print(road)ROAD = road[:-2]self.select_road_frame.destroy()self.window_page_size((1000, 560))self.create_canvas()configuration_project(ROAD)self.recording_time()self.display_typing_speed()self.replay_button()self.return_button()self.window_page_size((500, 300))self.select_road_frame = tk.Frame(self.root)self.select_road_frame.place(x=0, y=0, width=500, height=300)for road in ['Python赛道','Java赛道','MySql赛道']:b = tk.Button(self.select_road_frame, text=road,font=('华文行楷', 26),relief=tk.RAISED,cursor='hand2',width=12,height=1)b.pack(pady=20)b.bind("<Button-1>", func)# 创建一张画布def create_canvas(self):self.canvas = tk.Canvas(self.root, width=1000, height=400, bg=self.bgcolor)self.canvas.place(x=0, y=0)# 创建一条路——赛道def create_road(self,roadtype):# self.road = Road('Java') # 实列化一个路的对象(Java类型的路)self.road = Road(roadtype) # 实列化一个路的对象(Python类型的路)self.road_img = tk.PhotoImage(file='./sucai/road.png')self.c_road = [self.canvas.create_image(i, 200, image=self.road_img, tag=f'c_road{i}') for i in range(500, self.road.road_number * 1000, 1000)]self.tag_road = [f'c_road{i}' for i in range(500, (self.road.road_number - 2) * 1000, 1000)]# 创建两棵树def create_tree(self):self.tree1 = Tree(posx=160, posy=350,filepath='./sucai/tree1.png',treetag='tree1')self.tree1.tree_create(self.canvas)self.tree2 = Tree(posx=230, posy=340,filepath='./sucai/tree2.png', treetag='tree2')self.tree2.tree_create(self.canvas)# 创建跑程进度条def displayprogressbar(self,caroop_list):maximum = self.road.road_lengthself.progressbar_list = []for i in range(4):progressbar = ttk.Progressbar(self.canvas, length=200, maximum=maximum)progressbar.place(x=10, y= 20 if i == 0 else i*40 + 20)tk.Label(self.canvas,text=caroop_list[i].username,fg='#191970').place(x=215,y=20 if i == 0 else i*40 + 20)self.progressbar_list.append(progressbar)# 重新开始按钮def replay_button(self):def function():global FLAG,CARFLAG,end_label_list,dtFLAG = FalseCARFLAG = Falsefor t in threading.enumerate()[1:]:stop_thread(t)self.canvas.destroy()self.text_frame.destroy()if end_label_list:for i in end_label_list: i.destroy()del dtFLAG = TrueCARFLAG = Trueself.create_canvas()configuration_project(ROAD)self.recording_time()self.return_button()self.replaybutton_img = tk.PhotoImage(file='./sucai/replay.png')tk.Label(self.root,text='重新开始').place(x=920,y=480)replaybutton = tk.Button(self.root, image=self.replaybutton_img, command=function)replaybutton.place(x=910,y=400)# 返回按钮def return_button(self):def function():global FLAG,CARFLAG,ROAD,end_label_list,dtFLAG = FalseCARFLAG = FalseROAD = ''for t in threading.enumerate()[2:]:stop_thread(t)self.canvas.destroy()self.text_frame.destroy()self.cpm_label.destroy()self.wpm_label.destroy()if end_label_list:for i in end_label_list: i.destroy()del dtself.select_road()self.returnbutton_img = tk.PhotoImage(file='./sucai/return.png')returnbutton = tk.Button(self.root,text='返回',image=self.returnbutton_img,command=function)returnbutton.place(x=900,y=50)# 记录游戏时间def recording_time(self):time_label = tk.Label(self.canvas, text='时长:00:00:00', font=("华文行楷", 15), background='#DAEFE6')time_label.place(x=870, y=20)start_time = datetime.datetime.now()def run():global FLAGif FLAG:time_label.after(1000, run)update_time = datetime.datetime.now() - start_timeself.time_ = f'时长:{update_time}'.split('.')[0]time_label.configure(text=self.time_) # 不显示时长的毫秒值run()# 展示文本def display_text_frame(self):self.text_frame = tk.Frame(self.root, bg='white')self.text_frame.place(x=100, y=400, width=800, height=150)# 显示打字速度def display_typing_speed(self):self.cpm_label = tk.Label(self.root,text='cpm:0', font=("微软雅黑", 13),fg='#A52A2A')self.cpm_label.place(x=8,y=410)self.wpm_label = tk.Label(self.root, text='wpm:0', font=("微软雅黑", 13),fg='#A52A2A')self.wpm_label.place(x=8, y=440)# 播放背景音乐函数def playmusic(self,):global FLAGmixer.init()mixer.music.load('./sucai/bgmusic.mp3')mixer.music.play()while FLAG:time.sleep(2)mixer.music.stop()# 显示窗口def displaywindow(self):self.root.resizable(False, False)self.root.mainloop()def _async_raise(tid, exctype):tid = ctypes.c_long(tid)if not inspect.isclass(exctype):exctype = type(exctype)res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))if res == 0:raise ValueError("invalid thread id")elif res != 1:ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)raise SystemError("PyThreadState_SetAsyncExc failed")# 停止正在运行中的线程def stop_thread(thread):_async_raise(thread.ident, SystemExit)# 监测小车移动时的数据变化def monitoring_data(gw,caroop_list,dt):global FLAG,CARFLAG,end_label_listtime.sleep(2.5) # 休眠2.5秒后才开始gw.displayprogressbar(caroop_list) #显示完成跑道的进度条gw.canvas.delete('begin') # 删除起点线gw.road.destination(gw.canvas) # 创建终点线player_car_s = player.car.car_move_distance[0][1]timesleep3_posx_s_list = {}for i in caroop_list:timesleep3_posx_s_list[i.username] = i.car.car_move_distance[0][1]print(i.username,'已跑起来')while FLAG:CARFLAG = Falsefor idx,p in enumerate(gw.progressbar_list):p['value'] = timesleep3_posx_s_list[caroop_list[idx].username]if max(timesleep3_posx_s_list.values()) > gw.road.road_length:FLAG = Falseranking = sorted(timesleep3_posx_s_list.items(), key=lambda x: x[1]) # 排名for idx,username in enumerate(ranking[::-1]):l = tk.Label(gw.root, text=username[0] + f' 第{idx + 1}名', font=('微软雅黑', 28), bg='white')l.pack(pady=30)end_label_list.append(l)print('游戏结束')returnplayer.car.speed = dt.typspeed #使小车速度 = 打字速度player_car_s += player.car.speed #让小车此时已移动的路程加上小车速度timesleep3_posx_s_list[player.username] = player_car_sfor i, caroop in enumerate(caroop_list[1:]):caroop.car.posx += caroop.car.speed - player.car.speedtimesleep3_posx_s_list[caroop.username] = timesleep3_posx_s_list[caroop.username] + caroop.car.speedgw.road.roadmove(gw.canvas, gw.tag_road) # 赛道相对小车的速度,开始移动gw.tree1.treemove(gw.canvas) # 树1相对小车的速度,开始移动gw.tree2.treemove(gw.canvas) # 树2相对小车的速度,开始移动time.sleep(0.0095)# 配置运行流程def configuration_project(roadtype):print('游戏开始')global player,gw,dt,end_label_listtplaymusic = threading.Thread(target=gw.playmusic) # 开启一个播放背景音乐的线程tplaymusic.setDaemon(True)tplaymusic.start()gw.create_road(roadtype) # 创建赛道gw.create_tree() # 创建树gw.road.begin(gw.canvas) #创建一条起点线gw.display_text_frame() # 创建展示文本的frameend_label_list = []# 游戏结束时,存放显示名次的标签列表caroop_list = []# 添加所有玩家(小车)对象carposy_list = [90, 147, 250, 309] # 定义四个小车初始化的y轴坐标player = Player('yyds') # 创建一个真人玩家对象player.car_create(gw.canvas, carposy_list[0]) # 生成一个属于真人玩家的小车caroop_list.append(player)for i in range(3): #创建三个电脑玩家computer = Computer(f'[电脑]{i+1}')computer.car_create(gw.canvas,f'./sucai/car{i+2}.png', carposy_list[i+1], f'img{i+2}', computer.username)# 生成属于电脑玩家的小车caroop_list.append(computer)for caroop in caroop_list:tcm = threading.Thread(target=caroop.car.car_move,args=(gw.canvas,caroop.car_img)) # 为每一个玩家开启一个线程,用来启动各自的小车tcm.setDaemon(True)tcm.start()tcsc = threading.Thread(target=caroop.car.car_speed_change) #为每一辆小车定时随机改变小车的移动速度tcsc.setDaemon(True)tcsc.start()dt = display_text(gw) # 实例化一个打字所用的文本内容对象tdt = threading.Thread(target=dt.typing_speed) # 开启线程来记录打字的速度tdt.setDaemon(True)tdt.start()tmd = threading.Thread(target=monitoring_data, args=(gw, caroop_list, dt)) # 开启线程来记录每一辆小车移动时的数据变化tmd.setDaemon(True)tmd.start()def start():global gwgw = GameWindow() # 实例化一个游戏窗口对象gw.select_road() # 选择赛道gw.displaywindow()if __name__ == '__main__':start()

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。