On sprite behaviour

Discussion in 'Game Development (Technical)' started by HairyTroll, Jun 18, 2005.

  1. HairyTroll

    Original Member

    Joined:
    Jul 29, 2004
    Messages:
    582
    Likes Received:
    0
    For my sprite behaviour/handling code, each sprite has an .update(int timescale) method, that is called from the Engine on each game loop. The sprite's behaviour is modified at runtime by adding or removing 'action' classes in the sprite's .update() method. So for example, having a status message shoot in from the left of the screen, then bounce a few times before dropping off the bottom of the screen would look like this...

    Code:
    status.addAction(new MoveAction(status, speed, startx, starty, endx, endy))
    status.addAction(new BounceAction(status, speed, height, gravity, number))
    status.addAction(new MoveAction(status, speed, endx, endy))
    
    The sprite maintains a list of these actions, calling .update on the first action object each game loop until completion, then removing this object from the list and moving onto the next action object. A sort of poor-man's scripting system.

    I'm curious, is this mechanism similar to what anyone else uses for sprite behaviour?
     
    #1 HairyTroll, Jun 18, 2005
    Last edited: Jun 18, 2005
  2. ggambett

    Moderator Original Member Indie Author

    Joined:
    Jul 26, 2004
    Messages:
    1,982
    Likes Received:
    6
    Nope, yours is a lot more advanced :D For simple sprites (a "$100" that files to the cash register), the mode's onUpdate() moves it. For complex entities (Customer, Thief) they are separate classes which have a collection of sprites, which are moved in the class onUpdate().

    I thought of having sprites and attaching behaviors but in a different context - in my framework, a Button is a Sprite subclass which reacts to onMouseEnter(), onMouseLeave() and others, which are NOPs in the base class. Instead, I'd like to have a ButtonBehavior class and attach it to a Sprite or to a Sprite subclass; this separates the visual aspect (Sprite, AnimatedSprite, whatever) from the behavior (send a message when clicked).
     
  3. HairyTroll

    Original Member

    Joined:
    Jul 29, 2004
    Messages:
    582
    Likes Received:
    0
    I think this is where multimethods become useful. Not something offered in Java or C++, but rather the Lisps.

    A multimethod is a method that does not belong to any class. Very useful to capture a behaviour when behaviour is shared between two or more classes, or if you can't decide if the behaviour should be in class A or class B so you end up making a class C that contains both A and B.

    A multimethod stands by itself, but it can still make use of inheritance/polymorphism etc. without the help of a class.

    So, for example you could say:

    Code:
    OnUpdate(Person Class, Policeman Class)
    
    or specialize further:

    Code:
    OnUpdate(Thief Class, Customer Class)
    OnUpdate(Customer Class, Policeman Class) 
    OnUpdate(Customer Class, Attendant Class, Thief Class)
    
    or specialize even further:

    Code:
    OnUpdate(Thief Class == BadGuy1, Policeman Class == DirtyHarry)
    OnUpdate(Thief Class == BadGirl1, Policeman Class == NotSoDirtyHarry)
    
    Leaving system to figure out the correct method to call.

    I find these things interesting anyway.
     
  4. electronicStar

    Original Member

    Joined:
    Feb 28, 2005
    Messages:
    2,068
    Likes Received:
    0
    Yes your method is fairly advanced,if it's not too slow to process (on a large number of sprites) then it's a good achievement. I am curious, what language are you using?
     
  5. Bad Sector

    Original Member

    Joined:
    May 28, 2005
    Messages:
    2,742
    Likes Received:
    5
    I think that what you describe as 'multimethod' can be achieved using templates in C++.

    My framework's sprite/entity stuff is like this. There is a World class, which contains a list of Entity objects. Each entity has a pointer to an EntityClass object which defines the characteristics of an entity. The EntityClass has a pointer to a Sprite object and a pointer to a Behaviour object. Sprite has information about the graphical representation of an entity (frames, animation, etc) and contains functions for manipulating this data. Behaviour has information about the behaviour of an entity. It is actually an abstract class with functions suck as create, destroy, timer (timed update), tick (per-frame update), collide, etc. A behaviour is defined by creating new classes derived from the Behaviour one.

    The World itself has a timer and a tick function. These functions are called by the GameScreen object in which the World belongs to (GameScreen is a class derived from the Screen class - different Screen classes are used for different game screens, such as menu screens, story screens and game screens) and in turn they call the timer and tick functions of all entities.

    It took me some time to design and implement the above, but i think that it is worth the effort since once you have a strong framework, later you can do a lot of things easier :).

    Now about the speed... well, i don't have speed issues. But then again it's a bit hard to have speed issues in 2D games with Athlon64 3200+ :D.

    (but i didn't noticed any performance issues in my father's P3 @ 600Mhz either, even if i had some rotating and scaling sprites on the screen - i think that this computer is old enough)

    When the library is finished and the game we're developing is ready, i'm thinking to put binary versions for MinGW, Linux x86 and Linux x86_64 available for free for non-commercial purposes :). This, with it's GUI-based world editor will provide a good resource for some developers, even if it's only about prototyping games (i'm trying to make the library as prototyping-friendly as possible, since i have lots of game ideas which i want to see them in practice :-D).
     
  6. HairyTroll

    Original Member

    Joined:
    Jul 29, 2004
    Messages:
    582
    Likes Received:
    0
    It's all done in Java. It seemed to run fine with about 50 sprites bouncing around when I tested it on an old P/75 laptop I have laying around. There was a marked difference between the old Microsoft JVM and new Sun version; obviously the MS JVM was a lot slower. The caveat is the engine has no collision detection - I hadn't gotten round to implementing that.
     
  7. princec

    Indie Author

    Joined:
    Jul 27, 2004
    Messages:
    4,873
    Likes Received:
    0
    Bit concerned about the number of new objects being created there. With a few thousand sprites on screen that's an awful lot of creating and collecting going to go on.

    Cas :)
     
  8. electronicStar

    Original Member

    Joined:
    Feb 28, 2005
    Messages:
    2,068
    Likes Received:
    0
    Yeah by looking at the syntax I was thinking it was done in Java. I have found out that Java is great for making fast, high-level 2d engines. You should try the collision detection thing, it's less difficult than it seems.
     
  9. GBGames

    Indie Author

    Joined:
    Jul 27, 2004
    Messages:
    1,255
    Likes Received:
    0
    In Kyra, KrSprite objects can change Actions. Below are some examples from a project of mine:

    Code:
    void Player::kill()
    {
        alive = false;
        playerSprite->SetAction( Char_DEAD );
    }
    
    Code:
    if ( GameEngine::instance()->key[SDLK_DOWN] )
            {
                playerSprite->SetAction(Char_DOWN);
                moveY( speed );
            } else if ( GameEngine::instance()->key[SDLK_UP] )
            {
                playerSprite->SetAction(Char_UP);
                moveY( -speed );
            }
    
    
    KrSprite::SetPos() is used to move a sprite, but you can also embed offsets so that DoStep() will simultaneously change to the next frame in the Action's animation and move the sprite.
     
  10. James C. Smith

    Moderator Original Member

    Joined:
    Aug 21, 2004
    Messages:
    1,768
    Likes Received:
    0
    This is very similar to system used in many of the games I have worked on. Each time a sprites Update() function is called it ends up updating many of the "actions" that are currently plugged into it. Sometimes these actions are added and removed at runtime. But it is more common for them to assembled at level design time in the level editor.
     
  11. HairyTroll

    Original Member

    Joined:
    Jul 29, 2004
    Messages:
    582
    Likes Received:
    0
    What type is "Char_Dead"? Is this a enum, or a class instance?

    -Luke
     
  12. cliffski

    Moderator Original Member

    Joined:
    Jul 27, 2004
    Messages:
    3,897
    Likes Received:
    0
    this is a valid concern. many coders underestimate the slowdwon that can be caused by memory allocation and garbage collection. Managing your own memory can become a must-have feature for systems that do this kind of stuff. You tend to learn this the first time you try to write a fast particle system :D
     
  13. HairyTroll

    Original Member

    Joined:
    Jul 29, 2004
    Messages:
    582
    Likes Received:
    0
    I have yet to benchmark the impact the garbage collector will have using a couple hundred sprites.

    -Luke
     
    #13 HairyTroll, Jul 5, 2005
    Last edited: Jul 5, 2005
  14. C_Coder

    Original Member

    Joined:
    Dec 21, 2004
    Messages:
    297
    Likes Received:
    0
    100% agree. Try to avoid memory allocations at all costs. Allocate a big chunk of memory and then do your own memory management. You can find memory pool managers for free today. The Boost library has one as well.
     
  15. princec

    Indie Author

    Joined:
    Jul 27, 2004
    Messages:
    4,873
    Likes Received:
    0
    100% unsubstantiated too :) download the evidence from my site... The trick is to understand what sort of objects it's OK to create every frame and what to pool. Particles are fine to allocate with new() every time, but you don't want then to be creating objects every frame for every sprite just to get them to do things.

    Cas :)
     

Share This Page

  • About Indie Gamer

    When the original Dexterity Forums closed in 2004, Indie Gamer was born and a diverse community has grown out of a passion for creating great games. Here you will find over 10 years of in-depth discussion on game design, the business of game development, and marketing/sales. Indie Gamer also provides a friendly place to meet up with other Developers, Artists, Composers and Writers.
  • Buy us a beer!

    Indie Gamer is delicately held together by a single poor bastard who thankfully gets help from various community volunteers. If you frequent this site or have found value in something you've learned here, help keep the site running by donating a few dollars (for beer of course)!

    Sure, I'll Buy You a Beer