0
\$\begingroup\$

I'm trying to make a basic snake game with OpenGL. I hold all the game object locations in a matrix called MAP. And when i render them, i operate the location info from MAP (that comes as x and y [0 < x < 40 and 0 < y < 20]) so that i can use it in the glTranslatef().

I use the same equation for all objects. Snake's head is rendering correctly and can be move to anywhere in the screen but tails and bait are only rendering to half of the screen. Here's the code:

void SetLocationE()
{
    glLoadIdentity();
    glTranslatef(-11.5f, -8.125f, .0f);
}

void ScreenBuffer::RenderToScreen(GLvoid)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    /* DRAW */
    for (int i = 0; i < 20; i++)
    {
        for (int j = 0; j < 40; j++)
        {
            
            if (MAP[i][j] == 'x')
            {
                SetLocationE();
                bx = j;
                by = i;
                /* BAIT */
                bxx = bx * 23 / 40;
                byy = by * 16.25 / 40;
                glTranslatef(bxx, byy, zet);
                glBegin(GL_QUADS);
                //painting
                glColor3f(0.0f, 0.0f, 0.0f);
                //drawing  TOP RIGHT -> TOP LEFT
                //         -> BOTTOM LEFT -> BOTTOM RIGHT
                glVertex3f(0.15f, 0.15f, .0f);  //tr
                glVertex3f(-0.15f, 0.15f, .0f);  //tl
                glVertex3f(-0.15f, -0.15f, .0f);  //bl
                glVertex3f(0.15f, -0.15f, .0f);  //br
                glEnd();

            }

            else if (MAP[i][j] == '0')
            {
                SetLocationE();
                hx = j;
                hy = i;
                /* HEAD */
                hxx = hx * 23 / 40;
                hyy = hy * 16.25 / 20;
                glTranslatef(hxx, hyy, zet);
                glBegin(GL_QUADS);
                //painting
                glColor3f(0.0f, 0.3f, 0.1f);
                //drawing  TOP RIGHT -> TOP LEFT
                //         -> BOTTOM LEFT -> BOTTOM RIGHT
                glVertex3f(0.15f, 0.15f, .0f);  //tr
                glVertex3f(-0.15f, 0.15f, .0f);  //tl
                glVertex3f(-0.15f, -0.15f, .0f);  //bl
                glVertex3f(0.15f, -0.15f, .0f);  //br
                glEnd();
            }

            else if (MAP[i][j] == 'o')
            {
                SetLocationE();
                /* TAIL */
                txx = j * 23 / 40;
                tyy = i * 16.25 / 40;
                glTranslatef(txx, tyy, zet);
                glBegin(GL_QUADS);
                //painting
                glColor3f(0.0f, 0.7f, 0.2f);
                //drawing  TOP RIGHT -> TOP LEFT
                //         -> BOTTOM LEFT -> BOTTOM RIGHT
                glVertex3f(0.15f, 0.15f, .0f);  //tr
                glVertex3f(-0.15f, 0.15f, .0f);  //tl
                glVertex3f(-0.15f, -0.15f, .0f);  //bl
                glVertex3f(0.15f, -0.15f, .0f);  //br
                glEnd();

            }
        }
    }
}

Moving of the head is correct. When out of borders, it reappears again. Same thing is available for the tails but they reappear if they are at the horizontally half line. Tails and bait is rendering between red lines:

enter image description here

It was a console game at first. Now i'm trying to implement OpenGL to the old codes. I don't know what causes this. Thanks in advance.

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

I think you have a typo in these lines (BAIT and TAILS), it should be divided by 20 instead of 40 (HEAD divides y by 20). That explains why they are shown only on the bottom half of the screen.

byy = by * 16.25 / 40;    // should be 20.0 instead of 40

tyy = i * 16.25 / 40;     // should be 20.0 instead of 40

Also you are doing integer divisions in the same lines. Use 40.0 instead of 40 to force a float division

/* BAIT */
bxx = bx * 23 / 40.0;
byy = by * 16.25 / 20.0;

/* HEAD */
hxx = hx * 23 / 40.0;
hyy = hy * 16.25 / 20.0;

/* TAIL */
txx = j * 23 / 40.0;
tyy = i * 16.25 / 20.0;

Also you can extract the drawing of the quad to another function, because it is the same code.

void SetLocationE()
{
    glLoadIdentity();
    glTranslatef(-11.5f, -8.125f, .0f);
}  

void ScreenBuffer::drawQuad(int column, int row, float r, float g, float b) 
{
    // Draw quad
    SetLocationE();
    float x = column * 23.0 / 40.0;
    float y = row * 16.25 / 20.0;
    glTranslatef(x, y, zet);
    glBegin(GL_QUADS);
    //painting
    glColor3f(r, g, b);            
    //drawing  TOP RIGHT -> TOP LEFT
    //         -> BOTTOM LEFT -> BOTTOM RIGHT
    glVertex3f(0.15f, 0.15f, .0f);  //tr
    glVertex3f(-0.15f, 0.15f, .0f);  //tl    
    glVertex3f(-0.15f, -0.15f, .0f);  //bl    
    glVertex3f(0.15f, -0.15f, .0f);  //br
    glEnd();
}

void ScreenBuffer::RenderToScreen(GLvoid)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    /* DRAW */
    for (int i = 0; i < 20; i++)  // Y [0-20]
    {
        for (int j = 0; j < 40; j++)  // X [0-40]
        {
            // select color            
            if (MAP[i][j] == 'x') { 
                 drawQuad(j, i, 0.0f, 0.0f, 0.0f); 
            }
            else if (MAP[i][j] == '0') 
            { 
                drawQuad(j, i, 0.0f, 0.3f, 0.1f); 
            }
            else if (MAP[i][j] == 'o') 
            { 
                drawQuad(j, i, 0.0f, 0.7f, 0.2f); 
            }
        }
    }
}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Thank you! It was clearly a rookie mistake. And drawQuad() is really helpful, only it must take 6 parameters (r,g,b,x,y,z). Thanks again! \$\endgroup\$
    – anbvy
    Jul 27, 2022 at 11:45
  • \$\begingroup\$ Welcome! yes it needs at least the i,j. I'll include them in the answer. \$\endgroup\$
    – gotanod
    Jul 27, 2022 at 11:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .