目录:
1.项目介绍
2.代码
3.结尾
项目介绍
本项目由Fool开发,是Python初学者不错的进阶项目。
主要由tkinter和pygame实现,如有不足的地方,请大家指出
结构:
电子木鱼
-- game_log
-- log.log
-- icon
-- muyu.ico
-- image
-- bg.png
-- gongde.png
-- Logo.png
代码
pygame核心代码(Game.py):
import pygame #导入模块
import time
class Game(object): #创建主类
def __init__(self, sg, **op):
self.exitwindow = op['exit_window'] #退出时显示的窗口
self.screen = None
self.f = None
self.sg = sg
try:
self.count = int(op['count']) #打开进度时的次数
self.base_count = int(op['count'])
except KeyError:
self.count = 0
self.speed = None
self.rect_my = None
self.bg = None
self.img_gd = None
self.muyumusic = None
def init(self):
pygame.init()
pygame.display.init()
pygame.mixer.init()
# 设置窗口大小,以及名称
self.screen = pygame.display.set_mode((1000, 800))
self.screen.fill((255, 255, 255))
pygame.display.set_caption("电子木鱼")
# 加载图片、声音(敲打声,功德,木鱼,背景)
self.muyumusic = pygame.mixer.Sound('sound\\muyu.mp3')
self.img_gd = pygame.image.load("image\\gongde.png")
img_muyu = pygame.image.load("image\\muyu.png")
self.bg = pygame.image.load("image\\bg.png")
# 设置'功德'显示位置,以及设置木鱼图片的初始位置
self.rect_my = img_muyu.get_rect().move(300, 200)
# 设置功德上升的速度,以及控制功德移动
self.speed = [0, -20]
# 显示木鱼
self.screen.blit(img_muyu, self.rect_my)
# 计数器
self.f = pygame.font.SysFont('Microsoft YaHei UI', 30, True)
text1 = self.f.render("今日积累功德" + str(self.count) + "次", True, (255, 0, 0), (255, 255, 255))
text1Rect = text1.get_rect()
text1Rect.topleft = (700, 50)
self.screen.blit(text1, text1Rect)
# 设置移动函数
def move(self, image, x, y):
rect = image.get_rect().move(x, y)
i = 5
while i > 0:
rect_init = rect
rect = rect.move(self.speed)
self.screen.blit(self.bg, rect_init)
self.screen.blit(image, rect)
pygame.display.flip()
time.sleep(0.1)
i -= 1
self.screen.blit(self.bg, rect)
def go(self):
try:
while True:
for event in pygame.event.get():
if pygame.mouse.get_focused():
# 获取光标所在的位置
ball_x, ball_y = pygame.mouse.get_pos()
# 检测鼠标点击事件
else:
ball_x, ball_y = 0, 0
# noinspection PyUnboundLocalVariable
if pygame.Rect.collidepoint(self.rect_my, (ball_x, ball_y)) and event.type == pygame.MOUSEBUTTONDOWN:
self.muyumusic.play()
self.move(self.img_gd, 400, 150)
self.count += 1
text1 = self.f.render("今日积累功德" + str(self.count) + "次", True, (255, 0, 0), (255, 255, 255))
text1Rect = text1.get_rect()
text1Rect.topleft = (700, 50)
self.screen.blit(text1, text1Rect)
print(self.count)
if event.type == pygame.QUIT:
ew = self.exitwindow(self.count)
if self.count != 0 and self.count != self.base_count:
if ew.asksave():
ew.save()
pygame.quit()
self.sg(Game, self.exitwindow).show()
pygame.display.flip()
except pygame.error as e:
if str(e) != 'video system not initialized': # 判断是否为退出错误,否则报错
raise
UI代码,主要由tkinter实现(GameWindow.py):
# 导入模块
from tkinter import *
from tkinter import ttk
import tkinter.messagebox
import tkinter.filedialog
import tkinter.font
import time
import sys
# 定义功能函数
def add(_list):
v = ''
for item in _list:
v += item
return v
def insert(_list, value, index=None):
if index is None:
index = []
for i in index:
_list.insert(i, value)
class GameExit(object): # 游戏退出时执行
def __init__(self, count=0):
self.fn = 'game_log\\log.log'
self.log = 'MuyuGameLog:\ntime=%s\ncount=%s\n%s\n' % (
time.strftime('%Y-%m-%d %H:%M:%S 星期%w -- %z', time.localtime()), str(count), '-'*50)
@staticmethod
def asksave(): # 询问是否保存
return tkinter.messagebox.askyesno('选择', '是否保存当前进度?')
def save(self): # 保存
with open(self.fn, 'a') as tf:
tf.write(self.log)
tkinter.messagebox.showinfo('提示', '进度已成功保存')
class StartGame(object): # 开始游戏前执行
def __init__(self, GameObj, ew: GameExit):
self.c = None
self.old_win = None
self.tree = None
with open('用前必看.txt', encoding='utf-8') as help_file:
self.help_string = help_file.read()
self.GO = None
self.ew = ew
self.time = time.strftime('%Y-%m-%d %H:%M:%S %w -- %z', time.localtime())
self.GameObj = GameObj
pbl_string = f'Powered by Python{sys.version_info[0]}.{sys.version_info[1]}.{sys.version_info[2]} Tk/Tcl Ui Module And Pygame Game Module'
self.win = Tk()
self.win.title('电子木鱼(作者:金针菇)')
self.win.resizable(0, 0)
self.win.iconbitmap('icon\\muyu.ico')
self.ScreenWidth = self.win.winfo_screenwidth()
self.ScreenHeight = self.win.winfo_screenheight()
width = 310
height = 165
left = (self.ScreenWidth - width) / 2
top = (self.ScreenHeight - height) / 2
self.win.geometry("%dx%d+%d+%d" % (width, height, left, top))
self.win.wm_attributes('-topmost', 1)
font = tkinter.font.Font(family='微软雅黑', size=20)
self.wl = ttk.Label(self.win, text='欢迎使用电子木鱼!', font=font)
self.begb = ttk.Button(self.win, text='新建木鱼', width=10, command=self.begin)
self.oldb = ttk.Button(self.win, text='打开旧进度', width=10, command=self.openold)
self.exitb = ttk.Button(self.win, text='用前必读', width=10, command=self.help)
self.pbl = Label(self.win, text=pbl_string, font=('微软雅黑', 6))
def close(self):
self.win.destroy()
exit(0)
# 功能
def help(self):
help_win = Toplevel(self.win)
help_win.title('帮助')
help_win.wm_attributes('-topmost', 1)
width = 700
height = 500
left = (self.ScreenWidth - width) / 2
top = (self.ScreenHeight - height) / 2
help_win.geometry("%dx%d+%d+%d" % (width, height, left, top))
logo = PhotoImage(file='image\\Logo.png')
ht = Text(help_win, width=80, font=('微软雅黑', 10), background='#EEEEEE')
ht.insert(END, self.help_string)
ht.config(state=DISABLED)
ht.place(x=22, y=10)
Label(ht, image=logo, relief=SUNKEN, borderwidth=5).place(x=480, y=300)
h_scrollbar0 = Scrollbar(help_win)
h_scrollbar0.pack(side=RIGHT, fill=Y)
ht['yscrollcommand'] = h_scrollbar0.set
h_scrollbar0['command'] = ht.yview
h_scrollbar1 = Scrollbar(help_win, orient=HORIZONTAL)
h_scrollbar1.pack(side=BOTTOM, fill=X)
ht['xscrollcommand'] = h_scrollbar1.set
h_scrollbar1['command'] = ht.xview
help_win.mainloop()
def begin(self):
self.win.destroy()
self.GO = self.GameObj(StartGame, exit_window=self.ew, count=0)
self.GO.init()
self.GO.go()
def check(self, event):
sel = event.widget.selection()
try:
self.GO = self.GameObj(StartGame, count=self.tree.item(sel, "values")[2], exit_window=self.ew)
self.GO.init()
self.win.destroy()
self.GO.go()
except IndexError:
pass
def clear(self):
if tkinter.messagebox.askyesno('选择', '您确定要清空所有进度吗?'):
open('game_log\\log.log', 'w').close()
x = self.tree.get_children()
for item in x:
self.tree.delete(item)
tkinter.messagebox.showinfo('提示', '已成功清空进度!')
def delete(self, event):
sel = event.widget.selection()
with open('game_log\\log.log', 'w') as lf:
index = int(self.tree.item(sel, "values")[0])-1
self.c.pop(index)
insert(self.c, f"\n{'-'*50}\n", [item for item in range(len(self.c)) if item % 2 == 1])
lf.write(add(self.c))
self.tree.delete(sel)
def openold(self):
self.old_win = Toplevel(self.win)
self.old_win.iconbitmap('icon\\muyu.ico')
self.old_win.title('双击选择进度')
self.old_win.wm_attributes('-topmost', 1)
width = 418
height = 305
left = (self.ScreenWidth - width) / 2
top = (self.ScreenHeight - height) / 2
self.old_win.geometry("%dx%d+%d+%d" % (width, height, left, top))
self.old_win.resizable(0, 0)
labelframe = LabelFrame(self.old_win, text="进度列表")
labelframe.place(x=17, y=15)
self.tree = ttk.Treeview(labelframe, show="headings", columns=("a", "b", "c"))
vbar = ttk.Scrollbar(labelframe, orient=VERTICAL, command=self.tree.yview)
self.tree.configure(yscrollcommand=vbar.set)
self.tree.column("a", width=50, anchor="center")
self.tree.column("b", width=250, anchor="center")
self.tree.column("c", width=80, anchor="center")
self.tree.heading("a", text="编号")
self.tree.heading("b", text="时间")
self.tree.heading("c", text="敲击次数")
with open('game_log\\log.log', encoding='gbk') as tf:
self.c = tf.read().split(f'\n{"-"*50}\n')
for i in range(len(self.c)):
try:
_time = self.c[i].split('\n')[1].split('=')[1].split(' -- ')[0]
_count = self.c[i].split('\n')[2].split('=')[1]
self.tree.insert("", 'end', values=(i+1, _time, _count))
except IndexError:
pass
ttk.Button(self.old_win, text='清空进度', command=self.clear).place(x=170, y=270)
self.tree.bind("<Double-1>", self.check)
self.tree.bind("<Delete>", self.delete)
self.tree.pack()
self.old_win.mainloop()
def gettime(self):
return self.time
def show(self):
self.wl.place(x=38, y=10)
self.begb.place(x=115, y=55)
self.oldb.place(x=115, y=82)
self.exitb.place(x=115, y=110)
self.pbl.place(x=15, y=150)
self.win.mainloop()
主程序,可用于快捷方式入口(main.py):
# 很简单,不用多加注释了吧。。。
import GameWindow
import Game
ig = GameWindow.StartGame(Game.Game, GameWindow.GameExit)
ig.show()
想要图片和音频私信我哦~
加个关注吧!