Runtime Revolution
 
Articles Other News

Cannonballs! Part 2.1


by Robert Cailliau


Before we go on with our cannon, we have to learn how to place and move objects. We will take a few pages to do that, and it will mean making a separate mainstack to learn this.

Placing and moving Objects in Revolution

Each object has a location, abbreviated to loc. Start Revolution and make a new mainstack. Use the inspector to call it Motion. Save it somewhere.

Use the oval tool to draw a circle:

I highlighted the oval tool with blue, as usual. You can hold down the shift key to restrain the oval to a circle (likewise to restrain a rectangle to a square etc.). Using the inspector, call the circle Ball and increase the linesize to 4 so it looks a bit more solid.

Draw a button, call it Reset, draw another one and call it Move:

We are going to move the circle around, but we want to be able to bring it back to its original position, and that is what the Reset button is for. We write the script of the Reset button first. You can right-click the button and select Edit Script:

Or you can open the script window from the inspector or from the Application Browser. Use what suits you best.

Now write this handler in the script window of the Reset button:

on MouseUp

set the loc of graphic "Ball" to 40,60

end MouseUp

Press the "Apply" button and save your work.

The circle object we called Ball is a graphic. Revolution classifies objects into these categories: buttons, fields, scrollbars, graphics, images, players (for sound and movies), groups, cards and stacks. We will talk about them as the tutorials need them.

Run the program by choosing the browse tool (). Nothing happens of course, but if you press the Reset button, the circle will move slightly. Its centre is now at location 40,60. That is 40 pixels to the left of the stack window and 60 pixels below the title bar.

These two numbers are called coordinates, and they are distances measured in pixels. The horizontal distance is usually called the x-coordinate and the vertical one the y-coordinate.

A pair of numbers like 40,60 is also called a point.

Here we encounter a problem that is going to cause a lot of irritation later on: on computer screens, the coordinates are measured left-to-right for the first coordinate (40) or the x-coordinate, but they are measured top-to-bottom for the second coordinate (60) or the y-coordinate. In maths and physics and everywhere else, the y-coordinate is measured bottom-to-top.

 
Normal axes, y is measured up. Computer screens: y is measured down.

Summary and Notes

A location is two numbers: a horizontal or x distance and a vertical or y distance.

Coordinates are in pixels.

Each object has a location, which is an x and a y coordinate.

A location or a point is written as two consecutive numbers separated by a comma, with no quotes or parentheses necessary, e.g. 40,60

A point can be any two expressions that give numbers, separated by a comma. Hence we can write code like:

put 20 into SomeLength

set the loc of button "Cancel" to SomeLength*3,the bottom of this card - SomeLength

The second line sets the x-coordinate of the button to SomeLength*3 and the y-coordinate to the bottom of this card - SomeLength. This piece of code is not very readable, because the comma is easily overlooked. Parentheses and spaces can help, for example:

put 20 into SomeLength

set the loc of button "Cancel" to (SomeLength*3) , (the bottom of this card -SomeLength)

On with moving the ball

Let's move the ball horizontally, by 4 pixels at a time, and do this 20 times. The ball will then have moved 20*4 = 80 pixels.

First go to development mode by selecting the Select tool (). Then right-click on the Move button to edit its script and type:

on MouseUp

put the loc of graphic "Ball" into lBallLocation

put item 1 of lBallLocation into lX

put item 2 of lBallLocation into lY

repeat 20 times

set the loc of graphic "Ball" to lX,lY

add 4 to lX

end repeat

end MouseUp

Press Apply, save your work. Then let's look at that code line by line:

First, we get the location of the ball and save it in a local variable called lBallLocation.

I always use a capital letter to start any name I invent, and I always use a prefix letter to indicate the type of thing it is. I will come back to this later, for now it is sufficient to know that lBallLocation is a local variable and I prefix those with a lower-case letter l.

The next line uses the phrase "item 1 of". In Transcript, any list of things separated by commas is a list of items. Now, the location is two numbers separated by a comma, so it is a list of two items: item 1 and item 2. I can get the x-coordinate of the loc by specifying "item 1 of". Likewise I can get the y-coordinate by specifying "item 2 of". Those two lines will therefore take the location apart into its two components. We need that because we are only going to move the ball along horizontally.

Then there is a line repeat 20 times. That indicates that we will do someting for 20 times. The actions that will be repeated are between the repeat 20 times statement and the end repeat statement that you see three lines further down. As we saw in the first tutorial, the end repeat only shows where the repeated stuff ends, it does not mean "stop repeating", it means "here is the end of the statements that are repeated".

We repeat two things:

  1. To set the loc of the ball to a point lX,lY
  2. To add 4 to lX, which then will be used again next time.

The ball starts out at 40,60 and the consecutive locations of the ball will thus be:

40,60 44,60 48,60 52,60 56,60 60,60 64,60 ... 120,60

Select the browse tool () to run the program. Then press the Move button.

The ball moves suddenly!

That is because the movement happens so quickly that we can't see it. We need to slow down the repeat.

First press the Reset button to bring the ball back to its original location.

Open the script window (select the select tool first etc., but you should know this by now so I will no longer repeat it).

Add a wait-statement:

on MouseUp

put the loc of graphic "Ball" into lBallLocation

put item 1 of lBallLocation into lX

put item 2 of lBallLocation into lY

repeat 20 times

set the loc of graphic "Ball" to lX,lY

add 4 to lX

wait for 10 ticks

end repeat

end MouseUp

The statement wait for 10 ticks tells the program to wait for 10 sixtieths of a second. A "tick" is 1/60 of a second. Press Apply, select the browse tool and press the Move button. That's much better!  But maybe not very smooth. You can experiment with the number of ticks to wait, the number of pixels to move at each round of the repeat, and the number of times you repeat the motion.

Don't forget to press Reset before pressing Move.

Try also to move vertically as well as horizontally:

on MouseUp

put the loc of graphic "Ball" into lBallLocation

put item 1 of lBallLocation into lX

put item 2 of lBallLocation into lY

repeat 100 times

set the loc of graphic "Ball" to lX,lY

add 1 to lX; add 2 to lY

wait for 2 ticks

end repeat

end MouseUp

In this last example I have placed two instructions on the same line:

add 1 to lX; add 2 to lY

You can do that as long as there is a semicolon (";") between the statements. Put more than one statement on a single line only when there is a good reason for it. Here the good reason is this: the increase of the X and Y coordinates really do belong together and you should not write other stuff in between those two statements.

Summary and Notes

Motion can be simulated by changing the location of an object.

Changing the location involves changing the x or y coordinate or both.

The simulation happens by a list of statements that is repeated.

Question: why do we write put 10 into lX but set the loc of graphic "Ball" to lX,lY ?
Why don't we write put lX,lY into the loc of graphic "Ball" ?
There is in fact no good reason. Revolution just decided that to put values into containers you use put and to set properties of objects you use set.

The add statement is a shorthand for a put statement:

add 1 to 1X does exactly the same as put lX+1 into lX.

(although computer geeks will know that the add may be a little faster than the put in this case).

Sending messages

It's not very convenient to have to press the Reset button before being able to press the Move button. You can make the Move button tell the Reset button to do its job before the Move button starts on its own job:

on MouseUp

send "MouseUp" to button "Reset"

put the loc of graphic "Ball" into lBallLocation

...

end MouseUp

The first line sends a message to the Reset button to tell it to do whatever it does when the mouse goes up there. This modification is actually very nice, because we still have the Reset button, we did not have to modify it, nor did we have to copy a piece of program.

General Programming Note

It is important to know that the send command waits until the Reset button has finished doing its job before it goes on. Otherwise we might be attempting to move the ball before it got back to its initial position.

The Transcript manual specifies this explicitly. It is very important that the manual of a programming language specifies exactly what happens in all circumstances. Otherwise you do not know how to write correct code, and you get very nasty surprises. A language that is not completely specified is horrible to work with. C and BASIC are two examples of languages that were not completely specified. The result is that many "dialects" of BASIC exist, and they do different things. In the case of C the situation was so bad that several attempts were made to standardise the language which finally led to an acceptable specification.

 
©2005 Runtime Revolution Ltd, 15-19 York Place, Edinburgh, Scotland, UK, EH1 3EB.
Questions? Email info@runrev.com for answers.