You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python图形化骰子滚轮开发:shape未定义错误求助

Fixing the "shape is not defined" Error for Your Rolling Dice Effect

Hey there! Let's break down why you're hitting that "shape is not defined" error and get your dice rolling smoothly.

The Root of the Problem

In each of your dice functions (One(), Two(), etc.), the shape variable is a local variable—that means it only exists inside the function it's defined in. Once the function finishes running, you can't access shape from outside the function, which is why calling shape.undraw() later throws an error. Plus, you're not just drawing the rectangle—you're also drawing dots, so you need to undraw those too to clear the previous dice completely!

A Simple Fix for Your Code

Let's adjust your functions to return all the shapes they draw, so you can undraw everything later. We'll also clean up the loop to make the rolling effect work better:

First, update each dice function to return a list of all the drawn objects:

from graphics import *
from random import choice  # 用choice更方便随机选骰子函数
import time

win = GraphWin("Rolling Dice", 200, 200)
win.yUp()  # 注意这里要加括号,这是一个方法调用!

def One():
    shape = Rectangle(Point(150,150), Point(60,60))
    shape.draw(win)
    middleDot = Circle(Point(105,105), 8)
    middleDot.setFill('black')
    middleDot.draw(win)
    return [shape, middleDot]  # 返回所有绘制的图形

def Two():
    shape = Rectangle(Point(150,150), Point(60,60))
    shape.draw(win)
    RightDot = Circle(Point(125,125), 8)
    RightDot.setFill('black')
    RightDot.draw(win)
    LeftDot = Circle(Point(85,85), 8)
    LeftDot.setFill('black')
    LeftDot.draw(win)
    return [shape, RightDot, LeftDot]

def Three():
    shape = Rectangle(Point(150,150), Point(60,60))
    shape.draw(win)
    midDot = Circle(Point(105,108), 8)
    midDot.setFill('black')
    midDot.draw(win)
    topDot = Circle(Point(105,80),8)
    topDot.setFill('black')
    topDot.draw(win)
    botDot = Circle(Point(105,135), 8)
    botDot.setFill('black')
    botDot.draw(win)
    return [shape, midDot, topDot, botDot]

def Four():
    shape = Rectangle(Point(150,150), Point(60,60))
    shape.draw(win)
    topleft = Circle(Point(85,85),8)
    topleft.setFill('black')
    topleft.draw(win)
    topright = Circle(Point(125,85),8)
    topright.setFill('black')
    topright.draw(win)
    botleft = Circle(Point(85,125),8)
    botleft.setFill('black')
    botleft.draw(win)
    botright = Circle(Point(125,125),8)
    botright.setFill('black')
    botright.draw(win)
    return [shape, topleft, topright, botleft, botright]

def Five():
    shape = Rectangle(Point(150,150), Point(60,60))
    shape.draw(win)
    topleft = Circle(Point(85,85),8)
    topleft.setFill('black')
    topleft.draw(win)
    topright = Circle(Point(125,85),8)
    topright.setFill('black')
    topright.draw(win)
    botleft = Circle(Point(85,125),8)
    botleft.setFill('black')
    botleft.draw(win)
    botright = Circle(Point(125,125),8)
    botright.setFill('black')
    botright.draw(win)
    middleDot = Circle(Point(105,105), 8)
    middleDot.setFill('black')
    middleDot.draw(win)
    return [shape, topleft, topright, botleft, botright, middleDot]

def Six():
    shape = Rectangle(Point(150,150), Point(60,60))
    shape.draw(win)
    topleft = Circle(Point(85,85),8)
    topleft.setFill('black')
    topleft.draw(win)
    topright = Circle(Point(125,85),8)
    topright.setFill('black')
    topright.draw(win)
    botleft = Circle(Point(85,125),8)
    botleft.setFill('black')
    botleft.draw(win)
    botright = Circle(Point(125,125),8)
    botright.setFill('black')
    botright.draw(win)
    left = Circle(Point(85,105),8)
    left.setFill('black')
    left.draw(win)
    right = Circle(Point(125,105),8)
    right.setFill('black')
    right.draw(win)
    return [shape, topleft, topright, botleft, botright, left, right]

Then update the loop to handle rolling and clearing each dice:

Dice = [One, Two, Three, Four, Five, Six]

# 模拟5次骰子滚动,你可以改这个数字让滚动次数更多
for _ in range(5):
    # 随机选一个骰子函数
    current_dice = choice(Dice)
    # 调用函数并拿到所有绘制的图形
    drawn_objects = current_dice()
    # 停留0.2秒
    time.sleep(0.2)
    # 逐个取消绘制所有图形,清除当前骰子
    for obj in drawn_objects:
        obj.undraw()

# 最后可以显示一个最终的骰子结果
final_dice = choice(Dice)
final_dice()

# 保持窗口打开,直到点击关闭
win.getMouse()
win.close()

Key Changes Explained

  • Returning drawn objects: Each function now gives back a list of every shape it draws, so we can access them outside the function to undraw.
  • Using choice(): This is a simpler way to pick a random dice function from the list instead of using randint and conditionals.
  • Fixing win.yUp(): You forgot the parentheses here—this is a method that needs to be called to flip the y-axis!
  • Clearing all elements: We undraw every shape from the previous dice, not just the rectangle, so the screen is clean for the next roll.

This should get your dice rolling without the "shape is not defined" error, and create a smooth visual effect!

内容的提问来源于stack exchange,提问作者InternalFecalSeepage

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:01:03