s = new Turtle to make a
second turtle. Each turtle is called an instance, and
Turtle is a class that can be used to make
many instances of the same type. Send function calls to an
instance by using a dot after its name:
s.fd 50 moves the second turtlea
forward by 50.
s = new Turtle # Create a new Turtle and hold it under the name s. s.wear red # Tell s to color itself red. s.rt 90 # Tell s to turn right. s.fd 50 # Tell s to move forward.
2. Invent a new subclass of Turtle that always comes in red. Try this:
class Drifter extends Turtle # Define a new type of Turtle called Drifter. constructor: -> # constructor is a special function for making a new Drifter. super() # super() means: first make a normal Turtle. @wear red # @ means "tell this new object to" wear red. @speed Infinity # Then set this object's speed to Infinity. d = new Drifter # Make one of our new type of object. d.fd 25 # Notice that it is red, and it moves instantly.
The code above defines a class
the built-in base class
Turtle. It will act just like
a normal turtle, except that it will start with infinite speed, wearing red.
Drifter to add two new properties and
a method, like this:
class Drifter extends Turtle constructor: (@spin, @vel) -> # The constructor takes and saves two properties spin and vel. super() @wear red @speed Infinity drift: -> # Define the drift() method @movexy @vel # Change x and y by the vector v @rt @spin # Turn right by the angle spin d = new Drifter(60, [20, 50]) # Make a Drifter with spin = 60 and vel = [20, 50] see 'spin', d.spin # Print out the spin property of d. see 'vel', d.vel # Print out the vel property of d. d.drift() # Tell the drifter to run its drift() method.
(@spin, @vel)in the
constructor, the properties
velare added to each drifter as part of the
new Driftercall. For example,
d = new Drifter(60, [20, 30])creates a
d.spinset to 60 and with
d.velset to the vector [20, 30].
driftis a method of the
Drifterclass. When it runs
@rt @spin, it means "turn this object right by this object's
d.spinto access the
d.drift()to call its
@to use properties and methods of "this" object:
@spinto access a property or
@movexy @velto call the
4. Add a class variable to keep a list of all the drifters and a class method to animate them:
class Drifter extends Turtle constructor: (@spin, @vel) -> super() @wear red @speed Infinity Drifter.list.push(@) # Add this object to the list when it is created. drift: -> @movexy @vel @rt @spin @list:  # This list is a property of the Drifter class itself. @run: -> # This is a method of the Drifter class itself. tick 60, -> # Set up an animation to run 60 times per second: for d in Drifter.list # Loop over each drifter in the list. d.drift() # Call d.drift() on each drifter. new Drifter(1, [1, 1]) # Make a drifter with a slower velocity. new Drifter(2, [-1, 2]) # Make a second drifter. Drifter.run() # Call the class method to get the animation going.
@(the object being constructed) into the list
Drifter.listis a class variable defined by
@list: . Because it is declared with an
@, it is a property of the
Drifterclass itself, not each instance. That means there is just one
runis a class method attached to the
Drifterclass instead of each instance.
5. Now experiment! Here is a
that keeps the Drifters inside a box:
class Drifter extends Turtle constructor: (@spin, @vel) -> super() @wear red @speed Infinity Drifter.list.push(@) bounce: -> # Define the bounce() method for each instance. pos = @getxy() # Set pos to the current [x, y] of the drifter. for i in [0..1] # Check each (x and y) component if outside 0..100: if pos[i] < (edge = 0) or pos[i] > (edge = 100) # set edge where crossed. pos[i] = 2 * edge - pos[i] # Reflect over the crossed edge. @moveto pos # Move inside the crossed edge. @vel[i] = -@vel[i] # Reflect the velocity. @spin = -@spin # Reverse the spin. drift: -> @movexy @vel @bounce() # Bounce after each move. @rt @spin @list:  @run: -> tick 60, -> for d in Drifter.list d.drift() for [1..5] # Make five Drifters with random velocity and spin. new Drifter(random(), [random(), random()]) Drifter.run() pen blue; (fd 100; rt 90) for [1..4]; ht() # With the main turtle, draw a square.
Can you add gravity? Can you add interaction with the mouse?