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:
- Setting the loc of the ball to the nozzle of the cannon.
- 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.
- 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.
|