PDA

View Full Version : Modifying Movie clips after they have been created with AddChild();



fishbulb
July 5th, 2007, 04:47 PM
For newest question: Go to last post.

So i'm making a little tank game and i made it so whenever i click a movie clip gets created and is rotated and positioned at the end of the turret barrel. I'd like it so the Movie Clip can move after it has been created.


function shoot(Event:MouseEvent):void
{
var newBullet:bullet = new bullet();
newBullet.x = turret.x + Math.cos(turret.rotation * Math.PI / 180) * bulletDistance;
newBullet.y = turret.y + Math.sin(turret.rotation * Math.PI / 180) * bulletDistance;
newBullet.rotation = turret.rotation + 90;
this.addChild(newBullet);
}So all of that code is fine, but after i have created it i want it to move linear-ly. I've tried modifying newBullet but i get a compiler error: 1120: Access of undefined property newBullet.

I thought about making a class, but i am very inexperienced with classes and want to know if there is an easier way to do it inside the .fla.

Thanks ahead of time.

Sirisian
July 5th, 2007, 06:22 PM
Create an array of of the bullets outside of the function. Like:
public var bullets:Array = new Array();

then in your shoot command you do all of your code but at the end after the addChild put:
bullets.push(newBullet);

Then on your ENTER_FRAME event just do:

var b:bullet;
for(var bulletIterator:uint = 0; bulletIterator < bullets.length; ++bulletIterator){
b = bullets[bulletIterator];
b.x += b.vel.x;
b.y += b.vel.y;
}I'm not really sure what "bullet" is. Is it a dynamic movie clip?

function shoot(Event:MouseEvent):void
{
var newBullet:bullet = new bullet();
newBullet.x = turret.x + Math.cos(turret.rotation * Math.PI / 180) * bulletDistance;
newBullet.y = turret.y + Math.sin(turret.rotation * Math.PI / 180) * bulletDistance;
newBullet.rotation = turret.rotation + 90;
this.addChild(newBullet);
bullets.push(newBullet);
}Honestly learn OOP since that's what you're going to be using with AS3. Either that or your going to end up with messy code.

Okay here's a bullet class using our favorite friend the Shape class.
in Bullet.as put:

package {
import flash.display.*;
import flash.geom.*;
public class Bullet extends Shape{
public var vel:point;
public function Bullet(x_:Number, y_:Number, vx_:Number, vy_:Number):void {
this.x = x_;
this.y = y_;
this.vel = new Point(vx_, vy_);
this.graphics.beginFill(0x000000);
this.graphics.drawRect(-5,-2, 10, 4);
this.graphics.endFill();
this.rotation = Math.atan2(vy_, vx_);
this.stage.addChild(this);
}
public function Remove(){
this.stage.removeChild(this);
}
}
}coded this all in browser, so you might have to do some error checking

you'd use the class like:

function shoot(Event:MouseEvent):void
{
var newBullet:Bullet = new Bullet(turret.x + Math.cos(turret.rotation * Math.PI / 180) * bulletDistance,turret.y + Math.sin(turret.rotation * Math.PI / 180) * startDistanceFromTurret, Math.cos(turret.rotation * Math.PI / 180)* bulletSpeed, Math.sin(turret.rotation * Math.PI / 180) * bulletSpeed);
);

fishbulb
July 5th, 2007, 07:06 PM
I tried what you said and it didn't like the bullet.as file.

Here is what i have so far, and all i have to do is make them fire off.

http://www.davidzych.com/marc/tanks.swf

Don't mind the horrible drawings either.

fishbulb
July 6th, 2007, 01:21 PM
I continued to mess around with this and i ended up making a movie clip inside of the main bullet movie clip and the clip inside of that moves up so it looks fine, but will this limit me in anyway such as doing a hit test and rotating it?? I'm going to give the class method another shot because that would probably be the best way.

Also, if you have a separate .as file for a class, do you need that file to play the game after it has been published? Say i upload the .swf somewhere, will i need to upload the .as to the same location as the .swf?

Krilnon
July 6th, 2007, 01:59 PM
Also, if you have a separate .as file for a class, do you need that file to play the game after it has been published? Say i upload the .swf somewhere, will i need to upload the .as to the same location as the .swf?

No, the class that the .as file defines is compiled into the .swf file.

Sirisian
July 8th, 2007, 02:17 AM
I've been busy with work and stuff. Sorry I didn't post this sooner.
Example (w,a,s,d and mouse click) (http://www.sirisian.templarian.com/flash/flashTankDriver/index.html)
Source (http://www.sirisian.templarian.com/flash/flashTankDriver/source.zip)
If you have any question feel free to ask. I kept it all unoptimized so the code is somewhat readable. There are some random comments in there to help you get an idea of what's happening. Good luck. :)
//edit there's a bug somewhere in the code. Probably in the add and removing of the bullets or the particles. I'll look at it tomorrow after work.

fishbulb
July 8th, 2007, 03:49 PM
That game looks really good. For the movement i had the up arrow move it up and if the rotation wasn't 0 or 180 then it would rotate to 0 or 180. Looks kind of clunky at times and i might switch mine to the left and right keys rotate it and up and down move it forward and backwards.

I actually found a different method to create the movieclip and i found that in the Adobe sample files found on their site.

Instead of

var newBullet:bullet = new bullet();You can use this


var newBullet:MovieClip = new BulletClass();and in any function you want to call this movieclip to modify it just add this at the beginning


var newBullet:MovieClip = event.currentTarget as MovieClip;Works great and now i can easily at the smoke trail to the bullets and such. Using this method, what is the best way to remove these movieclips? Would you do something like this?


function remove(event:Event):void
{
if(particle.alpha < .1)
{
removeChild(this);
}
}I haven't tried this since i haven't had time to add the particle effects yet.

Also: I have another problem with banking the shots off of the walls. For now i just have a box surrounding the stage and when the bullets hit the walls i want them to bounce off in the correct angle. By doing this i have this code:


function bulletHit(event:Event):void
{
var newBullet:MovieClip = event.currentTarget as MovieClip;
if(newBullet.hitTestObject(wall_r))
{
newBullet.rotation = newBullet.rotation * -1;
}
if(newBullet.hitTestObject(wall_l))
{
newBullet.rotation = newBullet.rotation * -1;
}
if(newBullet.hitTestObject(wall_t))
{
newBullet.rotation = newBullet.rotation * 2;
}
if(newBullet.hitTestObject(wall_b))
{
newBullet.rotation = newBullet.rotation * -2;
}
}wall_r is the right wall, wall_l is left and so on. The right and left work wonderfully but i do not know the proper calculation to make the bullet bounce off at an equal angle on the top of bottom walls. My code is all correct, it's just what to do to the rotation property to make it bounce off at the right angle.

Another quicky: When i hold down the up arrow the move function is run once, then after a little bit it is run again. If you hold down a single key in a text box it does the same thing, so how can i fix this so when you hold it down it doesn't have a pause time?

EDIT: I actually figured out how to do the top and bottom walls. Add 180 to the rotation and multiply it by negative 1. Figured that out because sin changes signs every 180 degrees so the direction of the bullet would be changed if i added 180 degrees.

-Thanks!

Sirisian
July 8th, 2007, 09:16 PM
Look at my source. Notice how I set a variable on keydown then make it false when the key is released. You might just be using the key repeat rate.

As for bouncing the bullet. I'd just perform a line to line intersection test using the first line:
pt1.x = bullet[i].pos.x;
pt1.y = bullet[i].pos.y;
pt2.x = bullet[i].pos.x + bullet[i].vel.x * bullet[i].velMag;
pt2.y = bullet[i].pos.y + bullet[i].vel.y * bullet[i].velMag;
Then perform a collision against the boundary lines of the object you want to check collision against.
Here's the line to line intersection equation I use.

public function LineToLineIntersect(x1:Number, y1:Number, x2:Number, y2:Number, x3:Number, y3:Number, x4:Number, y4:Number):Object {
var UBottom:Number;
var Ua:Number, Ub:Number;
var interceptX:Number, interceptY:Number;
var i:Object = {b:false, x:0, y:0};
UBottom = ((y4-y3)*(x2-x1))-((x4-x3)*(y2-y1));
if (UBottom != 0) {
Ua = (((x4-x3)*(y1-y3))-((y4-y3)*(x1-x3)))/UBottom;
Ub = (((x2-x1)*(y1-y3))-((y2-y1)*(x1-x3)))/UBottom;
if ((Ua>=0) && (Ua<=1) && (Ub>=0) && (Ub<=1)) {
interceptX = x1+(Ua*(x2-x1));
interceptY = y1+(Ua*(y2-y1));
i.b = true;
i.x = interceptX;
i.y = interceptY;
return i;
}
}
return i;
}It return an object so doing:
var i:Object = LineToLineIntersect(pt1.x, pt1.y, pt2.x, pt2.y, boundaryLinePt1.x,boundaryLinePt1.y,boundaryLinePt 2.x,boundaryLinePt2.y);
if(i.b){
//move the bullet to i.x,i.y and then move it Number.MIN_VALUE using the wall's normal
}
Then do the simple vector reflection:
http://www.tonypa.pri.ee/vectors/tut06.html
If you wish I will add it into the demo I made for you.
//Edit I updated the source so the bug isn't there anymore I believe.
//Edit bullet trails added into the source and the example, be reminded though, when you do bouncing bullets you will have to store each position of change in an array. I have old C++ examples, but if you need some AS3 of this, then feel free to ask.