Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I been working with scrolling this week but I recently encounter a problem that I don't understand why it's happening.

In a 2D scroller I want to scroll a tilemap pixel per pixel which gives a smooth scrolling in the game, but I encounter a weird problem, when the movement of the map corresponds with the exact size of the tile, for example, the map it's scrolling 32 pixels to the right, the map seems to jump to the next tile and not the one that corresponds correctly with the screen.

This is the code for drawing the map:

bool Tilemap::drawTilemap(GLfloat sizeTile, int indexTileset)
{
    offsetX++;
    if (offsetX >= 320.f) offsetX = 320.f;

    GLfloat widthTilesetImage = tilesetList.at(indexTileset).getWidthImage();
    GLfloat heightTilesetImage = tilesetList.at(indexTileset).getHeightImage();

    int widthMap = 40 + offsetX/32;
    int heigthMap = 23;


    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glEnableClientState( GL_VERTEX_ARRAY );
    glEnableClientState( GL_TEXTURE_COORD_ARRAY );  

    glBindTexture( GL_TEXTURE_2D, tilesetList.at(indexTileset).getTexture() );


    for (int i = 0; i < heigthMap; i++)
    {
        int startX = offsetX/32;

        for (int j = 0; j < 40; j++) 
        {
            int frameIndex = layerMap[i][startX];

            if (frameIndex == 0)
            { 
                continue; 
            }

            frameIndex -= 1;

            const GLfloat tileX = 0.0f + ( (sizeTile)*j);
            const GLfloat tileY = 0.0f + (sizeTile*i);

            const GLfloat verts[] = {
                    tileX, tileY,
                    tileX + sizeTile, tileY,
                    tileX + sizeTile, tileY + sizeTile,
                    tileX, tileY + sizeTile
            };


            const GLfloat textureWidth = (sizeTile - offsetX/widthTilesetImage) / (GLfloat)widthTilesetImage;
            const GLfloat textureHeight = sizeTile / (GLfloat)heightTilesetImage;
            const int numFramePerRow = (GLfloat)widthTilesetImage / sizeTile;
            const GLfloat textureX = ((frameIndex % numFramePerRow) * textureWidth)+offsetX/widthTilesetImage;
            const GLfloat textureY = (frameIndex / numFramePerRow ) * textureHeight;

            const GLfloat texVerts[] = {
                    textureX, textureY,
                    textureX + textureWidth, textureY,
                    textureX + textureWidth, textureY + textureHeight,
                    textureX, textureY + textureHeight
            };

            glVertexPointer(2, GL_FLOAT, 0, verts);
            glTexCoordPointer(2, GL_FLOAT, 0, texVerts);
            glDrawArrays(GL_QUADS, 0, 4);

            startX++;

        }   
    }

    glDisableClientState( GL_VERTEX_ARRAY );            
    glDisableClientState( GL_TEXTURE_COORD_ARRAY );

    return true;
}

The variable offsetX it's the one that helps me move one tile at a time the map. The variable startX indicates when it's no longer drawing one tile, so in this one start in the next column of the matrix of tiles.

So, what could be wrong in my code?

Thanks for the help.

share|improve this question
add comment

1 Answer 1

up vote 1 down vote accepted

Sorry for the late answer. I already find out the problem, I leave the new code so maybe someone will find this useful. The problem was handling the different offset in each row of the tilemap, but now it's solved.

void Tilemap::drawTilemap(int indexTileset)
{
    GLfloat offsetXTemp = offset.x;

    offsetXTemp = transformOffsetXToIntervalValues(offset.x);

    GLfloat variableSizeTile = 32.f;

    GLfloat widthTilesetImage = tilesetList.at(indexTileset).getWidthImage();
    GLfloat heightTilesetImage = tilesetList.at(indexTileset).getHeightImage();

    int widthMap = (1280 / (int)sizeTiles) + 1;
    int heigthMap = (int) ceil( 720.0f / sizeTiles );

    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glEnableClientState( GL_VERTEX_ARRAY );
    glEnableClientState( GL_TEXTURE_COORD_ARRAY );  

    glBindTexture( GL_TEXTURE_2D, tilesetList.at(indexTileset).getTexture() );

    GLfloat posXPrevious = 0.0f, posXPreviousOnTexture = 0.0f;

    for (int i = 0; i < heigthMap; i++)
    {
        int startX = (int)floor(offset.x/sizeTiles);
        posXPrevious = 0.0f;

        posXPrevious -= offsetXTemp;
        variableSizeTile = 32.f;

        for (int j = 0; j < widthMap; j++) 
        {
            if ( startX == widthLevelInTiles )
            {
                break;
            }

            int frameIndex = layerMap[i][startX].getID();

            if ( frameIndex == 0 )
            { 
                startX++;
                variableSizeTile = 32.f;
                posXPrevious = posXPrevious + variableSizeTile;

                continue; 
            }

            if ( j == 0 && offsetXTemp != sizeTiles)
            {
                posXPreviousOnTexture = offsetXTemp/widthTilesetImage;
                variableSizeTile -= offsetXTemp;
                posXPrevious = 0.0f;
            }

            else 
            { 
                variableSizeTile = 32.f; 
                posXPreviousOnTexture = 0.0f;
            }

            if ( j == 40 )
            {
                variableSizeTile = offsetXTemp;
            }

            frameIndex -= 1;

            const GLfloat tileX = posXPrevious;
            const GLfloat tileY = sizeTiles * i;
            posXPrevious = tileX + variableSizeTile;

            const GLfloat verts[] = {
                    tileX, tileY,
                    tileX + variableSizeTile, tileY,
                    tileX + variableSizeTile, tileY + sizeTiles,
                    tileX, tileY + sizeTiles
            };

            const GLfloat textureWidth = variableSizeTile / (GLfloat)widthTilesetImage;
            const GLfloat textureHeight = sizeTiles / (GLfloat)heightTilesetImage;
            const int numFramePerRow = (int)widthTilesetImage / (int)sizeTiles;
            const GLfloat textureX = ( (frameIndex % numFramePerRow) * sizeTiles/(GLfloat)widthTilesetImage ) 
                                    + posXPreviousOnTexture;
            const GLfloat textureY = ( frameIndex / numFramePerRow ) * textureHeight;

            const GLfloat texVerts[] = {
                    textureX, textureY,
                    textureX + textureWidth, textureY,
                    textureX + textureWidth, textureY + textureHeight,
                    textureX, textureY + textureHeight
            };

            glVertexPointer(2, GL_FLOAT, 0, verts);
            glTexCoordPointer(2, GL_FLOAT, 0, texVerts);
            glDrawArrays(GL_QUADS, 0, 4);

            startX++;
        }   
    }

    glDisableClientState( GL_VERTEX_ARRAY );            
    glDisableClientState( GL_TEXTURE_COORD_ARRAY );
}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.