bertrand bertrand - 1 month ago 16
Python Question

Logic error in python turtle

I am coding in python 3.2 turtle and I have this beautiful drawing of a tank. and I know how to move it left and write. However, when trying to make the tank move up and down. I am faced with the problem that it goes up but if I let go and press the up button again. It turns to the left. It might be hard to explain so I included code.

"""
Programmer: Bert
Tank Run 1
"""

#------------------------------------------------------------------------------
#Importing random modules geddit
from turtle import *
from turtle import Turtle
import turtle
import random

#Welcome Statement and story
input("WELCOME TO TANK RUN 1!! PRESS ENTER TO CONTINUE")
Name = input("Name your Tank: ")
quitFunction = input(
"""The """ + Name + """ is in a battle and heading toward the
enemy base camp so that the """ + Name + """ can blow it up
Get to the base camp and do not let enemy
artillery, or soldiers kill you. Good luck"""
)

#setting up variables
unVar1 = 25
unVar2 = 100
unVar3 = 90
unVar4 = 150
unVar5 = -30
unVar6 = 75
unVar7 = 50
t = Turtle()

#defining shapes
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 polyCircle(t, x, y, radius):
t.up()
t.goto(x, y)
t.down()
t.hideturtle()
t.circle(radius)
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 drawLine(t, x1, x2, y1, y2):
t.up()
t.hideturtle()
t.goto(x1, y1)
t.do+wn()
t.goto(x2, y2)

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
tank = turtle
tank.shape("tank")

turtle.up() # get rid of the ink
screen = turtle.Screen()

def moveforward(): #I cannot get this function to work
tank.left(90)
tank.forward(40)

def movebackward(): #I cannot get this function to work
tank.left(90)
tank.backward(40)

def moveright():
tank.forward(40)

def moveleft():
tank.backward(40)

#Background color
t.screen.bgcolor("green")

#Movement of tank
screen.onkeypress(moveright, "Right")
screen.onkeypress(moveleft, "Left")
screen.onkeypress(moveforward, "Up")
screen.onkeypress(movebackward, "Down")

Answer

When drawing a custom cursor, unless you have a reason not to do so, keep your cursor design centered about the origin, (0, 0). If you draw to one side of the origin, then when your turtle turns right or left, it won't do so symmetrically. That is, as it turns in one direction, it will appear to do so quickly but in the opposite direction, it will appear to "take the long way around".

I've worked the polygons underlying the tank cursor so that it's center is the center of the turret and removed the setheading() calls from the drawing routines.

This example uses what I think is consistent motion: regardless of tank orientation, 'up' is forward, 'down' is backward, 'left' is 90 degrees to the left and 'right' is 90 degrees to the right. I've also stripped down the example just to demonstrate the motion:

import turtle

# Defining shapes
def polySquare(t, x, y, length):
    t.goto(x, y)
    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.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.
    """
    temporary = turtle.Turtle()
    temporary.hideturtle()
    temporary.penup()

    screen = turtle.getscreen()
    delay = screen.delay()
    screen.delay(0)

    tank = turtle.Shape("compound")
    tire1 = polyRectangle(temporary, -65, -75, 30, 75)  # Tire #1
    tank.addcomponent(tire1, "gray", "black")
    tire2 = polyRectangle(temporary, 35, -75, 30, 75)  # Tire #2
    tank.addcomponent(tire2, "gray", "black")
    tire3 = polyRectangle(temporary, 35, 0, 30, 75)  # Tire #3
    tank.addcomponent(tire3, "gray", "black")
    tire4 = polyRectangle(temporary, -65, 0, 30, 75)  # Tire #4
    tank.addcomponent(tire4, "gray", "black")
    bodyTank = polyRectangle(temporary, -55, -65, 110, 130)
    tank.addcomponent(bodyTank, "black", "gray")
    gunTank = polyRectangle(temporary, -10, 25, 20, 100)   # Gun
    tank.addcomponent(gunTank, "black", "gray")
    exhaustTank = polyRectangle(temporary, -25, -75, 10, 20)
    tank.addcomponent(exhaustTank, "black", "gray")
    turretTank = polySquare(temporary, -25, -25, 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

# Movement of tank
screen = turtle.Screen()
screen.onkeypress(lambda : turtle.right(90), "Right")
screen.onkeypress(lambda : turtle.left(90), "Left")
screen.onkeypress(lambda : turtle.forward(40), "Up")
screen.onkeypress(lambda : turtle.backward(40), "Down")

turtle.listen()

turtle.mainloop()