PDA

View Full Version : Basic 2D car game problem



Marc Colomé
08-11-2013, 01:52 PM
I'm programming the typical 2d car game in c++ with glut and opengl and i'm trying to acommplish this:

1. Two quads (4 tris), one for the circuit, the other for the car
2. The quad of the circuit has a texture of a circuit in his top view and is static, while the quad of the car has a texture of a car in a top view too and is not static

Circuit (example) http://caterhamf1.com/previews/2013/05-spa/img/TrackMap.png
Car (example) http://img2.netcarshow.com/Ferrari-F40_1987_800x600_wallpaper_27.jpg

That more or less i know how to do it but, here's my questions:

3. The car is like a "vector", if I press UP it goes in the positive direction of his vector, if I press DOWN goes in reverse direction and if I press RIGHT or LEFT the vector rotates a few grades and growing (something like the ++ in C++)

4. Could I have a chase cam with it? So only a ceratin area will apear in the screen (where the car is, not the full map

How I could do that? I'm not asking for a complete source code, just the way of how to do it ;)

Also OpenAL website does not work, there's other option apart of OpenAL


Thank you very much!

GClements
08-11-2013, 07:07 PM
4. Could I have a chase cam with it? So only a ceratin area will apear in the screen (where the car is, not the full map
glTranslatef(-car_x, -car_y, 0) before rendering the map.

Marc Colomé
08-12-2013, 11:29 AM
Thank you!

Also how I could make to have 2 quads at the same time? I'm only able to have one

Marc Colomé
08-14-2013, 07:56 AM
anyone knows?

Carmine
08-14-2013, 01:35 PM
Post your code. I'll try it out. If it works, I'll help you.

Marc Colomé
08-16-2013, 12:04 PM
//Is a modified code from videotutorialsrock.com, the best way i found for learning OGL!

#include <iostream>
#include <stdlib.h>
#include <glut.h>

using namespace std;

//Called when a key is pressed
void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key
exit(0);
}
}

//Initializes 3D rendering
void initRendering() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL); //Enable color
glClearColor(0.7f, 0.9f, 1.0f, 1.0f); //Background color is sky blue
}

//Called when the window is resized
void handleResize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (double)w / (double)h, 0.01/*Min render distance*/, 500.0/*Max distance*/);//Meters
}

float _angle = 30.0f;
float _cameraAngle = 0.0f;

//Draws the 3D scene
void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(-_cameraAngle, 0.0f, 1.0f, 0.0f);
glTranslatef(0.0f, 0.0f, -20.0f);//I have moved the circuit and the car 20 meters under, so now
//the camera is "set" at 20 meters high than the car and the circuit



glBegin(GL_QUADS); //Ferrari
glColor3f(1.0f, 0.0f, 0.0f); //Red Ferrari
glVertex3f(-2.25f, 1.0f, 0.0f); //Meters (4,5m long per 2,25m wide)
glVertex3f(2.25f, 1.0f, 0.0f);
glVertex3f(2.25f, -1.0f, 0.0f);
glVertex3f(-2.25f, -1.0f, 0.0f);
glEnd();




glBegin(GL_QUADS); //Circuit (A big parking
glColor3f(0.2f, 0.2f, 0.2f); //Asphalt color
glVertex3f(-200.0f, 200.0f, 0.0f); //Meters
glVertex3f(200.0f, 200.0f, 0.0f);
glVertex3f(200.0f, -200.0f, 0.0f);
glVertex3f(-200.0f, -200.0f, 0.0f);
glEnd();


glutSwapBuffers();
}

void update(int value) {
_angle += 2.0f;
if (_angle > 360) {
_angle -= 360;
}

glutPostRedisplay();
glutTimerFunc(25, update, 0);
}

int main(int argc, char** argv) {
//Initialize GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(320, 240);

//Create the window
glutCreateWindow("Test");
initRendering();

//Set handler functions
glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutReshapeFunc(handleResize);

glutTimerFunc(25, update, 0); //Add a timer

glutMainLoop();
return 0;
}





What I need to do is rotate the car and then make it go foward in his direction.

I can't do it

Carmine
08-16-2013, 01:12 PM
As promised, I ran your code. The good news is that it worked.
Though I think it's a bit of a stretch to call a red rectangle a Ferrari :)


Is a modified code from videotutorialsrock.com, the best way i found for learning OGL! I don't mean to be snide, but maybe this site isn't so good if you can't figure out how to rotate a rectangle!


What I need to do is rotate the car and then make it go foward in his direction. I can't do it One thing at a time - rotating the car. I assume you want to do this interactively using a key on the keyboard. Your code only needs a few changes to do this. First add another global variable called 'rotate_car' or something similar. Let's say you want to rotate it 1.0 degs when the 'r' key is pushed once. Add a line to the 'handleKeypress' routine - something like below ...



void handleKeypress (unsigned char key, int x, int y)
{
switch (key) {
case 'r': ++rotate_car; break;
case 27: exit(0);
}
}
You can add other 'case' lines for negative rotations and translations. Next, in your 'drawScene' routine replace '-_cameraAngle' with 'rotate_car' in the glRotatef command. The glTranslatef command just below that can be used to move the car (with more global variables and 'case' commands). This should get you started.

Marc Colomé
08-16-2013, 01:17 PM
No carmine! I meant to rotate the quad and then make the quad go in the direction of the car!

See it like a vector: Rotate it and then go foward through it direction, I could rotate it but not go in the foward direction

Thank you!


Marc

Marc Colomé
08-16-2013, 01:24 PM
1109


look at this

Carmine
08-16-2013, 01:42 PM
No carmine! I meant to rotate the quad and then make the quad go in the direction of the car! Yes. That's what you said. But your code doesn't show that you know how to do even basic rotations and translations. To me the code is the truth. It is where you are at. If you can do basic rotations and translations, show it to us in the code. Explain why you are not satisfied with them. I think you'll get more responses from there. You will from me.

Marc Colomé
08-17-2013, 05:31 AM
Yes. That's what you said. But your code doesn't show that you know how to do even basic rotations and translations. To me the code is the truth. It is where you are at. If you can do basic rotations and translations, show it to us in the code. Explain why you are not satisfied with them. I think you'll get more responses from there. You will from me.

Thank you Carmine! Here you have the code:

#include <iostream>
#include <stdlib.h>
#include <glut.h>

using namespace std;

float _angle = 0.0f;//For rotating the car
float xpos = 0.0f;//For moving the car in the X axis
float ypos = 0.0f;//For moving the car in the Y axis
float cameraheight = -20.0f;//For zoom or unzoom the camera

//Called when a key is pressed
void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //ESC
exit(0);
break;

case 49: //Number 1
_angle += 5.0f;
break;

case 50: //Number 2
_angle -= 5.0f;
break;

case 51: //Number 3
cameraheight -= 5.0f;
break;

case 52: //Number 4
cameraheight += 5.0f;
break;

case 53: //Number 5
xpos += 1.0f;
break;

case 54: //Number 6
xpos -= 1.0f;
break;

case 55: //Number 7
ypos += 1.0f;
break;

case 56: //Number 8
ypos -= 1.0f;
break;

/*case 57: //Number 9

break;

case 58: //Number 0

break;*/

}
}


//Initializes 3D rendering
void initRendering() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL); //Enable color
glClearColor(0.7f, 0.9f, 1.0f, 1.0f); //Background color is sky blue
}

//Called when the window is resized
void handleResize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (double)w / (double)h, 0.01/*Min render distance*/, 1000.0/*Max distance*/);//Meters
}

//Draws the 3D scene
void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, cameraheight);//I have moved the circuit and the car 20 meters under, so now
//the camera is "set" at 20 meters high than the car and the circuit


//CAR
glPushMatrix(); //Save the transformations performed thus far
glTranslatef(xpos, ypos, 0.0f);
glRotatef(_angle, 0.0f, 0.0f, 1.0f); //Rotate about the z-axis


glBegin(GL_QUADS);
glColor3f(1.0f, 0.0f, 0.0f); //Red Ferrari
glVertex3f(-2.25f, 1.0f, 0.0f); //Meters (4,5m long per 2,25m wide)
glVertex3f(2.25f, 1.0f, 0.0f);
glVertex3f(2.25f, -1.0f, 0.0f);
glVertex3f(-2.25f, -1.0f, 0.0f);
glEnd();

glPopMatrix(); //Undo the move of the car


//CIRCUIT
glPushMatrix();
glScalef(0.25f, 0.25f, 0.25f);//25% original size

glBegin(GL_QUADS);
glColor3f(0.2f, 0.2f, 0.2f); //Asphalt color
glVertex3f(-200.0f, 200.0f, 0.0f); //Meters
glVertex3f(200.0f, 200.0f, 0.0f);
glVertex3f(200.0f, -200.0f, 0.0f);
glVertex3f(-200.0f, -200.0f, 0.0f);
glEnd();
glPopMatrix();


glutSwapBuffers();
}

void update(int value) {
if (_angle > 360) {
_angle -= 360;
}

glutPostRedisplay();
glutTimerFunc(16, update, 0);
}

int main(int argc, char** argv) {
//Initialize GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(320, 240);

//Create the window
glutCreateWindow("Test");
initRendering();

//Set handler functions
glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutReshapeFunc(handleResize);
glutTimerFunc(16, update, 0); //Add a timer

glutMainLoop();
return 0;
}











I'm not satisfied because when I rotate the car it not goes in the direction is facing, it only goes up/down/left/right. I don't know how to make it go correctly





So much thank you,

Marc

Carmine
08-17-2013, 01:28 PM
I'm not satisfied because when I rotate the car it not goes in the direction is facing, it only goes up/down/left/right. I don't know how to make it go correctly Good on you for posting your code. It compiles and runs for me. Now we can move forward. I THINK I understand what you want by the statement above. If so, you only have to make a minor change to get closer to your goal. In the line where you rotate the car in 'drawScene', try changing the Y rotation to a Z rotation (Z is perpendicular to the screen). This is done in my version of the code below. I did some minor reformatting so that it would fit my eye better. The animation is turned off to make debugging easier. The code that draws the car is put into a routine called 'Draw_Car'. Finally, I got rid of the big rectangle you call 'asphalt' and put that color in glClearColor. Note that if you use [ code] and [ /code] (without the spaces) with proper indenting. it will make your code much easier to read.


//---+----4----+----3----+----2----+----1----+---||---+----1----+----2----+----3----+----4----+---\\
//---+----4----+----3----+----2----+----1----+---||---+----1----+----2----+----3----+----4----+---\\

#include <stdio.h>
#include <stdlib.h>
#include <gl.h>
#include <glu.h>
#include <glut.h>

float _angle = 0.0f, // For rotating the car
xpos = 0.0f, // For moving the car in the X axis
ypos = 0.0f; // For moving the car in the Y axis

float cameraheight = -20.0f; // For zoom or unzoom the camera

//---+----4----+----3----+----2----+----1----+---||---+----1----+----2----+----3----+----4----+---\\
//-------------------------------------- handleKeypress -----------------------------------------

void handleKeypress (unsigned char key, int x, int y)
{
switch (key) {
case '1': _angle += 5.0f; break;
case '2': _angle -= 5.0f; break;
case '3': cameraheight -= 5.0f; break;
case '4': cameraheight += 5.0f; break;
case '5': xpos += 1.0f; break;
case '6': xpos -= 1.0f; break;
case '7': ypos += 1.0f; break;
case '8': ypos -= 1.0f; break;

case 'r': xpos = 0.0f;
ypos = 0.0f;
_angle = 0.0f;
cameraheight = -20.0f; break;

case 27: exit(0); break; // esc
}

glutPostRedisplay ();
}

//---+----4----+----3----+----2----+----1----+---||---+----1----+----2----+----3----+----4----+---\\
//--------------------------------------- initRendering ----------------------------------------

void initRendering (void)
{
glEnable (GL_DEPTH_TEST);
glEnable (GL_COLOR_MATERIAL);
glClearColor (0.2f, 0.2f, 0.2f, 1.0f);
}

//---+----4----+----3----+----2----+----1----+---||---+----1----+----2----+----3----+----4----+---\\
//--------------------------------------- handleResize -----------------------------------------

void handleResize (int w, int h)
{
glViewport (0, 0, w, h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (45.0, (double)w / (double)h, 0.01, 500.0);
}

//---+----4----+----3----+----2----+----1----+---||---+----1----+----2----+----3----+----4----+---\\
//----------------------------------------- Draw_Car -------------------------------------------

void Draw_Car (void)
{
glBegin (GL_QUADS); // Ferrari
glColor3f ( 1.0f , 0.0f, 0.0f); // Red Ferrari
glVertex3f (-2.25f, 1.0f, 0.0f); // Meters (4,5m long per 2,25m wide)
glVertex3f ( 2.25f, 1.0f, 0.0f);
glVertex3f ( 2.25f, -1.0f, 0.0f);
glVertex3f (-2.25f, -1.0f, 0.0f);
glEnd();
}

//---+----4----+----3----+----2----+----1----+---||---+----1----+----2----+----3----+----4----+---\\
//---------------------------------------- drawScene -------------------------------------------

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

glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();

// glRotatef (-_angle, 0.0f, 1.0f, 0.0f);
glRotatef (-_angle, 0.0f, 0.0f, 1.0f);
glTranslatef ( 0.0f, 0.0f, cameraheight);

glPushMatrix();
glTranslatef (xpos, ypos, 0.0f);
Draw_Car ();
glPopMatrix();

glutSwapBuffers();
}

//---+----4----+----3----+----2----+----1----+---||---+----1----+----2----+----3----+----4----+---\\
//------------------------------------------ update --------------------------------------------

void update (int value)
{
_angle += 0.1f;

if (_angle > 360 ) _angle -= 360;

glutPostRedisplay ();
glutTimerFunc (16, update, 0);
}

//---+----4----+----3----+----2----+----1----+---||---+----1----+----2----+----3----+----4----+---\\
//------------------------------------------- main ---------------------------------------------

int main (int argc, char* argv[])
{
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (640, 480);
glutInitWindowPosition (400, 200);

glutCreateWindow ("Test");
initRendering ();

glutDisplayFunc (drawScene);
glutKeyboardFunc (handleKeypress);
glutReshapeFunc (handleResize);
// glutTimerFunc (16, update, 0);

glutMainLoop ();
return 0;
}

//---+----4----+----3----+----2----+----1----+---||---+----1----+----2----+----3----+----4----+---\\

Marc Colomé
08-18-2013, 06:17 AM
Good on you for posting your code. It compiles and runs for me. Now we can move forward. I THINK I understand what you want by the statement above. If so, you only have to make a minor change to get closer to your goal. In the line where you rotate the car in 'drawScene', try changing the Y rotation to a Z rotation (Z is perpendicular to the screen). This is done in my version of the code below. I did some minor reformatting so that it would fit my eye better. The animation is turned off to make debugging easier. The code that draws the car is put into a routine called 'Draw_Car'. Finally, I got rid of the big rectangle you call 'asphalt' and put that color in glClearColor. Note that if you use [ code] and [ /code] (without the spaces) with proper indenting. it will make your code much easier to read.


//---+----4----+----3----+----2----+----1----+---||---+----1----+----2----+----3----+----4----+---\\
//---+----4----+----3----+----2----+----1----+---||---+----1----+----2----+----3----+----4----+---\\

#include <stdio.h>
#include <stdlib.h>
#include <gl.h>
#include <glu.h>
#include <glut.h>

float _angle = 0.0f, // For rotating the car
xpos = 0.0f, // For moving the car in the X axis
ypos = 0.0f; // For moving the car in the Y axis

float cameraheight = -20.0f; // For zoom or unzoom the camera

//---+----4----+----3----+----2----+----1----+---||---+----1----+----2----+----3----+----4----+---\\
//-------------------------------------- handleKeypress -----------------------------------------

void handleKeypress (unsigned char key, int x, int y)
{
switch (key) {
case '1': _angle += 5.0f; break;
case '2': _angle -= 5.0f; break;
case '3': cameraheight -= 5.0f; break;
case '4': cameraheight += 5.0f; break;
case '5': xpos += 1.0f; break;
case '6': xpos -= 1.0f; break;
case '7': ypos += 1.0f; break;
case '8': ypos -= 1.0f; break;

case 'r': xpos = 0.0f;
ypos = 0.0f;
_angle = 0.0f;
cameraheight = -20.0f; break;

case 27: exit(0); break; // esc
}

glutPostRedisplay ();
}

//---+----4----+----3----+----2----+----1----+---||---+----1----+----2----+----3----+----4----+---\\
//--------------------------------------- initRendering ----------------------------------------

void initRendering (void)
{
glEnable (GL_DEPTH_TEST);
glEnable (GL_COLOR_MATERIAL);
glClearColor (0.2f, 0.2f, 0.2f, 1.0f);
}

//---+----4----+----3----+----2----+----1----+---||---+----1----+----2----+----3----+----4----+---\\
//--------------------------------------- handleResize -----------------------------------------

void handleResize (int w, int h)
{
glViewport (0, 0, w, h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (45.0, (double)w / (double)h, 0.01, 500.0);
}

//---+----4----+----3----+----2----+----1----+---||---+----1----+----2----+----3----+----4----+---\\
//----------------------------------------- Draw_Car -------------------------------------------

void Draw_Car (void)
{
glBegin (GL_QUADS); // Ferrari
glColor3f ( 1.0f , 0.0f, 0.0f); // Red Ferrari
glVertex3f (-2.25f, 1.0f, 0.0f); // Meters (4,5m long per 2,25m wide)
glVertex3f ( 2.25f, 1.0f, 0.0f);
glVertex3f ( 2.25f, -1.0f, 0.0f);
glVertex3f (-2.25f, -1.0f, 0.0f);
glEnd();
}

//---+----4----+----3----+----2----+----1----+---||---+----1----+----2----+----3----+----4----+---\\
//---------------------------------------- drawScene -------------------------------------------

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

glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();

// glRotatef (-_angle, 0.0f, 1.0f, 0.0f);
glRotatef (-_angle, 0.0f, 0.0f, 1.0f);
glTranslatef ( 0.0f, 0.0f, cameraheight);

glPushMatrix();
glTranslatef (xpos, ypos, 0.0f);
Draw_Car ();
glPopMatrix();

glutSwapBuffers();
}

//---+----4----+----3----+----2----+----1----+---||---+----1----+----2----+----3----+----4----+---\\
//------------------------------------------ update --------------------------------------------

void update (int value)
{
_angle += 0.1f;

if (_angle > 360 ) _angle -= 360;

glutPostRedisplay ();
glutTimerFunc (16, update, 0);
}

//---+----4----+----3----+----2----+----1----+---||---+----1----+----2----+----3----+----4----+---\\
//------------------------------------------- main ---------------------------------------------

int main (int argc, char* argv[])
{
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (640, 480);
glutInitWindowPosition (400, 200);

glutCreateWindow ("Test");
initRendering ();

glutDisplayFunc (drawScene);
glutKeyboardFunc (handleKeypress);
glutReshapeFunc (handleResize);
// glutTimerFunc (16, update, 0);

glutMainLoop ();
return 0;
}

//---+----4----+----3----+----2----+----1----+---||---+----1----+----2----+----3----+----4----+---\\


Now almost perfect my friend! But the rotating center is at x=0 and y=0 everytime, it should be updated when I translate the car, because if I now rotate the car and then I translate it, it not rotates in its center of gravity, it does it around 0,0

Many thanks,

Marc

Carmine
08-19-2013, 01:35 PM
... I now rotate the car and then I translate it, it not rotates in its center of gravity, it does it around 0,0
Next - change the drawScene routine to the one I have below. The only change from the original routine is that the glRotate is moved. You'll get the same result. Now try switching the order of glRotate and glTranslate. What happens? It's important to experience this.


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

glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();

glTranslatef ( 0.0f, 0.0f, cameraheight);

// Rotation moved into Push-Pop block to make it only apply to car.
// Try code below. Then try putting glRotate after glTranslate.
// Neither way works. Something more sophisticated has to be done.

glPushMatrix();
glRotatef (-_angle, 0.0f, 0.0f, 1.0f);
glTranslatef (xpos, ypos, 0.0f);
Draw_Car ();
glPopMatrix();

glutSwapBuffers();
}