Exploring Objects and Classes

Do this on pencilcode.net

1. Use 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 Drifter that extends the built-in base class Turtle. It will act just like a normal turtle, except that it will start with infinite speed, wearing red.

3. Modify 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.
    @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.

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) ->
    @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.

5. Now experiment! Here is a bounce() method that keeps the Drifters inside a box:

class Drifter extends Turtle
  constructor: (@spin, @vel) ->
    @wear red
    @speed Infinity
  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
for [1..5]                                 # Make five Drifters with random velocity and spin.
  new Drifter(random(), [random(), random()])
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?