找回密码
 会员注册
查看: 40|回复: 0

python做简单小项目,python有趣的小项目

[复制链接]

2万

主题

0

回帖

7万

积分

超级版主

积分
71772
发表于 2024-9-6 18:59:36 | 显示全部楼层 |阅读模式
大家好,小编来为大家解答以下问题,python做简单小项目,python有趣的小项目,现在让我们一起来看看吧!今天分享7个学妹看见都惊呆的Python小项目!【附源码】建议收藏界面应用1、计算器1.案例介绍本例利用Python开发一个可以进行简单的四则运算的图形化计算器,会用到Tkinter图形组件进行开发。主要知识点:PythonTkinter界面编程;计算器逻辑运算实现学习python用什么书好。本例难度为初级,适合具有Python基础和Tkinter组件编程知识的用户学习。2.设计原理要制作一个计算器,首先需要知道它由哪些部分组成。示意如下图所示。从结构上来说,一个简单的图形界面,需要由界面组件、组件的事件监听器(响应各类事件的逻辑)和具体的事件处理逻辑组成。界面实现的主要工作是创建各个界面组件对象,对其进行初始化,以及控制各组件之间的层次关系和布局。3.示例效果4.示例源码import tkinterimport mathimport tkinter.messageboxclass Calculator(object):    # 界面布局方法    def __init__(self):        # 创建主界面,并且保存到成员属性中        self.root = tkinter.Tk()        self.root.minsize(280, 450)        self.root.maxsize(280, 470)        self.root.title('计算器')        # 设置显式面板的变量        self.result = tkinter.StringVar()        self.result.set(0)        # 设置一个全局变量  运算数字和f符号的列表        self.lists = []        # 添加一个用于判断是否按下运算符号的标志        self.ispresssign = False        # 界面布局        self.menus()        self.layout()        self.root.mainloop()    # 计算器菜单界面摆放    def menus(self):        # 添加菜单        # 创建总菜单        allmenu = tkinter.Menu(self.root)        # 添加子菜单        filemenu = tkinter.Menu(allmenu, tearoff=0)        # 添加选项卡        filemenu.add_command(            label='标准型(T)            Alt+1', command=self.myfunc)        filemenu.add_command(            label='科学型(S)            Alt+2', command=self.myfunc)        filemenu.add_command(            label='程序员(P)            Alt+3', command=self.myfunc)        filemenu.add_command(label='统计信息(A)        Alt+4', command=self.myfunc)        # 添加分割线        filemenu.add_separator()        # 添加选项卡        filemenu.add_command(label='历史记录(Y)      Ctrl+H', command=self.myfunc)        filemenu.add_command(label='数字分组(I)', command=self.myfunc)        # 添加分割线        filemenu.add_separator()        # 添加选项卡        filemenu.add_command(            label='基本(B)             Ctrl+F4', command=self.myfunc)        filemenu.add_command(label='单位转换(U)      Ctrl+U', command=self.myfunc)        filemenu.add_command(label='日期计算(D)      Ctrl+E', command=self.myfunc)        menu1 = tkinter.Menu(filemenu, tearoff=0)        menu1.add_command(label='抵押(M)', command=self.myfunc)        menu1.add_command(label='汽车租赁(V)', command=self.myfunc)        menu1.add_command(label='油耗(mpg)(F)', command=self.myfunc)        menu1.add_command(label='油耗(l/100km)(U)', command=self.myfunc)        filemenu.add_cascade(label='工作表(W)', menu=menu1)        allmenu.add_cascade(label='查看(V)', menu=filemenu)        # 添加子菜单2        editmenu = tkinter.Menu(allmenu, tearoff=0)        # 添加选项卡        editmenu.add_command(label='复制(C)         Ctrl+C', command=self.myfunc)        editmenu.add_command(label='粘贴(V)         Ctrl+V', command=self.myfunc)        # 添加分割线        editmenu.add_separator()        # 添加选项卡        menu2 = tkinter.Menu(filemenu, tearoff=0)        menu2.add_command(label='复制历史记录(I)', command=self.myfunc)        menu2.add_command(            label='编辑(E)                      F2', command=self.myfunc)        menu2.add_command(label='取消编辑(N)            Esc', command=self.myfunc)        menu2.add_command(label='清除(L)    Ctrl+Shift+D', command=self.myfunc)        editmenu.add_cascade(label='历史记录(H)', menu=menu2)        allmenu.add_cascade(label='编辑(E)', menu=editmenu)        # 添加子菜单3        helpmenu = tkinter.Menu(allmenu, tearoff=0)        # 添加选项卡        helpmenu.add_command(label='查看帮助(V)       F1', command=self.myfunc)        # 添加分割线        helpmenu.add_separator()        # 添加选项卡        helpmenu.add_command(label='关于计算器(A)', command=self.myfunc)        allmenu.add_cascade(label='帮助(H)', menu=helpmenu)        self.root.config(menu=allmenu)    # 计算器主界面摆放    def layout(self):        # 显示屏        result = tkinter.StringVar()        result.set(0)        show_label = tkinter.Label(self.root, bd=3, bg='white', font=(            '宋体', 30), anchor='e', textvariable=self.result)        show_label.place(x=5, y=20, width=270, height=70)        # 功能按钮MC        button_mc = tkinter.Button(self.root, text='MC', command=self.wait)        button_mc.place(x=5, y=95, width=50, height=50)        # 功能按钮MR        button_mr = tkinter.Button(self.root, text='MR', command=self.wait)        button_mr.place(x=60, y=95, width=50, height=50)        # 功能按钮MS        button_ms = tkinter.Button(self.root, text='MS', command=self.wait)        button_ms.place(x=115, y=95, width=50, height=50)        # 功能按钮M+        button_mjia = tkinter.Button(self.root, text='M+', command=self.wait)        button_mjia.place(x=170, y=95, width=50, height=50)        # 功能按钮M-        button_mjian = tkinter.Button(self.root, text='M-', command=self.wait)        button_mjian.place(x=225, y=95, width=50, height=50)        # 功能按钮←        button_zuo = tkinter.Button(self.root, text='←', command=self.dele_one)        button_zuo.place(x=5, y=150, width=50, height=50)        # 功能按钮CE        button_ce = tkinter.Button(            self.root, text='CE', command=lambda: self.result.set(0))        button_ce.place(x=60, y=150, width=50, height=50)        # 功能按钮C        button_c = tkinter.Button(self.root, text='C', command=self.sweeppress)        button_c.place(x=115, y=150, width=50, height=50)        # 功能按钮±        button_zf = tkinter.Button(self.root, text='±', command=self.zf)        button_zf.place(x=170, y=150, width=50, height=50)        # 功能按钮√        button_kpf = tkinter.Button(self.root, text='√', command=self.kpf)        button_kpf.place(x=225, y=150, width=50, height=50)        # 数字按钮7        button_7 = tkinter.Button(            self.root, text='7', command=lambda: self.pressnum('7'))        button_7.place(x=5, y=205, width=50, height=50)        # 数字按钮8        button_8 = tkinter.Button(            self.root, text='8', command=lambda: self.pressnum('8'))        button_8.place(x=60, y=205, width=50, height=50)        # 数字按钮9        button_9 = tkinter.Button(            self.root, text='9', command=lambda: self.pressnum('9'))        button_9.place(x=115, y=205, width=50, height=50)        # 功能按钮/        button_division = tkinter.Button(            self.root, text='/', command=lambda: self.presscalculate('/'))        button_division.place(x=170, y=205, width=50, height=50)        # 功能按钮%        button_remainder = tkinter.Button(            self.root, text='//', command=lambda: self.presscalculate('//'))        button_remainder.place(x=225, y=205, width=50, height=50)        # 数字按钮4        button_4 = tkinter.Button(            self.root, text='4', command=lambda: self.pressnum('4'))        button_4.place(x=5, y=260, width=50, height=50)        # 数字按钮5        button_5 = tkinter.Button(            self.root, text='5', command=lambda: self.pressnum('5'))        button_5.place(x=60, y=260, width=50, height=50)        # 数字按钮6        button_6 = tkinter.Button(            self.root, text='6', command=lambda: self.pressnum('6'))        button_6.place(x=115, y=260, width=50, height=50)        # 功能按钮*        button_multiplication = tkinter.Button(            self.root, text='*', command=lambda: self.presscalculate('*'))        button_multiplication.place(x=170, y=260, width=50, height=50)        # 功能按钮1/x        button_reciprocal = tkinter.Button(            self.root, text='1/x', command=self.ds)        button_reciprocal.place(x=225, y=260, width=50, height=50)        # 数字按钮1        button_1 = tkinter.Button(            self.root, text='1', command=lambda: self.pressnum('1'))        button_1.place(x=5, y=315, width=50, height=50)        # 数字按钮2        button_2 = tkinter.Button(            self.root, text='2', command=lambda: self.pressnum('2'))        button_2.place(x=60, y=315, width=50, height=50)        # 数字按钮3        button_3 = tkinter.Button(            self.root, text='3', command=lambda: self.pressnum('3'))        button_3.place(x=115, y=315, width=50, height=50)        # 功能按钮-        button_subtraction = tkinter.Button(            self.root, text='-', command=lambda: self.presscalculate('-'))        button_subtraction.place(x=170, y=315, width=50, height=50)        # 功能按钮=        button_equal = tkinter.Button(            self.root, text='=', command=lambda: self.pressequal())        button_equal.place(x=225, y=315, width=50, height=105)        # 数字按钮0        button_0 = tkinter.Button(            self.root, text='0', command=lambda: self.pressnum('0'))        button_0.place(x=5, y=370, width=105, height=50)        # 功能按钮.        button_point = tkinter.Button(            self.root, text='.', command=lambda: self.pressnum('.'))        button_point.place(x=115, y=370, width=50, height=50)        # 功能按钮+        button_plus = tkinter.Button(            self.root, text='+', command=lambda: self.presscalculate('+'))        button_plus.place(x=170, y=370, width=50, height=50)    # 计算器菜单功能    def myfunc(self):        tkinter.messagebox.showinfo('', '预留接口,学成之后,你是不是有冲动添加该功能.')    # 数字方法    def pressnum(self, num):        # 全局化变量        # 判断是否按下了运算符号        if self.ispresssign == False:            pass        else:            self.result.set(0)            # 重置运算符号的状态            self.ispresssign = False        if num == '.':            num = '0.'        # 获取面板中的原有数字        oldnum = self.result.get()        # 判断界面数字是否为0        if oldnum == '0':            self.result.set(num)        else:            # 连接上新按下的数字            newnum = oldnum + num            # 将按下的数字写到面板中            self.result.set(newnum)    # 运算函数    def presscalculate(self, sign):        # 保存已经按下的数字和运算符号        # 获取界面数字        num = self.result.get()        self.lists.append(num)        # 保存按下的操作符号        self.lists.append(sign)        # 设置运算符号为按下状态        self.ispresssign = True    # 获取运算结果    def pressequal(self):        # 获取所有的列表中的内容(之前的数字和操作)        # 获取当前界面上的数字        curnum = self.result.get()        # 将当前界面的数字存入列表        self.lists.append(curnum)        # 将列表转化为字符串        calculatestr = ''.join(self.lists)        # 使用eval执行字符串中的运算即可        endnum = eval(calculatestr)        # 将运算结果显示在界面中        self.result.set(str(endnum)[:10])        if self.lists != 0:            self.ispresssign = True        # 清空运算列表        self.lists.clear()    # 暂未开发说明    def wait(self):        tkinter.messagebox.showinfo('', '更新中......')    # ←按键功能    def dele_one(self):        if self.result.get() == '' or self.result.get() == '0':            self.result.set('0')            return        else:            num = len(self.result.get())            if num > 1:                strnum = self.result.get()                strnum = strnum[0:num - 1]                self.result.set(strnum)            else:                self.result.set('0')    # ±按键功能    def zf(self):        strnum = self.result.get()        if strnum[0] == '-':            self.result.set(strnum[1:])        elif strnum[0] != '-' and strnum != '0':            self.result.set('-' + strnum)    # 1/x按键功能    def ds(self):        dsnum = 1 / int(self.result.get())        self.result.set(str(dsnum)[:10])        if self.lists != 0:            self.ispresssign = True        # 清空运算列表        self.lists.clear()    # C按键功能    def sweeppress(self):        self.lists.clear()        self.result.set(0)    # √按键功能    def kpf(self):        strnum = float(self.result.get())        endnum = math.sqrt(strnum)        if str(endnum)[-1] == '0':            self.result.set(str(endnum)[:-2])        else:            self.result.set(str(endnum)[:10])        if self.lists != 0:            self.ispresssign = True        # 清空运算列表        self.lists.clear()# 实例化对象my_calculator = Calculator()2、记事本1.案例介绍tkinter是Python下面向tk的图形界面接口库,可以方便地进行图形界面设计和交互操作编程。tkinter的优点是简单易用、与Python的结合度好。tkinter在Python3.x下默认集成,不需要额外的安装操作;不足之处为缺少合适的可视化界面设计工具,需要通过代码来完成窗口设计和元素布局。本例采用的Python版本为3.8,如果想在python2.x下使用tkinter,请先进行安装。需要注意的是,不同Python版本下的tkinter使用方式可能略有不同,建议采用Python3.x版本。本例难度为中级,适合具有Python基础和Tkinter组件编程知识的用户学习。2.示例效果3.示例源码from tkinter import *from tkinter.filedialog import *from tkinter.messagebox import *import osfilename = ""def author():    showinfo(title="作者", message="Python")def power():    showinfo(title="版权信息", message="课堂练习")def mynew():    global top, filename, textPad    top.title("未命名文件")    filename = None    textPad.delete(1.0, END)def myopen():    global filename    filename = askopenfilename(defaultextension=".txt")    if filename == "":        filename = None    else:        top.title("记事本" + os.path.basename(filename))        textPad.delete(1.0, END)        f = open(filename, 'r')        textPad.insert(1.0, f.read())        f.close()def mysave():    global filename    try:        f = open(filename, 'w')        msg = textPad.get(1.0, 'end')        f.write(msg)        f.close()    except:        mysaveas()def mysaveas():    global filename    f = asksaveasfilename(initialfile="未命名.txt", defaultextension=".txt")    filename = f    fh = open(f, 'w')    msg = textPad.get(1.0, END)    fh.write(msg)    fh.close()    top.title("记事本 " + os.path.basename(f))def cut():    global textPad    textPad.event_generate("<>")def copy():    global textPad    textPad.event_generate("<>")def paste():    global textPad    textPad.event_generate("<>")def undo():    global textPad    textPad.event_generate("<>")def redo():    global textPad    textPad.event_generate("<>")def select_all():    global textPad    # textPad.event_generate("<>")    textPad.tag_add("sel", "1.0", "end")def find():    t = Toplevel(top)    t.title("查找")    t.geometry("260x60+200+250")    t.transient(top)    Label(t, text="查找:").grid(row=0, column=0, sticky="e")    v = StringVar()    e = Entry(t, width=20, textvariable=v)    e.grid(row=0, column=1, padx=2, pady=2, sticky="we")    e.focus_set()    c = IntVar()    Checkbutton(t, text="不区分大小写", variable=c).grid(row=1, column=1, sticky='e')    Button(t, text="查找所有", command=lambda: search(v.get(), c.get(),                                                  textPad, t, e)).grid(row=0, column=2, sticky="e" + "w", padx=2,                                                                       pady=2)    def close_search():        textPad.tag_remove("match", "1.0", END)        t.destroy()    t.protocol("WM_DELETE_WINDOW", close_search)def mypopup(event):    # global editmenu    editmenu.tk_popup(event.x_root, event.y_root)def search(needle, cssnstv, textPad, t, e):    textPad.tag_remove("match", "1.0", END)    count = 0    if needle:        pos = "1.0"        while True:            pos = textPad.search(needle, pos, nocase=cssnstv, stopindex=END)            if not pos:                break            lastpos = pos + str(len(needle))            textPad.tag_add("match", pos, lastpos)            count += 1            pos = lastpos        textPad.tag_config('match', fg='yellow', bg="green")        e.focus_set()        t.title(str(count) + "个被匹配")top = Tk()top.title("记事本")top.geometry("600x400+100+50")menubar = Menu(top)# 文件功能filemenu = Menu(top)filemenu.add_command(label="新建", accelerator="Ctrl+N", command=mynew)filemenu.add_command(label="打开", accelerator="Ctrl+O", command=myopen)filemenu.add_command(label="保存", accelerator="Ctrl+S", command=mysave)filemenu.add_command(label="另存为", accelerator="Ctrl+shift+s", command=mysaveas)menubar.add_cascade(label="文件", menu=filemenu)# 编辑功能editmenu = Menu(top)editmenu.add_command(label="撤销", accelerator="Ctrl+Z", command=undo)editmenu.add_command(label="重做", accelerator="Ctrl+Y", command=redo)editmenu.add_separator()editmenu.add_command(label="剪切", accelerator="Ctrl+X", command=cut)editmenu.add_command(label="复制", accelerator="Ctrl+C", command=copy)editmenu.add_command(label="粘贴", accelerator="Ctrl+V", command=paste)editmenu.add_separator()editmenu.add_command(label="查找", accelerator="Ctrl+F", command=find)editmenu.add_command(label="全选", accelerator="Ctrl+A", command=select_all)menubar.add_cascade(label="编辑", menu=editmenu)# 关于 功能aboutmenu = Menu(top)aboutmenu.add_command(label="作者", command=author)aboutmenu.add_command(label="版权", command=power)menubar.add_cascade(label="关于", menu=aboutmenu)top['menu'] = menubar# shortcutbar = Frame(top, height=25, bg='light sea green')# shortcutbar.pack(expand=NO, fill=X)# Inlabe = Label(top, width=2, bg='antique white')# Inlabe.pack(side=LEFT, anchor='nw', fill=Y)textPad = Text(top, undo=True)textPad.pack(expand=YES, fill=BOTH)scroll = Scrollbar(textPad)textPad.config(yscrollcommand=scroll.set)scroll.config(command=textPad.yview)scroll.pack(side=RIGHT, fill=Y)# 热键绑定textPad.bind("", mynew)textPad.bind("", mynew)textPad.bind("", myopen)textPad.bind("", myopen)textPad.bind("", mysave)textPad.bind("", mysave)textPad.bind("", select_all)textPad.bind("", select_all)textPad.bind("", find)textPad.bind("", find)textPad.bind("", mypopup)top.mainloop()3、登录和注册1.案例介绍本例设计一个用户登录和注册模块,使用Tkinter框架构建界面,主要用到画布、文本框、按钮等组件。涉及知识点:PythonTkinter界面编程、pickle数据存储。本例实现了基本的用户登录和注册互动界面,并提供用户信息存储和验证。pickle是python语言的一个标准模块,安装python后已包含pickle库,不需要单独再安装。pickle模块实现了基本的数据序列化和反序列化。通过pickle模块的序列化操作能够将程序中运行的对象信息保存到文件中去,永久存储;通过pickle模块的反序列化操作,能够从文件中创建上一次程序保存的对象。本例难度为中级,适合具有Python基础和Tkinter组件编程知识的用户学习。2.示例效果3.示例源码import tkinter as tkimport pickleimport tkinter.messageboxfrom IL import Image, ImageTk# 设置窗口---最开始的母体窗口window = tk.Tk()  # 建立一个窗口window.title('欢迎登录')window.geometry('450x300')  # 窗口大小为300x200# 画布canvas = tk.Canvas(window, height=200, width=900)# 加载图片im = Image.open("images/01.png")image_file = ImageTk.PhotoImage(im)# image_file = tk.PhotoImage(file='images/01.gif')image = canvas.create_image(100, 40, anchor='nw', image=image_file)canvas.pack(side='top')# 两个文字标签,用户名和密码两个部分tk.Label(window, text='用户名').place(x=100, y=150)tk.Label(window, text='密  码').place(x=100, y=190)var_usr_name = tk.StringVar()  # 讲文本框的内容,定义为字符串类型var_usr_name.set('amoxiang@163.com')  # 设置默认值var_usr_pwd = tk.StringVar()# 第一个输入框-用来输入用户名的。# textvariable 获取文本框的内容entry_usr_name = tk.Entry(window, textvariable=var_usr_name)entry_usr_name.place(x=160, y=150)# 第二个输入框-用来输入密码的。entry_usr_pwd = tk.Entry(window, textvariable=var_usr_pwd, show='*')entry_usr_pwd.place(x=160, y=190)def usr_login():    usr_name = var_usr_name.get()    usr_pwd = var_usr_pwd.get()    try:        with open('usrs_info.pickle', 'rb') as usr_file:            usrs_info = pickle.load(usr_file)    except FileNotFoundError:        with open('usrs_info.pickle', 'wb') as usr_file:            usrs_info = {'admin': 'admin'}            pickle.dump(usrs_info, usr_file)    if usr_name in usrs_info:        if usr_pwd == usrs_info[usr_name]:            tk.messagebox.showinfo(                title='欢迎光临', message=usr_name + ':请进入个人首页,查看最新资讯')        else:            tk.messagebox.showinfo(message='错误提示:密码不对,请重试')    else:        is_sign_up = tk.messagebox.askyesno('提示', '你还没有注册,请先注册')        print(is_sign_up)        if is_sign_up:            usr_sign_up()# 注册按钮def usr_sign_up():    def sign_to_Mofan_Python():        np = new_pwd.get()        npf = new_pwd_confirm.get()        nn = new_name.get()        # 上面是获取数据,下面是查看一下是否重复注册过        with open('usrs_info.pickle', 'rb') as usr_file:            exist_usr_info = pickle.load(usr_file)            if np != npf:                tk.messagebox.showerror('错误提示', '密码和确认密码必须一样')            elif nn in exist_usr_info:                tk.messagebox.showerror('错误提示', '用户名早就注册了!')            else:                exist_usr_info[nn] = np                with open('usrs_info.pickle', 'wb') as usr_file:                    pickle.dump(exist_usr_info, usr_file)                tk.messagebox.showinfo('欢迎', '你已经成功注册了')                window_sign_up.destroy()    # 点击注册之后,会弹出这个窗口界面。    window_sign_up = tk.Toplevel(window)    window_sign_up.title('欢迎注册')    window_sign_up.geometry('360x200')  # 中间是x,而不是*号    # 用户名框--这里输入用户名框。    new_name = tk.StringVar()    new_name.set('amoxiang@163.com')  # 设置的是默认值    tk.Label(window_sign_up, text='用户名').place(x=10, y=10)    entry_new_name = tk.Entry(window_sign_up, textvariable=new_name)    entry_new_name.place(x=100, y=10)    # 新密码框--这里输入注册时候的密码    new_pwd = tk.StringVar()    tk.Label(window_sign_up, text='密  码').place(x=10, y=50)    entry_usr_pwd = tk.Entry(window_sign_up, textvariable=new_pwd, show='*')    entry_usr_pwd.place(x=100, y=50)    # 密码确认框    new_pwd_confirm = tk.StringVar()    tk.Label(window_sign_up, text='确认密码').place(x=10, y=90)    entry_usr_pwd_confirm = tk.Entry(        window_sign_up, textvariable=new_pwd_confirm, show='*')    entry_usr_pwd_confirm.place(x=100, y=90)    btn_confirm_sign_up = tk.Button(        window_sign_up, text=' 注  册 ', command=sign_to_Mofan_Python)    btn_confirm_sign_up.place(x=120, y=130)# 创建注册和登录按钮btn_login = tk.Button(window, text=' 登  录 ', command=usr_login)btn_login.place(x=150, y=230)  # 用place来处理按钮的位置信息。btn_sign_up = tk.Button(window, text=' 注  册 ', command=usr_sign_up)btn_sign_up.place(x=250, y=230)window.mainloop()游戏开发1、20481.游戏简介2048是一款比较流行的数字游戏。游戏规则:每次可按上、下、左、右方向键滑动数字,每滑动一次,所有数字都会往滑动方向靠拢,同时在空白位置随机出现一个数字,相同数字在靠拢时会相加。不断叠加最终拼出2048这个数字算成功。2048最早于2014年3月20日发行。原版2048首先在GitHub上发布,原作者是GabrieleCirulli,后被移植到各个平台。本例难度为初级,适合具有Python基础和Pygame编程知识的用户学习。2.设计原理这个游戏的本质是二维列表,就以4*4的二位列表来分析关键的逻辑以及实现。二维列表如下图:所有的操作都是对这个二维列表的数据的操作。分为上下左右四个方向。先说向左的方向(如图)。向左操作的结果如下图;当向左的方向是,所有的数据沿着水平方向向左跑。水平说明操作的是二维列表的一行,而垂直操作的则是二位列表的一列。这样就可以将二维列表的操作变成遍历后对一维列表的操作。向左说明数据的优先考虑的位置是从左开始的。这样就确定了一维列表的遍历开始的位置。上面第2个图共四行,每一个行都能得到一个列表。list1:[0,0,2,0]list2:[0,4,2,0]list3:[0,0,4,4]list4:[2,0,2,0]这样一来向左的方向就变成。从上到下获得每一行的列表,方向向左。参数(row,left)。其他的三个方向在开始的时候记住是怎样获得以为列表的,等操作完才放回去这样就能实现了。**3.示例效果 **4.示例源码import randomimport sysimport pygamefrom pygame.locals import *PIXEL = 150SCORE_PIXEL = 100SIZE = 4# 地图的类class Map:    def __init__(self, size):        self.size = size        self.score = 0        self.map = [[0 for i in range(size)] for i in range(size)]        self.add()        self.add()    # 新增2或4,有1/4概率产生4    def add(self):        while True:            p = random.randint(0, self.size * self.size - 1)            if self.map[int(p / self.size)][int(p % self.size)] == 0:                x = random.randint(0, 3) > 0 and 2 or 4                self.map[int(p / self.size)][int(p % self.size)] = x                self.score += x                break    # 地图向左靠拢,其他方向的靠拢可以通过适当旋转实现,返回地图是否更新    def adjust(self):        changed = False        for a in self.map:            b = []            last = 0            for v in a:                if v != 0:                    if v == last:                        b.append(b.pop() << 1)                        last = 0                    else:                        b.append(v)                        last = v            b += [0] * (self.size - len(b))            for i in range(self.size):                if a[i] != b[i]:                    changed = True            a[:] = b        return changed     # 逆时针旋转地图90度    def rotate90(self):        self.map = [[self.map[c][r]                     for c in range(self.size)] for r in reversed(range(self.size))]     # 判断游戏结束    def over(self):        for r in range(self.size):            for c in range(self.size):                if self.map[r][c] == 0:                    return False        for r in range(self.size):            for c in range(self.size - 1):                if self.map[r][c] == self.map[r][c + 1]:                    return False        for r in range(self.size - 1):            for c in range(self.size):                if self.map[r][c] == self.map[r + 1][c]:                    return False        return True     def moveUp(self):        self.rotate90()        if self.adjust():            self.add()        self.rotate90()        self.rotate90()        self.rotate90()     def moveRight(self):        self.rotate90()        self.rotate90()        if self.adjust():            self.add()        self.rotate90()        self.rotate90()     def moveDown(self):        self.rotate90()        self.rotate90()        self.rotate90()        if self.adjust():            self.add()        self.rotate90()     def moveLeft(self):        if self.adjust():            self.add() # 更新屏幕 def show(map):    for i in range(SIZE):        for j in range(SIZE):            # 背景颜色块            screen.blit(map.map[i][j] == 0 and block[(i + j) % 2]                        or block[2 + (i + j) % 2], (PIXEL * j, IXEL * i))            # 数值显示            if map.map[i][j] != 0:                map_text = map_font.render(                    str(map.map[i][j]), True, (106, 90, 205))                text_rect = map_text.get_rect()                text_rect.center = (PIXEL * j + IXEL / 2,                                    IXEL * i + IXEL / 2)                screen.blit(map_text, text_rect)    # 分数显示    screen.blit(score_block, (0, IXEL * SIZE))    score_text = score_font.render((map.over(    ) and "Game over with score " or "Score: ") + str(map.score), True, (106, 90, 205))    score_rect = score_text.get_rect()    score_rect.center = (PIXEL * SIZE / 2, IXEL * SIZE + SCORE_PIXEL / 2)    screen.blit(score_text, score_rect)    pygame.display.update() map = Map(SIZE)pygame.init()screen = pygame.display.set_mode((PIXEL * SIZE, IXEL * SIZE + SCORE_PIXEL))pygame.display.set_caption("2048")block = [pygame.Surface((PIXEL, IXEL)) for i in range(4)]# 设置颜色block[0].fill((152, 251, 152))block[1].fill((240, 255, 255))block[2].fill((0, 255, 127))block[3].fill((225, 255, 255))score_block = pygame.Surface((PIXEL * SIZE, SCORE_PIXEL))score_block.fill((245, 245, 245))# 设置字体map_font = pygame.font.Font(None, int(PIXEL * 2 / 3))score_font = pygame.font.Font(None, int(SCORE_PIXEL * 2 / 3))clock = pygame.time.Clock()show(map) while not map.over():    # 12为实验参数    clock.tick(12)    for event in pygame.event.get():        if event.type == QUIT:            sys.exit()    # 接收玩家操作    pressed_keys = pygame.key.get_pressed()    if pressed_keys[K_w] or pressed_keys[K_UP]:        map.moveUp()    elif pressed_keys[K_s] or pressed_keys[K_DOWN]:        map.moveDown()    elif pressed_keys[K_a] or pressed_keys[K_LEFT]:        map.moveLeft()    elif pressed_keys[K_d] or pressed_keys[K_RIGHT]:        map.moveRight()    show(map) # 游戏结束pygame.time.delay(3000) 2、贪吃蛇 1. 案例介绍 贪吃蛇是一款经典的益智游戏,简单又耐玩。该游戏通过控制蛇头方向吃蛋,从而使得蛇变得越来越长。通过上下左右方向键控制蛇的方向,寻找吃的东西,每吃一口就能得到一定的积分,而且蛇的身子会越吃越长,身子越长玩的难度就越大,不能碰墙,不能咬到自己的身体,更不能咬自己的尾巴,等到了一定的分数,就能过关,然后继续玩下一关。本例难度为中级,适合具有 Python 基础和 Pygame 编程知识的用户学习。 2. 设计要点 游戏是基于 PyGame 框架制作的,程序核心逻辑如下:游戏界面分辨率是 640*480,蛇和食物都是由 1 个或多个 20*20 像素的正方形块儿(为了方便,下文用点表示 20*20 像素的正方形块儿) 组成,这样共有 32*24 个点,使用 pygame.draw.rect 来绘制每一个点;初始化时蛇的长度是 3,食物是 1 个点,蛇初始的移动的方向是右,用一个数组代表蛇,数组的每个元素是蛇每个点的坐标,因此数组的第一个坐标是蛇尾,最后一个坐标是蛇头;游戏开始后,根据蛇的当前移动方向,将蛇运动方向的前方的那个点 append 到蛇数组的末位,再把蛇尾去掉,蛇的坐标数组就相当于往前挪了一位;如果蛇吃到了食物,即蛇头的坐标等于食物的坐标,那么在第 2 点中蛇尾就不用去掉,就产生了蛇长度增加的效果;食物被吃掉后,随机在空的位置(不能与蛇的身体重合) 再生成一个;通过 PyGame 的 event 监控按键,改变蛇的方向,例如当蛇向右时,下一次改变方向只能向上或者向下;当蛇撞上自身或墙壁,游戏结束,蛇头装上自身,那么蛇坐标数组里就有和舌头坐标重复的数据,撞上墙壁则是蛇头坐标超过了边界,都很好判断;其他细节:做了个开始的欢迎界面;食物的颜色随机生成;吃到实物的时候有声音提示等。 3. 示例效果 4. 示例源码 2、贪吃蛇 1. 案例介绍 贪吃蛇是一款经典的益智游戏,简单又耐玩。该游戏通过控制蛇头方向吃蛋,从而使得蛇变得越来越长。通过上下左右方向键控制蛇的方向,寻找吃的东西,每吃一口就能得到一定的积分,而且蛇的身子会越吃越长,身子越长玩的难度就越大,不能碰墙,不能咬到自己的身体,更不能咬自己的尾巴,等到了一定的分数,就能过关,然后继续玩下一关。本例难度为中级,适合具有 Python 基础和 Pygame 编程知识的用户学习。 2. 设计要点 游戏是基于 PyGame 框架制作的,程序核心逻辑如下:游戏界面分辨率是 640*480,蛇和食物都是由 1 个或多个 20*20 像素的正方形块儿(为了方便,下文用点表示 20*20 像素的正方形块儿) 组成,这样共有 32*24 个点,使用 pygame.draw.rect 来绘制每一个点;初始化时蛇的长度是 3,食物是 1 个点,蛇初始的移动的方向是右,用一个数组代表蛇,数组的每个元素是蛇每个点的坐标,因此数组的第一个坐标是蛇尾,最后一个坐标是蛇头;游戏开始后,根据蛇的当前移动方向,将蛇运动方向的前方的那个点 append 到蛇数组的末位,再把蛇尾去掉,蛇的坐标数组就相当于往前挪了一位;如果蛇吃到了食物,即蛇头的坐标等于食物的坐标,那么在第 2 点中蛇尾就不用去掉,就产生了蛇长度增加的效果;食物被吃掉后,随机在空的位置(不能与蛇的身体重合) 再生成一个;通过 PyGame 的 event 监控按键,改变蛇的方向,例如当蛇向右时,下一次改变方向只能向上或者向下;当蛇撞上自身或墙壁,游戏结束,蛇头装上自身,那么蛇坐标数组里就有和舌头坐标重复的数据,撞上墙壁则是蛇头坐标超过了边界,都很好判断;其他细节:做了个开始的欢迎界面;食物的颜色随机生成;吃到实物的时候有声音提示等。 3. 示例效果 4. 示例源码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-10 14:01 , Processed in 0.436684 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表