Python实例练手项目汇总(附源码)

Posted aszeno

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python实例练手项目汇总(附源码)相关的知识,希望对你有一定的参考价值。

 

 Python学习基础后,是不是不知道怎么加固练习?今天分享几个小游戏,让你在游戏中把知识给巩固了。

小时候大家一定都玩过俄罗斯方块,下面我们看看Python是怎么实现这个游戏的.

 

1、绑定功能

技术图片
# 绑定功能
class App(Frame):
    def __init__(self,master):
        Frame.__init__(self)
        master.bind(<Up>,self.Up)
        master.bind(<Left>,self.Left)
        master.bind(<Right>,self.Right)
        master.bind(<Down>,self.Down)

        master.bind(<space>,self.Space)
        master.bind(<Control-Shift-Key-F12>,self.Play)
        master.bind(<Key-P>,self.Pause)
        master.bind(<Key-S>,self.StartByS)

        # rgb颜色值
        self.backg="#%02x%02x%02x" % (120,150,30)    #大背景
        self.frontg="#%02x%02x%02x" % (40,120,150)    #下一个形状颜色
        self.nextg="#%02x%02x%02x" % (150,100,100)    #小背景
        self.flashg="#%02x%02x%02x" % (210,130,100)    #炸的颜色

        self.LineDisplay=Label(master,text=Lines: ,bg=black,fg=red)
        self.Line=Label(master,text=0,bg=black,fg=red)
        self.ScoreDisplay=Label(master,text=Score: ,bg=black,fg=red)
        self.Score=Label(master,text=0,bg=black,fg=red)
        self.SpendTimeDisplay=Label(master,text=Time: ,bg=black,fg=red)
        self.SpendTime=Label(master,text=0.0,bg=black,fg=red)

        self.LineDisplay.grid(row=HEIGHT-2,column=WIDTH,columnspan=2)
        self.Line.grid(row=HEIGHT-2,column=WIDTH+2,columnspan=3)
        self.ScoreDisplay.grid(row=HEIGHT-1,column=WIDTH,columnspan=2)
        self.Score.grid(row=HEIGHT-1,column=WIDTH+2,columnspan=3)
        self.SpendTimeDisplay.grid(row=HEIGHT-4,column=WIDTH,columnspan=2)
        self.SpendTime.grid(row=HEIGHT-4,column=WIDTH+2,columnspan=3)

        self.TotalTime=0.0
        self.TotalLine=0
        self.TotalScore=0

        #游戏结束
        self.isgameover=FALSE
        #暂停
        self.isPause=FALSE
        #开始
        self.isStart=FALSE
        self.NextList=[]        #整个小背景
        self.NextRowList=[]     #一行小背景

        self.px=0
        self.py=0       #记录方块参考点

        #渲染小背景
        r=0;c=0
        for k in range(4*4):
            LN=Label(master,text=    ,bg=str(self.nextg),fg=white,relief=FLAT,bd=3)
            LN.grid(row=r,column=WIDTH+c,sticky=N+E+S+W)
            self.NextRowList.append(LN)
            c=c+1
            if c>=4:
                r=r+1;c=0
                self.NextList.append(self.NextRowList)
                self.NextRowList=[]

        #渲染大背景
        self.BlockList=[]
        self.BlockRowList=[]
        self.LabelList=[]
        self.LabelRowList=[]
        row=0;col=0
        for i in range(HEIGHT*WIDTH):
            L=Label(master,text=    ,bg=str(self.backg),fg=white,relief=FLAT,bd=4)
            L.grid(row=row,column=col,sticky=N+E+S+W)
            L.row=row;L.col=col;L.isactive=PASSIVE
            self.BlockRowList.append(0);    #大背景每个格子初始化为0值
            self.LabelRowList.append(L)
            col=col+1
            if col>=WIDTH:
                row=row+1;col=0
                self.BlockList.append(self.BlockRowList)
                self.LabelList.append(self.LabelRowList)
                self.BlockRowList=[]
                self.LabelRowList=[]

        #file
        fw=open(text.txt,a)
        fw.close()
        hasHead=FALSE
        f=open(text.txt,r)
        if f.read(5)==score:
            hasHead=TRUE
        f.close()
        self.file=open(text.txt,a)
        if hasHead==FALSE:
            self.file.write(score    line    time    scorePtime    linePtime    scorePline    date/n)
            self.file.flush()

        self.time=1000
        self.OnTimer()
View Code

 

2、实现对俄罗斯方块的翻转

技术图片
# 俄罗斯方块的翻转
def Up(self,event):
        BL=self.BlockList   #格子的值
        LL=self.LabelList   #格子Label

        Moveable=TRUE       #是否可旋转

        #代码编写开始
        nowStyle = style[self.xnow][(self.ynow)]
        newStyle = style[self.xnow][(self.ynow+1)%4]  #算出下一俄罗斯方块
        self.ynow = (self.ynow+1)%4 #此行代码非常重要,否则响应UP时,只能变第一次

        print("nowStyle:"+str(nowStyle)+"=====>>newStyle:"+str(newStyle))

        #根据现有形状中每个label的坐标计算出旋转后目标坐标(x,y)
        SourceList=[];DestList=[]

        for i in range(4):
            SourceList.append([ nowStyle[i][0]+self.px, nowStyle[i][1]+self.py])
            x = newStyle[i][0]+self.px
            y = newStyle[i][1]+self.py
            DestList.append([x, y])

            if x<0 or x>=HEIGHT or y<0 or y>=WIDTH : #or BL[x][y]==1 or LL[x][y].isactive==PASSIVE
                Moveable=FALSE

        if Moveable==TRUE:
            for i in range(len(SourceList)):
                self.Empty(SourceList[i][0],SourceList[i][1])
            for i in range(len(DestList)):
                self.Fill(DestList[i][0],DestList[i][1])

    def Left(self,event):
        BL=self.BlockList;LL=self.LabelList
        Moveable=TRUE
        for i in range(HEIGHT):
            for j in range(WIDTH):
                if LL[i][j].isactive==ACTIVE and j-1<0:Moveable=FALSE
                if LL[i][j].isactive==ACTIVE and j-1>=0 and BL[i][j-1]==1 and LL[i][j-1].isactive==PASSIVE:Moveable=FALSE
        if Moveable==TRUE:
            self.py-=1
            for i in range(HEIGHT):
                for j in range(WIDTH):
                    if j-1>=0 and LL[i][j].isactive==ACTIVE and BL[i][j-1]==0:
                        self.Fill(i,j-1);self.Empty(i,j)

    def Right(self,event):
        BL=self.BlockList;LL=self.LabelList
        Moveable=TRUE
        for i in range(HEIGHT):
            for j in range(WIDTH):
                if LL[i][j].isactive==ACTIVE and j+1>=WIDTH:Moveable=FALSE
                if LL[i][j].isactive==ACTIVE and j+1<WIDTH and BL[i][j+1]==1 and LL[i][j+1].isactive==PASSIVE:Moveable=FALSE
        if Moveable==TRUE:
            self.py+=1
            for i in range(HEIGHT-1,-1,-1):
                for j in range(WIDTH-1,-1,-1):
                    if j+1<WIDTH and LL[i][j].isactive==ACTIVE and BL[i][j+1]==0:
                        self.Fill(i,j+1);self.Empty(i,j)

    def Down(self,event):
        BL=self.BlockList;LL=self.LabelList
        Moveable=TRUE
        for i in range(HEIGHT):
            for j in range(WIDTH):
                if LL[i][j].isactive==ACTIVE and i+1>=HEIGHT:Moveable=FALSE
                if LL[i][j].isactive==ACTIVE and i+1<HEIGHT and BL[i+1][j]==1 and LL[i+1][j].isactive==PASSIVE:Moveable=FALSE
        if Moveable==TRUE and self.isStart :
            self.px+=1
            for i in range(HEIGHT-1,-1,-1):
                for j in range(WIDTH-1,-1,-1):
                    if i+1<HEIGHT and LL[i][j].isactive==ACTIVE and BL[i+1][j]==0:
                        self.Fill(i+1,j);self.Empty(i,j);
        if Moveable==FALSE:
            for i in range(HEIGHT):
                for j in range(WIDTH):
                    LL[i][j].isactive=PASSIVE
            self.JudgeLineFill()
            self.Start()
            if self.isgameover==TRUE:showinfo(T_T,The game is over!);self.Distroy();return FALSE
            for i in range(4):
                for j in range(4):
                    self.NextEmpty(i,j)
            self.Rnd()
        return Moveable

    def Space(self,event):
        while 1:
            if self.Down(0)==FALSE:break
View Code

 

3、完整项目代码

技术图片
#_*_ coding:utf-8 _*_
from tkinter import *
import random
import time
import tkinter.messagebox


#俄罗斯方块界面的高度
HEIGHT  = 20

#俄罗斯方块界面的宽度
WIDTH   = 10

ACTIVE  = 1
PASSIVE = 0
TRUE    = 1
FALSE   = 0

style = [
            [[(0,0),(0,1),(1,1),(2,1)],[(1,0),(1,1),(1,2),(0,2)],[(0,1),(1,1),(2,1),(2,2)],[(1,0),(2,0),(1,1),(1,2)]],#j
            [[(1,0),(1,1),(1,2),(2,1)],[(1,0),(0,1),(1,1),(2,1)],[(1,0),(1,1),(1,2),(0,1)],[(0,1),(1,1),(2,1),(1,2)]],#T
            [[(0,1),(1,1),(2,1),(2,0)],[(0,0),(1,0),(1,1),(1,2)],[(0,1),(1,1),(2,1),(0,2)],[(1,0),(1,1),(1,2),(2,2)]],#反L
            [[(0,0),(0,1),(1,1),(1,2)],[(2,1),(1,1),(1,2),(0,2)],[(0,0),(0,1),(1,1),(1,2)],[(2,1),(1,1),(1,2),(0,2)]],#Z
            [[(1,0),(1,1),(0,1),(0,2)],[(0,1),(1,1),(1,2),(2,2)],[(1,0),(1,1),(0,1),(0,2)],[(0,1),(1,1),(1,2),(2,2)]],#反Z
            [[(0,0),(0,1),(1,1),(1,0)],[(0,0),(0,1),(1,1),(1,0)],[(0,0),(0,1),(1,1),(1,0)],[(0,0),(0,1),(1,1),(1,0)]],#
            [[(1,0),(1,1),(1,2),(1,3)],[(0,1),(1,1),(2,1),(3,1)],[(1,0),(1,1),(1,2),(1,3)],[(0,1),(1,1),(2,1),(3,1)]]#长条
    ]

root=Tk();
root.title(俄罗斯方块)

class App(Frame):
    def __init__(self,master):
        Frame.__init__(self)
        master.bind(<Up>,self.Up)
        master.bind(<Left>,self.Left)
        master.bind(<Right>,self.Right)
        master.bind(<Down>,self.Down)

        master.bind(<space>,self.Space)
        master.bind(<Control-Shift-Key-F12>,self.Play)
        master.bind(<Key-P>,self.Pause)
        master.bind(<Key-S>,self.StartByS)

        # rgb颜色值
        self.backg="#%02x%02x%02x" % (120,150,30)    #大背景
        self.frontg="#%02x%02x%02x" % (40,120,150)    #下一个形状颜色
        self.nextg="#%02x%02x%02x" % (150,100,100)    #小背景
        self.flashg="#%02x%02x%02x" % (210,130,100)    #炸的颜色

        self.LineDisplay=Label(master,text=Lines: ,bg=black,fg=red)
        self.Line=Label(master,text=0,bg=black,fg=red)
        self.ScoreDisplay=Label(master,text=Score: ,bg=black,fg=red)
        self.Score=Label(master,text=0,bg=black,fg=red)
        self.SpendTimeDisplay=Label(master,text=Time: ,bg=black,fg=red)
        self.SpendTime=Label(master,text=0.0,bg=black,fg=red)

        self.LineDisplay.grid(row=HEIGHT-2,column=WIDTH,columnspan=2)
        self.Line.grid(row=HEIGHT-2,column=WIDTH+2,columnspan=3)
        self.ScoreDisplay.grid(row=HEIGHT-1,column=WIDTH,columnspan=2)
        self.Score.grid(row=HEIGHT-1,column=WIDTH+2,columnspan=3)
        self.SpendTimeDisplay.grid(row=HEIGHT-4,column=WIDTH,columnspan=2)
        self.SpendTime.grid(row=HEIGHT-4,column=WIDTH+2,columnspan=3)

        self.TotalTime=0.0
        self.TotalLine=0
        self.TotalScore=0

        #游戏结束
        self.isgameover=FALSE
        #暂停
        self.isPause=FALSE
        #开始
        self.isStart=FALSE
        self.NextList=[]        #整个小背景
        self.NextRowList=[]     #一行小背景

        self.px=0
        self.py=0       #记录方块参考点

        #渲染小背景
        r=0;c=0
        for k in range(4*4):
            LN=Label(master,text=    ,bg=str(self.nextg),fg=white,relief=FLAT,bd=3)
            LN.grid(row=r,column=WIDTH+c,sticky=N+E+S+W)
            self.NextRowList.append(LN)
            c=c+1
            if c>=4:
                r=r+1;c=0
                self.NextList.append(self.NextRowList)
                self.NextRowList=[]

        #渲染大背景
        self.BlockList=[]
        self.BlockRowList=[]
        self.LabelList=[]
        self.LabelRowList=[]
        row=0;col=0
        for i in range(HEIGHT*WIDTH):
            L=Label(master,text=    ,bg=str(self.backg),fg=white,relief=FLAT,bd=4)
            L.grid(row=row,column=col,sticky=N+E+S+W)
            L.row=row;L.col=col;L.isactive=PASSIVE
            self.BlockRowList.append(0);    #大背景每个格子初始化为0值
            self.LabelRowList.append(L)
            col=col+1
            if col>=WIDTH:
                row=row+1;col=0
                self.BlockList.append(self.BlockRowList)
                self.LabelList.append(self.LabelRowList)
                self.BlockRowList=[]
                self.LabelRowList=[]

        #file
        fw=open(text.txt,a)
        fw.close()
        hasHead=FALSE
        f=open(text.txt,r)
        if f.read(5)==score:
            hasHead=TRUE
        f.close()
        self.file=open(text.txt,a)
        if hasHead==FALSE:
            self.file.write(score    line    time    scorePtime    linePtime    scorePline    date/n)
            self.file.flush()

        self.time=1000
        self.OnTimer()

    def __del__(self):
        #self.file.close()
        pass

    def Pause(self,event):
        self.isPause=1-self.isPause

    def Up(self,event):
        BL=self.BlockList   #格子的值
        LL=self.LabelList   #格子Label

        Moveable=TRUE       #是否可旋转

        #代码编写开始
        nowStyle = style[self.xnow][(self.ynow)]
        newStyle = style[self.xnow][(self.ynow+1)%4]  #算出下一俄罗斯方块
        self.ynow = (self.ynow+1)%4 #此行代码非常重要,否则响应UP时,只能变第一次

        print("nowStyle:"+str(nowStyle)+"=====>>newStyle:"+str(newStyle))

        #根据现有形状中每个label的坐标计算出旋转后目标坐标(x,y)
        SourceList=[];DestList=[]

        for i in range(4):
            SourceList.append([ nowStyle[i][0]+self.px, nowStyle[i][1]+self.py])
            x = newStyle[i][0]+self.px
            y = newStyle[i][1]+self.py
            DestList.append([x, y])

            if x<0 or x>=HEIGHT or y<0 or y>=WIDTH : #or BL[x][y]==1 or LL[x][y].isactive==PASSIVE
                Moveable=FALSE

        if Moveable==TRUE:
            for i in range(len(SourceList)):
                self.Empty(SourceList[i][0],SourceList[i][1])
            for i in range(len(DestList)):
                self.Fill(DestList[i][0],DestList[i][1])

    def Left(self,event):
        BL=self.BlockList;LL=self.LabelList
        Moveable=TRUE
        for i in range(HEIGHT):
            for j in range(WIDTH):
                if LL[i][j].isactive==ACTIVE and j-1<0:Moveable=FALSE
                if LL[i][j].isactive==ACTIVE and j-1>=0 and BL[i][j-1]==1 and LL[i][j-1].isactive==PASSIVE:Moveable=FALSE
        if Moveable==TRUE:
            self.py-=1
            for i in range(HEIGHT):
                for j in range(WIDTH):
                    if j-1>=0 and LL[i][j].isactive==ACTIVE and BL[i][j-1]==0:
                        self.Fill(i,j-1);self.Empty(i,j)

    def Right(self,event):
        BL=self.BlockList;LL=self.LabelList
        Moveable=TRUE
        for i in range(HEIGHT):
            for j in range(WIDTH):
                if LL[i][j].isactive==ACTIVE and j+1>=WIDTH:Moveable=FALSE
                if LL[i][j].isactive==ACTIVE and j+1<WIDTH and BL[i][j+1]==1 and LL[i][j+1].isactive==PASSIVE:Moveable=FALSE
        if Moveable==TRUE:
            self.py+=1
            for i in range(HEIGHT-1,-1,-1):
                for j in range(WIDTH-1,-1,-1):
                    if j+1<WIDTH and LL[i][j].isactive==ACTIVE and BL[i][j+1]==0:
                        self.Fill(i,j+1);self.Empty(i,j)

    def Down(self,event):
        BL=self.BlockList;LL=self.LabelList
        Moveable=TRUE
        for i in range(HEIGHT):
            for j in range(WIDTH):
                if LL[i][j].isactive==ACTIVE and i+1>=HEIGHT:Moveable=FALSE
                if LL[i][j].isactive==ACTIVE and i+1<HEIGHT and BL[i+1][j]==1 and LL[i+1][j].isactive==PASSIVE:Moveable=FALSE
        if Moveable==TRUE and self.isStart :
            self.px+=1
            for i in range(HEIGHT-1,-1,-1):
                for j in range(WIDTH-1,-1,-1):
                    if i+1<HEIGHT and LL[i][j].isactive==ACTIVE and BL[i+1][j]==0:
                        self.Fill(i+1,j);self.Empty(i,j);
        if Moveable==FALSE:
            for i in range(HEIGHT):
                for j in range(WIDTH):
                    LL[i][j].isactive=PASSIVE
            self.JudgeLineFill()
            self.Start()
            if self.isgameover==TRUE:showinfo(T_T,The game is over!);self.Distroy();return FALSE
            for i in range(4):
                for j in range(4):
                    self.NextEmpty(i,j)
            self.Rnd()
        return Moveable

    def Space(self,event):
        while 1:
            if self.Down(0)==FALSE:break

    def OnTimer(self):
        if self.isStart==TRUE and self.isPause==FALSE:
            self.TotalTime = self.TotalTime + float(self.time)/1000
            self.SpendTime.config(text=str(self.TotalTime))

        if self.isPause==FALSE:
            self.Down(0)
        if self.TotalScore>=1000:self.time=900
        if self.TotalScore>=2000:self.time=750
        if self.TotalScore>=3000:self.time=600
        if self.TotalScore>=4000:self.time=400
        self.after(self.time,self.OnTimer)      #随着分数增大,俄罗斯方块下降速度加快

    def JudgeLineFill(self):
        BL=self.BlockList;LL=self.LabelList
        count=0;LineList=[]
        for i in range(WIDTH):LineList.append(1)
        #display flash
        for i in range(HEIGHT):
            if BL[i]==LineList:
                count=count+1
                for k in range(WIDTH):
                    LL[i][k].config(bg=str(self.flashg))
                    LL[i][k].update()
        if count!=0:self.after(100)
        #delete block
        for i in range(HEIGHT):
            if BL[i]==LineList:
                #count=count+1
                for j in range(i,0,-1):
                    for k in range(WIDTH):
                        BL[j][k]=BL[j-1][k]
                        LL[j][k][relief]=LL[j-1][k].cget(relief)
                        LL[j][k][bg]=LL[j-1][k].cget(bg)
                for l in range(WIDTH):
                    BL[0][l]=0
                    LL[0][l].config(relief=FLAT,bg=str(self.backg))
        self.TotalLine=self.TotalLine+count
        if count==1:self.TotalScore=self.TotalScore+1*WIDTH
        if count==2:self.TotalScore=self.TotalScore+3*WIDTH
        if count==3:self.TotalScore=self.TotalScore+6*WIDTH
        if count==4:self.TotalScore=self.TotalScore+10*WIDTH
        self.Line.config(text=str(self.TotalLine))
        self.Score.config(text=str(self.TotalScore))

    def Fill(self,i,j):
        if j<0:return
        if self.BlockList[i][j]==1:self.isgameover=TRUE
        self.BlockList[i][j]=1
        self.LabelList[i][j].isactive=ACTIVE
        self.LabelList[i][j].config(relief=RAISED,bg=str(self.frontg))

    def Empty(self,i,j):
        self.BlockList[i][j]=0
        self.LabelList[i][j].isactive=PASSIVE
        self.LabelList[i][j].config(relief=FLAT,bg=str(self.backg))

    def Play(self,event):
        showinfo(Made in China,^_^)

    def NextFill(self,i,j):
        self.NextList[i][j].config(relief=RAISED,bg=str(self.frontg))

    def NextEmpty(self,i,j):
        self.NextList[i][j].config(relief=FLAT,bg=str(self.nextg))

    def Distroy(self):
        #save
        if self.TotalScore!=0:
            #cehkongfu
            savestr=%-9u%-8u%-8.2f%-14.2f%-13.2f%-14.2f%s/n % (
                self.TotalScore,self.TotalLine,self.TotalTime
               ,self.TotalScore/self.TotalTime
               ,self.TotalLine/self.TotalTime
               ,float(self.TotalScore)/self.TotalLine
               ,time.strftime(%Y-%m-%d %H:%M:%S,time.localtime()))
            self.file.seek(0,2)
            self.file.write(savestr)
            self.file.flush()

        for i in range(HEIGHT):
            for j in range(WIDTH):
                self.Empty(i,j)
        self.TotalLine=0;self.TotalScore=0;self.TotalTime=0.0
        self.Line.config(text=str(self.TotalLine))
        self.Score.config(text=str(self.TotalScore))
        self.SpendTime.config(text=str(self.TotalTime))
        self.isgameover=FALSE
        self.isStart=FALSE
        self.time=1000
        for i in range(4):
            for j in range(4):
                self.NextEmpty(i,j)

    #游戏开始方块
    def Start(self):
        nextStyle = style[self.x][self.y]   #下一形状
        self.xnow = self.x
        self.ynow = self.y          #记录大背景中的方块
        self.py = random.randint(0,6)
        print("给py赋任意值:"+str(self.py))
        self.px = 0
        for ii in range(4):
            self.Fill(int(nextStyle[ii][0]),int(nextStyle[ii][1])+self.py)
        self.isStart=TRUE   #游戏开始

    #预处理方块
    def Rnd(self):
        self.x=random.randint(0,6)
        self.y=random.randint(0,3)
        nextStyle = style[self.x][self.y]   #下一形状
        for ii in range(4):
            self.NextFill(int(nextStyle[ii][0]),int(nextStyle[ii][1]))

    #游戏开始给出一次任意形状的方块
    def RndFirst(self):
        self.x=random.randint(0,6)  #选择第一个方块style
        self.y=random.randint(0,3)

    def Show(self):
        self.file.seek(0)
        strHeadLine=self.file.readline()
        dictLine={}
        strTotalLine=‘‘
        for OneLine in self.file.readlines():
            temp=int(OneLine[:5])
            dictLine[temp]=OneLine

        list=sorted(dictLine.items(),key=lambda d:d[0])
        ii=0
        for onerecord in reversed(list):
            ii=ii+1
            if ii<11:
                strTotalLine+=onerecord[1]
        showinfo(Ranking, strHeadLine+strTotalLine)

    def StartByS(self,event):
        self.RndFirst()
        self.Start()
        self.Rnd()

def Start():
    app.RndFirst()
    app.Start()
    app.Rnd()

def End():
    app.Distroy()

def Set():
    print("设置功能待完善...")

def Show():
    app.Show()

#主菜单
mainmenu=Menu(root)
root[menu]=mainmenu

#二级菜单:game
gamemenu=Menu(mainmenu)
mainmenu.add_cascade(label=游戏,menu=gamemenu)
gamemenu.add_command(label=开始,command=Start)
gamemenu.add_command(label=结束,command=End)
gamemenu.add_separator()
gamemenu.add_command(label=退出,command=root.quit)

#二级菜单:set
setmenu=Menu(mainmenu)
mainmenu.add_cascade(label=设置,menu=setmenu)
setmenu.add_command(label=设置,command=Set)

#二级菜单:show
showmenu=Menu(mainmenu)
mainmenu.add_cascade(label=展示,menu=showmenu)
showmenu.add_command(label=展示,command=Show)

#绑定功能

app=App(root)
#程序入口
root.mainloop()
View Code

 

游戏效果:

 

 技术图片

 

 

二、经典的贪吃蛇游戏

这个游戏就非常经典了,试试Python的执行效果

源码:

技术图片
import random
import pygame
import sys
from pygame.locals import *

Snakespeed = 9
Window_Width = 800
Window_Height = 500
Cell_Size = 20  # Width and height of the cells
# Ensuring that the cells fit perfectly in the window. eg if cell size was
# 10     and window width or window height were 15 only 1.5 cells would
# fit.
assert Window_Width % Cell_Size == 0, "Window width must be a multiple of cell size."
# Ensuring that only whole integer number of cells fit perfectly in the window.
assert Window_Height % Cell_Size == 0, "Window height must be a multiple of cell size."
Cell_W = int(Window_Width / Cell_Size)  # Cell Width
Cell_H = int(Window_Height / Cell_Size)  # Cell Height

White = (255, 255, 255)
Black = (0, 0, 0)
Red = (255, 0, 0)  # Defining element colors for the program.
Green = (0, 255, 0)
DARKGreen = (0, 155, 0)
DARKGRAY = (40, 40, 40)
YELLOW = (255, 255, 0)
Red_DARK = (150, 0, 0)
BLUE = (0, 0, 255)
BLUE_DARK = (0, 0, 150)

BGCOLOR = Black  # Background color

UP = up
DOWN = down  # Defining keyboard keys.
LEFT = left
RIGHT = right

HEAD = 0  # Syntactic sugar: index of the snake‘s head


def main():
    global SnakespeedCLOCK, DISPLAYSURF, BASICFONT

    pygame.init()
    SnakespeedCLOCK = pygame.time.Clock()
    DISPLAYSURF = pygame.display.set_mode((Window_Width, Window_Height))
    BASICFONT = pygame.font.Font(freesansbold.ttf, 18)
    pygame.display.set_caption(Snake)

    showStartScreen()
    while True:
        runGame()
        showGameOverScreen()


def runGame():
    # Set a random start point.
    startx = random.randint(5, Cell_W - 6)
    starty = random.randint(5, Cell_H - 6)
    wormCoords = [{x: startx, y: starty},
                  {x: startx - 1, y: starty},
                  {x: startx - 2, y: starty}]
    direction = RIGHT

    # Start the apple in a random place.
    apple = getRandomLocation()

    while True:  # main game loop
        for event in pygame.event.get():  # event handling loop
            if event.type == QUIT:
                terminate()
            elif event.type == KEYDOWN:
                if (event.key == K_LEFT) and direction != RIGHT:
                    direction = LEFT
                elif (event.key == K_RIGHT) and direction != LEFT:
                    direction = RIGHT
                elif (event.key == K_UP) and direction != DOWN:
                    direction = UP
                elif (event.key == K_DOWN) and direction != UP:
                    direction = DOWN
                elif event.key == K_ESCAPE:
                    terminate()

        # check if the Snake has hit itself or the edge
        if wormCoords[HEAD][x] == -1 or wormCoords[HEAD][x] == Cell_W or wormCoords[HEAD][y] == -1 or                 wormCoords[HEAD][y] == Cell_H:
            return  # game over
        for wormBody in wormCoords[1:]:
            if wormBody[x] == wormCoords[HEAD][x] and wormBody[y] == wormCoords[HEAD][y]:
                return  # game over

        # check if Snake has eaten an apply
        if wormCoords[HEAD][x] == apple[x] and wormCoords[HEAD][y] == apple[y]:
            # don‘t remove worm‘s tail segment
            apple = getRandomLocation()  # set a new apple somewhere
        else:
            del wormCoords[-1]  # remove worm‘s tail segment

        # move the worm by adding a segment in the direction it is moving
        if direction == UP:
            newHead = {x: wormCoords[HEAD][x],
                       y: wormCoords[HEAD][y] - 1}
        elif direction == DOWN:
            newHead = {x: wormCoords[HEAD][x],
                       y: wormCoords[HEAD][y] + 1}
        elif direction == LEFT:
            newHead = {x: wormCoords[HEAD][
                                x] - 1, y: wormCoords[HEAD][y]}
        elif direction == RIGHT:
            newHead = {x: wormCoords[HEAD][
                                x] + 1, y: wormCoords[HEAD][y]}
        wormCoords.insert(0, newHead)
        DISPLAYSURF.fill(BGCOLOR)
        drawGrid()
        drawWorm(wormCoords)
        drawApple(apple)
        drawScore(len(wormCoords) - 3)
        pygame.display.update()
        SnakespeedCLOCK.tick(Snakespeed)


def drawPressKeyMsg():
    pressKeySurf = BASICFONT.render(Press a key to play., True, White)
    pressKeyRect = pressKeySurf.get_rect()
    pressKeyRect.topleft = (Window_Width - 200, Window_Height - 30)
    DISPLAYSURF.blit(pressKeySurf, pressKeyRect)


def checkForKeyPress():
    if len(pygame.event.get(QUIT)) > 0:
        terminate()
    keyUpEvents = pygame.event.get(KEYUP)
    if len(keyUpEvents) == 0:
        return None
    if keyUpEvents[0].key == K_ESCAPE:
        terminate()
    return keyUpEvents[0].key


def showStartScreen():
    titleFont = pygame.font.Font(freesansbold.ttf, 100)
    titleSurf1 = titleFont.render(Snake!, True, White, DARKGreen)
    degrees1 = 0
    degrees2 = 0
    while True:
        DISPLAYSURF.fill(BGCOLOR)
        rotatedSurf1 = pygame.transform.rotate(titleSurf1, degrees1)
        rotatedRect1 = rotatedSurf1.get_rect()
        rotatedRect1.center = (Window_Width / 2, Window_Height / 2)
        DISPLAYSURF.blit(rotatedSurf1, rotatedRect1)

        drawPressKeyMsg()

        if checkForKeyPress():
            pygame.event.get()  # clear event queue
            return
        pygame.display.update()
        SnakespeedCLOCK.tick(Snakespeed)
        degrees1 += 3  # rotate by 3 degrees each frame
        degrees2 += 7  # rotate by 7 degrees each frame


def terminate():
    pygame.quit()
    sys.exit()


def getRandomLocation():
    return {x: random.randint(0, Cell_W - 1), y: random.randint(0, Cell_H - 1)}


def showGameOverScreen():
    gameOverFont = pygame.font.Font(freesansbold.ttf, 100)
    gameSurf = gameOverFont.render(Game, True, White)
    overSurf = gameOverFont.render(Over, True, White)
    gameRect = gameSurf.get_rect()
    overRect = overSurf.get_rect()
    gameRect.midtop = (Window_Width / 2, 10)
    overRect.midtop = (Window_Width / 2, gameRect.height + 10 + 25)

    DISPLAYSURF.blit(gameSurf, gameRect)
    DISPLAYSURF.blit(overSurf, overRect)
    drawPressKeyMsg()
    pygame.display.update()
    pygame.time.wait(500)
    checkForKeyPress()  # clear out any key presses in the event queue

    while True:
        if checkForKeyPress():
            pygame.event.get()  # clear event queue
            return


def drawScore(score):
    scoreSurf = BASICFONT.render(Score: %s % (score), True, White)
    scoreRect = scoreSurf.get_rect()
    scoreRect.topleft = (Window_Width - 120, 10)
    DISPLAYSURF.blit(scoreSurf, scoreRect)


def drawWorm(wormCoords):
    for coord in wormCoords:
        x = coord[x] * Cell_Size
        y = coord[y] * Cell_Size
        wormSegmentRect = pygame.Rect(x, y, Cell_Size, Cell_Size)
        pygame.draw.rect(DISPLAYSURF, DARKGreen, wormSegmentRect)
        wormInnerSegmentRect = pygame.Rect(
            x + 4, y + 4, Cell_Size - 8, Cell_Size - 8)
        pygame.draw.rect(DISPLAYSURF, Green, wormInnerSegmentRect)


def drawApple(coord):
    x = coord[x] * Cell_Size


    y = coord[y] * Cell_Size
    appleRect = pygame.Rect(x, y, Cell_Size, Cell_Size)
    pygame.draw.rect(DISPLAYSURF, Red, appleRect)


def drawGrid():
    for x in range(0, Window_Width, Cell_Size):  # draw vertical lines
        pygame.draw.line(DISPLAYSURF, DARKGRAY, (x, 0), (x, Window_Height))
    for y in range(0, Window_Height, Cell_Size):  # draw horizontal lines
        pygame.draw.line(DISPLAYSURF, DARKGRAY, (0, y), (Window_Width, y))


if __name__ == __main__:
    try:
        main()
    except SystemExit:
        pass
View Code

 

游戏效果:

技术图片

 

 

 

 

三、关不掉的窗口

技术图片
from tkinter import *
class YouLikeMe:
    def __init__(self):
        window=Tk()
        label=Label(window,text=你是不是喜欢我?)
        self.btyes=Button(window,text=不是,height=1,width=6)
        self.btno=Button(window,text=是的,height=1,width=6)
        label.place(x=60,y=70)
        self.btyes.place(x=40,y=130)
        self.btno.place(x=120,y=130)
        self.btyes.bind(<Enter>,self.event1)#将按钮与鼠标事件绑定,<Enter>是指鼠标光标进入按钮区域
        self.btno.bind(<Enter>,self.event2)
        window.mainloop()
    def event1(self,event):#切换按钮文字
        self.btyes[text]=是的
        self.btno[text]=不是
    def event2(self,event):
        self.btyes[text]=不是
        self.btno[text]=是的

YouLikeMe()
window=Tk()
label=Label(window,text=关闭窗口也改变不了你喜欢我的事实)
label.place(x=2,y=80)
button=Button(window,text=确定,command=window.destroy)
button.place(x=80,y=150)
window.mainloop()
View Code

 游戏效果

技术图片

 

 

 

四、画玫瑰花

技术图片
import turtle
import time
turtle.speed(5) #画笔移动的速度



# 设置初始位置

turtle.penup()  #提起画笔,移动画笔但并不会绘制图形
turtle.left(90)  #逆时针转动画笔90度
turtle.fd(200)
turtle.pendown()  #放下画笔,移动画笔即开始绘制
turtle.right(90)
#设置画笔的大小
turtle.pensize(2)

# 花蕊

turtle.fillcolor("red")  #填充颜色
turtle.begin_fill()  #开始填充
turtle.circle(10,180)
turtle.circle(25,110)
turtle.left(50)
turtle.circle(60,45)
turtle.circle(20,170)
turtle.right(24)
turtle.fd(30)
turtle.left(10)
turtle.circle(30,110)
turtle.fd(20)
turtle.left(40)
turtle.circle(90,70)
turtle.circle(30,150)
turtle.right(30)
turtle.fd(15)
turtle.circle(80,90)
turtle.left(15)
turtle.fd(45)
turtle.right(165)
turtle.fd(20)
turtle.left(155)
turtle.circle(150,80)
turtle.left(50)
turtle.circle(150,90)
turtle.end_fill()  #结束填充

# 花瓣1

turtle.left(150)
turtle.circle(-90,70)
turtle.left(20)
turtle.circle(75,105)
turtle.setheading(60)
turtle.circle(80,98)
turtle.circle(-90,40)



# 花瓣2
turtle.left(180)
turtle.circle(90,40)
turtle.circle(-80,98)
turtle.setheading(-83)

# 叶子1
turtle.fd(30)
turtle.left(90)
turtle.fd(25)
turtle.left(45)
turtle.fillcolor("green")
turtle.begin_fill()
turtle.circle(-80,90)
turtle.right(90)
turtle.circle(-80,90)
turtle.end_fill()



turtle.right(135)
turtle.fd(60)
turtle.left(180)
turtle.fd(85)
turtle.left(90)
turtle.fd(80)


# 叶子2
turtle.right(90)
turtle.right(45)
turtle.fillcolor("green")
turtle.begin_fill()
turtle.circle(80,90)
turtle.left(90)
turtle.circle(80,90)
turtle.end_fill()


turtle.left(135)
turtle.fd(60)
turtle.left(180)
turtle.fd(60)
turtle.right(90)
turtle.circle(200,50)  #画一个圆 200 是半径,50 是弧度

#不让自动退出,放在程序的最后一行
#不然画画结束后会自动退出
turtle.done()
View Code

游戏效果:

 技术图片

 

 

 

五、优美的彩虹线条

技术图片
import turtle
q = turtle.Pen()
turtle.bgcolor("black")
sides = 7
colors =["red","orange","yellow","green","cyan","blue","blue","purple"]
for x in range(360):
    q.pencolor(colors[x%sides])
    q.forward(x*3/sides+x)
    q.left(360/sides+1)
    q.width(x*sides/200)
View Code

 

游戏效果:

技术图片

 

 

 

六、实时钟表

技术图片
# -*- coding:utf-8 –*-
# 用turtlr画时钟
# 以自定义shape的方式实现
import turtle as t
import datetime as d
def skip(step):  # 抬笔,跳到一个地方
    t.penup()
    t.forward(step)
    t.pendown()
def drawClock(radius):  # 画表盘
    t.speed(0)
    t.mode("logo")  # 以Logo坐标、角度方式
    t.hideturtle()
    t.pensize(7)
    t.home()  # 回到圆点
    for j in range(60):
        skip(radius)
        if (j % 5 == 0):
            t.forward(20)
            skip(-radius - 20)
        else:
            t.dot(5)
            skip(-radius)
        t.right(6)
def makePoint(pointName, len):  # 钟的指针,时针、分针、秒针
    t.penup()
    t.home()
    t.begin_poly()
    t.back(0.1 * len)
    t.forward(len * 1.1)
    t.end_poly()
    poly = t.get_poly()
    t.register_shape(pointName, poly)  # 注册为一个shape
def drawPoint():  # 画指针
    global hourPoint, minPoint, secPoint, fontWriter
    makePoint("hourPoint", 100)
    makePoint("minPoint", 120)
    makePoint("secPoint", 140)
    hourPoint = t.Pen()  # 每个指针是一只新turtle
    hourPoint.shape("hourPoint")
    hourPoint.shapesize(1, 1, 6)
    minPoint = t.Pen()
    minPoint.shape("minPoint")
    minPoint.shapesize(1, 1, 4)
    secPoint = t.Pen()
    secPoint.shape("secPoint")
    secPoint.pencolor(red)
    fontWriter = t.Pen()
    fontWriter.pencolor(gray)
    fontWriter.hideturtle()
def getWeekName(weekday):
    weekName = [星期一, 星期二, 星期三, 星期四, 星期五, 星期六, 星期日]
    return weekName[weekday]
def getDate(year, month, day):
    return "%s-%s-%s" % (year, month, day)
def realTime():
    curr = d.datetime.now()
    curr_year = curr.year
    curr_month = curr.month
    curr_day = curr.day
    curr_hour = curr.hour
    curr_minute = curr.minute
    curr_second = curr.second
    curr_weekday = curr.weekday()
    t.tracer(False)
    secPoint.setheading(360 / 60 * curr_second)
    minPoint.setheading(360 / 60 * curr_minute)
    hourPoint.setheading(360 / 12 * curr_hour + 30 / 60 * curr_minute)
    fontWriter.clear()
    fontWriter.home()
    fontWriter.penup()
    fontWriter.forward(80)
    # 用turtle写文字
    fontWriter.write(getWeekName(curr_weekday), align="center", font=("Courier", 14, "bold"))
    fontWriter.forward(-160)
    fontWriter.write(getDate(curr_year, curr_month, curr_day), align="center", font=("Courier", 14, "bold"))
    t.tracer(True)
    print(curr_second)
    t.ontimer(realTime, 100)  # 每隔100毫秒调用一次realTime()
def main():
    t.tracer(False)
    drawClock(160)
    drawPoint()
    realTime()
    t.tracer(True)
    t.mainloop()
if __name__ == __main__:
    main()
View Code

 

游戏效果

技术图片

 

七、画佩奇

技术图片
# coding: utf-8

import turtle as t

t.screensize(400, 300)
t.pensize(4)  # 设置画笔的大小
t.colormode(255)  # 设置GBK颜色范围为0-255
t.color((255, 155, 192), "pink")  # 设置画笔颜色和填充颜色(pink)
t.setup(840, 500)  # 设置主窗口的大小为840*500
t.speed(10)  # 设置画笔速度为10
# 鼻子
t.pu()  # 提笔
t.goto(-100, 100)  # 画笔前往坐标(-100,100)
t.pd()  # 下笔
t.seth(-30)  # 笔的角度为-30°
t.begin_fill()  # 外形填充的开始标志
a = 0.4
for i in range(120):
    if 0 <= i < 30 or 60 <= i < 90:
        a = a + 0.08
        t.lt(3)  # 向左转3度
        t.fd(a)  # 向前走a的步长
    else:
        a = a - 0.08
        t.lt(3)
        t.fd(a)
t.end_fill()  # 依据轮廓填充
t.pu()  # 提笔
t.seth(90)  # 笔的角度为90度
t.fd(25)  # 向前移动25
t.seth(0)  # 转换画笔的角度为0
t.fd(10)
t.pd()
t.pencolor(255, 155, 192)  # 设置画笔颜色
t.seth(10)
t.begin_fill()
t.circle(5)  # 画一个半径为5的圆
t.color(160, 82, 45)  # 设置画笔和填充颜色
t.end_fill()
t.pu()
t.seth(0)
t.fd(20)
t.pd()
t.pencolor(255, 155, 192)
t.seth(10)
t.begin_fill()
t.circle(5)
t.color(160, 82, 45)
t.end_fill()
#
t.color((255, 155, 192), "pink")
t.pu()
t.seth(90)
t.fd(41)
t.seth(0)
t.fd(0)
t.pd()
t.begin_fill()
t.seth(180)
t.circle(300, -30)  # 顺时针画一个半径为300,圆心角为30°的园
t.circle(100, -60)
t.circle(80, -100)
t.circle(150, -20)
t.circle(60, -95)
t.seth(161)
t.circle(-300, 15)
t.pu()
t.goto(-100, 100)
t.pd()
t.seth(-30)
a = 0.4
for i in range(60):
    if 0 <= i < 30 or 60 <= i < 90:
        a = a + 0.08
        t.lt(3)  # 向左转3度
        t.fd(a)  # 向前走a的步长
    else:
        a = a - 0.08
        t.lt(3)
        t.fd(a)
t.end_fill()
# 耳朵
t.color((255, 155, 192), "pink")
t.pu()
t.seth(90)
t.fd(-7)
t.seth(0)
t.fd(70)
t.pd()
t.begin_fill()
t.seth(100)
t.circle(-50, 50)
t.circle(-10, 120)
t.circle(-50, 54)
t.end_fill()
t.pu()
t.seth(90)
t.fd(-12)
t.seth(0)
t.fd(30)
t.pd()
t.begin_fill()
t.seth(100)
t.circle(-50, 50)
t.circle(-10, 120)
t.circle(-50, 56)
t.end_fill()
# 眼睛
t.color((255, 155, 192), "white")
t.pu()
t.seth(90)
t.fd(-20)
t.seth(0)
t.fd(-95)
t.pd()
t.begin_fill()
t.circle(15)
t.end_fill()
t.color("black")
t.pu()
t.seth(90)
t.fd(12)
t.seth(0)
t.fd(-3)
t.pd()
t.begin_fill()
t.circle(3)
t.end_fill()
t.color((255, 155, 192), "white")
t.pu()
t.seth(90)
t.fd(-25)
t.seth(0)
t.fd(40)
t.pd()
t.begin_fill()
t.circle(15)
t.end_fill()
t.color("black")
t.pu()
t.seth(90)
t.fd(12)
t.seth(0)
t.fd(-3)
t.pd()
t.begin_fill()
t.circle(3)
t.end_fill()
#
t.color((255, 155, 192))
t.pu()
t.seth(90)
t.fd(-95)
t.seth(0)
t.fd(65)
t.pd()
t.begin_fill()
t.circle(30)
t.end_fill()
#
t.color(239, 69, 19)
t.pu()
t.seth(90)
t.fd(15)
t.seth(0)
t.fd(-100)
t.pd()
t.seth(-80)
t.circle(30, 40)
t.circle(40, 80)
# 身体
t.color("red", (255, 99, 71))
t.pu()
t.seth(90)
t.fd(-20)
t.seth(0)
t.fd(-78)
t.pd()
t.begin_fill()
t.seth(-130)
t.circle(100, 10)
t.circle(300, 30)
t.seth(0)
t.fd(230)
t.seth(90)
t.circle(300, 30)
t.circle(100, 3)
t.color((255, 155, 192), (255, 100, 100))
t.seth(-135)
t.circle(-80, 63)
t.circle(-150, 24)
t.end_fill()
#
t.color((255, 155, 192))
t.pu()
t.seth(90)
t.fd(-40)
t.seth(0)
t.fd(-27)
t.pd()
t.seth(-160)
t.circle(300, 15)
t.pu()
t.seth(90)
t.fd(15)
t.seth(0)
t.fd(0)
t.pd()
t.seth(-10)
t.circle(-20, 90)
t.pu()
t.seth(90)
t.fd(30)
t.seth(0)
t.fd(237)
t.pd()
t.seth(-20)
t.circle(-300, 15)
t.pu()
t.seth(90)
t.fd(20)
t.seth(0)
t.fd(0)
t.pd()
t.seth(-170)
t.circle(20, 90)
#
t.pensize(10)
t.color((240, 128, 128))
t.pu()
t.seth(90)
t.fd(-75)
t.seth(0)
t.fd(-180)
t.pd()
t.seth(-90)
t.fd(40)
t.seth(-180)
t.color("black")
t.pensize(15)
t.fd(20)
t.pensize(10)
t.color((240, 128, 128))
t.pu()
t.seth(90)
t.fd(40)
t.seth(0)
t.fd(90)
t.pd()
t.seth(-90)
t.fd(40)
t.seth(-180)
t.color("black")
t.pensize(15)
t.fd(20)
# 尾巴
t.pensize(4)
t.color((255, 155, 192))
t.pu()
t.seth(90)
t.fd(70)
t.seth(0)
t.fd(95)
t.pd()
t.seth(0)
t.circle(70, 20)
t.circle(10, 330)
t.circle(70, 30)
t.done()
View Code

 

游戏效果

技术图片

 

 

八、黑客代码雨

技术图片
#  -*- coding:utf-8 -*-

#导入系统文件库
import pygame
import random
from pygame.locals import *
from random import randint


#定义一些窗体参数及加载字体文件
SCREEN_WIDTH  = 900         # 窗体宽度
SCREEN_HEIGHT = 600         # 窗体宽度
LOW_SPEED  = 4              # 字体移动最低速度
HIGH_SPEED = 10             # 字体移动最快速度
FONT_COLOR = (00,150,00)    # 字体颜色
FONT_SIZE = 5               # 字体尺寸
FONT_NOM  = 20              # 显示字体数量  从0开始
FONT_NAME = "calibrii.ttf"  # 注意字体的文件名必须与真实文件完全相同(注意ttf的大小写),且文件名不能是中文
FREQUENCE = 10              # 时间频度
times = 0                   # 初始化时间


# 定义随机参数
def randomspeed() :
    return randint(LOW_SPEED,HIGH_SPEED)
def randomposition() :
    return randint(0,SCREEN_WIDTH),randint(0,SCREEN_HEIGHT)
def randomoname() :
    return randint(0,100000)
def randomvalue() :
    return randint(0,100)              # this is your own display number range


#class of sprite
class Word(pygame.sprite.Sprite) :
    def __init__(self,bornposition) :
        pygame.sprite.Sprite.__init__(self)
        self.value = randomvalue()
        self.font = pygame.font.Font(None,FONT_SIZE)
        self.image = self.font.render(str(self.value),True,FONT_COLOR)
        self.speed = randomspeed()
        self.rect = self.image.get_rect()
        self.rect.topleft = bornposition

    def update(self) :
        self.rect = self.rect.move(0,self.speed)
        if self.rect.top > SCREEN_HEIGHT :
            self.kill()


#init the available modules
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH,SCREEN_HEIGHT))
pygame.display.set_caption("ViatorSun CodeRain")
clock = pygame.time.Clock()
group = pygame.sprite.Group()
group_count = int(SCREEN_WIDTH / FONT_NOM)


#mainloop
while True :
    time = clock.tick(FREQUENCE)
    for event in pygame.event.get() :
        if event.type == QUIT :
            pygame.quit()
            exit()

    screen.fill((0,0,0))
    for i in range(0,group_count) :
        group.add(Word((i * FONT_NOM,-FONT_NOM)))

    group.update()
    group.draw(screen)
    pygame.display.update()
View Code

游戏效果

 技术图片

 

 

 

 

 

 

最后,欢迎关注我的公众号"测试情报局",这里分享Python/Java技术,自动化、以及认知感悟。不定期赠送技术书籍、资料。

公众号内回复:全栈;可获取Python全栈视频资料

技术图片

以上是关于Python实例练手项目汇总(附源码)的主要内容,如果未能解决你的问题,请参考以下文章

熬夜整理了70个Python经典实用练手项目(附源码)

Python实例练手项目源码 - 代码雨

Python实例练手项目源码 - 代码雨

10个用来练手的Python迷你项目,附源码!

70个python练手项目,提升编程水平,小白也能适用!(附源码链接)

2022最新版40个前端练手项目附视频+源码