Runtime Revolution
 
Articles Other News

Cannonballs! Part 3.2


by Robert Cailliau


Firing the Ball

Edit the script of the Fire button:

on MouseUp

set the loc of graphic "Ball" to the pNozzleLoc of image "cannonBarrel.png"

put 0.2 into lk3

put the pPowder of image "cannonBarrel.png" into lPowder

put the pElevation of image "cannonBarrel.png" into lElevation

put lPowder*cos(lElevation*pi/180)*lk3 into lVx

put lPowder*sin(lElevation*pi/180)*lk3 into lVy

send "Fly " & lVx & "," & lVy to graphic "Ball"

end MouseUp

There are three parts to this handler:

  1. Setting the loc of the ball to the nozzle of the cannon.
  2. Calculating the x and y components of the starting speed. Here we obtain the powder and elevation from the barrel object, and we use the cos and sin functions again. We also multiply the powder size by some number k3 which we will choose to make things look right.
  3. Sending a message to the ball to make it fly. This message must be a string of characters. It must start with the name of the handler that the ball must use, and it must have the two components of the speed, separated by a comma. The & sign strings it all together into a single string of characters. If lVx were 5 and lVy were 4, then the message that would be sent would be Fly 5,4. You can read "Fly " & lVx & "," & lVy as follows: take the letters "Fly ", then write after them the value of lVx, then write a comma after that, then write the value of lVy after that.

Now we must let the ball do the flying. Edit the script of the ball graphic to add the Fly handler:

on Fly fVx,fVy

put 0.5 into lk1

put 0.5 into lk2

put 0.5 into lA

put item 1 of the loc of me into lX

put item 2 of the loc of me into lY

repeat 90 times

set the loc of me to round(lX),round(lY)

add fVx*lk1 to lX

subtract fVy*lk1 from lY

subtract lA*lk2 from fVy

wait 1 ticks

end repeat

end Fly

If you have understood the handlers of the Motion program, then this handler should be quite simple to grasp. First we set all our famous k numbers, the lA is the acceleration from the force of gravity. Then we copy the current x and y coordinates into local variables.

Then we do a repeat in which we move the ball, add to the x and add to the y (but since the y is measured upside-down, we have to subtract), and we subtract from the speed's y-component because gravity works downward.

Save your work.

GO!

We are ready. Run the program. Set the elevation to about 40 degrees, set the powder load to about 60. Press the Fire button.

The ball flies indeed. It describes the parabolic trajectory that was already known to Galileo.

But where does it land?

Experiment a little with the elevation and the powder to see what happens.

Hitting the ground

Our repeat goes for 90 times. That is sometimes too often and sometimes not enough. What we really need to do is stop when the ball hits the ground.

The ground is at 120 pixels from the bottom of the window, or at 480 pixels from the top. The ball has hit the ground when its y is equal to 480. But we should not use a number. We should use a description, such as the top of graphic "Grass".

The first impulse is to write:

on Fly fVx,fVy

...

repeat until lY = the top of graphic "Grass"

...

end repeat

end Fly

If you try that, you will have a BIG problem! That is because lY may be just above the top in one cycle of the repeat, and then in the next one it may be changed to just below it. In other words, it may never be exactly equal to the top of the grass. If that happens, the repeat will never end and the ball will go off the bottom of the window.

The program never stops

If the y of the ball never matches the top of the grass exactly, the program does not stop and we have lost control over it. There is only one way to stop it then: pressing command-period (hold down the command key and press the full-stop key). On Windows you have to press control-period.

Fortunately Revolution has this emergency brake. It stops the program and it shows an error.

Avoiding never stopping programs

A good programmer makes sure that all loops always stop.

One good tip is never to test equality of numbers that are not whole numbers. We should stop when lY >= the top of grahic "Grass" because that will indeed happen. The >= means greater than or equal.

Gravity will always subtract from the vertical speed, and therefore at some point the vertical speed will become negative. The ball will start to go down and its y will increase (we're measuring y downwards!) and keep increasing. Its y will have to become greater than the top of the grass.

...

repeat until lY >= the top of graphic "Grass"

...

Run the program and fire a cannonball. Not perfect, but very good indeed. Congratulations if you came this far! That's almost the end of the construction of the program.

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