Bale Example: Dodgeball

Dodgeball is a very simple game using a bale wherein the player moves the turtle from the left to right sides of the screen using the keyboard.

This is similar to a popular example used to teach Scratch, and the basic concept should be familiar to most Scratch learners.

In the case of this example, there are multiple balls that are controlled by a ‘bale’, a group of turtles who all execute the same code, first the code in the bale’s init procedure, and then the code in the ‘main’ procedure repeatedly. Each member of the bale executes consecutively, and once all members of a bale have executed (a cycle), the bale’s graphical output (its ‘turtle tracks’) is updated.

The bale’s execution is started by Myrtle, using the startbale command.

Myrtle checks to see if the user has pressed any of the movement keys and moves if required. She also checks to see if she’s been hit by a ball, or if she’s reached the right side of the screen, and if either condition has been met, the game ends.

The balls meanwhile move up and down at different speeds, gradually sliding towards the left side of the screen (to prevent Myrtle from procrastinating!)

NEWTURTLE "myrtle

TO start
  ;this is a very simple yet addicting and frustrating game
  ;add in your own sound effects!

  reset
  setmodel [bk 7.5 stamp "myrtle]
  ;myrtle's position is usually her tail, so we need to move her a bit
  ;so that her position is center-ish of her shell

  startbale "balls 11
  pu
  setxy -170 0
  rt 90
  forever [
    if keyp [
      make "key lowercase readchar
      if :key = "k [sr 10]
      if :key = "i [sl 10]
      if :key = "j [bk 10]
      if :key = "l [fd 10]
    ]
    ;pressing keys causes turtle to move

    if nearp 15 [pr "ouch! repeat 1000 [rt 1] finish]
    ;got hit by a ball

    if xpos > 180 [pr "win! finish]
    ;made it to the other side!
  ]
END

ON start flag queue []
  start
END


NEWTURTLE "snappy


NEWTURTLE "libby


NEWBALE "balls

TO init
  setmodel {"setfc baleindex "ico 10}
  st
  penup
  setxy -160 + baleindex * 30 100
  output {"dir 1 "speed 1 + (0.1 * random (5 * (5 + baleindex)))}

END

TO main
  if :dir = 0 [bk :speed] [fd :speed]

  slideleft 0.1
  ;the balls gradually move toward the left side
  ;of the screen to discourage procrastination!

  if ypos < -100 [make "dir 1]
  if ypos > 100 [make "dir 0]
END