2.11 TURTLE OBJECTS

 

 

INTRODUCTION

 

In nature, a turtle is an individual with its own specific identity. In an exhibition at the zoo you could give each turtle its own name, for example Pepe or Maya. However, turtles also have things in common: they are reptiles belonging to the animal class of tortoises. These notions of classes and individuals have been so successful that they were introduced into computer science as a fundamental concept, called object-oriented programming (OOP). It will be easy for you to learn the basic principles of OOP using turtle graphics.

PROGRAMMING CONCEPTS: Class, object, object-oriented programming, constructor, clones

 

 

CREATING A TURTLE OBJECT

 

The turtle was previously used as an anonymous object which we did not use a name for. If you want to use multiple turtles at the same time, you must give every turtle an identity by naming it. You can then use the name as a variable name.

With the statement maya = Turtle() you create a turtle named maya.
With the statement pepe = Turtle()  you create a turtle named pepe.

You can control the named turtles with the commands you already know, but you always have to say which turtle you mean. Put the turtle name first, followed by a point, and finally the command, for example maya.forward(100).

In the first example maya draws a ladder. You do not need the line makeTurtle() anymore since you are creating the turtle yourself.

 
from gturtle import *

maya = Turtle()
maya.setColor("red")
maya.setPenColor("green")
maya.setPos(0, -200)

repeat 7:
    repeat 4:
        maya.forward(50)
        maya.right(90)
    maya.forward(50)
Highlight program code (Ctrl+C copy, Ctrl+V paste)

 

 

MEMO

 

Similar objects are grouped into classes. An object of a class is made (we also say "instantiated") by using the class name with a set of parentheses. We call this the constructor of the class.

In the future we will call functions that belong to a particular class methods.

 

 

CREATING MORE TURTLE OBJECTS

 

Now you know all too well that you can use multiple turtles in the same program in the way previously described. If you want to create maya and pepe, then write
maya = Turtle() und pepe = Turtle()

These two turtles each end up in their own turtle window. You can put them into the same turtle enclosure by generating the enclosure as an object of the class TurtleFrame:
tf = TurtleFrame()
This object variable should be passed to the Turtle constructor while creating the turtles. At the same time that maya builds the same ladder as before, pepe builds a horizontal black ladder.

 
from gturtle import *

tf = TurtleFrame()

maya = Turtle(tf)
maya.setColor("red")
maya.setPenColor("red")
maya.setPos(0, -200)

pepe = Turtle(tf)
pepe.setColor("black")
pepe.setPenColor("black")
pepe.setPos(200, 0)
pepe.left(90)

repeat 7:
    repeat 4:
        maya.forward(50)
        maya.right(90)
        pepe.forward(50)
        pepe.left(90)
    maya.forward(50)    
    pepe.forward(50)
Highlight program code (Ctrl+C copy, Ctrl+V paste)

 

 

MEMO

 

If you want to put multiple turtles into the same window you need to create a TurtleFrame and specify it as a constructor parameter for the turtle. The turtles do not run into each other but rather move (so to speak) over one another, whereby the turtle moving last always ends up on top of all the others.

 

 

TURTLE PARAMETERS

 

Turtle objects can also be used as function parameters. Because the same code is used to draw a single ladder for both turtles, it is easiest to define a function step(). As a (formal) parameter you can use any name you would like, for example, just t. You then call the function twice, once passing it maya, and the other time passing it pepe.

 
from gturtle import *

def step(t):
    repeat 4:
        t.forward(50)
        t.right(90)
    t.forward(50)
    
tf = TurtleFrame()

maya = Turtle(tf, "sprites/beetle.gif")
maya.setPenColor("green")
maya.setPos(0, -150)
pepe = Turtle(tf, "sprites/cuteturtle.gif")
pepe.setPos(200, 0)
pepe.left(90)

repeat 7:
    step(maya)
    step(pepe)
Highlight program code (Ctrl+C copy, Ctrl+V paste)

 

 

MEMO

 

You can use your own image for each turtle if you specify the path to the image file while creating them. In the previous example, you used two image files beetle.gif and cuteturtle.gif which are located in the distribution of TigerJython.

 

 

MICE PROBLEM WITH A CLONED TURTLE

 

During the famous mice (or beetle) problem [more... The pursuit curves are after the mathematician Brocard logarithmic spirals with the polygon center as a pole] n beetles start at the corners of a regular n-gon and chase each other at a constant speed. The position of the beetles is fixed at equal steps of time and each one is rotated in the direction of the beetle in the next polygon corner. Afterwards, all of the beetles move forward at a steady increment.

You can nicely solve this problem by first drawing the polygon with the nameless (global) turtle and then by putting a cloned turtle at each corner. Here you choose a square and create the turtle clones t1, t2, t3, and t4 with clone(). A clone is a new turtle object with identical properties.

After that, you adjust their viewing direction in an endless loop with setHeading() and move them forward by 5. The drawing becomes especially nice if you draw out the connecting lines between each chasing turtle.

The easiest way to do this is to define the function drawLine(a, b), with which the turtle a will draw a trail to turtle b and then go back again by using moveTo().

 
from gturtle import *

s = 360

makeTurtle()
setPos(-s/2, -s/2)

def drawLine(a, b):
    ax = a.getX()
    ay = a.getY()
    ah = a.heading()
    a.moveTo(b.getX(), b.getY())
    a.setPos(ax, ay)
    a.heading(ah)
    
# generate Turtle clone
t1 = clone() 
t1.speed(-1)
forward(s)
right(90)
t2 = clone()
t2.speed(-1)
forward(s)
right(90)
t3 = clone()
t3.speed(-1)
forward(s)
right(90)
t4 = clone()
t4.speed(-1)
forward(s)
right(90)
hideTurtle()

while True:
    t1.setHeading(t1.towards(t2))
    t2.setHeading(t2.towards(t3))
    t3.setHeading(t3.towards(t4))
    t4.setHeading(t4.towards(t1))
   
    drawLine(t1, t2)
    drawLine(t2, t3)
    drawLine(t3, t4)
    drawLine(t4, t1)

    t1.forward(5)
    t2.forward(5)
    t3.forward(5)
    t4.forward(5)
Highlight program code (Ctrl+C copy, Ctrl+V paste)

 

 

MEMO

 

By using clone() you are creating a new turtle from the global turtle, so it will have the same position, the same viewing direction, and the same color (if you are using a custom turtle icon, it will have the same image) [more... The use of clone corresponding to a modern programming paradigm: the prototype-based programming] .

The function drawLine() can be simplified if you save the position and orientation of the turtle with pushState(). The state can then be retrieved again with popState():

def drawLine(a, b):
    a.pushState()
    a.moveTo(b.getX(), b.getY())
    a.popState()

The emerging chasing curves can be calculated mathematically (see here).

 

 

EXERCISES

 

1.


Three turtles should alternately, point by point, draw a five-pointed star. The turtles should be colored cyan (the standard color), red, and green. The turtle's color can be specified as an additional parameter of the constructor.




2.

A green mother turtle constantly draws a circle with a green pen color. At first, the red child turtle is far away from the mother turtle and then moves with the red pen towards the mother.

(The child turtle named child can determine the direction of the mother using direction = child.towards(mother)
 

3.
 

Laura draws (not filled) squares. After each square is drawn, a second turtle jumps in and colors it green.

Use different turtle images for the two turtles. The images available in tigerjython2.jar are beetle.gif, beetle1.gif, beetle2.gif, and spider.png. You can also use your own images. If you do, you have to save it in the subdirectory sprites, which is located in the same directory as your program.

4.

Create chasing graphics for 6 turtles that start their chase at the corners of a regular 6-gon, similar to the example "beetle problems".


 

 

 

EXTRA MATERIAL


 

CREATING TURTLES WITH A MOUSE CLICK

 

With every mouse click your program will create a new turtle that draws a star, at the location of the mouse cursor, independently of other existing turtles. In this example you can experience the full scope and the beauty of object-oriented programming as well as event control.

To process the mouse click, you define the function drawStar(). In order for the function to be called by your system when you press the left mouse button, you must use the parameter mouseHit in the constructor of the turtle frame and give it the name of this function.
 
from gturtle import *

def drawStar(x, y):
    t = Turtle(tf)
    t.setPos(x, y)
    t.fillToPoint(x, y)
    for i in range(6):
        t.forward(40)
        t.right(140)
        t.forward(40)
        t.left(80)

tf = TurtleFrame(mouseHit = drawStar)
Highlight program code (Ctrl+C copy, Ctrl+V paste)

 

 

MEMO

 

Objects that have the same capabilities and similar properties are defined as classes in OOP. You can create individual objects with the constructor (instances).

In order to process a mouse click, you have to write a function with a name of your choice (including two parameters, x and y) and then pass this name to the parameter mouseHit in the constructor of the TurtleFrame.

x and y provide the coordinates of the mouse click.