【python知识】用 Tkinter实现“剪刀-石头-布”和“弹球游戏 ”

一、提要

Tkinter是一个Python内置模块,它提供了一个简单易用的界面来创建GUI。

在实现一些动态的画面、如游戏还是需要一些创新性思维的。在本文中,我们将使用 Tkinter 探索 Python GUI 编程。我们将介绍 Tkinter 的基础知识,并演示如何使用 Tkinter 创建一个简单的 GUI 应用程序。

二、Tkinter的基础介绍

Tkinter是一个Python内置模块,它提供了一个简单易用的界面来创建GUI。

Tkinter 提供了一组可用于创建 GUI 的小部件。小部件是提供特定功能(如按钮、标签或输入字段)的图形元素。小部件可以排列在窗口中以创建 GUI。

创建 Tkinter GUI 的基本步骤是:

  1. 导入 Tkinter 模块
  2. 创建窗口
  3. 向窗口添加微件
  4. 配置微件
  5. 向微件添加功能
  6. 启动主事件循环

下面是使用 Tkinter 创建窗口的简单示例:

import tkinter as tk

window = tk.Tk()
window.mainloop()

三、剪刀石头布游戏

如果您想了解有关 Tkinter 的更多信息,我会在本文末尾放置一个链接。所以,我想和Tk一起做点什么。我最终做了石头剪刀布,我想和你分享。让我们看一下代码和结果。

代码不长。它拥有这款游戏所需的所有东西。首先,我们制作可以玩游戏的屏幕。

# Import Required Library
from tkinter import *
import random

# Create Object
root = Tk()

# Set geometry
root.geometry("300x300")

# Set title
root.title("Rock Paper Scissor Game")

接下来,我为计算机分配值,因为在游戏过程中,您将与计算机竞争。

# Computer Value
computer_value = {
 "0": "Rock",
 "1": "Paper",
 "2": "Scissor"
}

然后,我做了一些功能。根据玩家的选择,计算机或玩家获胜。因此,如果玩家选择石头,并且函数也选择石头,他们就会平局。当然,这也适用于剪刀对剪刀。如果你不知道这个游戏,中间有一个简短的解释:

  • 石头>剪刀
  • 剪刀>纸
  • >石头

这部分提供匹配结果。

# Reset The Game
def reset_game():
 b1["state"] = "active"
 b2["state"] = "active"
 b3["state"] = "active"
 l1.config(text="Player    ")
 l3.config(text="Computer")
 l4.config(text="")

# Disable the Button
def button_disable():
 b1["state"] = "disable"
 b2["state"] = "disable"
 b3["state"] = "disable"

# If player selected rock
def isrock():
 c_v = computer_value[str(random.randint(0, 2))]
 if c_v == "Rock":
  match_result = "Match Draw"
 elif c_v == "Scissor":
  match_result = "Player Win"
 else:
  match_result = "Computer Win"
 l4.config(text=match_result)
 l1.config(text="Rock   ")
 l3.config(text=c_v)
 button_disable()

# If player selected paper
def ispaper():
 c_v = computer_value[str(random.randint(0, 2))]
 if c_v == "Paper":
  match_result = "Match Draw"
 elif c_v == "Scissor":
  match_result = "Computer Win"
 else:
  match_result = "Player Win"
 l4.config(text=match_result)
 l1.config(text="Paper   ")
 l3.config(text=c_v)
 button_disable()

# If player selected scissor
def isscissor():
 c_v = computer_value[str(random.randint(0, 2))]
 if c_v == "Rock":
  match_result = "Computer Win"
 elif c_v == "Scissor":
  match_result = "Match Draw"
 else:
  match_result = "Player Win"
 l4.config(text=match_result)
 l1.config(text="Scissor   ")
 l3.config(text=c_v)
 button_disable()

代码的最后一部分,将所有内容打包在一起并编写最后的细节,以便它能够工作并完成代码。这包括在石头、纸或剪刀之间进行选择的按钮。还需要制作文本。

# Add Labels, Frames and Button
Label(root,
 text="Rock Paper Scissor",
 font="normal 20 bold",
 fg="blue").pack(pady=20)

frame = Frame(root)
frame.pack()

l1 = Label(frame,
  text="Player    ",
  font=10)

l2 = Label(frame,
  text="VS    ",
  font="normal 10 bold")

l3 = Label(frame, text="Computer", font=10)

l1.pack(side=LEFT)
l2.pack(side=LEFT)
l3.pack()

l4 = Label(root,
  text="",
  font="normal 20 bold",
  bg="white",
  width=15,
  borderwidth=2,
  relief="solid")
l4.pack(pady=20)

frame1 = Frame(root)
frame1.pack()

b1 = Button(frame1, text="Rock",
   font=10, width=7,
   command=isrock)

b2 = Button(frame1, text="Paper ",
   font=10, width=7,
   command=ispaper)

b3 = Button(frame1, text="Scissor",
   font=10, width=7,
   command=isscissor)

b1.pack(side=LEFT, padx=10)
b2.pack(side=LEFT, padx=10)
b3.pack(padx=10)

Button(root, text="Reset Game",
 font=10, fg="red",
 bg="black", command=reset_game).pack(pady=20)

# Execute Tkinter
root.mainloop()

四、更复杂游戏--弹球游戏

4.1 窗口布局类实现

窗口和外观,首先是最外层Frame的设定,请看代码:

python 复制代码
from tkinter import *
import random
import time

# Creating the window:
window = Tk()
window.title("Bounce")
window.geometry('600x600')
window.resizable(False, False)

这里对窗口一系列设定:

窗口语句 功能
window = Tk() 创建最外层主窗口
window.title("Bounce") 设标题
window.geometry('600x600') 设窗口高度、宽度
window.resizable(False, False) 设定窗口固定大小

4.2 建立画布对象

画布是刻画动画功能的对象,画布需要放置在桌面,不可独立存在。因此,桌面就是画布的承载对象。因此,画布有一系列初始化函数,请看下面代码:

python 复制代码
window = Tk()

# Creating the canvas containing the game:
canvas = Canvas(window, width = 450, height = 450, bg = "black")
canvas.pack(padx = 50, pady= 50)
score = canvas.create_text(10, 20, fill = "white")
window.update()

4.3 建立小球对象

4.3.1 小球对象类

小球相关的物体是:画布、球拍;即小球在画布内游动,小球被球拍打击而折返。

因此,小球对象初始化需要两个外界物体,画布、球拍。

python 复制代码
class Ball:
    def __init__(self, canvas1, paddle1, color):

4.3.2 小球绘制

小球是椭圆绘制函数,原型如下:

复制代码
`id = C.create_oval(x0, y0, x1, y1, option, ...)`
python 复制代码
        self.canvas.move(self.id, 190, 160)
        starting_direction = [-3, -2, -1, 0, 1, 2, 3]
        random.shuffle(starting_direction)
        self.x = starting_direction[0]
        self.y = -3
        self.canvas_height = self.canvas.winfo_height()
        self.canvas_width = self.canvas.winfo_width()
小球内初始化代码 意义
self.canvas.move(self.id, 190, 160) 将小球移动到画布的位置。
starting_direction = [-3, -2, -1, 0, 1, 2, 3] 小球移动方向【横、竖、斜】
random.shuffle(starting_direction) 混淆方向
self.x = starting_direction[0] 选一个初始方向
self.y = -3
self.canvas_height = self.canvas.winfo_height() 取出画布的高、宽,用以判别小球移动范围
self.canvas_width = self.canvas.winfo_width() 取出画布的高、宽,用以判别小球移动范围

def hit_paddle(self, ballcoords): 球拍击球处理

def draw(self): 随小球位置重画

self.canvas.move(self.id, self.x, self.y)

4.3.3 小球数据的合理设计

小球数据因该分成两种:显式数据、隐含数据;显式数据针对画布而言,隐式数据针对小球运动,方向、位置变化等而设定。

4.4 全部程序代码

在以上游戏调试完成后,我们实现一个更复杂的动态任务。实现弹球游戏,通过<--和-->件移动平板接球,下文是tkinter的应用实例:

python 复制代码
from tkinter import *
import random
import time

# Creating the window:
window = Tk()
window.title("Bounce")
window.geometry('600x600')
window.resizable(False, False)

# Creating the canvas containing the game:
canvas = Canvas(window, width = 450, height = 450, bg = "black")
canvas.pack(padx = 50, pady= 50)
score = canvas.create_text(10, 20, fill = "white")

window.update()

class Ball:
    def __init__(self, canvas1, paddle1, color):
        self.canvas = canvas1
        self.paddle = paddle1
        self.id = canvas1.create_oval(10, 10, 25, 25, fill = color)  # The starting point of the ball
        self.canvas.move(self.id, 190, 160)
        starting_direction = [-3, -2, -1, 0, 1, 2, 3]
        random.shuffle(starting_direction)
        self.x = starting_direction[0]
        self.y = -3
        self.canvas_height = self.canvas.winfo_height()
        self.canvas_width = self.canvas.winfo_width()

    # Detecting the collision between the ball and the paddle:
    def hit_paddle(self, ballcoords):
        paddle_pos = self.canvas.coords(self.paddle.id)
        if ballcoords[0] <= paddle_pos[2] and ballcoords[2] >= paddle_pos[0]:
            if paddle_pos[3] >= ballcoords[3] >= paddle_pos[1]:
                return True
        return False

    # Detecting the collision between the the ball and the canvas sides:
    def draw(self):
        self.canvas.move(self.id, self.x, self.y)
        ballcoords = self.canvas.coords(self.id)
        if ballcoords[1] <= 0:
            self.y = 3
        if ballcoords[3] >= self.canvas_height:
            self.y = 0
            self.x = 0
            self.canvas.create_text(225, 150, text = "Game Over!", font = ("Arial", 16), fill = "white")
        if ballcoords[0] <= 0:
            self.x = 3
        if ballcoords[2] >= self.canvas_width:
            self.x = -3
        if self.hit_paddle(ballcoords):
            self.y = -3


class Paddle:
    def __init__(self, canvas1, color):
        self.canvas1 = canvas
        self.id = canvas.create_rectangle(0, 0, 100, 10, fill = color)
        self.canvas1.move(self.id, 180, 350)
        self.x = 0
        self.y = 0
        self.canvas1_width = canvas1.winfo_width()
        self.canvas1.bind_all("<Left>", self.left)
        self.canvas1.bind_all("<Right>", self.right)

    def draw(self):
        self.canvas1.move(self.id, self.x, 0)
        paddlecoords = self.canvas1.coords(self.id)
        if paddlecoords[0] <= 0:
            self.x = 0
        if paddlecoords[2] >= self.canvas1_width:
            self.x = 0

    def right(self, event):
        self.x = 3

    def left(self, event):
        self.x = -3


paddle = Paddle(canvas, color = "white")
ball = Ball(canvas, paddle, color = "red")

# New code after here
def handler():
    global run
    run = False

window.protocol("WM_DELETE_WINDOW", handler)
run = True

while run:
    # New code before here
    ball.draw()
    paddle.draw()
    window.update_idletasks()
    window.update()
    time.sleep(0.01)

window.destroy()    # should always destroy window before exit

五、程序结果

相关推荐
南宫理的日知录16 分钟前
99、Python并发编程:多线程的问题、临界资源以及同步机制
开发语言·python·学习·编程学习
coberup25 分钟前
django Forbidden (403)错误解决方法
python·django·403错误
我要洋人死1 小时前
导航栏及下拉菜单的实现
前端·css·css3
龙哥说跨境1 小时前
如何利用指纹浏览器爬虫绕过Cloudflare的防护?
服务器·网络·python·网络爬虫
科技探秘人1 小时前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人1 小时前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR1 小时前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香1 小时前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q2498596931 小时前
前端预览word、excel、ppt
前端·word·excel
小白学大数据1 小时前
正则表达式在Kotlin中的应用:提取图片链接
开发语言·python·selenium·正则表达式·kotlin