00:00
00:00
Newgrounds Background Image Theme

Chan99 just joined the crew!

We need you on the team, too.

Support Newgrounds and get tons of perks for just $2.99!

Create a Free Account and then..

Become a Supporter!

As: Canon (projectile Launcher)

6,972 Views | 25 Replies
New Topic Respond to this Topic

As: Canon (projectile Launcher) 2006-03-18 22:11:52


AS: CANON

NOTE: I have designed this tutorial with the begining actionscriptor in mind, so I do a lot of in-depth explanation of code. If you feel that you are above this level, feel free to just skip around.

------------------------------------------
----------------
RELATED
AS: Main
AS: Variables
AS: Following/Shooting at Mouse
------------------------------------------
-----------------

Today you will be learning how to make a canon much like
this
Pardon the abysmal graphics, I just whipped it up in a few minutes. Use the UP and DOWN arrow keys to aim the canon, and press the SPACEBAR when the power meter is where you want it.

Creating a canon is actually quite simple once you break down the parts. So what do you need?
-You have to get the power
-You have to calculate the x and y components
-You have to make the canon shoot

NOTE: THE SAMPLE IS 30 FPS. CHANGE YOUR FRAMERATE TO 30 BEFORE FOLLOWING THIS TUTORIAL.

GETTING THE POWER (OR VELOCITY)
In the sample, there is a little power meter in the upper left corner. If you press the spacebar when the power meter is at the right, you get a lot of power in your shot. If you press it at the left, you get next to none.

NOTE: GO TO THE VIEW MENU, AND CLICK ON RULERS. THEY WILL PROVE TO BE USEFUL.

1) Start by opening a new document in Flash, and creating a rectangle (make it whatever color you wish, I used a liner gradient). Make it have a width of 200 pixels (you can type it in the Properties Inspector once you've drawn it).

Convert it to a movie clip (F8).

2) Put the rectangle where you want it to be on the stage (the center should be around 130 px.)

3) Not that we don't trust your positioning skills, but we're going to type in this code anyway:
onClipEvent(load) {
this._x=130
}

This will set the x coordinate to 130 pixels when the movie first loads up. Make sure you've typed this is the actions panel of the movie clip, and NOT a frame on the main timeline.

4) Draw a triangle, and convert it to a movie clip (F8). Give it an instance name of "pointer", and have it point to somewhere on your rectange.

NOTE: THE INSTANCE NAME CAN BE TYPED IN THE PROPERTIES INSPECTOR, AFTER SELECTING THE MOVIE CLIP.

5) Here's where the coding comes in (it goes in the actions panel of the movie clip). I'll walk you through.

onClipEvent (load) {
this._x=230;
decrease = true;
scan = true;
}

First, we set the pointer's x-coordinate to 230, which puts it at the end of the rectangle. We then define a few variables, which we will see again in a bit. This all happens when the MC (movie clip) first loads.

onClipEvent (enterFrame) {
if (scan==true) {
if (decrease == true) {
this._x -= 10;
} else if (decrease == false) {
this._x += 10;
}
if (this._x == 30) {
decrease = false;
} else if (this._x == 230) {
decrease = true;
}
}

The enterFrame tells Flash to run this script on every frame, rather than when it first loads.
We have set up a variable called decrease. When decrease is true, the pointer moves 10 pixels to the left each frame. Otherwise, if it is false, the pointer will move 10 pixels to the right. This results in a scrolling motion.

We then have to set up some boundries. If the pointer's x-coordinate reaches 30 (the far left) we tell Flash that decreasing is false, and the pointer begins to move to the right. Likewise, if it reaches 230 (the far right) we tell Flash that drecreasing is true, and it moves to the left again. We have created a scanning motion.

All of this happens while the variable "scan" is true.

if (Key.isDown(Key.SPACE)) {
scan = false;
}
power = (this._x-30)/10;
}

See where we're going with this? If the user presses the spacebar, we set the variable "scan" to false, so the pointer doesn't move anymore. Based on where the pointer is, we tell Flash what we want the power of our shot to be. We use the formula THIS._X-30/10.

this._x-30 will be a value between 0 and 200. Since the farthest our pointer can go on each side is 30 and 230, subtracting 30 just gives us a cleaner range. We divide by 10 to reduce the power, because a canonball move at 200 px. per frame would go too fast for our game.

Ta-da! We have our power! One down, two to go.

CONTINUED ON NEXT PAGE.....

Response to As: Canon (projectile Launcher) 2006-03-18 22:14:40


AS: CANON - PAGE TWO

GETTING THE X AND Y COMPONENTS
It's gonna get a bit more complicated here. To get the angle, you'll have to learn some basic trigonometry. But let's not get ahead of ourselves.

1) Dive right in and create a canon (a simple rectangle will suffice, this isn't a drawing tutorial.) Convert it to a symbol (F8) and give it an instance name of "canon".

2) Set the transformation point to the bottom of your canon, unless you want it rotating around the center (which you don't, by the way.)

3) Ah, time for code already? Don't worry, it's not that complicated. Put this in the canon MC.
onClipEvent (enterFrame) {
if (Key.isDown(Key.UP)) {
_rotation -= 5;
} else if (Key.isDown(Key.DOWN)) {
_rotation += 5;
}
}

In this code, we use the _rotation property. The _rotation property...you guess it...rotates an object.

When you press the UP arrow, it rotates to the left, when you press the DOWN arrow, it rotates to the right.

NOTE: _ROTATION SPECIFIES THE ROTATION OF THE MOVIE CLIP IN DEGREES

Alright! Now we can change the angle we shoot at!

We won't go over any more direct code in this section, just concepts. However, if you wish to get a full understanding, you CAN NOT skip over the rest of this section.

TRIGONOMETRY
Some of you may know it, some of you may not. And for those who do know, and think that they'll be able to whiz through this part, Flash still has a few tricks up it's sleeve (apparently the creators of actionscript tried to make coding difficult.)

We will be using the sine and cosine(written as sin and cos, or Math.sin and Math.cos in Flash) functions making this part of the game.
As a general rule, in a triangle:
sin(angle) = opposite side / hypotenuse
cos(angle) = adjacent side / hypotenuse
see fig. 1

So what do triangles have to do with canons?
Everything, actually. Remember the power variable we calculated in part 1? That's the hypotenuse. But we can tell the canonball to move like that without the x and y components.

Assuming that you've completed basic algebra, you know that we have to isolate the variable. In this case, it's vx and vy (x velocity and y velocity). We know our degree (_rotation) and we know our hypotenuse (power). So let's get cracking!

Eventually, this will be going in the code for the canonball, and that will produce a problem. As you may already know, variables defined in one MC apply ONLY to the MC. So while pointer will know what "power" is, our canonball will have no clue!

We have to tell Flash to use the "power" variable from the pointer. The code for this is _root.pointer.power.

The _root brings us back up to the main timeline, and the .pointer takes us into the pointer MC. Finally, we grab the power variable.

Basic algebra will tell us that...
Math.sin(_rotation) = vy / _root.pointer.power
Math.sin(_rotation) * _root.pointer.power = vy

Likewise:
Math.cos(_rotation) * _root.pointer.power = vx

However this is not the case in Flash. The problem is that while rotation gives us an MC's rotation in DEGREES, Math.sin and Math.cos give us the number in RADIANS!
We'll have to convert the number. The equation to convert radians to degrees is:
radian = Math.PI/180 * degree

Not a problem! Just plug in _rotation for the degree, and put the whole thing in the equation. We end up with:
vy = _root.pointer.power*(Math.sin(Math.PI/180*
_rotation));

And:
vx = _root.pointer.power*(Math.cos(Math.PI/180*
_rotation));

Whew! We've got the x and y components. Moving on to the final part...

MAKING THE CANON SHOOT
We're finally ready to make the canon shoot. This is where everything comes together ('bout time).

1) Draw a cicle, and convert it to a movie clip (F8). Give it an instance name of "ball".

2) We're probably gonna want to send this to the back, so select it and press Ctrl+Shift+Down

3) And now for the code. We'll start off by defining "launched" as soon as the MC loads.
onClipEvent (load) {
launched = false;
}

Obviously, we don't want the ball to be launched yet, so we have set it to false.

onClipEvent (enterFrame) {
if (Key.isDown(Key.SPACE)) {
launched = true;
}

This simply sets "launched" to true when the user presses the spacebar.

if (launched == false) {
this._rotation = _root.canon._rotation;
this._x = _root.canon._x;
this._y = _root.canon._y;
vx = _root.pointer.power*(Math.cos(Math.PI/180*
_rotation));
vy = _root.pointer.power*(Math.sin(Math.PI/180*
_rotation));

Now, what happens here? When the ball has not been launched, we set it's x and y coordinates to that of the canon.

Then we set it's vx and vy, which we found (painstakingly) in part 2.

} else if (launched == true) {
this._x += vx;
this._y += vy;
vy += 1;
}

And what if "launched" is true? The ball's x and y simply increase by the vx and vy that we just defined. Simple, no?

But what of the vy+=1, you ask? Well, without it, our ball would simply travel in a straight line off the screen.

The last line provides gravity, so our ball travels in a nice arc.

if(_x>Stage.width || _x<0 || _y<0 || _y>Stage.height){
launched=false;
_root.pointer.scan=true;
}
}

We finish up the code in the ball by setting some boundries. In flash "||" means "OR". "Stage.width"and

"Stage.height" are the maximum width and heights in our document. 0 is the lowest. See where we're going?
If the ball goes past any one of our boundries, we set "launched" back to false, so we can shoot the ball all over again.

We also tell the pointer to scan the rectangle again, by saying "_root.pointer.scan=true;".

------------------------------------------
-----------------------------

And there you have it! Test your movie, and you should have a working canon!

Feel free to post any questions or comments you may have.

Response to As: Canon (projectile Launcher) 2006-03-18 22:22:16


At 3/18/06 10:20 PM, pyro111 wrote: Good, but its cannon.

Aw, crap. I said "canon" throughout the whole thing, didn't I?

Response to As: Canon (projectile Launcher) 2006-03-19 10:59:32


At 3/19/06 10:52 AM, onnet092 wrote: Only one problem with it how do you fix the ball coming from behind the cannon so you can see it?

That's just my graphics. If I took a little more time to draw it (which I probably should have), I would have the cannon cover up the ball.
Better Example

Response to As: Canon (projectile Launcher) 2006-03-19 11:06:50


But sometimes it comes out from the side of the cannon. This needs some checking.

Response to As: Canon (projectile Launcher) 2006-03-19 11:11:18


At 3/19/06 11:06 AM, -Paradox- wrote: But sometimes it comes out from the side of the cannon. This needs some checking.

Where? Please tell me, and I'll try to find the glitch.

Response to As: Canon (projectile Launcher) 2006-03-19 11:29:11


Oh, nevermind, I see. The problem is that gravity kicks in before the ball actually leaves the cannon. The correct code is:

if (this.hitTest(_root.canon)) {
this._x += vx;
this._y += vy;
} else {
this._x += vx;
this._y += vy;
vy += 1;
}

This would go in the else if (launched==true) { section.

Response to As: Canon (projectile Launcher) 2006-03-25 14:49:53


Can u E-mail me the .FLA file just for me to understand better. my mail is
this

Response to As: Canon (projectile Launcher) 2006-03-25 14:59:33


Hey, perhaps you can help me.

http://denvish.net/u.._Cannon%20Engine.php

See, only the first shoot works. Take a look at the code:


//on Load
onClipEvent (load) {
//declaring variables
var Speed:Number = 5;
var Inertia:Number = 0;
var Rotate:Number = 1;
var SpeedInc:Number = 0.08;
var Shot:Boolean = false;
var b:Number = 1;
var Gravity:Number = 0.06;
var Resistance:Number = 0.001;
var Score:Number = 0;
//making this be on top of everything else.
this.swapDepths(99999);
//declares the function 'reset'
function reset() {
Inertia = 0;
Speed = 5;
this._rotation = 34.5909729003906;
}
//Closing on load
}
//On enterframe
onClipEvent (enterFrame) {
//making the textboxes be the same as the variables
_root.speed = Speed;
_root.inertia = Inertia;
_root.rotation = this._rotation;
_root.score = Score;
_root.yaxis = _root["bomb"+b]._y;
//this will ONLY happen when the bomb HASNT been shot
if (!Shot) {
//If speed is lower or the same as zero, speed wont decrease.
if (Speed<=0) {
Speed = 0;
//Else if speed is higher than 5, it wont increase
} else if (Speed>5) {
Speed = 5;
}
//if Inertia is lower than 0, wont decrease
if (Inertia<=0) {
Inertia = 0;
// if inertia is higher than 5, it wont increase
} else if (Inertia>5) {
Inertia = 5;
}
//If key UP is pressed, and speed is higher than 0, the cannon rotates. Speed decreases, while inertia increases
if (Key.isDown(Key.UP) && Speed>0) {
this._rotation -= Rotate;
Speed -= SpeedInc;
Inertia += SpeedInc;
//Else if key down is pressed, and speed is lower than 5, cannon rotates down. Speed increases and inertia decreases
} else if (Key.isDown(Key.DOWN) && Speed<5) {
this._rotation += Rotate;
Speed += SpeedInc;
Inertia -= SpeedInc;
}
//Activating Shot if Space is pressed. Attaching the BOMB MovieClip.
if (Key.isDown(Key.SPACE) && !Shot) {
Shot = true;
_root.attachMovie("bomb", "bomb"+b, 1337+b);
_root["bomb"+b]._y = this.thing._y+500;
_root["bomb"+b]._x = this.thing._x-50;
}
//Resetting Shot!
!Key.isDown(Key.SPACE) ? Shot=false : null;
//Closing IF
}
//opening onEnterframe of BOMB
_root["bomb"+b].onEnterFrame = function() {
//Decreasing Y.
_root["bomb"+b]._y -= ((Inertia*3)*Math.cos(Math.PI/180*this._ro
tation));
//Increasing X
_root["bomb"+b]._x += ((Speed*2)*Math.cos(Math.PI/180*this._rota
tion));
//Gravity takes action
Inertia -= Gravity;
//Lowering Speed
if (Speed>0) {
Speed -= Resistance;
}
//if bomb hittests diamond
if (_root.diamond.hitTest(_root["bomb"+b])) {
//score goes up
Score++;
//diamond MOVES
_root.diamond._y = Math.random()*350;
}
//removing the bomb and resetting shot again
if (_root["bomb"+b]._y>600) {
_root["bomb"+b].removeMovieClip();
b++;
Shot = false;
}
//closing enterframe
};
}

All code by me, btw.

Response to As: Canon (projectile Launcher) 2006-03-25 15:00:41


Thanks you sooooooooooooooo much!!! ive been asking this question for an age!


If a man that always tells the truth comes up to you and says that another man always tells lies, and the man who always lies come up to you and says "I'm lying", then is he?

BBS Signature

Response to As: Canon (projectile Launcher) 2006-03-25 15:04:58


this would be alot more accurate physically with a velocity of which the gravity is applied to so that the ball doesnt fall at constant rate, but at exponential rate

i.e. after 1 second the speed vertically is 2, after 2 seconds its 4, after 3 seconds its 8 rather than having a constant speed of 2 vertically (im using 2 in place of your value for gravity)

Response to As: Canon (projectile Launcher) 2006-03-25 15:15:46


i sorry but i looked over the tutorial again and tested all the codes and the one which moves the pointer thing is the biggest piece of crap ive ever seen!


If a man that always tells the truth comes up to you and says that another man always tells lies, and the man who always lies come up to you and says "I'm lying", then is he?

BBS Signature

Response to As: Canon (projectile Launcher) 2006-06-18 22:12:13


At 3/18/06 10:25 PM, pyro111 wrote: Yep. Well I think its cannon. Let me check google...checking.....yep you speelled it wrong.

You also SPELLED spelled wrong.

Response to As: Canon (projectile Launcher) 2006-08-02 06:04:51


I couldn't understand the bit that makes the cannonball the same roation as the cannon, where do we put the script? What function does it go under?


BBS Signature

Response to As: Canon (projectile Launcher) 2006-08-02 06:10:48


Sorry, i missed it when i was looking through the script on the cannonball, i've fixed it, i spelt cannon right in the instance name, so it didn't work, lol


BBS Signature

Response to As: Canon (projectile Launcher) 2006-08-02 09:21:29


I have a problem with AI cannon firing on my game, all works perfectly, except the AI cannon doesn't fire, click here to see what i mean.
I have this script on the enemy cannon:
onClipEvent(load){
setting = true;
}
onClipEvent(enterFrame){
if(_root.enemyturn){
if(setting){
rotto = random(85) - 10;
setting = false;
}
}
if(_rotation > rotto){
_rotation --;
}else if (_rotation < rotto){
_rotation ++;
}
if(_rotation == rotto){
_root.enpower = random(20) + 31.5
_root.enfire = true;
}
}

and this on the enemy ball:
onClipEvent (load) {
launched = false;
}
onClipEvent (enterFrame) {
if (_root.enfire) {
launched = true;
}
if (launched == false) {
this._rotation = _root.canon2._rotation;
this._x = _root.canon2._x;
this._y = _root.canon2._y;
vx = _root.enpower*(Math.cos(Math.PI/180*_rotat
ion));
vy = _root.enpower*(Math.sin(Math.PI/180*_rotat
ion));
} else if (launched == true) {
this._x -= vx;
this._y -= vy;
vy -= 1;
}
if(_currentframe != 1){
launched = false;
}
}
onClipEvent(enterFrame){
if(_root.ship.hitTest(this._x, this._y, true) && _currentframe == 1 && _root.enemyturn){
this.play();
_root.hp.rem -= 10;
}else if(_root.water.hitTest(this._x, this._y, true) && _currentframe == 1){
this.gotoAndPlay(6);
}
}

can anyone figure out what's wrong? if you can, please help


BBS Signature

Response to As: Canon (projectile Launcher) 2006-08-02 10:09:31


OK, i fixed that, but now i have a new problem. The ball fires out backwards, look here:
Clik

Script on the ball:
onClipEvent (load) {
launched = false;
}
onClipEvent (enterFrame) {
if (_root.enfire) {
launched = true;
}
if (launched == false) {
this._rotation = _root.canonb._rotation;
this._x = _root.canonb._x;
this._y = _root.canonb._y;
vx = _root.enpower*(Math.cos(Math.PI/180*_rotat
ion));
vy = _root.enpower*(Math.sin(Math.PI/180*_rotat
ion));
} else if (launched == true) {
this._x += vx;
this._y += vy;
vy += 1;
}
if(_currentframe != 1){
launched = false;
}
}
onClipEvent(enterFrame){
if(_root.ship.hitTest(this._x, this._y, true) && _currentframe == 1 && _root.enemyturn){
this.play();
_root.hp.rem -= 10;
}else if(_root.water.hitTest(this._x, this._y, true) && _currentframe == 1){
this.gotoAndPlay(6);
}
}

I tried changing this:
this._x += vx;
this._y += vy;
vy += 1;

to this:
this._x -= vx;
this._y += vy;
vy += 1;

but that just went really odd... any help would be appreciated


BBS Signature

Response to As: Canon (projectile Launcher) 2006-08-03 03:17:13


OK, it's mostly working now, but i have a couple of problems, sometimes the enemy cannon still glitches: Click Here

Anyway, script on the ball:
onClipEvent (load) {
launched = false;
}
onClipEvent (enterFrame) {
if (_root.enfire) {
launched = true;
}
if (launched == false) {
this._rotation = -_root.canonb._rotation;
this._x = _root.canonb._x;
this._y = _root.canonb._y;
vx = _root.enpower*(Math.cos(Math.PI/-180*_rota
tion));
vy = _root.enpower*(Math.sin(Math.PI/180*_rotat
ion));
} else if (launched == true && _root.enemyturn) {
this._x += -vx;
this._y += vy;
vy += 1;
}
if(_currentframe != 1){
launched = false;
_root.enfire = false;
_root.enemyturn = false;
}
}
onClipEvent(enterFrame){
if(_root.ship.hitTest(this._x, this._y, true) && _currentframe == 1 && _root.enemyturn){
this.play();
_root.hp.rem -= 10;
}else if(_root.water.hitTest(this._x, this._y, true) && _currentframe == 1){
this.gotoAndPlay(6);
}
}

Cannon script is the same as above


BBS Signature

Response to As: Canon (projectile Launcher) 2006-08-26 18:30:39


Hi,

Im so frustrated! Where does this code go please?

onClipEvent (enterFrame) {
if (scan==true) {
if (decrease == true) {
this._x -= 10;
} else if (decrease == false) {
this._x += 10;
}
if (this._x == 30) {
decrease = false;
} else if (this._x == 230) {
decrease = true;

It fits in no where!

Response to As: Canon (projectile Launcher) 2006-08-27 14:52:08


Awwwww =[

Please...

Response to As: Canon (projectile Launcher) 2006-09-02 12:39:01


It goes to the power bar.


BBS Signature

Response to As: Canon (projectile Launcher) 2007-03-08 16:40:55


works perfect thanks so much!!!

Response to As: Canon (projectile Launcher) 2007-03-26 17:32:26


like we need another one of those games. nice tut anyway tho, props

Response to As: Canon (projectile Launcher) 2007-04-03 16:55:41


Hey! Thanks!
But, how do I make the cannon ball bump into a wall?

Response to As: Canon (projectile Launcher) 2007-04-03 19:04:09


Response to As: Canon (projectile Launcher) 2007-06-30 20:35:58


i have a problem with this game my problem is here
(sorry don't want to re-write it)