zoukankan      html  css  js  c++  java
  • 初识python:tkinter 实现 弹球小游戏(非面相对象)

     通过 tkinter 采用非面相对象式实现弹球小游戏(使用蹩脚式面相对象实现)

    #!/user/bin env python
    # author:Simple-Sir
    # time:2020/8/3 17:12
    import tkinter,time,random
    
    x = 1
    y = 1
    score = 0  # 分数
    level = 1  # 关卡
    
    # 创建颜色列表
    color_li = ['#feeeed','#f391a9','#fab27b','#454926','#181d4b','#a3cf62','#45b97c','#008792','#2585a6']
    
    # 创建窗口
    tk = tkinter.Tk()  # 声明一个TK,初始化一个“窗口”(画一个窗口)
    tk.title('弹球游戏')  # 窗口名称
    tk.resizable(width=False,height=False)  # 窗口是否可变(长、宽),也可用0,1表示
    tk.wm_attributes('-topmost',1)  # 窗口永远在前
    
    
    # 创建画布
    canvas = tkinter.Canvas(tk,width=600,height=500,bd=0)  # 创建一个“画布”
    
    # 创建画布组件
    
    filename = tkinter.PhotoImage(file="bg.png")  # 获取一张图片
    canvas.create_image(300, 250,image=filename)  # 将图片添加到画布,作为背景
    
    id_ball = canvas.create_oval(10, 10, 30, 30, fill=random.choice(color_li),width=0)  # 定义一个球
    id_paddle = canvas.create_rectangle(0,400,150,420,fill=random.choice(color_li),width=0)  # 定义木板
    canvas.move(id_paddle,225,0)
    canvas.create_text(400, 20, text='关卡:',fill='white',font=('宋体', '20'))
    canvas.create_text(500, 20, text='得分:',fill='white',font=('宋体', '20'))
    
    id_level = canvas.create_text(450, 20, text=1,fill='white',font=('宋体', '20'))
    id_score = canvas.create_text(550, 20, text=0,fill='white',font=('宋体', '20'))
    id_start_game = canvas.create_text(300,200,text='Start Game.',font=('宋体', '30'),fill=random.choice(color_li))
    
    canvas.pack()  # 将画布添加到窗口中
    tk.update()  # 刷新窗口
    
    wh = canvas.winfo_height()  # 获取窗口高度(update刷新之后才能获取)
    ww = canvas.winfo_width()  # 获取窗口宽度(update刷新之后才能获取)
    
    def turn_left(event):
        canvas.move(id_paddle, -10, 0)
    
    def turn_right(event):
        canvas.move(id_paddle, 10, 0)
    
    def start_game(event):
        canvas.move(id_start_game,0,10)
    
    canvas.bind_all('<KeyPress-Left>', turn_left)
    canvas.bind_all('<KeyPress-Right>', turn_right)
    canvas.bind_all('<Button-1>', start_game)
    
    # 保持起始界面
    while 1:
        tk.update()  # 刷新窗口
        p_start_game = canvas.coords(id_start_game)
        print(p_start_game)
        if p_start_game[1] == 210:
            canvas.delete(id_start_game)
            break
    
    # 让球跑起来
    while 1:
        tk.update()  # 刷新窗口
        time.sleep(0.01/level)  # 通过level控制速度(也考虑过用球的颜色控制速度)
        p_ball = canvas.coords(id_ball)  # 获取球当前位置坐标
        p_paddle = canvas.coords(id_paddle)  # 获取木板的坐标
    
        print('当前坐标:',p_ball)  # 打印当前坐标
        if p_ball[0] <= 0:  # 当球落到右边框时:左上角x坐标判断
            x = 1
        elif p_ball[2] >= ww:  # 当球落到右边框时,右下角x坐标判断
            x = -1
        if p_ball[1] <= 0:  # 当球落到上边框时,左上角y坐标判断
            y = 1
        elif p_ball[3] >= wh:  # 当球落到下边框时,右下角y坐标判断
            y = -1
        print(p_ball[2],p_paddle[0],p_paddle[2],p_ball[3])
        if p_ball[2]>=p_paddle[0] and p_ball[2]<=p_paddle[2] and p_ball[3] == p_paddle[1]:  # 球与模板接触:球的右下角x坐标在木板右上角x坐标内,且球的右下角x坐标在木板左下角x坐标内,球的右下角y坐标等于木板的左上角y坐标
            y = -1  # 让球向上移动
            score += 10  # 得分加10分
            canvas.itemconfig(id_ball, fill=random.choice(color_li))  # 修改球的颜色,随机颜色
            canvas.itemconfig(id_paddle, fill=random.choice(color_li))  # 修改木板的颜色,随机颜色
            canvas.itemconfig(id_score, text=score)  # 修改分数
            if score > 0 and score % 50 == 0:  # 每50分升一级
                level += 1  # 升级
                canvas.itemconfig(id_level, text=level)  # 修改等级
        canvas.move(id_ball, x, y)  # 移动
        if p_ball[3] == wh:  # 当球与下边框接触时,游戏失败。
            canvas.create_text(300, 250, text='Game Over !', font=('宋体', '30'), fill='red')  # 添加游戏结束界面
            break
    
    # 游戏结束,继续保持界面
    tk.mainloop()
    弹球小游戏

    最终执行效果:

     

     

     

    知识点

    1、导入模块 

    import tkinter

    2、生明一个tkinter实例(创建一个“窗口”)

    tk = tkinter.Tk()  # 声明一个tkinter,初始化一个“窗口”(画一个窗口)

    3、设置窗口属性

    tk.title('弹球游戏') # 窗口名称
    tk.resizable(width=False,height=False) # 窗口是否可变(长、宽),也可用0,1表示
    tk.wm_attributes('-topmost',1) # 窗口永远在前
    wm_attributes 可选属性字段:

     -topmost        是否是一个永远最前的窗口
     -alpha            窗口的透明度
     -fullscreen     窗口是否满屏显示
     -disabled       窗口是否是一个不可用的状态(不能有任何操作)

    4、组件实例

    首先弄清楚坐标概念:

    以画布的左上角为原点(0,0)
    以画一个圆为例,需要通过“矩形”的左上角、右下角两个坐标确定这个“矩形”的位置、大小,然后,在矩形中画这个圆

    tkinter.Canvas 创建画布

    #!/user/bin env python
    # author:Simple-Sir
    # time:2020/8/3 17:12
    import tkinter
    
    # 创建窗口
    tk = tkinter.Tk()  # 声明一个TK,初始化一个“窗口”(画一个窗口)
    tk.title('弹球游戏')  # 窗口名称
    tk.resizable(width=False,height=False)  # 窗口是否可变(长、宽),也可用0,1表示
    tk.wm_attributes('-topmost',1)  # 窗口永远在前
    
    canvas = tkinter.Canvas(tk,width=300,height=200,bd=0)  # 创建一个“画布”
    # width 宽
    # height 高
    # bd 边框宽度(像素)
    # bg 背景颜色
    # highlightthickness 颜色高亮
    
    canvas.pack()  # 将画布添加到窗口中
    tk.update()  # 刷新窗口
    
    
    # 进入消息循环
    tk.mainloop()  # 所有GUI程序都必须有一个主循环
    创建“画布”

    执行结果:

    画布属性:

    move 移动
    delete 删除
    winfo_height 获取窗口高度(update刷新之后才能获取)
    winfo_width() 获取窗口宽度(update刷新之后才能获取)
    coords 获取目标当前坐标
    itemconfig 修改组件属性

    画布组件:

    画布组件属性:

    fill                填充颜色,默认不填充
    stipple         位图平铺填充
    outline         边框颜色
    width           边框宽度,默认1
    dash            边框使用虚线。单独整数:虚线线段长度 (n1,n2,n3):线段的长度n1,间隔长度n2,虚线长度n3
    arrowshape 指定箭头形状。该选项是一个形如 "20 20 10" 的字符串,字符串中的三个整数依次指定填充长度、箭头长度、箭头宽度。
    joinstyle       直线连接点的风格: miter、round、bevel
    state            指定该画布对象的状态 NORMAL(正常,默认),DISABLED(不可用,不响应事件)和 HIDDEN(隐藏)

    canvas.create_arc 创建扇形:

    #!/user/bin env python
    # author:Simple-Sir
    # time:2020/8/3 17:12
    import tkinter
    
    # 创建窗口
    tk = tkinter.Tk()  # 声明一个TK,初始化一个“窗口”(画一个窗口)
    tk.title('弹球游戏')  # 窗口名称
    tk.resizable(width=False,height=False)  # 窗口是否可变(长、宽),也可用0,1表示
    tk.wm_attributes('-topmost',1)  # 窗口永远在前
    
    # 创建画布
    canvas = tkinter.Canvas(tk,width=300,height=200,bd=0)  # 创建一个“画布”
    # width 宽
    # height 高
    # bd 边框宽度(像素)
    # bg 背景颜色
    # highlightthickness 颜色高亮
    
    
    canvas.create_arc(0,0,100,100,start=0,extent=60,fill='red') # 指定坐标(左上、右下),开始度数,要画的度数,填充颜色
    # style  PIESLICE - 扇形、CHORD - 弓形、ARC - 只画一个弧)
    # start  扇形的起始角度,以3点钟位置为0度,逆时针方向增加度数。
    # extent 扇形要绘制的度数
    
    canvas.pack()  # 将画布添加到窗口中
    tk.update()  # 刷新窗口
    
    
    # 进入消息循环
    tk.mainloop()  # 所有GUI程序都必须有一个主循环
    创建扇形

    执行结果:

    canvas.create_oval 创建圆:

    #!/user/bin env python
    # author:Simple-Sir
    # time:2020/8/3 17:12
    import tkinter
    
    # 创建窗口
    tk = tkinter.Tk()  # 声明一个TK,初始化一个“窗口”(画一个窗口)
    tk.title('弹球游戏')  # 窗口名称
    tk.resizable(width=False,height=False)  # 窗口是否可变(长、宽),也可用0,1表示
    tk.wm_attributes('-topmost',1)  # 窗口永远在前
    
    # 创建画布
    canvas = tkinter.Canvas(tk,width=300,height=200,bd=0)  # 创建一个“画布”
    # width 宽
    # height 高
    # bd 边框宽度(像素)
    # bg 背景颜色
    # highlightthickness 颜色高亮
    
    # 创建圆
    canvas.create_oval(10,10,100,100,fill='red')
    
    canvas.pack()  # 将画布添加到窗口中
    tk.update()  # 刷新窗口
    
    
    # 进入消息循环
    tk.mainloop()  # 所有GUI程序都必须有一个主循环
    创建圆

    执行结果:

    canvascreate_image 创建图像

    #!/user/bin env python
    # author:Simple-Sir
    # time:2020/8/3 17:12
    import tkinter
    
    # 创建窗口
    tk = tkinter.Tk()  # 声明一个TK,初始化一个“窗口”(画一个窗口)
    tk.title('弹球游戏')  # 窗口名称
    tk.resizable(width=False,height=False)  # 窗口是否可变(长、宽),也可用0,1表示
    tk.wm_attributes('-topmost',1)  # 窗口永远在前
    
    # 创建画布
    canvas = tkinter.Canvas(tk,width=300,height=200,bd=0)  # 创建一个“画布”
    # width 宽
    # height 高
    # bd 边框宽度(像素)
    # bg 背景颜色
    # highlightthickness 颜色高亮
    
    # 创建图像
    filename = tkinter.PhotoImage(file="cat.png")
    canvas.create_image(10, 20, anchor='nw', image=filename)  # 西距离边框10,北距离边框20
    
    canvas.pack()  # 将画布添加到窗口中
    tk.update()  # 刷新窗口
    
    
    # 进入消息循环
    tk.mainloop()  # 所有GUI程序都必须有一个主循环
    创建图像

    执行结果:

    canvas.create_line 创建线条

    #!/user/bin env python
    # author:Simple-Sir
    # time:2020/8/3 17:12
    import tkinter
    
    # 创建窗口
    tk = tkinter.Tk()  # 声明一个TK,初始化一个“窗口”(画一个窗口)
    tk.title('弹球游戏')  # 窗口名称
    tk.resizable(width=False,height=False)  # 窗口是否可变(长、宽),也可用0,1表示
    tk.wm_attributes('-topmost',1)  # 窗口永远在前
    
    # 创建画布
    canvas = tkinter.Canvas(tk,width=300,height=200,bd=0)  # 创建一个“画布”
    # width 宽
    # height 高
    # bd 边框宽度(像素)
    # bg 背景颜色
    # highlightthickness 颜色高亮
    
    # line 线条
    canvas.create_line(0,0,100,100,50,60,200,300,arrow='last',joinstyle='bevel')  # 多个坐标会连续画
    # arrow 两端是否有箭头(none:两端无箭头、first:开始端有箭头、last:结束端有箭头、both:两端都有箭头。
    
    canvas.pack()  # 将画布添加到窗口中
    tk.update()  # 刷新窗口
    
    
    # 进入消息循环
    tk.mainloop()  # 所有GUI程序都必须有一个主循环
    创建线条

    执行结果:

    #!/user/bin env python
    # author:Simple-Sir
    # time:2020/8/3 17:12
    import tkinter
    
    # 创建窗口
    tk = tkinter.Tk()  # 声明一个TK,初始化一个“窗口”(画一个窗口)
    tk.title('弹球游戏')  # 窗口名称
    tk.resizable(width=False,height=False)  # 窗口是否可变(长、宽),也可用0,1表示
    tk.wm_attributes('-topmost',1)  # 窗口永远在前
    
    # 创建画布
    canvas = tkinter.Canvas(tk,width=300,height=200,bd=0)  # 创建一个“画布”
    # width 宽
    # height 高
    # bd 边框宽度(像素)
    # bg 背景颜色
    # highlightthickness 颜色高亮
    
    # rectangle 矩形
    canvas.create_rectangle(0,10,100,150,fill='blue',outline='red',stipple='error',width=10,dash=(10,50,100))
    # stipple 位图平铺填充
    # outline 边框颜色
    # width 边框宽度,默认1
    # dash 边框使用虚线。单独整数:虚线线段长度 (n1,n2,n3):虚线线段长度n1,间隔长度n2,虚线长度n3
    
    canvas.pack()  # 将画布添加到窗口中
    tk.update()  # 刷新窗口
    
    
    # 进入消息循环
    tk.mainloop()  # 所有GUI程序都必须有一个主循环
    创建矩形

    执行结果:

    创建多边形:

    #!/user/bin env python
    # author:Simple-Sir
    # time:2020/8/3 17:12
    import tkinter
    
    # 创建窗口
    tk = tkinter.Tk()  # 声明一个TK,初始化一个“窗口”(画一个窗口)
    tk.title('弹球游戏')  # 窗口名称
    tk.resizable(width=False,height=False)  # 窗口是否可变(长、宽),也可用0,1表示
    tk.wm_attributes('-topmost',1)  # 窗口永远在前
    
    # 创建画布
    canvas = tkinter.Canvas(tk,width=300,height=200,bd=0)  # 创建一个“画布”
    # width 宽
    # height 高
    # bd 边框宽度(像素)
    # bg 背景颜色
    # highlightthickness 颜色高亮
    
    # polygon 多边形
    canvas.create_polygon(0,0,100,200,100,250,50,300,fill='red',outline='red',stipple='error',width=10,dash=(10,50,100))
    
    canvas.pack()  # 将画布添加到窗口中
    tk.update()  # 刷新窗口
    
    
    # 进入消息循环
    tk.mainloop()  # 所有GUI程序都必须有一个主循环
    创建多边形

    执行结果:

    创建文字:

    #!/user/bin env python
    # author:Simple-Sir
    # time:2020/8/3 17:12
    import tkinter
    
    # 创建窗口
    tk = tkinter.Tk()  # 声明一个TK,初始化一个“窗口”(画一个窗口)
    tk.title('弹球游戏')  # 窗口名称
    tk.resizable(width=False,height=False)  # 窗口是否可变(长、宽),也可用0,1表示
    tk.wm_attributes('-topmost',1)  # 窗口永远在前
    
    # 创建画布
    canvas = tkinter.Canvas(tk,width=300,height=200,bd=0)  # 创建一个“画布”
    # width 宽
    # height 高
    # bd 边框宽度(像素)
    # bg 背景颜色
    # highlightthickness 颜色高亮
    
    
    canvas.create_text(100,100,text='使用text绘制文字',font='宋体',fill='red',anchor='n',justify='left',)
    # justify 文字的对齐方式:center、left、right
    
    canvas.pack()  # 将画布添加到窗口中
    tk.update()  # 刷新窗口
    
    
    # 进入消息循环
    tk.mainloop()  # 所有GUI程序都必须有一个主循环
    创建文字

    执行结果:

    事件

    三种绑定方式:
    canvas.bind() # 绑定到某一个组件上
    canvas.bind_all() # 绑定到所有组件上
    canvas.bind_class() # 绑定到某一类组件上

    键盘事件:
    <Left>
    <Right>
    <Up>
    <Down>
    <BackSpace>
    <Delete>
    <Tab>
    <Return>
    <Shift_L>
    <Shift_R>
    <Control_L>
    <Control_R>
    <Alt_L>
    <Alt_R>
    <Home>
    <Key> 或者 <KeyPress> 任意键盘按键

    鼠标事件 
    <Button-1> 鼠标点击(1-左键,2-中键,3-右键)
    <Double-Button-1> 鼠标双击(1-左键,2-中键,3-右键)
    <B1-Motion> 鼠标拖动(1-左键,2-中键,3-右键)
    <ButtonRelease-1> 鼠标按下之后释放(1-左键,2-中键,3-右键)
    <Enter> 鼠标进入控件范围
    <Leave> 鼠标离开控件范围

  • 相关阅读:
    nginx 开启 gzip 压缩
    React Native 开发豆瓣评分(八)首页开发
    flutter报错--ProcessException: Process... gradlew.bat ...exited abnormally
    React Native 开发豆瓣评分(七)首页组件开发
    React Native 开发豆瓣评分(六)添加字体图标
    React Native 开发豆瓣评分(五)屏幕适配方案
    随笔
    MySQL的安装与配置
    mybatisXMLsql
    数据类型转换
  • 原文地址:https://www.cnblogs.com/simple-li/p/13447613.html
Copyright © 2011-2022 走看看