#!/usr/bin/wish

# bounce_balls.tcl
# animated bouncing balls
#
# Copyright 2005: Andre Adrian, adrianandre aT compuserve dOt de
# Version: 21aug2005
#
# License: Use this software like you want. You are not allowed to
# delete the name of the original author (Andre Adrian).
# You are not allowed to monopolize this software or the algorithms
# as your intellectual property.
# There is no warrenty, no fitness for purpose and so on.


proc ovaldraw {tag color x y dx dy w dw} {
  # draw one bouncing ball
  # tag: graphical objects tag
  # color: Tk color name
  # x y: position of center in canvas
  # dx dy: movement vector
  # w: distance center to left border of ball
  # dw: w change parameter. Can be positive or negative

  set h [expr 100-$w] ;# ball y extension depends on x extension
  
  # erase old graphical object, draw new one
  .ca delete $tag
  .ca create oval [expr $x-$w] [expr $y-$h] \
    [expr $x+$w] [expr $y+$h] -tags $tag \
    -outline $color -fill $color
    
  # graphical object shape change
  set w [expr $w + $dw]
  if {$w < 33 || $w > 66} {
    set dw [expr 0-$dw]
  }
  
  # graphical object Bouncer movement
  set x [expr $x + $dx]
  if {$x < 33 || $x > [.ca cget -width]-33} {
    set dx [expr 0-$dx] ;# change direction
  }
  
  set y [expr $y + $dy]
  if {$y < 33 || $y > [.ca cget -height]-33} {
    set dy [expr 0-$dy] ;# change direction
  }

  # parameters for call again
  return [list ovaldraw $tag $color $x $y $dx $dy $w $dw]
}

proc dodrawlist {dl} {
  # draw all graphical objects (do it in one go to avoid flicker)
  # dl: commands with parameters list
  # returns nothing, but calls itself with after
  
  foreach command $dl {
    # execute the command. The return is the new command
    # with parameters. 
    lappend newdl [eval $command]
  }
  
  # call again with new parameters
  after 40 [list dodrawlist $newdl]
}  

# create a canvas to draw the graphical objects on
canvas .ca -width 400 -height 400
pack .ca

# setup drawlist
lappend dl [list ovaldraw Ball1 green  100 100   2    1    50 0.5]
lappend dl [list ovaldraw Ball2 orange 200 200  -1    2.5  50 0.7]
lappend dl [list ovaldraw Ball3 blue   300 300   1.7 -1.7  50 0.9]

# start animation
dodrawlist $dl
