> This feels like going back to procedural programming again and it makes
> me wonder why the hell i even bother making a Bullet class in the first
> place if the amount of functionality i can give a class has to be
> supplied in raving great lumps like this or little to none at all.

Hmmm... yeah... kinda. OOP is great -- it's easier to code in, easier
to debug, easier to understand if you're looking at it, easier to
re-use, easier to extend, etc, but, unfortunately, relies heavily on
function calls which is the one thing you want to avoid more than
anything else if you want speed in ActionScript. If you have ten
bullets it doesn't really matter. If you have a few hundred it matters
a great deal.

What I mean is this:
A Bullet class still makes sense, each instance would be a collection
of properties, the state of the bullet etc. But, instead of keeping
the logic in several methods you call on each bullet, have a
BulletManager class that has the update(), move(), updateClip() etc
methods that basically work the same like the ones you have now, but
that loop through the bullets and operate on 'myBullet' instead of
'this'. If you have many bullets, then this will likely be the part
that takes the longest to execute, and every little optimization you
do pays off hundred fold, so being a bit anal about it can't hurt.
Code that only gets executed once each frame doesn't matter much --
keep that clean, as readable as possible. But bullets are the things
you'll have the most of, so this is where optimizing pays off.

So, right now you have update() that you call on each bullet. update()
checks if the bullet is expired, and if not, calls move(), which
updates the position and then calls updateClip() which moves the clip.
That's very readable and easy to follow, but once you have it working
and move on to optimizing it just comment it all out (so you can go
back to the easily readable and debuggable code if you want to improve
it in a few months) and, yes, cram it into two lines:

...
   update ( time ) {
      // check if still alive here
      // and then...:
      this.clip._x = this.position.x += this.vector.x * time;
      this.clip._y = this.position.y += this.vector.y * time;
   }
...

That's saving you two function calls per bullet and frame without too
much pain. The reason why I explicitly wrote the 'this' is that,
instead of calling the update() method on each bullet, you could have
a BulletManager class that loops through the bullets (you have
something like that anyway to call the update() method) and that would
look the same inside the loop, but have 'myBullet' instead of 'this'.
Third function call per bullet saved.

Your handleEvent() method can well be called on the bullet like you
have it now. That doesn't happen to often, so better keep it clean as
it is. What bothers me, though, is the checkEvents() method you again
call each frame on each bullet:

        private function checkEvents(){

                for(var i = events.length;i--;){

                        if(age>=events[i].triggerTime){

                                handleEvent(events[i]);

                                events.splice(i,1);

                        }

                }

        }


Depending on how many events you have cued up and if you add new ones,
it could help to call sortOn( "triggerTime" ) on the events Array when
you instantiate the bullet (Array.sortOn() is very fast). That way
you'd only have to check the first event. If it isn't due yet, neither
can be the ones after it. So, in your BulletManager loop, you could
have something like this:

while( myBullet.events[ 0 ].triggerTime <= age ) {
   myBullet.handleEvent( myBullet.shift() );
}

instead of looping through all events each frame (plus a saved
function call #4 on top of that).

Yes, that all tastes a bit procedural. But if you can have more
bullets flying around, that's a small price to pay, especially since
you can optimize it after you're done debugging.

While I'm at it:
Your "for(var i = events.length;i--;){" loop is very fast (the
fastest, AFAIK), but for the bullets I'd use an object instead of an
array. for..in loops are slightly slower (contrary to popular belief),
but if you reference them via an ID instead of an index you can remove
them with a simple delete when they have hit instead of looping
through the array and splicing them out.
Also, you use "angle*180/Math.PI" -- in your updateClipRotation()
method it doesn't really matter because it hardly ever gets called,
but if you get used to writing "angle*(180/Math.PI)" instead the
compiler will notice that (180/Math.PI) always yields the same result
and optimize it for you.

Hth,
Mark

--
http://snafoo.org/
_______________________________________________
[email protected]
To change your subscription options or search the archive:
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders

Brought to you by Fig Leaf Software
Premier Authorized Adobe Consulting and Training
http://www.figleaf.com
http://training.figleaf.com

Reply via email to