Object-1 电子木鱼项目开发

目录:

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()

想要图片和音频私信我哦~

加个关注吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值