Download Chapter 11

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

C Sharp syntax wikipedia , lookup

Transcript
Chapter 11: Ballistics simulation
This chapter builds on the previous one to describe ballistics simulation, namely, the
simulation of the firing of a projectile into the air. When studying this chapter, you will




learn the basic mathematics and physics of projectile motion, including simulation
of the effects of gravity
practice building an application involving collision checking
understand the benefits of dividing a project into steps
gain experience using the Flash features for Clipevents, the hitTest
method, adding audio effects, and providing drop and drag operations
Motivating Example
The cannonball application featured in this chapter can serve as a basis for a shooting
type of game. The initial screen is
Figure 1. Opening screen of cannonball.
The player clicks on the FIRE button. The cannonball travels in an arc and either hits the
ground or the target. The player can change the angle of the cannon by entering a new
amount in the field next to the static text field Degrees, initially set at 45, or can change
the speed out of the mouth of the cannon by changing the text field next to the static text
field Speed, initially set to 10. The player also can drag the target using the mouse
buttons.
If the ball hits the target, it turns red and tilts, with a sound played. Figure 2 shows the
screen after a successful firing of the cannon.
Figure 2. Screen after the cannonball hits the target and it tilts.
The critical features required by this application include
 the features described for the bouncing ball application: the ability to re-position
objects on the screen and to produce animation by doing the re-positioning at
intervals of time
 calculating vertical and horizontal components of velocity
 calculating the effects of [simulated] gravity to produce the characteristic arc of
projectile motion
 determining collisions
 calculating the orientation of a tilting object
 changing the color of a Flash movie clip
 producing a sound
TIP: This application requires some basic mathematics. Do not be frightened. The
equations are all supplied and you will not need to consult any tables or do any
calculations. What you need to do is understand the use of built-in Math methods.
Seeing the mathematical functions in use should help your understanding.
Introduction to concepts
When someone throws a ball or shoots an arrow or fires a missile, the projectile travels in
an arc in the shape of a parabola. This is because the force of gravity acts on the object.
In the previous chapter, it was noted that the requirements of most computer systems
made it necessary to separate the horizontal and vertical components of velocity.
Ballistics simulation provides another reason for this separation. Gravity acts to change
the vertical component, not the horizontal component. The horizontal component is
changed by forces such as the drag from the air, but we assume a more idealized
situation. The horizontal velocity remains constant and the vertical velocity changes.
EXAMPLE: The simulation is to move (animate) the cannonball through the air using
calculations based on the initial velocity out of the cannon, the resolution of that vector
into horizontal and vertical components, and the effects of gravity to change the vertical
vector.
In simulations involving virtual worlds, the program often must check if the position of
one object overlays the position of another. A generic term for these checks is collision
detection. The checks are to determine if the virtual objects collide.
EXAMPLE: Checks are made to see if the cannonball hits the ground or hits a target.
These checks are set up to be done throughout the flight using different programming
techniques.
The simulation is enhanced by allowing the player to change the angle of the cannon and
the velocity out of the cannon. The player also can move the target by dragging and then
dropping it using the mouse. Lastly, the simulation produces a sound and makes the
target slowly rotate when the hit is detected. These all involve various coding techniques,
some specific to Flash, and others applicable to other programming languages.
A lesson for all programming is to divide implementation into steps. This will be
demonstrated by dividing the implementation of the cannonball application into multiple
steps. This is an important principle to keep in mind for all projects.
Description: simulation of projectile motion
In the bouncing ball simulation, the ball is re-positioned horizontally and vertically over
and over again to produce the look of animation. For the cannonball simulation, it is
necessary to determine the horizontal and vertical components of the velocity. The initial
information is the speed of the cannonball out of the cannon and the angle of the cannon.
Figure 3 shows how the vector v representing the cannonball departing the cannon
oriented at angle a can be decomposed (resolved) into horizontal and vertical vectors, vx
and vy.
velocity v out
of cannon
vertical component vy
a
horizontal component vx
Figure 3. Initial speed as sum of component parts.
The magnitude of the two vectors turns out to be easy to calculate using the built-in
trigonometric functions. Look at the triangle shown in Figure 3. It is a right triangle,
meaning that two of the sides are perpendicular. The side opposite the right angle is
called the hypotenuse. The angle at the left is of size a. In any triangle of this shape,
meaning any right triangle with one of the other angles of size a, the ratio of the side next
to angle a, vx, to the hypotenuse, v, is the same known value called the cosine of the
angle a. Similarly, the ratio of the side opposite, vy, to the hypotenuse, v, is the same
known value, called the sine of the angle a. These ratios are definitions of the
trigonometric functions sine and cosine.
Using pseudo-code and the common abbreviations of the functions:
vx = v * cos(a)
vy = v * sin(a)
Most programming languages have built-in functions or methods for producing the
trigonometric functions and this is the case with ActionScript:
vx = v * Math.cos(a);
vy = v * Math.sin(a);
Math.cos and Math.sin are class methods. The parameter a is the angle. Stating
this in practical terms, once the value v, the velocity of the cannonball out of the cannon,
and the angle a, the rotation of the cannon, are known, you can write the code to
calculate the horizontal and vertical velocities for moving the cannonball.
TECHNICAL NOTE: What are the units for the angle? This question may not have
occurred to you because you assume that degrees, 360 indicating a full circle, are the only
way of measuring angles. We all are familiar with degrees--90 degrees to a right angle;
making a u-turn is "doing a 180"--but this measurement is totally arbitrary and it is not
the only possibility. Many computer programming languages use radians in place of
degrees. Imagine taking the radius of a circle and using it as the ruler to measure the arcs
around the circle. There are 2 * pi radians to go all the way around. One radian is a little
less than 60 degrees. This unit may seem strange to us, but calculations are easier.
Consequently, radian is the standard unit for many programming languages. You need to
determine what units the built-in trigonometric functions expect and adjust accordingly.
The cannonball application expects the player to input the angle in the familiar degrees.
The built-in functions expect angles to be expressed in radians. The program, therefore,
must make the conversion. Fortunately, ActionScript provides a Math class variable
Math.PI. The code for the conversion is
angle_radians = angle_degrees * Math.PI/180
Now that is clear how to determine the initial values to use to animate the cannonball, it
is time to move on to describe how to include the effects of gravity. The vertical velocity
must change. Exploring this requires a return to the equations of motion. Velocity
changes position: it causes displacement. The displacement is calculated using the
formula
new_position = old_position + velocity * time
Gravity is a force that brings about acceleration. Acceleration changes velocity. The
technical term acceleration means any change in velocity, not just getting faster by
pushing on the car gas pedal. Acceleration can mean going faster or slower and it also
can refer to changes in direction. The relevant formula is
new_velocity = old_velocity + acceleration * time
Assuming constant acceleration, the velocity at the end of the time interval chosen for the
simulation is the velocity at the start of the interval plus the value of the acceleration.
Note that the sign (positive or negative) of the acceleration does not matter for these
equations to be valid. What is the velocity to be used for re-positioning the object? The
answer is to take the average of the starting and ending values.
average_velocity = (old_velocity + new_velocity)/2
Combining the last two equations,
average_velocity = (old velocity + old_velocity+acceleration*time)/2
Now putting this value into the displacement equation,
new_position =
old_position + ((old_velocity+old_velocity+acceleration*time)/2)*time
Simplifying this
new_position = old_position + old_velocity*time + .5 *acceleration*time2
The simplification is done to show that the value assigned for the new position is a
quadratic expression in terms of the time variable. This is the reason that the path is a
parabolic arc. The horizontal component of the velocity remains constant so the object
keeps moving horizontally as it started. The horizontal movement is proportional to the
time elapsed. The vertical component undergoes the changes corresponding to the
quadratic expression. For the ballistics simulation, assuming the cannon is pointing up
and to the right, the vertical velocity begins moving the projectile upward, changes to
moving upward slower and slower, then changes to moving downwards, then moving
downwards faster and faster. Figure 4 is an attempt to convey this.
Figure 4. Arc (may not be perfect parabola!)
When you get to the coding, you will learn about the signs of the relevant variables and
how this produces the desired effect, but this mathematics and physics lesson is over. If
you work on action games or simulation of many phenomena of nature, you will need to
explore more equations such as these involving forces and vectors.
Description: collision detection
The ballistics simulation featured in this chapter requires two calculations involving
collisions: the ball hitting the ground and the ball hitting the target. The object nature of
Flash and ActionScript provide features that makes the programming more-or-less
intuitive but in this and other programming environments, it is important to understand
that you, the programmer, need to check explicitly for the conditions that indicate a
collision. There are no cannonballs, targets and ground inside the computer.
Graphical objects are characterized by their positions on the screen or in the virtual world
and numbers or formulas defining their shapes. The position generally is the location of
the registration point or nominal origin of the object so it is critical to know what the
registration point is. In Flash, the registration point would be indicated by a + sign on the
Stage. You draw the graphics keeping this registration point in mind. However, if it turns
out that you need to re-position the graphics in terms of the registration point, you can
select everything using the arrow selection tool and move the material. Alternatively,
you can change the coordinates given in the Properties panel directly.
Figure 5 shows 4 rectangles with circles representing the registration points. (A filled-in
circle is used here to indicate the registration point.) The first rectangle has the
registration point in the middle. The next two on the top row have the registration point
in or near corners. The rectangle on the bottom row has the registration point away from
the rectangle itself. When these items are positioned, the value of the position
coordinates is the location for the registration points.
Figure 5. Examples of registration points.
Figure 6 shows stars positioned 'near' the rectangles, that is, near the rectangle
registration points. Notice the very different effects.
Figure 6. Rectangles positioned.
TIP: The registration point or origin may or may not be under your control. For example,
images in HTML are positioned in terms of the upper left corner. In Flash, you can
define the registration point to be anywhere you want, including making it away from the
actual graphical material.
If you know the registration point and the shape of an object, you can write code to
determine if a point is within the boundaries of an object. The Flash system has a method
that performs such tests, which will be explained next. However, just in case your
language does not have it, and to increase your understanding, consider the following
situation involving a rectangle. If a rectangle's origin is the upper left corner and
origin at rx, ry
width rwidth
height rheight
and the question is whether or not the point mx, my is within the rectangle, the check is
the compound if test
if ((mx>=rx) && (my >= ry) && (mx <=(rx+rwidth)) && (my<=(ry+rheight)))
rx, ry
rheight
mx, my
mx, my
rwidth
Figure 7. Point (mx, my) inside and outside of rectangle.
Figure 7 shows one point inside the rectangle and one outside. Which of the conditions
fails for the point outside? Imagine other points outside the rectangle and see if you can
identify which of the 4 conditions fail.
A rectangle is a relatively simple shape. You have seen the coding for the expression for
determining if a point lies within a rectangle. The coding for other graphical shapes may
be more complex. For this reason, the bounding rectangle, also called the bounding box,
for a graphical object is defined as the smallest rectangle that encloses all the material of
the object. Examples of bounding are shown in Figure 8.
Figure 8. Examples of bounding rectangles
ActionScript supports a method for movie clips, hitTest, that can check for a point
being in the same position as any graphical content of the movie clip: any pixel that has
had color added to it, any non-transparent point. The coding is
if (clip.hitTest(x, y, true))
This test will return true only if the point x,y indicates a pixel in the movie clip that is
not transparent. If the point x,y corresponds to any white pixel in the objects shown in
Figure 8, for example, the area in the center of the doughnut, the method will return false.
If the third parameter in the call to hitTest is false, the check will be the point
against the bounding rectangle of the movie clip.
You also can use the hitTest method to compare one movie clip to another.
if (clip1.hitTest(clip2))
However, in this situation, the comparison is between the bounding rectangles of the
clips. The test is fairly fast and if it satisfies the requirements for the application, it should
be used. However, if the movie clips hold irregular shapes and it is important to have an
exact determination, you may want to consider other strategies.
For example, to check if a movie clip, circleclip, that is a circle shape and has origin
in the center has collided with a movie clip, wavyclip, you may want to use
if (wavyclip.hitTest(circleclip._x, circleclip._y, true))
rather than
if (wavyclip.hitTest(circleclip)
The first expression checks if the center of circleclip is on any occupied pixel of
wavyclip. The second checks if the bounding box of circleclip intersects with
the bounding box of wavyclip. This will return true for many more situations. Figure
9 shows two configurations of circleclip and wavyclip. The bounding
rectangles overlap in both cases. However, the hitTest that checks a point would
return false for the configuration on the left and true for the configuration on the right.
Figure 9. circleclip and wavyclip.
TECHNICAL NOTE: The two variations of the hitTest method, movie clip versus
movie clip and movie clip versus point, demonstrate overloading. The Flash system
distinguishes between the two based on the parameters.
Sometimes it is possible to use a relatively simple test to determine a critical condition.
For example, in the cannonball application, the code checking if the ball has hit the
ground actually checks if the vertical coordinate of the ball is equal or greater than the
vertical coordinate of the ground object. This is just one comparison operation.
Remember that vertical values increase moving down the screen.
TIP: You do need to make sure that the registration point for the ground movie clip is on
the ground and not way above or below.
You also need to be wary of imposing too strict a test for collisions, especially if you are
requiring a player to use the mouse to position something. Often, it is necessary to define
a level of tolerance. For example, if the requirement is for the point x,y to be 'at' x0, y0,
you may want the condition to be
if ((Math.abs(x-x0)<tolerance) && (Math.abs(y-y0)<tolerance))
where tolerance has been set to a value such as 50. The Math method abs stands for
absolute value.
Math.abs(f) is f if f>=0 and –f is f<0
The absolute value function returns the magnitude of the argument independent of the
sign. In the if condition checking of a point x,y was near enough to the point x0,y0, this
means that you do not care if the point was to the left or the right of the target, if
x>=x0 or x<x0
The code checks that regardless of what side, the difference is less than the tolerance
amount. You can experiment.
EXAMPLE: The cannonball application uses the Flash hitTest method to determine if
and when the cannonball hits the target.
Description: dragging and dropping of objects
A typical operation in modern interactive computer applications is dragging and
dropping. Dragging begins by pressing down on the standard mouse button when the
cursor controlled by the mouse is over a certain area of the screen. This indicates that
dragging is to start. The user then moves the mouse. The item in question is now moved
across the screen as long as the mouse button stays down. When the mouse button is
released, the item stays put.
Different programming languages provide different types of support for dragging and
dropping. The mechanisms in Flash work as follows. It is possible to specify a handler
for the mousedown event for any movie clip. This event is triggered if and when the
mouse button is pressed down anywhere on the screen. The event handler then can check
if the mouse is over the material of the movie clip by using the hitTest described
earlier. If this is the case, the movie clip can be set to be dragged by invoking a movie
clip method. Because it is sometimes the case that you may want to let the user/player
click anywhere on the movie clip to start the dragging, but you want the dragging to be
from the registration point, an argument to the startdrag method indicates true if
you want dragging to be from the movie clip origin and false otherwise. The code to
start dragging a movie clip is:
onClipEvent (mouseDown) {
if (this.hitTest(_root._xmouse, _root._ymouse,true))
{
this.startdrag(false);
}
}
The _root._xmouse and _root._ymouse give the coordinates of the mouse. The
this indicates this movie clip. The startdrag is a method applicable to all movie
clips.
TECHNICAL NOTE: The false is a parameter indicating dragging is to take place
from the initial point of contact. Setting this parameter to true would indicate that you
wanted dragging to be done in terms of the registration point (origin) of the movie clip.
The effect would be that the cursor would jump to origin.
Stopping dragging is simpler than starting dragging. There is an event for monitoring the
mouse button being released. When this happens, the event handler can include a call to
the function stopdrag. This stops all dragging.
onClipEvent(mouseUp) {
stopdrag();
}
TECHNICAL NOTE: Some programming languages provide less support for dragging.
You may need to write code to monitor the mouse move event and then move the item
explicitly by saving old and new coordinates and computing the changes.
EXAMPLE: The cannonball application allows the player to re-position the target using
the mouse.
Description: audio (sound)
The addition of audio to a computer application can increase the target audience to
include people with visual impairments, improve usability in busy environments through
the use of attention-getting signals, or simply make an application more dramatic.
A feature of an audio clip is that it takes up a certain amount of time. You, the
programmer, must coordinate the playing of the audio clip with whatever else is
happening in the application. The statement that starts the audio clip does just that: starts
it. The sound probably goes on while other statements are being executed.
EXAMPLE: The cannonball application makes a sound when the target is hit. This is
really just for fun, but it does illustrate an important concept in interactive applications:
provide feedback to your user.
TECHNICAL NOTE: There are different file formats for audio just as there are different
file formats for images. The wav format actually is a family of formats corresponding to
different sample rates (frequencies) and different amounts of data recorded at each
instance of sampling. The mpeg family of formats represents a highly efficient way of
compressing audio files. You need to understand the specifications for the programming
language you are using in order to incorporate audio files.
Description: iterative development
Programs can be complex. A way to deal with the complexity is to divide the work into
small[er] parts. It is easy to make the general statement, but more challenging in practice.
One rule of thumb is that if it is possible to program a small part of an application and
test it independently, do so. The application featured here will be described in several
steps. No claims are made that these steps are the only ones possible or the best ones, but
they do serve to divide the work.
NOTE ON TERMINOLOGY: To avoid confusion with the Stage of Flash, the term 'step'
is used in place of 'stage'.
EXAMPLE: The cannonball application is excellent for practicing iterative development.
Do the basics first and then add the bells-and-whistles.
Reading checks
1. How are the trigonometric functions, sine and cosine, used for ballistics
simulation?
2. What is the formula relating radians to degrees?
3. Why is it necessary to convert from degrees to radians?
4. What are the mouse events that are significant for performing a drag-and-drop
operation?
Application
Review of previous examples
The application featured in Chapter 10 made use of the playing of frames to simulate the
behavior of a ball bouncing in a 2-dimensional box. This application will build on that
methodology to simulate the shooting of a cannonball out of a cannon.
Plan of attack for cannonball
The strategy for cannonball is to use the same 3 frame scheme demonstrated in the
bouncing ball application to do the simulation. See Figure 10. The first frame will
contain function definitions and global variables, including any initializing of values. The
second frame, named continue, will contain free-standing code to animate the
cannonball. The third frame will contain free-standing code that will send play back to
frame 2 if the cannonball is in flight.
Figure 10. Timeline for cannonball.
The graphical material of the application includes 4 movie clips: cannon, ball,
target and ground. You need to create these movie clip symbols and move instances
to the Stage. The instance name for the target movie clip was made target1 to hint
that it is possible to have multiple targets.
Because the plan is to have target1 appear to sink into the ground, the ground
movie clip is in its own layer, also named ground, above the board layer holding
everything else. This means that the ground remains in front of the target1. See
Figure 10.
It is recommended that you begin with simple graphics as shown here. When you have
the application working, you can enhance the graphics. See the What can go wrong
section for a common error concerning the cannon.
The material also includes a button showing the word FIRE, and text fields: two static
ones holding Speed and Degrees and next to each of these input text fields with var
names speed and anglein. Figure 11 shows the material in all 3 frames. Note the
registration point of the cannon and note also that it is oriented horizontally—flat on the
ground. The initial setting of the text field anglein is 45. The code in the
firecannon function to be described later will rotate the cannon to its specified
angle.
Figure 11. Material for cannonball.
The implementation will be done in steps, starting with implementing the cannonball
traveling in a parabolic arc based on the speed and angles specified in the input text
fields. When working properly, application at this first iteration does not stop! You need
to close the window. The next step will add the collision testing and subsequent steps
will add other features.
Use of concepts in implementation
Implementing a program in steps is an example of the adage "make haste slowly".
Working on one thing at a time makes the work go faster.
Step 1: parabolic arc, no stopping
The first step of implementation is to rotate the cannon as designated by the angle,
position the cannonball at the mouth of the cannon and move the cannonball according to
the equations of motion. Since this step does not have anything to stop the flight, it will
be necessary to close the window showing the movie. This may feel silly but once this
much of the program works, you have the most difficult part completed.
Frame 1 ActionScript contains the global variable declarations and the definition of the
function firecannon. The coding for the global variables and their purpose is
indicated in the following table.
var inflight;
var then;
Boolean indicating whether flight is to
continue or not
Used to store start of time interval
var
var
var
var
now;
elapsed;
hspeed;
vspeed1;
var vspeed2;
var gravity = 9.8/12;
var angle;
Used to store end of time interval
Used to hold elapsed time
Horizontal component of the velocity
Vertical component of velocity at the
start of the time interval
Vertical component of the velocity at
the end of the time interval
A made up number representing the
magnitude of the change in velocity due
to gravity
The angle in radians, converted from
the degrees input by the player
The on(release) for the button is to invoke firecannon. The function definition
is:
function firecannon() {
inflight = true;
cannon._rotation = - anglein;
ball._x = cannon._x
+cannon._width +(.5* ball._width);
ball._y = cannon._y cannon._height -(.5*ball._height);
angle = anglein * Math.PI/180;
ball._visible = true;
hspeed = Math.cos(angle)*speed;
vspeed1 = -Math.sin(angle)*speed;
vspeed2 = vspeed1;
then = getTimer();
gotoAndPlay("continue");
function header
set inflight to true indicating the
ball is in flight
Rotate the cannon the
designated amount, sign
changed to be counter
clockwise.
Position ball horizontally next
to right end of cannon
Position ball vertically in
middle of cannon
Convert from degrees to radians
Make ball visible
Calculate horizontal component
Calculate vertical component.
Negative sign due to screen
coordinates having origin at the
top
To start with, starting and
ending velocities are the same
Get time
Go to continue frame (frame 2)
}
The Frame 2 ActionScript is free-standing code. This frame is labeled "continue". It
moves the ball horizontally using the fixed horizontal speed and vertically according to
the average of the vertical speeds at the start and the end of the time interval.
if (inflight) {
Still in flight?
now = getTimer();
elapsed = 12*(now - then)/1000;
ball._x += hspeed * elapsed;
vspeed1 = vspeed2;
vspeed2 = vspeed1 + gravity*
elapsed;
ball._y += elapsed * (vspeed1 +
vspeed2)*.5;
then = now;
}
Get the time
Calculate the elapsed time
Move ball over horizontally
Set the vertical speed for the start
what it was at the end of the last time
interval
Calculate the vertical speed at the end
using the formula for acceleration
Move the ball over vertically using the
average
Set the starting time for the next
iteration
End of true clause
The Frame 3 ActionScript sends play back to the continue frame or stops depending on
the value of the inflight variable. For this step, nothing changes inflight, so the ball
keeps going.
if (inflight) {
gotoAndPlay("continue");}
else {
stop();
}
Try to get this working. You need to check the program with different values for the
speed out of the cannon and for the angle. The cannon should rotate corresponding to the
different angles. (See the exercises for a challenge regarding the angle.)
Step 2: checking for ground and checking for the target
The next step is to put in code to stop the flight, either when the cannonball hits the target
or hits the ground. You could do this symmetrically, but here is another approach. The
check for hitting the target will be placed in a ClipEvent of the target1 instance.
You need to select the target1 instance in each of frame 2 and frame 3 and enter the code
onClipEvent (enterFrame) {
if (this.hitTest(_root.ball)) {
_root.ball._visible = false;
_root.inflight = false;
}
}
The qualifier _root means to use the ball and the inflight defined in the main
movie. Otherwise, the language processor looks for variables defined locally, say in the
target1 movie clip. If the variable or instance is defined in the main movie, it is never
incorrect to use the _root qualifier, so when in doubt, use it.
Putting the code in the onClipEvent (enterframe) means that it gets executed
over and over because the one frame of the target1 instance is played over and over.
Checking for the ball hitting the ground is done by placing code in frame 2. In the true
clause of the if (inflight) statement, insert
if ((ball._y + ball._height) > ground._y) {
inflight = false;
ball._y = ground._y - ball._height;
}
This is an example of using a simple test to determine if there is a collision. In this case,
the test is essentially: has the ball gone beyond the level of the ground. Remember that
further down the screen is a greater y value. If this is the case, the line
ball._y = ground._y - ball._height;
makes the ball lie on the ground. Think of it as correcting the fact that the check is done
at discrete intervals so the ball may have below ground level.
Now test the program. Sometimes students believe testing is complete when they make
the cannonball hit the target. This is thinking like a game player and not the game
builder. You must check different combinations. An amusing situation is when the
cannonball flies over the target. Assuming the programming is correct, it will stop when
it reaches the vertical level of the ground even if it is off-screen.
Step 3: making the target turn red
This next enhancement to the project does not add any significant functionality, but is
more of a 'bells and whistles'. See the exercises for an alternative.
Flash and ActionScript provide a way to associate colors with movie clips. A Color
object variable is created as associated with a movie clip instance. Add the following
statement to Frame 1, with the other global variables.
var zap = new Color(target1);
In the firecannon function definition, add the statement
zap.setRGB(0x000000);
The setRGB method of Color objects sets the color using red-green-blue hexadecimal
coding. A hexadecimal character is 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, or F. Think
of it as 0 to 15. The 0x indicates an hexadecimal string. There are 3 times 2 = 6
hexadecimal characters hold 2 for red, 2 for green and 2 for blue. The two values used for
this application are easy enough to understand: all zeroes represents the absence of color,
black. Red is represented by 0xFF0000. To find out the hexadecimal pattern for other
numbers, you can consult books on HTML or use a drawing program such as JASC Paint
Shop Pro or Adobe Photo Shop.
Assuming that the original movie clip is all black, this statement does not do anything the
very first time. However, you do want the target to turn back to black when you hit the
FIRE button again.
To make the target change color, select the target1 instance and add the following
statement in the onClipEvent(enterframe) code, in the true clause indicating ball
has hit the target
_root.zap.setRGB(0xFF0000);
You do need to add the _root here to get the global variable zap changed. You make
this addition to both frames 2 and 3.
Try it! Again, make sure the program works for different settings of speed and angle.
This means you need to check that the target does not change color if it is not hit by the
ball. You also need to check that the target changes back to black when you, acting as
the player, hit the FIRE button again after the target has turned red.
Step 4: adding sound
Adding sound is another 'bells-and-whistles' enhancement. The first step is to acquire a
sound from the Common Library/Sound. My choice was Bucket Sound. Select it and
drag to the Library. Figure 12 shows panels from both the Common Library and the
Library for the cannonball application. The two wave patterns represent the signals sent
to the two speakers. You can use the setPan and setVolume methods to control the
sounds from the left and right speakers.
Figure 12. Sounds Library and Library for project shown.
The next step is to
1. Select the Bucket Hit in the Library
2. Right click and click on Linkage
3. Click on the check box for Export for ActionScript. The Export in first frame will
be checked, also. Type in an identifier: buckethit is what is used in the code.
This is shown in Figure 13. Click OK.
Figure 13. Linkage Properties for sounds.
The coding now is somewhat like that for the color change, but there is a difference. You
need to make sure that the sound is just started once.
In Frame 1, add the following to the global variables:
var soundc = new Sound();
soundc.attachSound("buckethit");
var okforsound;
The soundc object is a sound controller to which you need to attach a sound. The
okforsound is a variable used in this program to determine if it is okay to start playing
the sound.
In the firecannon function definition, add the statement
okforsound = true;
Now, just as you did for the color change, select target1 instance in frame 2 and add to
the onClipEvent(enterframe) code, to the true clause, the following:
if (_root.okforsound) {
_root.soundc.start(0, 1);
_root.okforsound = false;
}
Repeat for frame 3. This starts the sound. The first parameter to the start method, 0
here, indicates that the sound is to start from the beginning. You can signal the sound to
start a specified number of seconds into the sound clip. The second parameter indicates
the number of times the sound clip is to repeat, to loop. The code here indicates the
sound is to play just one time. The last statement in the clause sets the variable
okforsound to false. This means that the sound will not be started again.
Step 5: hit target tilts
The next enhancement is to make the target appear to tilt and sink into the ground. This
is accomplished over the playing of several frames of the target1 instance. The first step
is, again, additions to the global variables in frame 1.
var oktofall;
var origrotation = target1._rotation;
The oktofall is not Boolean, but will hold a number, initialized in firecannon to
be zero and incremented until it is 10. The tilting will take place if the target1
instance is hit and if oktofall is under 10. The origrotation holds the original
rotation for the target1 instance. It is needed to reset the rotation after hitting.
In the firecannon function definition, add
oktofall = 0;
target1._rotation = origrotation;
Now, moving again to the onClipEvent(enterframe) coding as in steps 3 and 4,
the code is shown in full. The addition is the if statement checking if oktofall is less
than 10.
onClipEvent (enterFrame) {
if (this.hitTest(_root.ball)) {
_root.zap.setRGB(0xFF0000);
_root.ball._visible = false;
_root.inflight = false;
if (_root.okforsound) {
_root.soundc.start(0, 1);
_root.okforsound = false;
}
if (_root.oktofall<10) {
_root.oktofall += 1;
_root.target1._rotation += 1;
_root.target1._y += .3;
}
}
}
The if statement checks if it is still ok to fall. If this is the case, the oktofall variable
is incremented. The target1 instance is rotated by 1 degree and its vertical (y) coordinate
is increased by 3 pixels. Because the ground layer is above the board layer that holds
target1 instance, this has the effect of the target1 sinking and tilting.
The three enhancements could be added in any order, but it certainly makes sense to add
them one at a time.
Step 6: dragging and dropping
The last enhancement is to add the facility to move the target (target1 instance). The
Flash/ActionScript product makes this very simple to do. Select the target1 instance and
add the following to all 3 frames:
onClipEvent (mouseDown) {
if (this.hitTest(_root._xmouse, _root._ymouse)) {
this.startdrag(false);
}
}
onClipEvent(mouseUp) {
stopdrag();
}
This coding has been explained already. Test the program. Move the target by pressing
the mouse button down and dragging. You can move the target up above the ground and
then click on the FIRE button. See if you can 'catch' the cannonball in flight. What
happens? If you do not want the target to be up in the air and look rather silly tilting over
as shown in Figure 14, you need to do some more programming!
Figure 14. Target up in the 'air' when hit.
Add one more global variable in frame 1:
var origy = target1._y;
This stores the original vertical location of the target1 instance so it can be restored once
the FIRE button is pressed. In the firecannon definition, add
target1._y = origy;
This will 'bring the target down to earth' if it has been moved. To test the program
properly, you need to check if it still works if you do not move the target and if you do.
Remember that working means doing the appropriate action when the cannonball hits the
target and when it does not hit the target.
Reading checks
1. Review each step to check that you know what will the application is to do at that
step.
2. At what step will you see the parabolic arc?
3. At what step is there a check if the target has been hit?
4. What would be the effects of changing the value for gravity? How is that done?
5. Why must there be a check that the sound has started?
6. How is the tilting done and why must there be a check to stop the tilting?
7. Why is the ground instance put in a layer on top of everything else?
8. What happens in the first frame? The second frame? The third frame? Give your
answer in words, not code.
What can go wrong
This application is meant to inspire readers to build an improved version. However, the
recommendations already mentioned deserve repetition: start with simple graphics and
work in steps.
One common error is to design an elaborate cannon or find a picture of one on-line (this
would be theft of someone else's work, so don't do it). At rest, the cannon appears to be
fine. However, the coding rotates the movie clip instance named cannon with the
rotation done at the registration point. You don't want the base and the wheels of the
cannon to be rotated off the ground. Be sure your cannon movie clip is essentially a
rectangle with the registration point at the left end. After you have the basic application
working, you may decide to design a cannon assembly consisting of two or more separate
movie clips. One will have instance named cannon and be the one that is referenced in
the code.
This application has code in each of the 3 frames, code associated with the button and
code associated with the target1 instance. If the code is not in the correct place, the
program will not work. For example, if the mouse event handlers for the target1
instance are placed as Actions in the Frame, you will see a little a in the ground layer as
indicated in Figure 15.
Figure 15. Putting instance code in the wrong place.
When you test the program, an error message will appear as shown in Figure 16.
Figure 16. Error message.
This is a signal that you need to move the coding so that it is associated with a movie clip
instance.
Chapter Summary and Reflection
This chapter covered programming features necessary to simulate projectile motion. The
basics for the computed animation were addressed in the previous chapter. This chapter
focused on the mathematical operations necessary to represent (resolve) a vector into
vertical and horizontal components and calculate the changing vertical velocity. These
would be similar in any programming language. The application also required
implementation of accepting player input, collision detection, drag-and-drop operations
and playing a sound.
The cannonball application, along with the bouncing ball of the previous chapter, shows
the power of computed animation. The program, based on inputs and actions by the
player/user, produces a complex display. You can begin to appreciate that a computer
program can produce results that were not specifically predicted by the
designers/programmers, but still under their control.
The radians versus degrees issue brings up an important point for interface design. Build
an interface for the user, not for the programming language. People use degrees. It is the
programmer's job to code any conversions to satisfy the internal system requirements .
The application shows event-driven, interactive programming. The events include the
passage of time, the player entering information into text fields and the player clicking a
button.
Review the 3 enhancements to the project: color change, sound and tilting. Their
implementations had features that were similar: each required global variables and the
main code was all in the same place in the onClipEvent(enterframe) for the
target1 instance. However, there also were differences, mainly relating to time. The
color change was instantaneous. The sound was not instantaneous; that is, it had a
duration more than an instant. However, in terms of the ActionScript programming, it
was critical to just invoke the sound once. Lastly, the tilting also lasted a certain amount
of time and it was under the control of the ActionScript programming.
If you were a programmer
Ballistics simulation was one of the earliest applications of computers. Simulation and
control of missiles and rockets still are important applications. A question to ask is how
much of the material in this chapter applies to programming languages other than Flash
and ActionScript. The answer is most of it: the laws of physics are the same. The
equations of motion are the same. Setting up events and event handlers varies, but the
general design considerations would apply to any programming system.
Of course, if you were working on an application to simulate, track or control real
phenomena, you would need to pay closer attention to values and units. For the
cannonball application, the value for gravity, 9.8 pixels/sec/sec, was chosen because of its
closeness to a constant the author remembered and because it produces a nice-looking arc
on the screen. Programs created to help scientists, engineers and planners better visualize
and understand situations may require that the simulation run at variable rates, slower
and/or faster than the real thing.
The general lessons of this chapter on dividing implementation into steps and testing all
situations apply even more to work in industry than to projects found in books.
Organizations may even have groups of professionals whose main assignments are to
plan the steps of work or perform system testing.
What's next
The next chapter presents a different kind of simulation, the virtual dog. It represents the
class of applications characterized as finite-state, stochastic processes. The
implementation language will be HTML and JavaScript.
Exercises
1. Math/physics problem: a toy moves 5 inches/second. How far does it go in 30
seconds? 10 seconds? 2 minutes? 3 and ½ minutes? three-quarters of an hour?
2. Math/physics problem: a toy is not moving. It accelerates at the rate of
10inch/sec/sec. How fast is it going after 5 seconds?
3. Do research (this can include personal experience, but be careful): what are
typical rates of acceleration when driving a car: starting from rest? Driving at 55
miles/hour? How quickly can you decelerate from 55miles/hour to 30
miles/hour?
4. The cannonball application as presented does no checking on the angle entered by
the player. See what happens when the player puts in 90 for 90 degrees. Fix this
bug by checking the value to make sure it is a positive integer and to not accept a
value over 89 degrees.
5. What is the ActionScript to initiate dragging for the movie clip house?
6. What is the ActionScript to stop all dragging?
7. True or False: the event onClipEvent(mousedown) for a specific movie clip
will be triggered by the mouse being down anywhere on the screen, not just on
top of material in the movie clip.
8. Recalling the formula for the area of a circle (Area = pi * the square of the
radius), write the expression in ActionScript that calculates the area of a circle
with radius r.
Projects
9. Add scoring and a scoreboard to the cannonball game.
10. Improve the graphics of the game. Make the cannon look like a cannon as hinted
at in the chapter. You will create a cannon assembly consisting of more than one
movie clip. Consider making the target smaller. See next two exercises.
11. Turn this into a shooting rockets in space game by taking out gravity: the vertical
velocity remains the same.
12. Produce a more general ballistics simulation by making it possible to change
gravity. You can provide the player choices, such as Earth, Moon, Mars for 3 set
values. Consider changing the background graphics to correspond with each
choice.
13. Change the target to something other than a rectangle. Now change the collision
detection code to use the point versus clip hitTest . Define the point to be the
center of cannonball.
14. The cannonball application as presented changes the color of the target when it is
hit, makes a sound, and tilts the target into the ground. Instead, create a new
movie clip representing a target that has been hit. Bring an instance to the Stage,
off-stage, and name it hit_target. When the target is deemed to have been
hit, set target1 to be invisible, move hit_target to the same location and
make it visible.
15. Create a moving target. There are at least two ways to do this. You can move the
target using computed animation. Think of combining bouncing ball and
cannonball. Alternatively, you can create a movie clip that itself has multiple
frames producing cel animation for the target.
16. Investigate what happens if an over-eager player clicks on the FIRE button while
the cannonball is in flight. Fix this by adding code to check the inflight
variable in the firebutton function.
17. The cannonball is a ball, or, more specifically, a circle. Think about what is
necessary to implement an arrow shot at a target. You want the arrow to rotate so
that the tip leads as it moves up, levels and then moves down. You will need to
use trigonometry to rotate the arrow. What is necessary is to calculate the angle
using arctangent: the angle whose tangent is the argument of the function. The
code would be (substituting arrow for ball, though you certainly could keep
ball as the instance name):
vspeeda = (vspeed1+vspeed2)*.5;
arrow._y += elapsed * vspeeda;
var anga = Math.atan(vspeeda/hspeed);
var angad = anga*(180)/Math.PI;
arrow._rotation = angad;
For an arrow as opposed to a ball, you also want to determine hitting the target
based on the tip of the arrow hitting the target. Set alength to be the length of
the arrow. Then the coordinates of the tip are calculated as follows:
aangr = arrow._rotation*Math.PI/180;
apx = arrow._x+Math.cos(aangr)*alength;
apy = arrow._y+Math.sin(aangr)*alength;
if (this.hitTest(apx, apy, true)) {
For teachers only:
Tips for Teachers
Most students enjoy doing cannonball, though it is a challenge. The main problem is that
students' ambitions exceed their abilities. You need to slow them down and force them to
do the project in steps, and, initially, with simple graphics. A common problem is that
students draw elaborate cannons. They will need to separate the cannon housing from the
part of the cannon that rotates.
Set up distinct due dates for the different steps, or at least steps 1 and 2, and do not accept
later steps until the first ones are complete. This also is a way to make sure that they
have done the work.
Many students will groan if and when you talk about trigonometry. A tactic is to say the
following: in the past, you learned or maybe did not learn some terminology. Here is a
chance to use it. You do not have to figure out the coding. It is provided to you. You do
not have to look up values in tables. The built-in methods provide the coding. Once you
understand the workings of vectors, you can build very complex applications.