[英]How to launch a turtle program with a tkinter messagebox?
I am trying to launch a turtle game stored in one file with a message box from tkinter
stored in another py file but both in the same directory. 我正在尝试启动一个存储在一个文件中的乌龟游戏,其中一个消息框来自存储在另一个py文件中的
tkinter
消息,但两者都在同一目录中。 However, I receive a _tkinter.TclError: image "pyimage2" doesn't exist
error. 但是,我收到
_tkinter.TclError: image "pyimage2" doesn't exist
错误。
I have a function inside the game code that is called upon in the launcher code. 我在启动器代码中调用的游戏代码中有一个函数。 This function runs all of the code inside the main game program apart from importing modules which I have included in the function but makes no difference.
除了导入模块(我已包含在函数中)外,此函数运行主游戏程序中的所有代码,但没有区别。
Sorry for showing all but as I don't know what the problem is I thought this was best(removed as much code irrelevant to problem as I could(Assume anything unnamed that is called is deleted as irrelevant code) 很抱歉显示了所有内容,但我不知道问题出在哪里,我认为这是最好的(删除了尽可能多的与问题无关的代码(假设任何未命名的名称都被删除为无关的代码)
def start():
import turtle
import math
import time
counter = 0
wn = turtle.Screen()
wn.setup(800, 600)
wn.bgcolor("black")
wn.title("Trooper shooter")
wn.bgpic("background1.png")
wn.update()
turtle.register_shape("invader.gif")
turtle.register_shape("plane.gif")
turtle.register_shape("troop.gif")
turtle.register_shape("player1.gif")
turtle.register_shape("player2.gif")
turtle.register_shape("bomb.gif")
turtle.register_shape("boom.gif")
#player
soldier = turtle.Turtle()
soldier.color("blue")
soldier.shape("player1.gif")
soldier.penup()
soldier.speed(0)
soldier.setposition(0,-200)
soldier.setheading(90)
soldierspd = 20
#Bomb
Numbombs = 2
bombs = []
for i in range(Numbombs):
bombs.append(turtle.Turtle())
for bomb in bombs:
bomb.shape("bomb.gif")
bomb.penup()
bomb.speed(0)
bomb.ht()
x = -1700
y = 2700
bomb.setposition(x+30,y)
bomb.setheading(270)
bombspeed = 10
#Plane
plane = turtle.Turtle()
plane.color("red")
plane.shape("plane.gif")
plane.penup()
plane.speed(0)
plane.setposition(-270,200)
plane.setheading(360)
planespd = 20
#Plane2
plane2 = turtle.Turtle()
plane2.ht()
plane2.color("red")
plane2.shape("plane.gif")
plane2.penup()
plane2.speed(0)
plane2.setposition(-270,200)
plane2.setheading(360)
planespd2 = 20
#ParaTroopers
num = 5
Troopers = []
for i in range(num):
Troopers.append(turtle.Turtle())
for Troop in Troopers:
Troop.color("Purple")
Troop.shape("troop.gif")
Troop.penup()
Troop.speed(0)
Troop.ht()
x = -170
y = 270
Troop.setposition(x+30,y)
Troop.setheading(270)
Troopspeed = 3
#Bullet
bullet = turtle.Turtle()
bullet.color("yellow")
bullet.shape("triangle")
bullet.penup()
bullet.speed(0)
bullet.setheading(90)
bullet.shapesize(0.5, 0.5)
bullet.ht()
bulletspeed = 30
#Define bullet state
#ready = ready to fire
#fire = bullet is firing
state = "ready"
#Move player left
def Left():
x = soldier.xcor()
x -= soldierspd
soldier.setx(x)
soldier.shape("player1.gif")
if x < -280:
x = -280
soldier.setx(x)
#Move player right
def Right():
x = soldier.xcor()
x += soldierspd
soldier.setx(x)
soldier.shape("player2.gif")
if x > 280:
x = 280
soldier.setx(x)
#Shoot bullet
def Shoot():
#Declare bullet state as global
global state
if state == "ready":
state = "fire"
#Move bullet above player
x = soldier.xcor()
y = soldier.ycor()
bullet.setposition(x, y +10)
bullet.showturtle()
#HitBoxes
def checkCollision(A,B):
distance = math.sqrt(math.pow(A.xcor() - B.xcor(), 2) +
math.pow(A.ycor() - B.ycor(), 2))
if distance < 30:
return True
else:
return False
#Move plane
def MovePlane():
x = plane.xcor()
x += planespd
plane.speed(1)
plane.setx(x)
if plane.xcor() > 280:
plane.ht()
turtle.listen()
turtle.onkey(Left,"Left")
turtle.onkey(Right,"Right")
turtle.onkey(Shoot,"space")
while True:
#Move Plane
MovePlane()
#Move count
incCount()
#Show Paratrooper
x = -200
for Troop in Troopers:
if plane.xcor() > x+50:
x += 80
Troop.setx(x)
Troop.showturtle()
y = Troop.ycor()
y -= Troopspeed
Troop.sety(y)
if y < -280:
Troop.ht()
if checkCollision(bullet, Troop):
# Reset bullet
bullet.ht()
state = "ready"
bullet.setposition(0, -400)
Troop.shape("boom.gif")
# Update Scoreboard
score += 10
scorestring = "Score: %s" % score
score_pen.clear()
score_pen.write(scorestring, False, align="left", font=("Arial", 14, "normal"))
time.sleep(0.1)
Troop.setposition(1000, 1000)
#update background
if counter == 30:
wn.bgpic("background2.png")
wn.update()
if counter == 60:
wn.bgpic("background3.png")
wn.update()
if counter == 90:
wn.bgpic("background4.png")
wn.update()
if counter == 120:
wn.bgpic("background5.png")
wn.update()
if counter == 150:
wn.bgpic("background6.png")
wn.update()
wn.mainloop()
from tkinter import *
from tkinter import messagebox
import TrooperShooter
root = Tk()
launch = messagebox.askquestion("launcher","Play game?")
if launch == "yes":
TrooperShooter.start()
When the launcher is run a messagebox should appear saying do you wish to play and when "yes" is clicked the function to start the game is launched. 运行启动器时,将出现一个消息框,提示您是否要玩,单击“是”时,将启动启动游戏的功能。 However I receive the error:
但是我收到错误:
Traceback (most recent call last):
File "C:/Users/marco/Desktop/Trooper shooter/launcher.py", line 10, in <module>
TrooperShooter.start()
File "C:\Users\marco\Desktop\Trooper shooter\TrooperShooter.py", line 18, in start
wn.bgpic("background1.png")
File "C:\Program Files (x86)\Python37-32\lib\turtle.py", line 1482, in bgpic
self._setbgpic(self._bgpic, self._bgpics[picname])
File "C:\Program Files (x86)\Python37-32\lib\turtle.py", line 738, in _setbgpic
self.cv.itemconfig(item, image=image)
File "<string>", line 1, in itemconfig
File "C:\Program Files (x86)\Python37-32\lib\tkinter\__init__.py", line 2578, in itemconfigure
return self._configure(('itemconfigure', tagOrId), cnf, kw)
File "C:\Program Files (x86)\Python37-32\lib\tkinter\__init__.py", line 1476, in _configure
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: image "pyimage2" doesn't exist
Process finished with exit code 1
My first suggestion is that you use the turtle textinput()
method (new in Python 3) instead of dragging tkinter and messagebox into the picture. 我的第一个建议是使用乌龟
textinput()
方法(Python 3中的新增功能),而不是将tkinter和messagebox拖动到图片中。
But if you're going to combine tkinter and turtle, you need to do it correctly. 但是,如果您要将tkinter和turtle结合使用,则需要正确进行操作。 Turtle is designed to run either standalone with its own Tk window or embedded in an existing tkinter window.
Turtle被设计为既可以独立运行,也可以拥有自己的Tk窗口,也可以嵌入现有的tkinter窗口中。 You're attempting to run it standalone, embedded in a tkinter window.
您正在尝试独立运行它,将其嵌入到tkinter窗口中。 Ie instead of the standalone
Turtle
& Screen
interface, you should be working with the embedded TurtleScreen
, RawTurtle
and ScrolledCanvas
interface. 即,您应该使用嵌入式
TurtleScreen
, RawTurtle
和ScrolledCanvas
界面来代替独立的Turtle
& Screen
界面。
Besides this issue, your code is generally buggy. 除此问题外,您的代码通常是错误的。 You've lots of unfinished code.
您有许多未完成的代码。 Your use of
global
has to become nonlocal
when you move the entire program inside the start()
function. 在
start()
函数中移动整个程序时,对global
使用必须变为nonlocal
。 You're missing pieces of code necessary to run. 您缺少了运行所需的代码。 Finally, you have a
while True:
loop which has no business being in an event-driven environment like turtle. 最后,您有
while True:
循环,这与在诸如Turtle这样的事件驱动环境中没有任何关系。 I've repaced it with a timer event. 我用定时器事件来取消它。
I've reworked your code below to run as you intended. 我对您的代码进行了重新设计,使其可以按预期运行。 I've tossed incomplete and/or broken features to simplify the example.
为了简化示例,我抛弃了不完整和/或损坏的功能。 The startup code:
启动代码:
from tkinter import Tk
from tkinter import messagebox
import TrooperShooter
root = Tk()
launch = messagebox.askquestion("launcher", "Play game?")
if launch == "yes":
TrooperShooter.start(root)
TrooperShooter.py TrooperShooter.py
import tkinter as tk
from turtle import TurtleScreen, ScrolledCanvas, RawTurtle
def start(root):
# Move player left
def Left():
soldier.shape("player1.gif")
x = soldier.xcor() - soldierspd
soldier.setx(x)
if x < -280:
soldier.setx(-280)
# Move player right
def Right():
soldier.shape("player2.gif")
x = soldier.xcor() + soldierspd
soldier.setx(x)
if x > 280:
soldier.setx(280)
# Shoot bullet
def Shoot():
# Declare bullet state as global
nonlocal state
if state == "ready":
state = "fire"
# Move bullet above player
x, y = soldier.position()
bullet.setposition(x, y + 10)
bullet.showturtle()
# HitBoxes
def checkCollision(a, b):
return a.distance(b) < 30
# Move plane
def MovePlane():
x = plane.xcor() + plane_speed
plane.setx(x)
if plane.xcor() > 280:
plane.hideturtle()
def action():
nonlocal state, score
# Move Plane
MovePlane()
# Show Paratrooper
x = -200
for troop in troopers:
if plane.xcor() > x + 50:
x += 80
troop.setx(x)
troop.showturtle()
y = troop.ycor() - troop_speed
troop.sety(y)
if y < -280:
troop.hideturtle()
if checkCollision(bullet, troop):
# Reset bullet
bullet.hideturtle()
state = "ready"
bullet.setposition(0, -400)
troop.shape("boom.gif")
# Update Scoreboard
score += 10
scorestring = "Score: %s" % score
score_pen.clear()
score_pen.write(scorestring, align="left", font=("Arial", 14, "normal"))
troop.setposition(1000, 1000)
if state == "fire":
y = bullet.ycor()
if y > 300:
state = 'ready'
bullet.hideturtle()
else:
bullet.sety(y+ bullet_speed)
screen.ontimer(action, 100)
score = 0
# Define bullet state
# ready = ready to fire
# fire = bullet is firing
state = "ready"
root.geometry("800x600")
root.title("Trooper shooter")
canvas = ScrolledCanvas(root)
canvas.pack(fill=tk.BOTH, expand=tk.YES)
screen = TurtleScreen(canvas)
screen.bgcolor("black")
screen.bgpic("background1.png")
screen.register_shape("invader.gif")
screen.register_shape("plane.gif")
screen.register_shape("troop.gif")
screen.register_shape("player1.gif")
screen.register_shape("player2.gif")
screen.register_shape("boom.gif")
# Player
soldier = RawTurtle(screen)
soldier.color("blue")
soldier.shape("player1.gif")
soldier.penup()
soldier.speed('fastest')
soldier.setposition(0, -200)
soldier.setheading(90)
soldierspd = 20
# Score
score_pen = RawTurtle(screen)
score_pen.speed('fastest')
score_pen.hideturtle()
# Plane
plane = RawTurtle(screen)
plane.color("red")
plane.shape("plane.gif")
plane.penup()
plane.speed('fastest')
plane.setposition(-270, 200)
plane.setheading(360)
plane_speed = 20
# ParaTroopers
number_troops = 5
troopers = []
for _ in range(number_troops):
troop = RawTurtle(screen)
troop.color("Purple")
troop.shape("troop.gif")
troop.penup()
troop.speed('fastest')
troop.hideturtle()
x, y = -170, 270
troop.setposition(x + 30, y)
troop.setheading(270)
troopers.append(troop)
troop_speed = 3
# Bullet
bullet = RawTurtle(screen)
bullet.color("yellow")
bullet.shape("triangle")
bullet.penup()
bullet.speed('fastest')
bullet.setheading(90)
bullet.shapesize(0.5)
bullet.hideturtle()
bullet_speed = 30
screen.onkey(Left, "Left")
screen.onkey(Right, "Right")
screen.onkey(Shoot, "space")
screen.listen()
action()
screen.mainloop()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.