hd3.gif - 9Kb



The first couple of pages on CompoScript should have given you a chance to become familiar with the basic way in which it works and how you can use it to create and manipulate images. This page is designed to show how you can employ procedures to improve your scripts. It also shows how you can use a script to create animations. Along the way it introduces a few new commands and features of the language,

sky1.gif - 4011 bytes

The scripts and other files required for this page are inside the animation directory of the zip file which you can download. To start, load the file “sky” into Compo. This should produce a canvas with a pretty starfield backdrop. (For the Astronomers amongst us, I can confirm that this is a genuine starfield map created from the Yale star catalogue.)

sky2.gif - 4Kb

Next drop the script file “justload” onto the canvas. This will cause Compo to pop up a new window asking for you to load a directory. Drag the “planets” directory and drop it onto this loading window. You should find that this adds a sun and some planets to the canvas.

The main part of the script for this is as follows

#CompoScript

select all
select - "screen"
delete

repeat
 dragload directory "Drag and drop planets directory here" to plandir$
until plandir$ <> ""

repeat
 scandirectory plandir$ to found$
 if found$ <> "" then
 proc load_image
 endif
until found$ = ""

select none
end


The first part of this script selects all the objects that may be on the canvas. It then removes one object, “screen”, from its selections, and deletes all the remaining selected objects. The result is that any/all objects except “screen” will be deleted. These lines are an example of how the commands “select + object” and “select - object” can be used to add or remove objects from the currently selected list.

Next there is a repeat/until loop which contains the “dragload directory” command. This puts up a window with a message. The window acts as a target onto which you can drag and drop a directory. The loop continues until you drop a directory onto it. (Note for simplicity this code does no checking so it assumes that you have done what is expected. In practice some extra lines to test for errors are usually wise!) The name of the directory is then stored in the variable “plandir$”.

The second repeat/until loop now uses “scandirectory” to search the directory and finds each file it contains, one after another. Each time it finds a file it puts its name into the variable “found$”. Note that in both repeat/until loops the absence of a file or directory would cause the process to return an empty name “”, so you can test for this to see when the process is done.

The second loop then calls a procedure “load_image” each time it finds a new file inside the directory it has been given. Once all the files have been discovered the script clears any selections and ends.

If you examine the script file you will find that the procedure “load_image” is defined below the main part of the script. In this case the procedure is as follows.

defproc load_image
loadimage found$
select last
let xcen = 120 - .width/2
let ycen = 120 - .height/2
moveto <xcen> <ycen>
endproc


If you are familiar with computer languages like BASIC or ‘C’ it should be pretty clear what this does. The procedure is defined by a series of instructions placed between a starting “defproc <name of procedure>” and a finishing “endproc”. In this example, the first line of the procedure uses the script command “loadmage” to load the file named onto the canvas. (This will obviously only work if the file is an image of a type Compo can recognise.) The “select last” ensures that this newly loaded object is now selected for any manipulation.

The next three lines work out where to place the object so that it is centred at a position 120 OS units above and to the right of the bottom-left corner of the canvas, and then move the object there. (If you are puzzled by this and wonder why the planets don’t all appear in the same place. Note that each drawfile includes a transparent circle for the orbit and the planet is at its rim. You can’t see this circle, but it is there and this is what is centered.) By default, newly loaded objects will be loaded at the bottom left of the canvas.

The result of the “justload” script is therefore to load a series of objects (in this case drawfiles) and place them on the canvas. Any previously existing objects – with the exception of the background called “screen” – are removed.

animp3.gif - 26Kb

Having obtained a canvas with a starry background and some planets, drag and drop the script file “rotate” on the canvas and watch what happens. You should see the planets begin revolving about their sun. (Don’t worry, Compo will stop doing this after a few revolutions.) The script for this is as follows

#CompoScript

nib nobox

for loop = 0 to 720 step 10
proc turn
next

nib down

end

defproc turn

select "red"
rotateto <loop>
select "blue"
rotateto <loop>*2
select "purp"
rotateto <loop>/2
select none

endproc


In this case we can see that the procedure “turn” is used to rotate each of the drawfile objects that display a planet. The rotation rates are set by the values given to the “rotateto” commands. Unlike the for/next loops in earlier examples, this one uses an explicit step value of 10. A new feature in this example is the “nib” command. This instruction controls some aspects of the way in which the screen display is updated. It is therefore particularly useful when working with animations which, by their nature, can involve a lot of redrawing of the canvas.

The line “nib nobox” tells Compo to avoid continually redrawing the selection box (shown on the canvas as a red broken box around a selected object). This reduces the amounts of flickering. A related command is “nib up” which can also reduce flicker. Here the script ends with an explicit “nib down” which re-engages full redrawing. However in fact Compo does this by default anyway once a script ends so it is put in purely for ‘good practice’.

The above animation isn’t actually done very well. The repeated calls to rotate the object tend to lead to a series of calculations which can produce truncation or rounding errors. As a result the orbits aren’t very accurate and there is a tendency for the objects to wander off course a little. For this reason CompoScript has some special commands to aid smooth and accurate series of movements. They haven’t been used here for the sake of providing a clear an simple example. Instead, we can improve things a little by modifying the “turn” procedure as shown below

defproc turn

select "red"
proc center_up
rotateto <loop>
select "blue"
proc center_up
rotateto <loop>*2
select "purp"
proc center_up
rotateto <loop>/2
select none

endproc

defproc center_up

let xcen = 120 - .width/2
let ycen = 120 - .height/2
moveto xcen ycen

endproc


Here the new procedure “center_up” has been used to reposition each object again before it is rotated. If you try the script file “rotate2” you should see that this give slightly better results.

A later page will deal with file saving and loading and how to issue OS commands. These allow you to save animations in the form of GIFs suitable for web pages.



prevpage.gif - 1296 bytes homecc2.gif - 8Kb nextpage.gif - 1271 bytes


Content and pages maintained by: Jim Lesurf
using HTMLEdit, Compo, and TechWriter.