问题
I am trying to make my turtle move according to the arrow keys on my keyboard. Does anybody know how to make a turtle in python 3.2.2 move according to the command of my arrow keys? By the way, my turtle is in the form of a tank if that affects anything. Here is my code:
import turtle
unVar1 = 25
unVar2 = 100
unVar3 = 90
unVar4 = 150
unVar5 = -30
unVar6 = 75
unVar7 = 50
def polySquare(t, x, y, length):
t.goto(x, y)
t.setheading(270)
t.begin_poly()
for count in range(4):
t.forward(length)
t.left(90)
t.end_poly()
return t.get_poly()
def polyRectangle(t, x, y, length1, length2):
t.goto(x, y)
t.setheading(270)
t.begin_poly()
for count in range(2):
t.forward(length1)
t.left(90)
t.forward(length2)
t.left(90)
t.end_poly()
return t.get_poly()
def tankCursor():
"""
Create the tank cursor. An alternate solution is to toss the temporary turtle
and use the commented out polygon assignments instead of the poly function calls
"""
temporary = turtle.Turtle()
screen = turtle.getscreen()
delay = screen.delay()
screen.delay(0)
temporary.hideturtle()
temporary.penup()
tank = turtle.Shape("compound")
# tire1 = ((10, unVar1), (10, unVar1 - unVar6), (10 + 30, unVar1 - unVar6), (10 + 30, unVar1))
tire1 = polyRectangle(temporary, 10, unVar1, unVar6, 30) # Tire #1
tank.addcomponent(tire1, "gray", "black")
# tire2 = ((110, unVar1), (110, unVar1 - unVar6), (110 + 30, unVar1 - unVar6), (110 + 30, unVar1))
tire2 = polyRectangle(temporary, 110, unVar1, unVar6, 30) # Tire #2
tank.addcomponent(tire2, "gray", "black")
# tire3 = ((110, unVar2), (110, unVar2 - unVar6), (110 + 30, unVar2 - unVar6), (110 + 30, unVar2))
tire3 = polyRectangle(temporary, 110, unVar2, unVar6, 30) # Tire #3
tank.addcomponent(tire3, "gray", "black")
# tire4 = ((10, unVar2), (10, unVar2 - unVar6), (10 + 30, unVar2 - unVar6), (10 + 30, unVar2))
tire4 = polyRectangle(temporary, 10, unVar2, unVar6, 30) # Tire #4
tank.addcomponent(tire4, "gray", "black")
# bodyTank = ((20, unVar3), (20, unVar3 - 130), (20 + 110, unVar3 - 130), (20 + 110, unVar3))
bodyTank = polyRectangle(temporary, 20, unVar3, 130, 110)
tank.addcomponent(bodyTank, "black", "gray")
# gunTank = ((65, unVar4), (65, unVar4 - 100), (65 + 20, unVar4 - 100), (65 + 20, unVar4))
gunTank = polyRectangle(temporary, 65, unVar4, 100, 20) # Gun
tank.addcomponent(gunTank, "black", "gray")
# exhaustTank = ((50, unVar5), (50, unVar5 - 20), (50 + 10, unVar5 - 20), (50 + 10, unVar5))
exhaustTank = polyRectangle(temporary, 50, unVar5, 20, 10)
tank.addcomponent(exhaustTank, "black", "gray")
# turretTank = ((50, unVar7), (50, unVar7 - 50), (50 + 50, unVar7 - 50), (50 + 50, unVar7))
turretTank = polySquare(temporary, 50, unVar7, 50) # Turret
tank.addcomponent(turretTank, "red", "gray")
turtle.addshape("tank", shape=tank)
del temporary
screen.delay(delay)
tankCursor() # creates and registers the "tank" cursor shape
turtle.shape("tank")
turtle.up() # get rid of the ink
# show our tank in motion
while True:
turtle.forward(100)
turtle.left(90)
turtle.forward(100)
turtle.left(180)
turtle.forward(200)
回答1:
You can use turtle's built in key event handlers. This is the link to the documents: https://docs.python.org/3.2/library/turtle.html
Using your code, everything stays the same up to tankCursor()
(line 98). Now going down in order, this is what I did.
tankCursor() # creates and registers the "tank" cursor shape
tank = turtle
tank.shape("tank")
turtle.up() # get rid of the ink
screen = turtle.Screen()
I made the tank variable so you are interacting with that (you did turtle.foward, turtle.backward, etc.) instead of turtle. Just good practice, and now you can have multiple tanks on the screen, or multiple characters if you wish. The turtle.up()
is from your original code. The screen = turtle.Screen()
is so your code gets notified of the key events, ie. when the user clicks a key / releases a key.
def moveright():
tank.forward(40)
def moveleft():
tank.backward(40)
These are just functions, to move the tank right and left. Notice I used tank.forward, not turtle.forward. This corresponds to the tank = turtle
variable above. The name 'tank' can be anything you want, just make sure you use that name all the way through your code. The .forward
and .backward
functions are the same type you used in
while True:
turtle.forward(100)
turtle.left(90)
turtle.forward(100)
turtle.left(180)
turtle.forward(200)
all of those should work in the moveright
/ moveleft
functions as well.
screen.onkeypress(moveright, "Right")
screen.onkeypress(moveleft, "Left")
screen.listen()
screen.mainloop()
Now is the magic. The 2 screen.onkeypress
lines tell the computer to listen for a pressed key. It takes 2 arguments, the first is a function (that is what the moveright
, moveleft
parts are) and the second argument is a string relating to the desired key on the keyboard. Eg. 'e' -> 'e' key, 'w' -> letter w, -> 'Up' -> up arrow -> 'Right' -> right arrow, so on, so forth. **The key names must be in quotes, like in the example above. if you do screen.onkeypress(moveright, Right)
it will throw an error.
The screen.listen()
tells the computer to start listing for the key events, and the screen.mainloop
starts Turtle's mainloop so it continues to look until turtle.done()
is called. The screen.mainloop
is very important because without it your program would end and no events would be received.
Here is the full code, feel free to copy / paste and use it however you wish. Again, code continues from tankCursor()
, line 98.
tankCursor() # creates and registers the "tank" cursor shape
tank = turtle
tank.shape("tank")
turtle.up() # get rid of the ink
screen = turtle.Screen()
def moveright():
tank.forward(40)
def moveleft():
tank.backward(40)
screen.onkeypress(moveright, "Right")
screen.onkeypress(moveleft, "Left")
screen.listen()
screen.mainloop()
来源:https://stackoverflow.com/questions/36019509/moving-turtle-according-to-the-arrow-keys