Forum Topic: Game: Code Optimisation help!

(352 views • 18 replies)

This topic is 1 page long.

<< < > >>
Shouting

SunderEX

Reply To Post Reply & Quote

Posted at: 7/26/06 07:08 AM

SunderEX LIGHT LEVEL 09

Sign-Up: 04/02/03

Posts: 82

Hey! I'm an amateur flash developer, and I've been working on a heavily actionscript reliant game for the past few months. I've pretty much completed the game engine so far, and the end product is quite amusing. However, I'm running into a few problems at this stage of development, and would really appreciate some help.

These problems mainly pertain to the game pretty much slogging down into a mind-numbingly slow framerate in heated combat.

First let me talk about the structure of the game.

The game is basically a top-down space dogfighting simulation entitled - The Echo Path: Progenesis (relates to a book I'm trying to write, but thats mostly just backstory)

You can play the latest version of the engine at: www.feel-the-burn.co..ersonal/fighter.html

The controls are:

ARROW KEYS - Movement
SPACE - Fire Primary (projectile) Weapon
CTRL - Launch tracking beacon (hit an enemy and wait for a lockon, only one enemy can be tracked at a time)
Z - Toggle Primary Weapon
X - Toggle Secondary Weapon
C - Fire Secondary (Missile) Weapon (Note that Huntress and Starburst missiles require a lockon)
B - EMP burst - Destroys all nearby enemy missiles
TAB - Toggle on/off automatic shield regeneration (consumes power)

To spawn entities, click on one of the gold boxes situated on the top left hand corner of the screen. The buttons spawn, in respective order:
Enemies: Intercepter, Bomber, Hunter, Destroyer, Cruiser, Carrier (launches 5 intercepters)
Allies: Seraphim Fighter, Gun Turrent, Seraphim Carrier (has 2 gun turrents)

The bottom two buttons test the objective system and clean up all entities in play respectively.

Try spawning a fleet of enemies and allies and observe the AI code in action.

After experimenting with this game, I find that if I have anything more than four or five entities in play at once, I experience a slowdown in the frame rate. I'm not sure what might be causing it, but some suggestions are:

My Code Structure:
Basically how my game works is that entities are duplicated from a large bank of movie clips that are placed on the stage out of view. Each of these movie clips has large amount of code, including loops checking for collisions with projectile movie clips, code pertaining to an array() with details of all ally and enemy units in play for tracking. However, I can't think of how to reduce this code without comprimising the game engine.

Graphics:
Theres is minimal animation in this game, most movement is actionscript based, so I doubt if it's a graphical issue.

Exhaust Trails:
In order to make an exhaust trail effect for the ships and missiles, I duplicateMovieClip a fading gradiented circle that is positioned at the rear of each fighter and missile. This of course creates many movie clips each frame. I've thought of using draw tools to make a cleaner trail, but I have no idea how to do that.

Relative Positioning:

In order to keep my fighter at the center of the screen, everything else except for the fighter moves when the engine thrust is on. This is accomplished by everything having a relativemove() function that adds/subtracts to the clips x and y values according to the direction and supposed velocity of your ship.

Are there any suggestions that anyone can give me to help me optimise the code for better performance? Are there any programs that will help optimise the code?

If anyone is kind enough to take a look at the code and the .fla file, or help in any manner please contact me at sunderx@gmail.com.


None

DJStatika

Reply To Post Reply & Quote

Posted at: 7/26/06 08:12 AM

DJStatika NEUTRAL LEVEL 04

Sign-Up: 04/19/05

Posts: 43

I have made a similar game to this: http://www.newground..m/portal/view/232526
I had similar problems. The way i dealt with it was thinking more about how often the code is being called. E.g does an enemy need to check the exact position of the player even when they are a long way away? or could they do it every 20th frame? Do they need to make trails when they are off screen and not visible? etc

hope that helps


None

Glaiel-Gamer

Reply To Post Reply & Quote

Posted at: 7/26/06 08:27 AM

Glaiel-Gamer NEUTRAL LEVEL 26

Sign-Up: 12/28/04

Posts: 7,063

At 7/26/06 07:08 AM, SunderEX wrote: My Code Structure:

That's how I used to code for a long time, but since i've been learning c++ i've realized that an OOP approach is much easier to handle, and runs a little faster too. OOP will take a while to learn though, and you'd basically have to start from scratch

Graphics:
Theres is minimal animation in this game, most movement is actionscript based, so I doubt if it's a graphical issue.

No but the exhause tails are

Exhaust Trails:

I'd be willing to bet that it's the exhause that's causing lag. That and the explosions. Try to learn a little bitmap data, you'll find that it's really easy to make a trail with minimum movieclips. I have a class for it but it's not on this computer

Relative Positioning:

That way works, but i prefer to just move the _root._x. I dont know if it makes much difference in speed, but i find it easier to keep something centered if you only have to move 1 movieclip (_root) instead of the every one in the _root. I have a class for a camera too, but it's not here.

There's a lot of other things you can do to help. Write your own hittest funcions. If you are doing circle hittests, instead of sqrting the distance, square the radius. Same effect, much faster. Try learning some vector math to help reduce all the unnecessary trig. Work your engine into OOP. Try removing the trails for now and see what happens.


None

Fat-Lifeguard

Reply To Post Reply & Quote

Posted at: 7/26/06 08:43 AM

Fat-Lifeguard EVIL LEVEL 16

Sign-Up: 07/23/06

Posts: 278

Also write some code that when any ship or bullet is off screen, it is sent to an empty keyframe.

Flash still draws out all of the vectors of all the movieclips that currently exist, even if they are off screen and even if _visible is false. If you send it to an empty keyframe it should reduce the number of vectors to 0 for that clip.

Also, download ASProf. Just google it. It helps optimize code and shave off miliseconds from the processing time.

Oh, and I've read that array access is killer. Try to avoid it. Example:

for(blah blah blah) {
arrayOfMovieClips[i].dosomething();
arrayOfMovieClips[i].somethingelse();
arrayOfMovieClips[i].anotherthing();
arrayOfMovieClips[i].updatelocation();
arrayOfMovieClips[i].scratchyourass();
}
is better as
for(blah blah blah) {
var current:MovieClip = arrayOfMovieClips[i];
with(current) {
dosomething();
somethingelse();
anotherthing();
updatelocation();
scratchyourass();
}
}

And calling functions hurts too. If you only use a function a couple times, instead of calling the function, just paste the actions of the function right into the sequence that they are a part of.

Or wait for AS 3.0 to come out. Adobe says it'll be up to 10 times faster than AS 2.

Hope that helps some.


Questioning

Fat-Lifeguard

Reply To Post Reply & Quote

Posted at: 7/26/06 08:51 AM

Fat-Lifeguard EVIL LEVEL 16

Sign-Up: 07/23/06

Posts: 278

At 7/26/06 08:27 AM, Glaiel_Gamer wrote:
Exhaust Trails:
I'd be willing to bet that it's the exhause that's causing lag. That and the explosions. Try to learn a little bitmap data, you'll find that it's really easy to make a trail with minimum movieclips. I have a class for it but it's not on this computer

Huh? What do you mean by bitmap data?

There's a lot of other things you can do to help. Write your own hittest funcions. If you are doing circle hittests, instead of sqrting the distance, square the radius. Same effect, much faster. Try learning some vector math to help reduce all the unnecessary trig. Work your engine into OOP. Try removing the trails for now and see what happens.

I'm actually really interested in writing my own hitTest, but I haven't been able to find a way that will be as effective as the built in one with shapeFlag except when using circles as the objects to get collisions between. Could you explain what you did? And by reduce unnecessary trig, do you mean there's a way for me not to have to deal with sin, cos, tan anymore? Cause that would be pretty freaking sweet.


None

SunderEX

Reply To Post Reply & Quote

Posted at: 7/26/06 09:06 AM

SunderEX LIGHT LEVEL 09

Sign-Up: 04/02/03

Posts: 82


And calling functions hurts too. If you only use a function a couple times, instead of calling the function, just paste the actions of the function right into the sequence that they are a part of.

What?!? I was under the impression that functions helped. I have almost everything that is repeated in the game stuck up in functions declared on the main timeline :S.

I'm intrigued by the idea of writing your own hittest function, but would that really reduce the lag? I presume that it would involve creating a pseudo-collision circle around each object, and then checking to see if the total of the radii of the object collision circles is smaller than the actual distance between them?

Problem is that would require all movie clips to be centered. Hmmm...


None

Fat-Lifeguard

Reply To Post Reply & Quote

Posted at: 7/26/06 09:16 AM

Fat-Lifeguard EVIL LEVEL 16

Sign-Up: 07/23/06

Posts: 278

At 7/26/06 09:06 AM, SunderEX wrote:

And calling functions hurts too. If you only use a function a couple times, instead of calling the function, just paste the actions of the function right into the sequence that they are a part of.
What?!? I was under the impression that functions helped. I have almost everything that is repeated in the game stuck up in functions declared on the main timeline :S.

I'm intrigued by the idea of writing your own hittest function, but would that really reduce the lag? I presume that it would involve creating a pseudo-collision circle around each object, and then checking to see if the total of the radii of the object collision circles is smaller than the actual distance between them?

Problem is that would require all movie clips to be centered. Hmmm...

Or you could just do the math so that the circle is centered. I forgot some more tips.

Use as few onEnterFrame and setInterval functions as you can. If multiple objects behave the same way each frame, instead of having them each have the same onEnterFrame function, have a single function access each one of them from an array and do the necessary operations. Example:

var bullets:Array = new Array(b1,b2,b3,b4,b5.....b100000);
this.onEnterFrame = function () {
var bnum:Number = bullets.length;
for(var i=0;i<bnum;i++) {
bnum[i].move();
}
}

Which brings up another point. If you are cycling through an array with a for loop, and the array's length will not change during the cycles, DO NOT do this:

for(var i=0;theArray.length;i++) {}

It will look up the length every time it loops, which takes more time than a variable look up. So do this instead:

var arrayLength:Number = theArray.length;
for(var i=0;i<arrayLength;i++) {}

For especially long arrays, that save a LOT of time.

BTW, that game looks freaking amazing, forgot to mention that in first post.


None

Fat-Lifeguard

Reply To Post Reply & Quote

Posted at: 7/26/06 09:19 AM

Fat-Lifeguard EVIL LEVEL 16

Sign-Up: 07/23/06

Posts: 278

Dammit, forgot to address original querie.

Functions really help make code reusable and readable and all that good stuff, but transfering control from one function to another takes up processor time. Normally I wouldn't recommend doing this, but since you are really tight for time, if a function is only used once or twice, copy the actions straight into the sequence.


None

SunderEX

Reply To Post Reply & Quote

Posted at: 7/26/06 09:31 AM

SunderEX LIGHT LEVEL 09

Sign-Up: 04/02/03

Posts: 82

Thanks for all the advice and tips.

You mention ASProf before, I looked it up, but I don't really have any idea how it works/would help.

And do you think that creating my own hittest funciton would help reduce the lag significantly?


None

Fat-Lifeguard

Reply To Post Reply & Quote

Posted at: 7/26/06 09:48 AM

Fat-Lifeguard EVIL LEVEL 16

Sign-Up: 07/23/06

Posts: 278

At 7/26/06 09:31 AM, SunderEX wrote: Thanks for all the advice and tips.

You mention ASProf before, I looked it up, but I don't really have any idea how it works/would help.

And do you think that creating my own hittest funciton would help reduce the lag significantly?

ASProf let's you time how long it takes for a function to execute. You #include "ASProf.as" and then use its functions in order to time the code. That way, you can compare code and figure out which executes the fastest.

I don't know about the hitTest. Glail mentioned it, not me. My guess though is that if you are using distance comparison instead of hitTest, it should execute a bit faster.


None

SunderEX

Reply To Post Reply & Quote

Posted at: 7/26/06 11:39 AM

SunderEX LIGHT LEVEL 09

Sign-Up: 04/02/03

Posts: 82

does anyone know also if sound adds significantly to the processing of a flash?

By the way, I'm also currently looking for someone to find sound effects and possibly voiceovers for the game.


None

BleeBlap

Reply To Post Reply & Quote

Posted at: 7/26/06 07:14 PM

BleeBlap LIGHT LEVEL 24

Sign-Up: 03/08/05

Posts: 945

I don't think this was mentioned, but if you are using Flash 8 try adding this line:

MovieClip.prototype.cacheAsBitmap = true;

to the first frame of code. If you've not already done that it should prevent Flash from redrawing the plane and any of the other vector images every frame.

Also, using the distance formula even without the square root is about 1.5 times as long as a basic hit test and takes just a little longert than a shapeFlag hitTest. The advantage of using the distance formula or circle collisions is that the penetration vector is easy to calculate, which I don't think would be very useful in a shoot 'em up game.


None

SunderEX

Reply To Post Reply & Quote

Posted at: 7/27/06 01:50 AM

SunderEX LIGHT LEVEL 09

Sign-Up: 04/02/03

Posts: 82

Is it worth caching bitmaps of extremely simple vector movie clips, such as a straight line or a circle?

And can it be done on a movie clip that animates?


None

DFox

Reply To Post Reply & Quote

Posted at: 7/27/06 01:55 AM

DFox LIGHT LEVEL 30

Sign-Up: 08/09/03

Posts: 9,270

Well I see a problem with duplicating many enemies at start off the stage.

I mean those are using memory. I'm not sure how Flash handles it, but the code on the movieClips are even running, and there NOT being used. That's crazy.

My sugesstions:
Use attachMovie to spawn the enemies RIGHT when you need them.
Write code on the frame, not in movieClips. You can still detect colissions and everything.

But definitley loose those off stage movieClips. That's what's slowing it down.


None

DFox

Reply To Post Reply & Quote

Posted at: 7/27/06 01:59 AM

DFox LIGHT LEVEL 30

Sign-Up: 08/09/03

Posts: 9,270

ALSO!! Important. I'm not sure if anyones said this yet, but I'll say it.

With the trail movieClips that are duplicated, make SURE you do removeMovieClip() at the end to get rid of it. Otherwise they're all sitting on the stage in memory.


None

SunderEX

Reply To Post Reply & Quote

Posted at: 7/27/06 02:17 AM

SunderEX LIGHT LEVEL 09

Sign-Up: 04/02/03

Posts: 82

Yes, all used movie clips a removeMovieCliped immediately after usage.

In the offstage movie clips I have all of them with If (this._name<>"stagemoviename") { all the code}; Does this mean that none of the code inside is executed, or does it mean that flash runs through it but with no effect?


None

DFox

Reply To Post Reply & Quote

Posted at: 7/27/06 02:19 AM

DFox LIGHT LEVEL 30

Sign-Up: 08/09/03

Posts: 9,270

At 7/27/06 02:17 AM, SunderEX wrote: In the offstage movie clips I have all of them with If (this._name<>"stagemoviename") { all the code}; Does this mean that none of the code inside is executed, or does it mean that flash runs through it but with no effect?

I'm not sure what you mean.

What is that if supposed to do?


None

SunderEX

Reply To Post Reply & Quote

Posted at: 7/27/06 02:30 AM

SunderEX LIGHT LEVEL 09

Sign-Up: 04/02/03

Posts: 82

Basically, if the clip has the same name as the clip initially placed on the stage (i.e. it is th eoriginal duplicated clip) the code for the movie clip doesn't execute. I was wondering if the nonexecution o fthis code still contributes to processing.


None

DFox

Reply To Post Reply & Quote

Posted at: 7/27/06 02:33 AM

DFox LIGHT LEVEL 30

Sign-Up: 08/09/03

Posts: 9,270

At 7/27/06 02:30 AM, SunderEX wrote: Basically, if the clip has the same name as the clip initially placed on the stage (i.e. it is th eoriginal duplicated clip) the code for the movie clip doesn't execute. I was wondering if the nonexecution o fthis code still contributes to processing.

Yes, it does.

Here's my question. Why do you ever need to run that?

You should NEVER have a movieClip on the stage that's not being used. Don't duplicate off a movieClip. Use attachMovie.

The only time I ever use an off stage movie clip is to trigger my run every frame code on the main timeline. I have a movieClip called "Actions" that tells a function on my main timeline, like moveWorld() to do eveything. I think it's best to keep ALL your ActionScript on the main frame timeline. None on individual movieClips, especialy those that you're duplicating.


All times are Eastern Standard Time (GMT -5) | Current Time: 08:43 AM

<< Back

This topic is 1 page long.

<< < > >>
You need a Grounds Gold Account to post on the NG BBS! If you don't have one, click here to sign up now! It's fast, free, and easy — and opens up tons of great NG features!