Wiki

Clone wiki

agtools / Tutorial 4b - The Thinking Entity

Outline

ts4b.png

This example will include some small changes which control entity world position using the entity's own 'think' or tick function.

It will use this to implement a rudimentary version of viewport-relative drawing by moving the entity through the world in the same direction as the scroll, effectively tracking the background movement. This will result in the entities appearing at 'fixed' coordinates on the screen.

The purpose is to introduce the tick function while taking a small step towards screenspace drawing.

Setup

First we create a couple of variables we'll use to track changes in the scroll (x,y) world position.

static s16 g_viewport_changeinx = 0;
static s16 g_viewport_changeiny = 0;

Mainloop

In the mainloop, we just perform a before/after subtraction around the viewport (x,y) coordinate scroll update, to get the real change in coords (keep in mind the scroll can stop or change direction, so we do this without assuming anything).

        // keep copy of viewport's last position
        g_viewport_changeinx = g_viewport_worldx;
        g_viewport_changeiny = g_viewport_worldy;

// ...update the viewport scroll coords in some way...

        // get change in viewport coords since last update
        g_viewport_changeinx -= g_viewport_worldx;
        g_viewport_changeiny -= g_viewport_worldy;

The Tick Function

And we can now add the tick function to the entities we want to have track the viewport. This is a very simple function. It takes a single argument - a pointer to the entity being ticked. It is up to the tick to decide what to do with that entity instance at each moment in time.

void letter_fntick(entity_t *_pself)
{
    // compensate entity position for change in viewport position - track the viewport
    _pself->rx -= g_viewport_changeinx;
    _pself->ry -= g_viewport_changeiny;
}

In this case, we just update the entity's rectangle position (rx,ry) with the change in scroll (g_viewport_changeinx, g_viewport_changeiny) during the last update. Easy enough.

The Entity Dictionary

Last, we update the entity dictionary to assign this tick function to the entity types we're interested in. That means all of the letters: X e n o.

Before:

    // viewport
    { 0,0,0,                        

    // other objects...

    // letters
    { 0,0,0,            
    { 0,0,0,            
    { 0,0,0,            
    { 0,0,0,            

After:

    // viewport
    { 0,0,0,                        

    // other objects...

    // letters
    { &letter_fntick,0,0,           
    { &letter_fntick,0,0,           
    { &letter_fntick,0,0,           
    { &letter_fntick,0,0,           

The first slot in each dictionary entry is the tick function. We assign the address (&) of our new function letter_fntick. This will be called during every EntityTickAll() pass of the mainloop, for any entity instance of that type. Each entity will now update its own coordinates to track the playfield.

Summary

The entities now move under their own power, and appear to sit motionless on the screen as the background passes underneath. A small step towards more interesting things.

Wait, is that it? Didn't seem like a lot of changes.

Yep - that's it. As the tutorials go on, we should be able to do more and more complex stuff with small amounts of code. The tutorials will appear to get shorter and/or denser.

Updated