a question of code design

many times i stumble over a problem, which concerns the design of my games.

imaging the following situation:

a game-object, a spaceship (represented by a real java class/object) has e.g. an animation-object for getting the current frame. this animation object should be nothing more than a container for the frames and a counter, which one should be choosed next.

now the anim. can realize a looped animation, a single, a random and so on. so every time something special happens (pressing a key, ship is exploding) the ship sends a signal to the anim. to change the frameset and perhaps the kind of animating.

so far, so beatiful. now my problem:

many times the changing-relationship is reversed:
if the anim. shall animate x-frames and then change to the old frameset, the change depends on the animation, not on the ship.
so there are generally two way of getting the timepoint of changing:

the ship asks every frame, if the animation has expired. this is very elegant an not a good performance choice. but the preoblem is, that the ship-object has access to the animation, but the animation has no to the ship.

so i could give every little tool-object like the animation a reference to its “owner”-object (or perhaps implement the observer pattern). so everyone could send actions to everyone.

this would solve my problem, but i think that this would be terrible coding style.

In SPGL, my Sprites are Animated, and have an Animation. The Animation is executed one tick at a time, following a sequence of Commands. Some Commands end the frame (ie. setting a new Image for the Sprite).

One of those Commands is an EventCommand, which sets a special general purpose integer to an arbitrary value.

For example, here’s the Roving Eye from Alien Flux:


      <animation
            name="roving_eye_shoot.animation"
      >
            <frame i="spriteimage.roving_eye0010" d="2" />
            <frame i="spriteimage.roving_eye0011" d="2" />
            <frame i="spriteimage.roving_eye0012" d="2" />
            <frame i="spriteimage.roving_eye0013" d="10" />
            <event id="1" />
            <frame i="spriteimage.roving_eye0014" d="1" />
            <frame i="spriteimage.roving_eye0015" d="2" />
            <frame i="spriteimage.roving_eye0016" d="2" />
            <frame i="spriteimage.roving_eye0017" d="7" />
            <event id="1" />
            <frame i="spriteimage.roving_eye0014" d="1" />
            <frame i="spriteimage.roving_eye0015" d="2" />
            <frame i="spriteimage.roving_eye0016" d="2" />
            <frame i="spriteimage.roving_eye0017" d="7" />
            <event id="1" />
            <frame i="spriteimage.roving_eye0014" d="1" />
            <frame i="spriteimage.roving_eye0015" d="2" />
            <frame i="spriteimage.roving_eye0018" d="2" />
            <frame i="spriteimage.roving_eye0019" d="2" />
            <frame i="spriteimage.roving_eye0020" d="2" />
            <frame i="spriteimage.roving_eye0021" d="2" />
            <event id="2" />            
      </animation>

The roving eye, once it has called sprite.setAnimation(shootAnimation), polls its event and takes appropriate action. Here’s a snippet of the roving eye tick code:


                              switch (sprite.getEvent()) {
                                    case 0:
                                          // Wait
                                          break;
                                    case 1:
                                          // Fire
                                          fire();
                                          sprite.setEvent(0);
                                          break;
                                    case 2:
                                          // Move
                                          phase = PHASE_WOBBLING;
                                          sprite.setEvent(0);
                                          selectNewTarget();
                                          sprite.setAnimation(wobbleAnimationResource);
                                          shadowSprite.setAnimation(wobbleShadowAnimationResource);
                                          break;
                                    default:
                                          assert false;
                              }                              


Cas :slight_smile:

It might be worth noting that the Roving Eye is not a Sprite itself, it allocates and controls Sprites; and that Animated things, such as Sprites, contain all the necessary state to allow Animations to be stateless sequences (ie. completely reusable and re-entrant).

When you make a gidrah separate from Sprites you can do much more clever things with it. The Alien Brain on Level 20 for example is composed of no less than 12 separate sprites - brain, jar, two eyes and eight jets, and each jet has a smoke emitter too.

Cas :slight_smile:

Or think of making your animation a composite.
So you have certain animation class that perform a temporary ‘special’ animation and than falls back to a default one w/o notifying the ship. Something like that…

the composite idead is very nice and simple.

now that were on topic i would like to discuss one of my mentioned “solution”, the one where every object gets a reference of its owner.
in another forum some people mentioned that i should not waste any thoughts on using additional references (< 1000)
perhaps they are right in the question of memory usage but i think it is very important to defend the object-encapsulation.
(?!)

i would like to discuss another thing: the observer/ observable pattern.
im interested in the knowledge how it works. does the observerable do nothing more than passing a hidden reference to the obeserver ?

I think it’s the other way around. A reference to the observer is passed to the observable. The observable keeps a list and and broadcasts stuff to observers. This is essentially what Listeners are in the Java UI classes.

http://c2.com/cgi/wiki?ObserverPattern