【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

五、程序结果

相关推荐
范文杰3 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪3 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪3 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy4 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom5 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom5 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom5 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom5 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom5 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试
LaoZhangAI6 小时前
2025最全GPT-4o图像生成API指南:官方接口配置+15个实用提示词【保姆级教程】
前端