Please help with my C++ OpenGL code!
I am trying to make a simple game in OpenGL with C++ (my first). The issue I'm having is that the WSAD keys move the sphere AND the cube. Since the goal of the game is going to be to get points by placing the sphere over the cube, how would I make the sphere move all by itself? glTranslatef() is moving both at the same time, and I don't know how to tell it to move only one. Although that is my main/largest problem, I was also wondering two more things. How do I overlay text, so I could show the user the elapsed time and their score? Also, how do I make the sphere move smoothly, as opposed to going one pixel, stopping, then going again when you hold down a key? Right now I'm using SPI_SETKEYBOARDDELAY, but it's not working well at all. Thanks for all the help!
P.S.: If you provide code, could you please explain it? Also, could someone explain glutPostRedisplay, glutIdleFunc, glutMainLoop, glPushMatrix, glPopMatrix, and glutSwapBuffers? Thanks everyone!

#include <glut.h>
#include <cmath>
#include <time.h>
#include <string>
using namespace std;
 
int genrandom();
GLfloat tplayer;
GLfloat tobject;

double angle = 0;
double angleadd = 0.2;
int c = 0;
int d = 0;
int random;

void display()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glClear(GL_DEPTH_BUFFER_BIT);
    glPushMatrix(); 
    glRotatef(angle, 0, 0.5, 1);
	glColor3f (0, 0.2, 1);
    glutWireSphere(5, 10, 10);
    glPopMatrix();
	glPushMatrix();
	glTranslatef(10, 10, 0);
    glRotatef(angle, 0, 0.5, 1);
	glColor3f (1, 0, 0);
    glutWireCube(3);
    glPopMatrix();
    glutSwapBuffers();
}

int genrandom(){
srand ( time(NULL) );
random = rand() % 95 + -95;
return random;
}
 
void KeySet() { DWORD old = 0;
SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &old, 0);
SystemParametersInfo(SPI_SETKEYBOARDDELAY,0, &old, 0);
}

void keyboard(unsigned char key, int x, int y)
{
	KeySet();
    if(key == 27) exit (0);
	else if( (key == 119) && (95 > d) ){
	glTranslatef(0, 1, 0);
	d = d + 1;
	}
	else if( (key == 115) && (d > -95) ){
	glTranslatef(0, -1, 0);
	d = d - 1;
	}
	else if( (key == 97) && (c > -95) ){
	glTranslatef(-1, 0, 0);
	c = c - 1;
	}
	else if( (key == 100) && (95 > c) ){
	glTranslatef(1, 0, 0);
	c = c + 1;
	}
}

void idle()
{
    angle += angleadd;
    glutPostRedisplay();
}
 
int main (int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize (800, 800);
    glutInitWindowPosition (100, 100);
    glutCreateWindow ("Space Journey");
    glClearColor (0, 0, 0, 0);
    glColor3f (1, 1, 1);
    glEnable (GL_DEPTH_TEST);
    glMatrixMode (GL_MODELVIEW);
    glOrtho(-100, 100, -100, 100, -100, 100);
    glutDisplayFunc (display);
	glutKeyboardFunc (keyboard);
	glutIdleFunc (idle);
	glutFullScreen ();
    glutMainLoop ();
    return 0;
}

I'm only really use OpenGL ES for mobile devices, so don't quote me, but I think your keyboard procedure is the problem. You shouldn't be calling glTranslatef from inside the keyboard proc, because that one matrix will end up being applied to the entire scene. You have make your keyboard procedure store a position in the form of a vector, and then fetch that vector from your display procedure. Once you do that, then you have to fix your display procedure to have one call of glTranslatef per object in your scene(one for the cube, and one for the sphere). One of those translations of course will contain the information you stored in the vector from your keyboard procedure, and the other one will contain the world position of the cube.
example:

Vector3f spherePosition(10.0f, 5.0f, -10.0f); //initial position of sphere

void keyboard(unsigned char key, int x, int y)
{

KeySet();
if(key == 27) exit (0);
//I dont know which keycode is which letter =/
else if( (key == 119) && (95 > spherePosition[0]) )
{
  spherePosition[0] += 1;// +X
}
else if( (key == 115) && (spherePosition[0] > -95) )
{
  spherePosition[0] -= 1;// -X
}
else if( (key == 97) && (spherePosition[2] > -95) )
{
  spherePosition[2] -= 1;// -Z
}
else if( (key == 100) && (95 > spherePosition[2]) )
{
  spherePosition[2] += 1; // +Z
}

}


void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glPushMatrix(); //store the active matrix so that we can use ours

glTranslatef(spherePosition[0], spherePosition[1], spherePosition[2]);
glColor3f (0, 0.2, 1);
glutWireSphere(5, 10, 10);

glTranslatef(10, 0, -10);
glRotatef(angle, 0, 0.5, 1);
glColor3f (1, 0, 0);
glutWireCube(5);

glPopMatrix(); //put things back the way they were when we are done
glutSwapBuffers();
}

I think that should do it...someone correct me if I'm wrong here =D

Edited 6 Years Ago by VBNick: n/a

I get this error:

1>f:\stuff\opengl_2dgame.cpp(23) : error C2065: 'spherePosition' : undeclared identifier

did you put this:

Vector3f spherePosition(10.0f, 5.0f, -10.0f);

at the top of your project in the general declarations?
right under

int random;

or something

Now I'm getting new errors:

1>f:\stuffopengl_2dgame.cpp(7) : error C2078: too many initializers

AND

1>f:\stuff\opengl_2dgame.cpp(22) : error C2109: subscript requires array or pointer type

can you repost the whole file opengl_2dgame.cpp?

Edited 6 Years Ago by VBNick: n/a

#include <glut.h>
#include <cmath>
#include <time.h>
#include <string>
using namespace std;

Vector3f spherePosition(10.0f, 5.0f, -10.0f);
int genrandom();
GLfloat tplayer;
GLfloat tobject;

double angle = 0;
double angleadd = 0.2;
int c = 0;
int d = 0;
int random;

void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(spherePosition[0], spherePosition[1], spherePosition[2]);
glColor3f (0, 0.2, 1);
glutWireSphere(5, 10, 10);
glTranslatef(10, 0, -10);
glRotatef(angle, 0, 0.5, 1);
glColor3f (1, 0, 0);
glutWireCube(5);
glPopMatrix();
glutSwapBuffers();
}

int genrandom(){
srand ( time(NULL) );
random = rand() % 95 + -95;
return random;
}

void KeySet() { DWORD old = 0;
SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &old, 0);
SystemParametersInfo(SPI_SETKEYBOARDDELAY,0, &old, 0);
}

void keyboard(unsigned char key, int x, int y)
{
if(key == 27) exit (0);
else if( (key == 119) && (95 > spherePosition[0]) )
{
  spherePosition[0] += 1;// +X
}
else if( (key == 115) && (spherePosition[0] > -95) )
{
  spherePosition[0] -= 1;// -X
}
else if( (key == 97) && (spherePosition[2] > -95) )
{
  spherePosition[2] -= 1;// -Z
}
else if( (key == 100) && (95 > spherePosition[2]) )
{
  spherePosition[2] += 1; // +Z
}
}

void idle()
{
    angle += angleadd;
    glutPostRedisplay();
}

int main (int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize (800, 800);
    glutInitWindowPosition (100, 100);
    glutCreateWindow ("Space Journey");
    glClearColor (0, 0, 0, 0);
    glColor3f (1, 1, 1);
    glEnable (GL_DEPTH_TEST);
    glMatrixMode (GL_MODELVIEW);
    glOrtho(-100, 100, -100, 100, -100, 100);
    glutDisplayFunc (display);
    glutKeyboardFunc (keyboard);
    glutIdleFunc (idle);
    glutFullScreen ();
    glutMainLoop ();
    return 0;
}

Edited 3 Years Ago by mike_2000_17: Fixed formatting

These are the errors I'm getting:

1>------ Build started: Project: OpenGL_2DGame, Configuration: Debug Win32 ------
1>Compiling...
1>OpenGL_2DGame.cpp
1>f:\stuff\home\computer stuff\code\c++\new c++\opengl_2dgame\opengl_2dgame\opengl_2dgame.cpp(7) : error C2146: syntax error : missing ';' before identifier 'spherePosition'
1>f:\stuff\home\computer stuff\code\c++\new c++\opengl_2dgame\opengl_2dgame\opengl_2dgame.cpp(7) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>f:\stuff\home\computer stuff\code\c++\new c++\opengl_2dgame\opengl_2dgame\opengl_2dgame.cpp(7) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>f:\stuff\home\computer stuff\code\c++\new c++\opengl_2dgame\opengl_2dgame\opengl_2dgame.cpp(7) : error C2078: too many initializers
1>f:\stuff\home\computer stuff\code\c++\new c++\opengl_2dgame\opengl_2dgame\opengl_2dgame.cpp(22) : error C2109: subscript requires array or pointer type
1>f:\stuff\home\computer stuff\code\c++\new c++\opengl_2dgame\opengl_2dgame\opengl_2dgame.cpp(22) : error C2109: subscript requires array or pointer type
1>f:\stuff\home\computer stuff\code\c++\new c++\opengl_2dgame\opengl_2dgame\opengl_2dgame.cpp(22) : error C2109: subscript requires array or pointer type
1>f:\stuff\home\computer stuff\code\c++\new c++\opengl_2dgame\opengl_2dgame\opengl_2dgame.cpp(23) : warning C4305: 'argument' : truncation from 'double' to 'GLfloat'
1>f:\stuff\home\computer stuff\code\c++\new c++\opengl_2dgame\opengl_2dgame\opengl_2dgame.cpp(47) : error C2109: subscript requires array or pointer type
1>f:\stuff\home\computer stuff\code\c++\new c++\opengl_2dgame\opengl_2dgame\opengl_2dgame.cpp(49) : error C2109: subscript requires array or pointer type
1>f:\stuff\home\computer stuff\code\c++\new c++\opengl_2dgame\opengl_2dgame\opengl_2dgame.cpp(51) : error C2109: subscript requires array or pointer type
1>f:\stuff\home\computer stuff\code\c++\new c++\opengl_2dgame\opengl_2dgame\opengl_2dgame.cpp(53) : error C2109: subscript requires array or pointer type
1>f:\stuff\home\computer stuff\code\c++\new c++\opengl_2dgame\opengl_2dgame\opengl_2dgame.cpp(55) : error C2109: subscript requires array or pointer type
1>f:\stuff\home\computer stuff\code\c++\new c++\opengl_2dgame\opengl_2dgame\opengl_2dgame.cpp(57) : error C2109: subscript requires array or pointer type
1>f:\stuff\home\computer stuff\code\c++\new c++\opengl_2dgame\opengl_2dgame\opengl_2dgame.cpp(59) : error C2109: subscript requires array or pointer type
1>f:\stuff\home\computer stuff\code\c++\new c++\opengl_2dgame\opengl_2dgame\opengl_2dgame.cpp(61) : error C2109: subscript requires array or pointer type
1>Build log was saved at "file://f:\Stuff\Home\Computer Stuff\Code\C++\New C++\OpenGL_2DGame\OpenGL_2DGame\Debug\BuildLog.htm"
1>OpenGL_2DGame - 15 error(s), 1 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

sorry =/
my fault.
Vector3f spherePosition(10.0f, 5.0f, -10.0f);
should be
Vector3f spherePosition = Vector3f(10.0f, 5.0f, -10.0f);


I also didn't realize you intended this to be 2D =/
so you'll have to switch the axes around in there to your liking.

Edited 6 Years Ago by VBNick: n/a

Thanks for all your help, VBNick!
I got it working.

Here's my final code:

#include <glut.h>
#include <cmath>
#include <time.h>
#include <string>
using namespace std;
 
int genrandom();
GLfloat tplayer;
GLfloat tobject;

double angle = 0;
double angleadd = 0.2;
int c = 0;
int d = 0;
int random;

void display()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glClear(GL_DEPTH_BUFFER_BIT);
    glPushMatrix(); 
	glTranslatef(c, d, 0);
    glRotatef(angle, 0, 0.5, 1);
	glColor3f (0, 0.2, 1);
    glutWireSphere(5, 10, 10);
    glPopMatrix();
	glPushMatrix();
	glTranslatef(10, 10, 0);
    glRotatef(angle, 0, 0.5, 1);
	glColor3f (1, 0, 0);
    glutWireCube(3);
    glPopMatrix();
    glutSwapBuffers();
}

int genrandom(){
srand ( time(NULL) );
random = rand() % 95 + -95;
return random;
}
 
void KeySet() { DWORD old = 0;
SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &old, 0);
SystemParametersInfo(SPI_SETKEYBOARDDELAY,0, &old, 0);
}

void keyboard(unsigned char key, int x, int y)
{
	KeySet();
    if(key == 27) exit (0);
	else if( (key == 119) && (95 > d) ){
	d = d + 1;
	}
	else if( (key == 115) && (d > -95) ){
	d = d - 1;
	}
	else if( (key == 97) && (c > -95) ){
	c = c - 1;
	}
	else if( (key == 100) && (95 > c) ){
	c = c + 1;
	}
}

void idle()
{
    angle += angleadd;
    glutPostRedisplay();
}
 
int main (int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize (800, 800);
    glutInitWindowPosition (100, 100);
    glutCreateWindow ("Space Journey");
    glClearColor (0, 0, 0, 0);
    glColor3f (1, 1, 1);
    glEnable (GL_DEPTH_TEST);
    glMatrixMode (GL_MODELVIEW);
    glOrtho(-100, 100, -100, 100, -100, 100);
    glutDisplayFunc (display);
	glutKeyboardFunc (keyboard);
	glutIdleFunc (idle);
	glutFullScreen ();
    glutMainLoop ();
    return 0;
}
This question has already been answered. Start a new discussion instead.