PDA

View Full Version : Problem in my first openGL game [Snake]



nolfolk
03-10-2009, 11:56 PM
Hi everyone. I'm new in this forum, also, in "openGL world".

I made this simple game in like 2 days programming, its a Snake game, very simple, in 2D, openGL with C++. Its WORKING OK.

BUT, my FPS counter:



void getFPS(){
char tmp_str[40];

if( GetTickCount() - g_dwLastFPS >= 1000 ) // When A Second Has Passed...
{
g_dwLastFPS = GetTickCount(); // Update Our Time Variable
g_nFPS = g_nFrames; // Save The FPS
g_nFrames = 0; // Reset The FPS Counter
}
g_nFrames++;

glRasterPos2f(140, 10);
sprintf(tmp_str, "FPS: %d", g_nFPS);
Escreve(tmp_str);
}


Says me that the game is running at 8FPS in lvl 1 and at lvl 15 it goes to 32FPS.

I THINK that's because the glutPostRedisplay() is insite of a glutTimerFunc function, that updates every "140-lvl*8" (on harder levels, its going to update faster)

Well... If i put the glutPostRedisplay in the end of the glutDisplayFunc function, the game gots an strange bug ... its like... A shadow keeps following the Snake, really annoying!

I don't know if I made myself clear, but PLEASE help this begginer if you can :)

(Ask me if you need more information, I can post the hole code here if its necessary).

Thank You.

Rosario Leonardi
03-11-2009, 02:31 AM
An higher fps is not synonymous of better game.
In this case, the game is really simple and if you don't have any animation effect that need to be updated frequently you don't need an high fps. :)

If you want an higher fps you can setup the timer for an higher speed and your draw function should be something like that.


myDrawFun(){
if(elapseTime > levelTime(currentLevel){
updateSnakePosition();
}
drawScene();
}

but... in your case you will draws the same image multiple times


that updates every "140-lvl*8"
What will happens at level 18? :D

nolfolk
03-11-2009, 08:52 AM
Hmm... Ok, "An higher fps is not synonymous of better game.", you said. But I was thinking like... And if I got an enemy, that "runs" faster then my snake? I'll have to update the screen faster, see ? but if I do that, I'll got that "shadow" problem I said before.

Maybe with that code you writed I can solve the problem, I'll check it.

Oh, the MAX LVL is 15 ;) don't worry about it haha!

nolfolk
03-11-2009, 10:53 AM
Ok, I've tryied with your code. Kinda worked :D But now the snake blinks :(

I think its because I "repaint" the scenario, look what I did:



fJogo(); // Updates the background ( scenario )
if(update){ // if is ready to update ( like your elapseTime > levelTime(currentLevel) )
updateCobrinha(); // Updates the Snake
update = false; // Set update as false, so waits for next update
}

getFPS();

// Updates Screen
glutPostRedisplay();
glutSwapBuffers();

And when I do THAT, all the screen blinks:




if(update){ // if is ready to update ( like your elapseTime > levelTime(currentLevel) )
fJogo(); // Updates the background ( scenario )
updateCobrinha(); // Updates the Snake
update = false; // Set update as false, so waits for next update
}

getFPS();

// Updates Screen
glutPostRedisplay();
glutSwapBuffers();


Any suggestion ? :S There's a way to update JUST something on the screen, leting all the other stuff as they are ?

Rosario Leonardi
03-11-2009, 06:00 PM
Are you sure that you are drawing the snake every frame?
If you draw the background or you clear the frame buffer then you have to draw the snake too.

nolfolk
03-11-2009, 06:20 PM
~ SOLVED ~

True: I was not drawing the snake every frame ;P "Newbie error" hahaha!

Thanks for your help, now my work is completed :D Its kinda simple... There's no Oriented Programming on it, no sounds, no texturing, the snake only grows 40 "squares"... But it was just for test, I'm glad I made it :D

Thanks again! I'll put the whole code here in my next post, maybe it can help someone :)

nolfolk
03-11-2009, 06:23 PM
DEVELOPED WITH: DEV-C++ 4.9.9.2
Linker Parametres: -lglut32 -lglu32 -lopengl32 -lwinmm -lgdi32
O.S. : Windows XP
Final .exe : 246Kb
Lines : 292
Original language : Brazilian Portuguese ( thats why the comments are in portuguese )

Project: Cobrinha.dev
main.cpp


#include <stdio.h>
#include <time.h>
#include <windows.h>
#include <gl/glut.h>

#define CIMA 1
#define BAIXO 2
#define ESQUERDA 3
#define DIREITA 4

// Variaveis de status
GLint lvl = 1;
GLint bComidas = 0;
GLint tamanho = 0;
GLbyte gameOver = true;

// Variaveis da cobrinha
GLint corpoPos[2][40] = {{}};
GLint _x = 10;
GLint _y = 20;
GLint _oldX[2] = {};
GLint _oldY[2] = {};
GLbyte direcao = 0;

// Variaveis da comidinha
GLint _bx = 0;
GLint _by = 0;

// Variaveis da tela
GLint _w = 400;
GLint _h = 350;
GLint _Giw = 10;
GLint _Gih = 30;
GLint _Gfw = 270;
GLint _Gfh = 240;

// Variaveis para verificação de FPS
DWORD g_dwLastFPS = 0;
int g_nFPS = 0, g_nFrames = 0;

// Variaveis do mouse
//GLint Tx = 0;
//GLint Ty = 0;

void resetaJogo(){
_x = 10;
_y = 20;
direcao = 0;
lvl = 1;
bComidas = 0;
tamanho = 0;
gameOver = false;
}

void Escreve(char *string){
while(*string)
glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *string++);
}

void fTitulo(){
char tmp_str[40];

// Titulo
glColor3f(0, 0, 0);
glRectf(_Giw, _Gih, _Gfw, _Gfh);
glColor3f(1, 1, 1);
glRasterPos2f(85, 210);
Escreve("Jogo da Cobrinha");

glColor3f(.4, .4, .4);
glRectf(65, 180, 200, 195);
glColor3f(1, 1, 1);
glRasterPos2f(105, 185);
Escreve("Novo jogo");

// Mouse
/*
glColor3f(0, 0, 0);
glRasterPos2f(10, 10);
sprintf(tmp_str, "x: %d, y: %d", Tx, Ty);
Escreve(tmp_str);
*/
}

void updateCobrinha(){
int i;

// Cobrinha
// Cabeça
glPushMatrix();
glTranslatef(_x,_y,0.0);
glColor3f(1, 0, 0);
glRectf(10.0f, 10.0f, 20.0f, 20.0f);
glPopMatrix();

// Corpo
for(i=0; i<tamanho; i++){
glPushMatrix();
glTranslatef(corpoPos[0][i],corpoPos[1][i],0.0);
glColor3f(1, 0, 0);
glRectf(10.0f, 10.0f, 20.0f, 20.0f);
glPopMatrix();
}
}

void fJogo(){
char tmp_str[40];

// Fundo do jogo
glColor3f(0, 0, 0);
glRectf(_Giw, _Gih, _Gfw, _Gfh);

// Comidinha
glPushMatrix();
glTranslatef(_bx,_by,0.0);
glColor3f(1, 1, 0);
glRectf(10.0f, 10.0f, 20.0f, 20.0f);
glPopMatrix();

// Status
glColor3f(0, 0, 0);
glRasterPos2f(10, 10);
sprintf(tmp_str, "Lvl: %d Pts: %d", lvl, bComidas);
Escreve(tmp_str);
// Comentado: Status da posição X e Y
//glRasterPos2f(10, 10);
//sprintf(tmp_str, "Pos X: %d Pos Y: %d", _x, _y);
//Escreve(tmp_str);
}

int RandomNumber(int high, int low)
{
return (rand() % (high-low))+low;
}

void novaBolinha(){
time_t seconds;
time(&amp;seconds);
srand((unsigned int) seconds);
_bx = RandomNumber(_Gfw/10-_Giw, _Giw/10+1);
_bx = _bx*10;
_by = RandomNumber(_Gfh/10-_Gih, _Gih/10+1);
_by = _by*10;
}

bool colisao(){
int i;

for(i=0; i<tamanho; i++){
if(corpoPos[0][i] == _x &amp;&amp; corpoPos[1][i] == _y) return true;
}
return false;
}

void go(int value){
int i;

_oldX[1] = _x;
_oldY[1] = _y;
switch(direcao){
case DIREITA:
_x += 10;
if(_x > _Gfw-20) _x = _Giw-10;
break;
case ESQUERDA:
_x -= 10;
if(_x < 0) _x = _Gfw-20;
break;
case CIMA:
_y += 10;
if(_y > _Gfh-20) _y = _Gih-10;
break;
case BAIXO:
_y -= 10;
if(_y < 20) _y = _Gfh-20;
break;
}

if(colisao()) gameOver = true;

if(_x == _bx &amp;&amp; _y == _by){
bComidas++;
if(bComidas < 40) tamanho++;
if(bComidas%5 == 0 &amp;&amp; lvl < 15) lvl++;
novaBolinha();
}

for(i = 0; i<tamanho; i++){
_oldX[0] = _oldX[1];
_oldY[0] = _oldY[1];
_oldX[1] = corpoPos[0][i];
_oldY[1] = corpoPos[1][i];
corpoPos[0][i] = _oldX[0];
corpoPos[1][i] = _oldY[0];
}

glutTimerFunc(140-lvl*8, go, 0);
}

void getFPS(){
char tmp_str[40];

if( GetTickCount() - g_dwLastFPS >= 1000 ) // When A Second Has Passed...
{
g_dwLastFPS = GetTickCount(); // Update Our Time Variable
g_nFPS = g_nFrames; // Save The FPS
g_nFrames = 0; // Reset The FPS Counter
}
g_nFrames++;

glRasterPos2f(140, 10);
sprintf(tmp_str, "FPS: %d", g_nFPS);
Escreve(tmp_str);
}

void Desenha(void){
// Limpa tela
glClear(GL_COLOR_BUFFER_BIT);

if(!gameOver){
fJogo();
updateCobrinha();
}
else
fTitulo();

getFPS();

// Atualiza a tela
glutPostRedisplay();
glutSwapBuffers();
}

void teclado(int key, int x, int y){
switch(key){
case GLUT_KEY_RIGHT :
if(direcao != ESQUERDA)
direcao = DIREITA;
break;
case GLUT_KEY_LEFT :
if(direcao != DIREITA)
direcao = ESQUERDA;
break;
case GLUT_KEY_UP :
if(direcao != BAIXO)
direcao = CIMA;
break;
case GLUT_KEY_DOWN :
if(direcao != CIMA)
direcao = BAIXO;
break;
}
}

void mouse(int botao, int estado, int x, int y){
if(estado == GLUT_UP &amp;&amp; x > 90 &amp;&amp; x < 280 &amp;&amp; y > 80 &amp;&amp; y < 100)
resetaJogo();

// Tx = x;
// Ty = y;
}

void Inicializa (void){
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
}

void AlteraTamanhoJanela(GLsizei w, GLsizei h){
glViewport(0, 0, _w, _h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
gluOrtho2D (0.0f, 250.0f, 0.0f, 250.0f*_h/_w);
else
gluOrtho2D (0.0f, 250.0f*_w/_h, 0.0f, 250.0f);
}

int main(void){
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(_w,_h);
glutInitWindowPosition(500,400);
glutCreateWindow("Jogo da cobrinha");
glutSpecialFunc(teclado);
glutDisplayFunc(Desenha);
glutReshapeFunc(AlteraTamanhoJanela);
glutMouseFunc(mouse);

novaBolinha();
go(0);

Inicializa();
glutMainLoop();
}



BUGS THAT I JUST REALIZED:
* If you press quickly up and left when you'r going right, you die. :(
* Some foods seems to appear bellow the snake sometimes

Bimboi
09-28-2010, 07:13 PM
hi...

could someone help me..
i am new to openGl..

and i got a problem here..

i would like to have a triangle shape that would run..and when i press 'w' it would run upwards and when i press 's' it would run downwards..and when i press 'd' it would run to the right and when i press 'a' it would run to the left..

please help me....
badly needed it..

BionicBytes
09-29-2010, 07:23 AM
No you don't have a problem here. You have some reading to do and when you actually have something written and you actually have an issue with that (relating to OpenGL), then post a specific question with detail as to what the issue actually is and give as much information as possible.
Asking questions like "how do I program?", or "how to write a game?" is just going to get ignored because nobody has the time to write something for you.

ZbuffeR
09-29-2010, 08:37 AM
@Bimboi : I will add that it is particularly not interesting to produce code for someone else's homework. And you should have created your own topic anyway. But no need to do that yet, as said BionicBytes, first go search some basic OpenGL tutorials, then ask questions once you have something working.