Jump to content
  • Advertisement
Sign in to follow this  
belfegor

Advice for 2D game structure

This topic is 1747 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I want to make 2D top down view space shooter like game where you have wave after wave of enemies (something like a Chicken Invaders).
So i need some advices how people are usually organizing their data, here is what i thought:

Let say there might be 100 enemy ships (tops) shown on screen, and each of those can fire at least 2 rockets/bullets with relatively fast fire rate, then i have asteroids, particle effects, fonts...and what not.
So i thought to avoid lots of draw calls i would make one dynamic vertex buffer for all that stuff and play with initial/maximum vertex count until satisfied.
Also i would pack textures into atlases, as much as possible to further reduce DC.

Then i would have something like this:
struct Drawer
{
    VertexBuffer VBuffer;
    IndexBuffer IBuffer;
    int maxVertCnt;

    vector< vertex > vVerts; // all verts in scene

    void addVertex( vertex v ) { vVerts.push_back(v); }

    void drawAll()
    {
        setVB( vBuffer );
        setIB( IBuffer );

        vertex* pV;

        VBuffer->lock(&pV);
        for(i = 0; i < vVerts.size(); ++i)
        {
             ...// set pV
             if( i > maxVertCnt )
             {
                // unlock -> draw -> lock
             }
        }
        VBuffer->unlock();
        ...
        vVerts.clear(); // clear to be ready for next frame
    }
};

struct Sprite
{
    vec2 pos;
    vec2 dim;
    ...
    vector< vertex > vVerts; // could be array of 4 verts

    void update( dt )
    {
        // here i rotate vertices, move/animate texcoords...
        ...
        // then add to drawer
        for(i = 0; i < vVerts.size(); ++i)
             drawer->addVertex( vVerts[i] );
    }
};

Then i have simple vertex/pixel shader, just passing texcoords and colors... i update vertices on the cpu because there are various animation types (loop, once, ping-pong, different texture frames matrix sizes, based on input...).

I hope you understand what i meant because sometimes i cannot explain myself well with words.

Thank you for your time.
 
EDIT:
Actually i need to have some object in between sprite and drawer based on texture used:
struct Drawer
{
    VertexBuffer VBuffer;
    IndexBuffer IBuffer;
    int maxVertCnt;

    void drawBatch(const FooBar& foo)
    {
        setVB( vBuffer );
        setIB( IBuffer );

        vertex* pV;

        VBuffer->lock(&pV);
        for(i = 0; i < foo.vVerts.size(); ++i)
        {
             ...// set pV
             if( i > maxVertCnt )
             {
                // unlock -> draw -> lock
             }
        }
        VBuffer->unlock();
        ...
    }
};

struct FooBar // how to call you?
{
    Texture texture;
    vector< vertex > vVerts;

    void addVertex( vertex v ) { vVerts.push_back(v); }
};

struct Sprite
{
    vec2 pos;
    vec2 dim;
    FooBar* foo;
    ...
    vector< vertex > vVerts; // could be array of 4 verts

    void update( dt )
    {
        // here i rotate vertices, move/animate texcoords...
        ...
        // then add to foobar
        for(i = 0; i < vVerts.size(); ++i)
             foo->addVertex( vVerts[i] );
    }
};

stuct SceneManager
{
   vector< FooBar > foos;

   void drawAll()
   {
        setShader(...);
        for(i = 0; i < foos.size(); ++i)
        {
             setTexture( foos[i].texture );
             drawer->drawBatch( foos[i] );
        }
   }
};

Edited by belfegor

Share this post


Link to post
Share on other sites
Advertisement

So i thought to avoid lots of draw calls i would make one dynamic vertex buffer for all that stuff and play with initial/maximum vertex count until satisfied.

 

sounds like overkill.

 

space invaders with 3d graphics, but still a 2d playing field, right?

 

i'd have a database of models. i'd have a database of object types with stuff like max speed, max hp, what model to draw, etc. there would be an entry for each type of badguy, etc. or perhaps multiple "object type" databases, one for types of badguys, one for types of asteroids, etc. i'd probably have a list of badguys, a list of missiles, a list of terrain (asteroids, etc). perhaps a list of particle emitters too. and a data structure for the player. this divides things up based on what info each type stores. 

 

to draw, call i'd call a routine like draw_badguy that would set the world transform and draw the badguy's model. i'd do that for each list. drawall_badguys, drawall_bullets, drawall_terrrain, drawall_emitters. one draw call for each object. plenty fast, even in fixed function dx9. no dynamic buffers. dynamic buffers load FAST, at the cost of drawing SLOW. an implementation with static buffers would probably run faster than a dynamic buffer.

 

always start with brute force, then optimize, unless you KNOW brute force won't cut it.

Edited by Norman Barrows

Share this post


Link to post
Share on other sites

note that when i say database, i don't mean link in SQL or some god awful thing like that. an array of structs will do nicely.

 

in my graphics library i have databases for meshes, textures, materials, models, and animations.

 

a struct in the mesh database for example has fields like a VB, an IB, numverts, and numtris.

Share this post


Link to post
Share on other sites


...space invaders with 3d graphics, but still a 2d playing field, right?

No. I though i was obvious that i want 2D graphics, you can even tell if you read the code a bit.

If i use static buffers i will end up with thousands of draw calls and each have just 2 triangles to draw and number of shader permutations would be unmanageable.

 

Appreciate your input anyway.

Share this post


Link to post
Share on other sites

Thank you for your input.

Let me implement this what i had in mind first, i want to see how it will go and then i will look for alternatives if it fails.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!