Despawning MC's in AS2.0

43 posts

Flag Post

I have a game in wich you shoot bullets. These bullets are movieclips with a 2 second timer on it. After the 2 seconds the movie unloads using the function this.unloadMovie() .
This works fine, but after shooting 2000 bullets, the fps starts to drop and stutter. When I list the objects on the stage using the debugger, all bullets are listed, even the ones that I unloaded.

Is there a better way to remove movieclips from the stage?

 
Flag Post

It sounds like you’re removing the mc’s from the stage, as in, they are not a child of the stage anymore, but the objects themselves still exist, with x and y coordinates, alpha, speed, and whatever other variables they had.

Unfortunately I’m not familiar with AS2 syntax so I’m not sure what the apropriate function to use is.

 
Flag Post

All variables become ‘undefined’ after they get unloaded.

 
Flag Post

You need to make sure there’s no references to them anywhere after you unload them. That usually means splicing them out of an array in the game engine as well as removing them from the display list.

 
Flag Post

removeMovieClip() maybe.

I don’t know, I’ve not used AS2 much.

 
Flag Post

Make a function called destroy() in your bullet Class. in there remove all outside references and remove the movie clip.

Quite frankly if you’re shooting 2000 bullets and using AS2 you’re asking for trouble.

 
Flag Post
Originally posted by RTL_Shadow:

Quite frankly if you’re shooting 2000 bullets and using AS2 you’re asking for trouble.

 
Flag Post

Is it really impossible to drop the term ‘AS2’ and not have someone say it’s outdated and AS3 is better? Dear god..

 
Flag Post
Originally posted by JohnnyBohnny:

Is it really impossible to drop the term ‘AS2’ and not have someone say it’s outdated and AS3 is better? Dear god..

I said one sentence and what I said was completely true. Unless you’re optimizing some-insane amount you’re going to have troubles with it. I was not badmouthing AS2- just speaking the facts. That many bullets on an old engine is bound to give you trouble. I’m sorry you took it to heart.

 
Flag Post
Originally posted by feartehstickman:

removeMovieClip() maybe.

I don’t know, I’ve not used AS2 much.

Yeah, I’d definitely try using removeMovieClip as opposed to unloadMovie. See if that helps

 
Flag Post

the really fun part here is that removeMovieClip will destroy the object, but leave all references intact. the references report undefined, but if you create a new movieclip with the same name, all of the old references will be live again without assigning anything to them. i suspect that unloadMovie does exactly the same thing on movieclips as removeMovieClip (unloadMovie was meant to unload loaded SWFs).

Originally posted by JohnnyBohnny:

Is it really impossible to drop the term ‘AS2’ and not have someone say it’s outdated and AS3 is better? Dear god..

AS2 is completely horrible. there are numerous bugs that simply don’t make sense, it’s far slower and is entirely unsupported. it’s also depreciated, so be thankful anyone is still willing to help you with it: it’s slated to be completely removed from the runtime. the newest CS editions don’t even permit creating AS2 any longer if you needed proof that Adobe intends to completely dispose of AS2

and no, AS2 is not a stepping stone to AS3: they are completely different languages and badhabits learned from AS2 will only hurt you in AS3 (since you will try to treat AS3 as a newer AS2 when it is absolutely nothing of the sort)

 
Flag Post
Originally posted by JohnnyBohnny:

Is it really impossible to drop the term ‘AS2’ and not have someone say it’s outdated and AS3 is better? Dear god..

He said it’s “asking for trouble”, which, to be fair, would stand true even if you used AS3; having 2,000 MovieClips (when you don’t even need MovieClip functionallity), each taking care of its own timer and not knowing how to clean after yourself would result in a super laggy application which unnecessarily wastes a bunch of memory.

Telling you that “it’s asking for trouble” is really polite, tbh; the AS2 version of what you’re describing can only be resumed as “fucking unplayable crap”.

And yes, thankfully there’s always someone (more like everyone, actually) pointing out the huge crap that AS2 is. If lucky, someone reading the forums or getting redirected here after a search will read all of that and learn a sane language instead of AS2.

 
Flag Post

Post the part of your code where you’re creating them, and where you’re removing them. Then we can see where the problem is. If you add their names to an array in order to be able to loop through and remove them all, you probably just forgot to remove them from that. I’ve made the same mistake before, and it comes up here every so often too. The result is that you’re trying to loop through every single bullet you ever fired, even if it was already removed from the stage.

Originally posted by RTL_Shadow:

Quite frankly if you’re shooting 2000 bullets and using AS2 you’re asking for trouble.

How about if he’s shooting one bullet every second? He didn’t say anything about 2k bullets on screen at the same time (I think that was the point of him trying to unload them).

 
Flag Post

I’m shooting 4 bullets per second, wich means a maximum of 2*4=8 bullets displayed at the same time.
Here is a swf demonstrating it: link to the swf

Creating the bullets, this code is on frame 1 of the blue character, inside an onEnterFrame function, 40 fps:

shoottimer ++
	if(Key.isDown(1) && shoottimer > 10)
	{
		_root.oi ++
		var i = _root.oi
		_root.bullets_mc.attachMovie( "bullet", "bullet"+i, _root.bullets_mc.getNextHighestDepth())
		_root.bullets_mc["bullet"+i]._x = this._x
		_root.bullets_mc["bullet"+i]._y = this._y-20
		_root.bullets_mc["bullet"+i]._rotation = (Math.atan(_ymouse/_xmouse)*57.296)+(40*(Math.random()-0.5))
		if(_xmouse < 0) _root.bullets_mc["bullet"+i]._rotation += 180
		trace(_root.oi)
		
		
		shoottimer = 0
		
	}

_root.oi is an ‘object count’ variable that makes sure every created object (bullet/particle) has an unique name, besides “bullet”.
This is all the code for the bullet itself:

var speed:Number = 8
var yspeed:Number = Math.sin(this._rotation/(180/3.14159))*speed
var xspeed:Number = Math.cos(this._rotation/(180/3.14159))*speed
var lifetime:Number = 0

this.onEnterFrame = function()
{
	lifetime ++
	if(lifetime > 80)
	{
		this.unloadMovie()
	}
	this._x += xspeed
	this._y += yspeed
	
	//collision
	if(_root.collision_mc.hitTest( this._x, this._y, true))	this.unloadMovie()
}

I have no array listing all bullets, in fact, I have no reference to the bullets at all. To hitTest the bullets I hitTest the ‘bullets_mc’ clip in wich all the bullets are stored.

I am fully aware of the advantages that AS3 has, but I am only coding to have some fun doing it, and this project I decided to go with AS2. I am not that concerned about performance, but I just don’t want it to be unplayable.

 
Flag Post

So every bullet has an EnterFrame listener. That’s probably not the easiest/fastest way to do it.

 
Flag Post

Isn’t the frame handler itself a reference to the object? You have to delete that too.

Another thing you could do, given that you never have more than 8 bullets is to have a pool with that ammount of bullets (by pool I mean creating all of them at the start), then instead of attaching/creating a new one everytime you need it, simply grab an available bullet from the pool and set its values (depth, rotation, position) to whatever you need. Same when “destroying” it; just move it back to the pool and remove it from the display list.

And yes, don’t add frame handlers to each bullet; go with two arrays (available and used bullets) and use that in your main class/frame or whatever you’re using.

 
Flag Post

Thanks everyone, I am going to create some sort of recycle system, so that everytime a bullet gets fired, the last shot bullet just gets repositioned.

E: If I move the bullet enterframe script to one script for all bullets, do these bullets still need to be movieclips, or is there a faster way?

 
Flag Post

AS2 is too limited in that aspect; it includes BitmapData, but no Bitmap, so you still need a parent MovieClip to draw the data.
Other than that, it lacks all the other display options such as Bitmap, Shape or Sprite.

Going with the BitmapData would be the way to go with 2,000 bullets, to avoid the redraw overhead every frame, but since you’re only using eight, I think you can get away with MovieClip.

 
Flag Post

What is the best way to simulate slower computers? Not slower internet connections, but a slower CPU and GPU. Should I make a virtual machine?

 
Flag Post

I mentioned this once in a much older thread:
You should be able to throttle your CPU clock and/or usage limits via your power management settings (control panel), at the very least for a laptop (I can get mine down from 2GHz to 780MHz)
You can do something similar if you have a discrete graphics card, but I really wouldn’t bother

All this can be somewhat of a hassle if the options aren’t clearly available, in which case it’s most likely worthwhile to just host the swf on the net and get another computer to test it out

This is more of an irrelevant point, but it is possible to compile for mobile devices and simulate on the PC accordingly

 
Flag Post

Thanks.

FYI, the entire Fancy Pants series was created in AS2…

 
Flag Post
Originally posted by JohnnyBohnny:

Thanks.

FYI, the entire Fancy Pants series was created in AS2…

I thought they had been rewritten in AS3 at some point. Nevertheless you make a valid point – a dedicated programmer can most often make a great product even if they face tough limitations. There’s nothing “wrong” with AS2 (all programming languages, platforms, etc. will have their flaws) but AS3 is the better option now for almost everything.

 
Flag Post

Fancy Pants was never ported to AS3. I guess he didn’t because he already had a working game, and with so much code, it just isn’t worth the effort.

 
Flag Post

The fancy pants series also doesn’t appear to have lot going on each frame, AS2 is fine (sort of) for a game like that. In a shooter though, with lots of bullets zipping around (especially if each has its own onEnterFrame…omg don’t do that), well I’ll let this guy explain it:



@OP: You really should look into AS3. Take it from someone who made an entire game in AS2, only to turn around and port it to AS3, AS2 has NO redeeming qualities. The game in question runs much faster and smoother, even if much of the code/logic is the same in both versions.

Anyway:

1) Use removeMovieClip() instead of unloadMovie().

2) You don’t need to recycle your bullets. In fact, that’s more work than simply removing them. As long as you are properly removing them (again, try removeMovieClip() instead of unloadMovie()) there shouldn’t be any problems.

 
Flag Post

And I remember playing games with some nice physics which were done in AS1 and ran perfectly fine.
Having a capable and devoted programmer being able to make a decent game in AS1 or AS2 doesn’t make those languages any better. In most of those cases it was because they had no other option. Now there’s AS3 and the only reasons for using AS2 over it (besides being paid to do so) are stupidity, insanity or a total lack of a basic ability to understand programming.

The “X famous game was done in AS2” is a pretty flawed argument that people always seem to randomly throw in AS2 threads. The language is crap. Period.

If you don’t want to learn AS3 because it’s OMFG, SO HARD! that’s fine, but refrain from spamming missleading comments that will only hurt new developers by making them think that using AS2 is a good option at this point. Hell, up to date IDEs don’t even support it anymore.

@Aesica: It’s not only about rendering:

ActionScript 3.0 code executes up to 10 times faster than legacy ActionScript code.

That was said by Adobe staff three years ago. The number may be higher after the AS3.1 update, who knows.
You can run some random loop which doesn’t mess with the display list at all and see it yourself.