Sidharth D
Sidharth D

Reputation: 49

How do I move a turtle-graphics drawn object using only built in functions?

I want to make a turtle-drawn object move, but I can't use any downloaded modules (for reasons I don't want to get into). How would I do this?

Upvotes: 0

Views: 8574

Answers (2)

person0
person0

Reputation: 1378

In case it benefits anyone else. In the event you are willing to create a grid and draw at the per pixel level, I wrote a function that will sort through a list of lists (or tuple of tuples) which represent a graphical image. It draws a single pixel at a time, at whichever coordinates you input, and it centers the image to the provided coordinates.

This is not an optimal solution for real-world use, but is a fully functioning proof of concept nonetheless

# Snake head made from drawing pixel by pixel, with optional directionality
import turtle
import time

screen = turtle.Screen()
screen.bgcolor("#000000")
screen.tracer(0)

#              0 = black  1 = green  2 = Yellow  3 = red
head_colors = ["#000000", "#00AA66", "#FFFF00", "#FF0033"]

head_pixels = [
    [0,0,0,0,0,0,0,1,0,3,3,3,0,1,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0],
    [0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
    [0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],
    [0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],
    [0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
    [0,0,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,0,0],
    [0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,0,0,1,1,1,0],
    [0,1,1,0,0,2,2,0,0,1,1,1,0,0,2,2,0,0,1,1,0],
    [0,1,1,0,0,2,2,0,0,1,1,1,0,0,2,2,0,0,1,1,0],
    [1,1,1,1,0,0,0,0,1,1,1,1,1,0,0,0,0,1,1,1,1],
    [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
    [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
    [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
    [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
    [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
    [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
    [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
    [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
    [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
]

def turtle_graphic(colors, pixel_data, turt, go=(0,0), d="up"):
    turt.hideturtle()
    y = len(pixel_data) / 2
    x = len(pixel_data[0]) / 2
    turt.clear()

    if d == "left":
        turt.left(90)
    elif d == "right":
        turt.right(90)
    elif d == "down":
        turt.left(180)

    for row in range(len(pixel_data)):
        if d == "down":
            turt.goto(go[0]+x-1,go[1]-y+row)
        elif d == "left":
            turt.goto(go[0]-x+row,go[1]-y)
        elif d == "right":
            turt.goto(go[0]+x-row-1,go[1]+y)
        else:
            turt.goto(go[0]-x,go[1]+y-row)
        for pixel in pixel_data[row]:
            turt.pendown()
            turt.color(colors[pixel])
            turt.forward(1)
            turt.penup()
    
    turt.goto(go[0],go[1])
    if d == "left":
        turt.right(90)
    elif d == "right":
        turt.left(90)
    elif d == "down":
        turt.left(180)

snake_head = turtle.Turtle()
snake_head.speed(0)

direction = ["up", "right", "down", "left"]
index = 0

while True:
    screen.update()

    turtle_graphic(head_colors, head_pixels, snake_head, (0,0), direction[index])
    if index < 3:
        index +=1
    else:
        index = 0

    time.sleep(0.5)

Upvotes: 0

cdlane
cdlane

Reputation: 41872

I agree with @martineau's comment in general:

If you do the graphical drawing correctly using only commands which are relative to the current position, you can put all of them in a function and just before calling it, position the turtle to the location you want them all to be relative to.

But if your drawing is sufficiently simple, there's an alternative approach. You can make a turtle cursor that is your drawing, switch the turtle to that cursor and make your drawing do any move that the turtle cursor itself can do.

I'm going to illustrate using this house drawing from this An Hour of Code == An Hour of Fun page:

enter image description here

The following code invisibly draws the house and stashes it as a turtle cursor. It then sets the turtle shape to the house drawing and takes the house for a spin. Literally. After rotating the house in a circle, it shears it while moving it to the upper right of the drawing:

from turtle import Turtle, Screen, Shape

screen = Screen()
screen.bgcolor('SkyBlue')

shape = Shape('compound')

turtle = Turtle(visible=False)
turtle.speed('fastest')
turtle.penup()

turtle.goto(-100, 0)

turtle.begin_poly()
turtle.goto(-100, 50)
turtle.goto(100, 50)
turtle.goto(100, 0)
turtle.goto(-100, 0)
turtle.end_poly()
shape.addcomponent(turtle.get_poly(), 'red')

turtle.goto(-100, 50)

turtle.begin_poly()
turtle.goto(0, 100)
turtle.goto(100, 50)
turtle.goto(-100, 50)
turtle.end_poly()
shape.addcomponent(turtle.get_poly(), 'brown')

turtle.goto(-40, 0)

turtle.begin_poly()
turtle.goto(-40, 30)
turtle.goto(-20, 30)
turtle.goto(-20, 0)
turtle.goto(-40, 0)
turtle.end_poly()
shape.addcomponent(turtle.get_poly(), 'orange')

turtle.goto(20, 20)

turtle.begin_poly()
turtle.goto(20, 40)
turtle.goto(50, 40)
turtle.goto(50, 20)
turtle.goto(20, 20)
turtle.end_poly()
shape.addcomponent(turtle.get_poly(), 'white')

screen.register_shape('house', shape)

turtle.reset()
turtle.penup()

# Now we can move our house in any manner that we move a turtle:

turtle.shape('house')

for theta in range(0, 360, 10):
    turtle.setheading(theta)

turtle.setheading(90)
turtle.shearfactor(0.5)
turtle.goto(300, 300)
turtle.shearfactor(0)

screen.mainloop()

Again, this approach only works for simple drawings composed of filled polygons.

Upvotes: 5

Related Questions