ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

[Python GUI]Python内置图形界面tkinter Eye-Hand Coordination--游戏实战1

2020-12-18 23:04:29  阅读:271  来源: 互联网

标签:canvas Eye Python 图形界面 grid rect self 方块 size


[Python GUI]Python内置图形界面tkinter Hand-Eye Coordination--游戏实战1

游戏介绍

本文实现的是一种成为hand-eye coordination的游戏的简单实现。hand-eye coordination就是一种锻炼手眼协调控制的游戏,有些类似于别踩白块,虽然比别踩白块要简单,但是思想是一样的。
代码实现了可以通过设置画布大小和网格多少来初始化UI,并设置方块下落速度,以改变游戏难度,还可以设置方块出现多少次之后结束本次游戏。
此游戏初步实现一个简单的版本,还可继续完善,除了下面Todolist所列出的,有其他玩法,也欢迎在评论区留言讨论。
在这里插入图片描述
没有gif,只能靠描述了,点击上方的 START 之后开始游戏,会在第一行随机生成方块,然后一格一格往下掉,直到最后一行,继续往下掉就消失;或者是在下落的途中,有点击事件也会消失。

关键词

Hand-Eye Coordination
Tkinter,Canvas,Button,after

TodoList

  • 设置画布大小
  • 设置网格多少
  • 设置移动速度
  • 循环次数,默认无限次
  • 改成界面设置参数
  • 加个计算分数的功能
  • 增加方块的数量,随机颜色
  • 打包

改变玩法:

  • 可以改成全屏随机出现方块
  • 方块换仓图片就是打地鼠

代码详解

个人感觉代码注释的已经很清楚了,就不在多余去解释了。
就在这里讲讲设计思想和函数的作用吧。
OUTLINE
__init__(): 初始化各个参数;
delete_rect(): 绑定在方块上的函数,作用是删除方块,即点击事件调用的函数,或者掉到底部时调用;
draw_grid(): 被init_ui调用,用来画水平线和垂直线,生成网格;
gen_square(): 生成方块,同时绑定删除事件;
init_ui(): 初始化UI,设置并固定窗口大小,设置按钮和画布大小;
move_down(): 控制方块向下运动
还有一个控制延时的函数after,是实现运动的关键;
after(ms, func): 第一个参数是延时时长,单位是毫秒;第二个参数是延时之后运行的函数。对于这个函数,网上看了一些例子,感觉都不太好理解,是我太笨了;还有一些文章说延时时间不准,这也没有去深究,毕竟这个游戏对延时时间准确度要求没那么高。

import tkinter as tk
import random
class EyeHand:
    def __init__(self, 
            canvas:tuple = (500,500), 
            grid:tuple = (10,10), 
            speed:int = 1, 
            loop:int = 10
            ) -> None:
        # 网格的数量
        self.grid = grid
        # 计算每个grid的宽高,(方便点的话,限制grid为正方形,这里可以为矩形),
        # 然后确定canvas宽高,所以,输入的宽高只是个参考值
        # 每个小格的宽高
        self.grid_w = canvas[0] // self.grid[0]
        self.grid_h = canvas[1] // self.grid[1]
        # 画布的尺寸
        self.canvas_size = (self.grid_w*self.grid[0], self.grid_h*self.grid[1])
        # 方块移动的速度 1000ms // speed
        self.speed = 1000 // speed
        # # 出现几个方块之后结束
        # self.loop = loop
        # 窗口的尺寸
        self.win_size = str(self.canvas_size[0]+40)+"x"+str(self.canvas_size[1]+120)
        self.main_win = tk.Tk()
        # 窗口名
        self.main_win.title("Eye–hand coordination")
        # 初始化UI
        self.init_ui()
        # 窗口显示
        self.mainloop = self.main_win.mainloop
        # 方块向下走的步数
        self.step = 0
        # 最大步数
        self.max_step = self.grid[1]
        # 当前是否有方块
        self.square_exists = False
        # 循环次数
        self.count = 0
        # 最大循环次数
        self.max_count = loop

    def init_ui(self) -> None :
        self.main_win.geometry(self.win_size) # 设置窗口大小
        self.main_win.resizable(0, 0) # 固定窗口大小
        self.canvas = tk.Canvas(self.main_win, 
                                bg="#999AAA", 
                                cursor="plus", 
                                height=self.canvas_size[0], 
                                width=self.canvas_size[1]
                                ) # 设置画布
        self.canvas.place(x=20, y=50)
        self.draw_grid(self.grid) # 画网格
        self.btn1 = tk.Button(self.main_win, 
                                text="START", 
                                font=("Arial", 12), 
                                width=20, 
                                height=1, 
                                command=self.gen_square
                                ) # 设置"开始游戏"按钮
        self.btn1.pack()

    def draw_grid(self, size) -> None :
        for row in range(0, size[0]+1):
            self.canvas.create_line(0, 
                                self.grid_h*row, 
                                self.canvas_size[1], 
                                self.grid_h*row
                                ) # 画水平线
        for col in range(0, size[1]+1):
            self.canvas.create_line(self.grid_w*col, 
                                0, 
                                self.grid_w*col, 
                                self.canvas_size[0]
                                ) # 画垂直线

    def gen_square(self) -> None :
        # 生成矩形的次数达到最大限制则不再生成
        if self.count >= self.max_count:
            self.count = 0 # 一次游戏结束,循环次数置0,则可以按"start"键重新开始游戏
            return
        self.step = 0 # 每次生成方块,step置0
        try:
            self.delete_rect(tk.Event) # 如果界面中有方块,先清除
        except:
            pass
        offset = random.randint(0, self.grid[0]-1) # 第一行随机位置生成方块的变化量
        r = self.canvas.create_rectangle(self.grid_w*offset, 
                                0, 
                                self.grid_w*offset+self.grid_h, 
                                self.grid_h, 
                                fill='blue',
                                tags=("rect")
                                ) # 第一行随机位置生成方块
        self.square_exists = True
        self.canvas.tag_bind( 'rect' , '<Button-1>' , self.delete_rect)
        self.canvas.after(self.speed, self.move_down) # 关键方法,.after(deley_ms, func),延迟deley_ms毫秒后,执行func函数

    def move_down(self) -> None :
        self.step += 1 # 计数向下移动次数,到底还没被点击则删除
        if self.step >= self.max_step:
            self.delete_rect(tk.Event)
        if self.square_exists: # 有方块存在,向下移动方块
            self.canvas.move('rect', 0, self.grid_h)
            self.canvas.after(self.speed, self.move_down)
        else: # 没有方块存在,生成下一个方块
            self.count += 1
            self.canvas.after(self.speed, self.gen_square)

    def delete_rect(self, event) ->None : # 删除方块
        self.canvas.delete("rect")
        self.square_exists = False
        
game = EyeHand(canvas=(500,500), grid=(5,5), speed=5, loop=10)
game.mainloop()

代码还有可以优化和完善的地方,留待日后无聊的时候再说吧!

标签:canvas,Eye,Python,图形界面,grid,rect,self,方块,size
来源: https://blog.csdn.net/ayiya_Oese/article/details/111227271

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有