Lesson objective: By the time you're done
with this lesson, you'll be able to take movie clips you've
created and animate them in simple, yet random ways. You'll
also be able to make these movie clips seem to wrap within
the screen size you assign them.
You're going to alter your createAsteroid()
function now and add a lot more code. Enter the code
for this lesson or simply download lesson_2.fla and
follow along.
First of all, you want more than one asteroid to be generated.
You're going to accomplish this with a simple for-next loop
to create an array of object references to the asteroid
movie clips:
// at will be an array of object references to the Asteroids on the screen.
at = new Array();
Here you initialize at
as an array. In my experience, I've found that working with
arrays in Macromedia Flash is much faster and easier than
looping through movie clips with a similar naming convention.
You're setting up an array of object references to the asteroid
movie clips for the following reasons:
· Keep track of how many asteroids are on the stage
throughout the game play
· Refer to individual asteroids without knowing what
their instance name is
· Assign similar, randomized actions to individual
asteroids without having to retype those actions for every
asteroid that's created:
// diffLevel is initialized here.
// it's used for determining the difficulty at each level.
diffLevel = 1;
// a variable to keep track of the depths of
// our movie clips is initialized here:
_root.depth=0;
// let's create a set amount of Asteroids depending on the level.
for (i=0; i<_root.diffLevel+1; i++) {
at[i] = new Object ();
at[i] = createAsteroid(1, mf(mr()*400), mf(mr()*400));
} Let's first look at
the for-next loop. Making a for-next loop is all dependent
on a variable, starting at a certain value and meeting a
certain condition to continue looping. You use for-next
loops because you want to repeat some actions but you want
to limit the number of times it repeats.
Your for-next loop starts with the variable i,
which acts as a counter. You initialize i
by setting it equal to 0. As long as i
is less than the diffLevel
(plus 1 past that value), this loop will continue and all
code within the brackets of this loop will be executed that
many times. Where the code reads i++,
you're giving Macromedia Flash directions as to how you're
going to make the value of i
change. In this case, you're incrementing i
by 1 (adding one to its value).
For every time that Macromedia Flash goes through this
loop, it's initializing a new Object as an element, or member,
of the at array. An element
of an array is like an empty box. If you can picture that,
picture the object in that empty box as a command to turn
that box into compartments, although you aren't saying what
kind of compartments or how big they are. Basically, you're
telling the element of the array to be prepared to accept
a certain kind of information to hold onto.
In each element of the array, you're calling on your createAsteroid()
function. So when I call on at[0],
(element #0 in the at array) it's going to refer to an asteroid
movie clip. This is how object references work, especially
when working with arrays.
Your createAsteroid()
function generates the physical asteroid but you have a
lot more functionality to build.
If you notice that the first line of the createAsteroid()
function has been altered, you see that you now have some
information inside the parentheses:
createAsteroid = function (factor, x, y) { ... }
These items in the parentheses are called parameters,
or arguments. They're simply variables passed into
the function that will be used inside of the function. The
variables x and y
will pass an x and y coordinate into the function,
telling it where it should create the asteroid.
The x and y
variables are used in this code:
// put the Asteroid at the determined x and y on the stage.
rock._x = x;
if (rock._x>20 || rock._x<380) {
rock._y = mf(mr()*400);
} else {
rock._y = y;
}
You set the asteroid (remember you refer to it in the code
here as rock) to an x-position
equal to x. If that x-position
ends up being greater than "20," or if it ends
up being smaller than "380," the y-position is
assigned randomly. Otherwise, the y-position will be set
to the y passed into
the function.
The factor variable
will be used to determine if this asteroid has been hit
once, twice, or three times. Depending on how many times
an asteroid (or a fragment of the parent asteroid) has been
hit, the factor is used
in determining its fragment's size. It's used in this code,
still within the createAsteroid()
function:
// we want a little variety in the appearance of the Asteroids,
// so we set the x- and y-scale random within a certain range,
// dependent on the factor.
rock._xscale = (mf(mr()*50)+50)/factor;
rock._yscale = (mf(mr()*50)+50)/factor; That, in a nutshell, is
a "rock solid" (pun intended) example of parameters.
You still need to build an engine to handle the movement
of every asteroid on the stage. To help with that, assign
some random values relative to your specific asteroid: xv
(x-velocity), yv (y-velocity),
and r (rotation amount):
// We need to set a velocity value for the Asteroid's
// x- and y- movements.
rock.xv = mf(mr()*6)-3;
rock.yv = mf(mr()*6)-3;
// We also need to set a rate for rotation of the Asteroid,
// so it looks like it's drifting along in space.
rock.r = mf(mr()*360)-180; You're going to use these
variables in your movement engine.
If you've entered all the code, you can publish the movie
now and see a notable difference. You now have two hexagons
(your first asteroids) moving adrift on the stage. If you
watch closely enough, you'll see that when the asteroid
moves below a certain point, it reappears atop the stageas
if the window wrapped.
In fact that's exactly what's happening onEnterFrame.
Take a look over the four different if-statements:
if (at[i]._x<=_root.xmin+10) {
at[i]._x += _root.xmax-20;
}
if (at[i]._x>=_root.xmax-10) {
at[i]._x -= _root.xmax-20;
}
if (at[i]._y<=_root.ymin+10) {
at[i]._y += _root.ymax-20;
}
if (at[i]._y>=_root.ymax-10) {
at[i]._y -= _root.ymax-20;
} Although your movie
is sized at 600 x 400, you don't want to take up this whole
space with your game. You need 200 pixels worth of screen
real estate for the console, which will hold the scoreboard,
your lives, and any system messages and buttons. This means
you're going to make your playable space a nice 400 x 400
square.
I like having a 10-pixel border for asteroids, lasers,
and the spaceship so that once they cross, they have to
wrap around. That way, it doesn't look too weird during
the course of play when the screen wraps. Set these variables
up in the Game() function:
// define the bounds of the movie.
_root.xmax = 390;
_root.xmin = 10;
_root.ymax = 390;
_root.ymin = 10; Once you set up your boundaries,
focus on actually moving each asteroid. Remember that at
is an array where each element of the array is an object
reference to a unique "Asteroid" movie clip:
// this code will be executed everytime the frame refreshes.
this.onEnterFrame = function() {
for (i in at) {
at[i]._x += at[i].xv*at[i].level;
at[i]._y += at[i].yv*at[i].level;
at[i]._rotation += at[i].r/60;
}
}; This updates the x- and
y- position on every frame refresh by adding each x-, y-
and rotaion-value to themselves. This works well for making
objects move in a straight line. The asteroid's location
always grows in the same way, which makes it move in a straight
line. The only problem is that at a certain point the movie
clip's location will grow beyond the viewable area of your
movie clip. That's no good; you can't shoot something you
can't see. That's why you put in a checking system to move
the asteroid to the opposite horizontal and/or vertical
border when it passes the minimum or maximum:
if (at[i]._x<=_root.xmin+10) {
at[i]._x += _root.xmax-20;
}
if (at[i]._x>=_root.xmax-10) {
at[i]._x -= _root.xmax-20;
}
if (at[i]._y<=_root.ymin+10) {
at[i]._y += _root.ymax-20;
}
if (at[i]._y>=_root.ymax-10) {
at[i]._y -= _root.ymax-20;
}
|