Welcome to Beginner Programming 
Lesson #8

Course content Enter chat room Send email
to mailing list
Check calendar

In this lesson we are going to put everything we have learned together and create a cartoon.

We are going to learn some more about animation and about images.   We are going to make use of sound effects.
 
 

Step 1: taking stock

When this lesson is activated you should have received a bunch of .gif files as part of the email attachment.   These files are:
 
 
apple.gif
grapes.gif
chilli.gif
dwarf.gif
dwarf2.gif
dwarf3.gif
dwarf4.gif
dwarf5.gif
tree.gif

 

If you did not get these files please contact the course mailing list and we'll be sure to resend them.
 

Step 2: the preparation

The first thing we need to do is to copy these ".gif" files into your beginner folder.
 
NOTE:
If you are having trouble finding where your email program has stored those files go back and refresh your memory from lesson6.    Once you have located them on your hard disc copy them into the beginner folder.

 
 

Step 3: the code setup

We will be building upon lesson7 for this final lesson.   Using your text editor open the lesson7.tcl file in your beginner folder and resave it as lesson8.tcl.

Next go through the lesson8.tcl  file and change all the instances of lesson7 to read lesson8.
 
 

Step 4: let's start coding

One of the animation techniques that we have used so far is image movement (or blitting as it is called).    When our fruit fell we simply arranged to have the image move to a different location on the screen.

Another technique often used in animation effects is to have an image gradually get replaced by a series of progressive images.    This for example is how Disney will animate its cartoon characters.    We haven't got time in this short course to create a Disney cartoon but we can utilize a similar technique.

Before we go to the code we need to understand one other thing about images in Tcl/Tk.    Images can come in different formats as we have already discussed.    Within those formats themselves images can have different properties.

To illustrate what I am about to describe think of a picture in a frame hanging on a wall and a clear decal type sticker placed on your bedroom window pane.

In one case the picture is enclosed in a rectangular box.   You see none of the wall showing through in the area covered by the picture and frame.    In contrast the decal on the window pane allows you to see out into your back yard in the area up to the actual artwork itself.

In one case we are said to have an opaque background in the other it is called a transparent background.

For our cartoons to look realistic it is important that we have images that present a transparent background.

I have used some Linux software to convert the image of the dwarf into such an image.  Some of you may have access to similar image manipulation software.    If you are going to become a serious computer game or animation programmer these image manipulation software tools will be important.    For this course I have done all that work for you.

Let's introduce our dwarf to our animation scene.   In the main area of the code you need to use the image create sequence to convert and store the image of the dwarf for future manipulation within the Tcl/Tk program.   The code snips below contain some lines which you will already have in your program.

The idea here is for you to alter those lines which need to be altered and add the lines which are new.    The other idea is that you will run your program frequently as you make each of these small changes to begin to get a "feel" for how various parts of your program affect the others.
 
#
# initialize some images
#
image create photo apple -file apple.gif
image create photo grapes -file grapes.gif
image create photo chilli -file chilli.gif
image create photo dwarf -file dwarf.gif

Next we want to have our dwarf appear at the same time as the fruit appears on our screen.    In other words we want to add some lines to the showImage procedure.
 
BGCOLOR="#33CCFF">#
# remove the previous image and text
#
$f_a.c delete imagetag
$f_a.c delete texttag
$f_a.c delete dwarf

#
# display the new image and text
#
$f_a.c create image 10 10 -image $myimage -tag imagetag
$f_a.c create text 80 50 -text $myimage -tag texttag
$f_a.c create image 60 200 -image dwarf -tag dwarf

If you run the program at this stage you should see the dwarf appear on the animation screen as soon as you press any of the fruit buttons.
 

Step 5: let's make the dwarf disappear

Let's now arrange to have our little fellow disappear as soon as the cartoon sequence is complete.   In our dropImage procedure:
 
set nextdrop -8
for { } { $i < 5000 } { incr i 200 } {
	after $i "$f_a.c move imagetag 3 $nextdrop"
	set nextdrop [ expr $nextdrop + 4 ]
	}

after 5000 "s play"
after 6000 "$f_a.c delete dwarf"

Now when you run your program the dwarf will disappear at the 6 second mark of your little cartoon.

This is still pretty basic stuff, however.

Let's make our dwarf disappear in a wierd fashion.
 

Step 6: Star Trek "beam me up"

How about we make like he was transported by the Star Trek "beam me up".

For this we will take advantage of my Linux image manipulation software and the technique whereby we substitute a progressive series of images.    I've supplied the series of images that I created for you as dwarf2.gif through to dwarf5.gif.    Now all we have to do is arrange to display those in a sequence that makes it look like the dwarf was "beamed away".

First thing we need is to create a bunch more converted images in our main area of the program ... one for each of these new GIF images.
 
image create photo dwarf -file dwarf.gif
image create photo dwarf2 -file dwarf2.gif
image create photo dwarf3 -file dwarf3.gif
image create photo dwarf4 -file dwarf4.gif
image create photo dwarf5 -file dwarf5.gif

The next thing we need is a loop which schedules each of these images in sequence with a short delay between each.   In our dropImage procedure:
 
after 5000 "s play"

set j 2
for  { set  k  2000 }  { $k < 6000 }  { incr  k  1000 }  {
   after $k "$f_a.c delete dwarf;\ 
   $f_a.c create image 60 200 -image dwarf$j -tag dwarf"
   incr j
   }

after 6000 "$f_a.c delete dwarf"

Notice that we have made use of the semicolon ";" and the line continuation character "\" to run two statements at each of the time intervals in our loop.

The first statement arranges to delete the previous dwarf image.   The second statement arranges to create a new dwarf using the next image in our sequence of 5.

If you run your program now you will see the dwarf vanish in true Star Trek "beam me up" fashion.
 

Step 7: we need sound effects

This is still not very good because we need a sound effect at the point where the dwarf disappears.    Let's add another sound to our program.

I'll pick the Chimes.wav file that is on my system ... you can pick anything you please.

In the main area of the program you will need to add the new sound in exactly the same way you did the first one.
 
#

# initialize the sound
#
snack::sound s
s read c:/windows/media/Ding.wav

snack::sound s2
s2 read c:/windows/media/Chimes.wav
 

Where should we play it?   I would suggest around the time we make the dwarf vanish.
 
after 6000 "$f_a.c delete dwarf"
after 6200 "s2 play"

Now our little effect with the dwarf is complete.
 
 

Step 8: have our fruit fall from a tree

However, our falling fruit animation is not very good any more.

We need a tree from which our fruit will fall.

Let's add the image of the tree to our background.   Once again we have to create an internal representation of our tree from our tree.gif file.
 
image create photo chilli -file chilli.gif

image create photo tree -file tree.gif
image create photo dwarf -file dwarf.gif

We then need to arrange for our tree to become visible.
 
#
# set up our animation canvas
#
canvas $f_a.c -height 310 -width 400 -background lightBlue
$f_a.c create image 130 130 -image tree -tag tree
pack $f_a.c -side top

When you run this now you should see your dwarf appear and disappear underneath a tree.

Our animation is still messed up because our fruit must fall straight down and bop the dwarf on the head ... I would figure.

Let's adjust our code to do just that.
 
#========================================
# dropImage - entry point
#========================================
proc dropImage {} {
global f_a

set nextdrop 1
for { set i 0 } { $i < 1400 } { incr i 200 } {
	after $i "$f_a.c move imagetag 0 $nextdrop"
	set nextdrop [expr $nextdrop + 4] 
	}

after 1400 "s play"

set nextdrop -18
for { } { $i < 4200 } { incr i 200 } {
	after $i "$f_a.c move imagetag 6 $nextdrop"
	set nextdrop [expr $nextdrop + 4]
	}

after 4200 "s play"

set nextdrop -8
for { } { $i < 5400 } { incr i 200 } {
	after $i "$f_a.c move imagetag 3 $nextdrop"
	set nextdrop [expr $nextdrop + 4]
	}

after 5400 "s play"

Oops we don't quite have it right yet.   We need to move the starting point for the fruit so that it is placed in the tree directly over the dwarf's hat.
 
#========================================

# showImage - entry point
#========================================
proc showImage {myimage} {
global f_a

#
# remove the previous images
#
$f_a.c delete imagetag
$f_a.c delete dwarf

#
# display the new image and text
#
$f_a.c create image 60 200 -image dwarf -tag dwarf
$f_a.c create image 70 40 -image $myimage -tag imagetag

Our animation is getting pretty good now we just need to do a few cosmetic cleanups and we have it.
 

Step 9: a little code cleanup

The first thing we notice is that the drop button should be dimmed until we select a fruit from our fruit buttons.

This will involve 3 separate changes.

First we will have to dim the drop button initially.
 
button $f_b2.quit -text "quit" -command {set x_it 1}
button $f_b2.go -text "drop" -command { dropImage } -state disabled

Next we will have to "activate" the button once a fruit is selected.
 
#
# display the new image and text
#
$f_a.c  create  image  60 200  -image  dwarf  -tag dwarf
$f_a.c  create  image  70 40  -image  $myimage  -tag imagetag

#
# enable the drop button
#
$f_b2.go config -state active

}  ;# end showImage

Oops it doesn't work.  Why?   Remember the discussion surrounding variables and their scope.

The f_b2 variable which contains the drop button needs to be declared global.
 
global f_a
global f_b2

Finally let's dim the button once again after we make the fruit disappear.    In dropImage change:
 
after 6000 "$f_a.c delete dwarf"

after 6200 "s2 play"
after 6400 "$f_a.c delete imagetag"

$f_b2.go config -state disabled

If it still doesn't quite work remember that you need to declare the f_b2 as global in this dropImage procedure also.
 
 

Final source listing

#========================================
# FILE: lesson8.tcl
#
# AUTHOR:
#
# REVISIONS:
#
#========================================

package  require  snack

#========================================
# dropImage - entry point
#========================================
proc  dropImage { }   {
global  f_a
global  s
global f_b2

set  nextdrop  1
for { set i 0 } { $i < 1400 } { incr i 200 } {
	after $i "$f_a.c move imagetag 12 $nextdrop"
	set nextdrop [ expr $nextdrop + 4 ]
	}
after 1400 "s play"

set  nextdrop  -18
for { } { $i < 4200 } { incr i 200 } {
	after $i "$f_a.c move imagetag 6 $nextdrop"
	set  nextdrop  [ expr  $nextdrop  +  4 ]
	}
after 4200 "s play"

set  nextdrop  -8
for { } { $i < 5400 } { incr i 200 } {
	after $i "$f_a.c move imagetag 3 $nextdrop"
	set nextdrop [expr $nextdrop + 4]
	}
after 5400 "s play"

set j 2
for { set k 2000 } { $k < 6000 } { incr k 1000 } {
	after $k "$f_a.c delete dwarf;\ 
	$f_a.c create image 60 200 -image dwarf$j -tag dwarf"
	incr j
	}

after 6000 "$f_a.c delete dwarf"

after 6200 "s2 play"

after 6400 "$f_a.c delete imagetag"

$f_b2.go config -state disabled

puts  stdout  "dropImage:done"

}   ;#end dropImage

#========================================
# showImage - entry point
#========================================
proc  showImage  { myimage }   {
global  f_a
global f_b2

#
# remove the previous image and text
#
$f_a.c  delete  imagetag
$f_a.c  delete  texttag
$f_a.c  delete  dwarf

#
# display the new image and text
#
$f_a.c; create image 10 10 -image $myimage -tag imagetag
$f_a.c create image 60 200 -image dwarf -tag dwarf
$f_a.c create text 70 40 -text $myimage -tag texttag

#
# enable the drop button
#
$f_b2.go config -state active

}   ;# end showImage


#========================================
#  main - entry point
#========================================
destroy   .myArea

#
# setup top level window size, position and title
#
wm  geometry  . 350x400+10+10
wm  title   .   "lesson8"

#
# setup all the frames
#
set f [ frame .myArea -borderwidth 5 -background  blue ]
set f_a [ frame $f.animateFrame -background lightBlue ]
set f_b [ frame $f.buttons -background blue ]
set f_b2 [ frame $f.buttons2 ]

puts  stdout  "lesson8 starting"

#
# initialize some variables
#
set  x_it  0

#
# initialize some images
#
image  create  photo  apple  -file  apple.gif
image  create  photo  grapes  -file  grapes.gif
image  create  photo  chilli  -file  chilli.gif
image  create  photo  tree -file  tree.gif
image  create  photo  dwarf  -file  dwarf.gif
image  create  photo  dwarf2 -file  dwarf2.gif
image  create  photo  dwarf3 -file  dwarf3.gif
image  create  photo  dwarf4 -file  dwarf4.gif
image  create  photo  dwarf5 -file  dwarf5.gif

#
# set up our animation canvas
#
canvas  $f_a.c  -height  210  -width  300  -background  lightBlue
$f_a.c  create  image 130 130  -image tree  -tag tree
pack $f_a.c -side top

#
# set up our buttons
#
button $f_b.apple -image apple \
	-command  { showImage "apple" }

button $f_b.grapes -image grapes \
	-command  { showImage  "grapes" }

button $f_b.chilli -image chilli \
	-command  { showImage  "chilli" }

pack $f_b.apple $f_b.grapes $f_b.chilli -side left

button $f_b2.quit -text "quit" -command { set  x_it  1 }

button $f_b2.go -text "drop" -command { dropImage }  -state disabled
pack  $f_b2.go  $f_b2.quit  -side  left

#
# arrange the animation frame and button frames 
# in main frame
#
place  $f_a  -x  10  -y  10
place  $f_b  -x  30  -y  250
place  $f_b2  -x  70  -y  300

#
# make the whole thing visible
#
pack  $f  -side  top  -expand  true  -fill  both

#
# initialize the sound
#
snack::sound  s
s  read  c:/windows/media/Ding.wav

snack::sound s2
s2 read c:/windows/media/Chimes.wav

#
# pause here until we hit quit button
#
vwait  x_it

#
# disable the buttons
#
$f_b.apple   config   -state   disabled
$f_b.grapes   config   -state   disabled
$f_b.chilli   config   -state   disabled
$f_b2.quit   config   -state   disabled

#
# clear the canvas
#
$f_a.c   delete   imagetag
$f_a.c   delete   texttag

puts  stdout  "lesson8 done"

When you run this program and hit the drop button you should see an image similar to that below:


 

Summary

You have taken all that you have learned in this course and produced a simple animated cartoon.

End of Lesson 8.
 


Congratulations !!!   You have completed the Beginner Programming Course.   (That's right there are no exams here)

We hope that you have learned something about programming.   But most importantly we hope that we have shown you that programming a computer can be a lot of fun and a great creative outlet.

We will be introducing a whole series of courses over the coming months.   Courses in the planning stages include:

Please send us an email if you are interested in hearing about these new courses when they become available.