Tuesday, May 24, 2011

CAR Game part-1




Hi,
Here I come with yet another game.
This one came out rather too quickly as I had most of the functions already written and tested. :-) This is the game which i used to play in the video parlour, that was fun back then. well, Now there is fun in developing it.






#include "stdafx.h"

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

#include <GL/glut.h>

#include "imageloader.h"
#include "math.h"

using namespace std;

const int MAX_X=1200;
const int MAX_Y=900;
const int MIN_X=0;
const int MIN_Y=0;

int car_x = MAX_X/4;
int car_y = MAX_Y;


int car_width=100;
int car_length=200;
int rx = MAX_X/4;
int ry = MAX_Y;
int road_width = 420;
int path_width = 20;
int lane_distance = car_width+40;
int car_max_x = (car_x+path_width) + lane_distance;
int car_min_x = MAX_X/4;

int car_cnt = 1;
GLuint _textureId; //The id of the texture
GLuint _textureId1; //The id of the texture
GLuint _textureId2; //The id of the texture
GLuint _textureId3; //The id of the texture

GLuint current_textureId; //The id of the texture

int timedelay = 100;
void draw_car(int length,int width,int x, int y);

int move_cnt=0;

typedef struct vehicle {
int x,y;
int length,width;
int texture_id;
struct vehicle* next;
}VEHICLE;

VEHICLE *head=NULL;
int current_y=0;

void create_vehicles() {
int rand_x = 0;

if(current_y>car_length) {
current_y = -200;
} else {
return;
}
// Create a new vehicle;
VEHICLE* temp = new VEHICLE;
temp->length = car_length;
temp->width = car_width;
temp->next = NULL;
temp->x = car_x+path_width;
temp->y = current_y;
if(car_cnt==1) {
temp->texture_id = _textureId1;
} else if(car_cnt==2) {
temp->texture_id = _textureId2;
} else if(car_cnt==3) {
temp->texture_id = _textureId3;
}

car_cnt++;
if(car_cnt==4) car_cnt = 1;

// Add it to the list
if(!head) {
head = temp;
} else {
VEHICLE* t = head;
while(t->next) {
t = t->next;
}
t->next = temp;
}
}

void draw_vehicles() {

VEHICLE* temp = head;
while(temp) {

int car_width = temp->width;
int car_length = temp->length;
int car_x = temp->x;
int car_y = temp->y;
current_textureId = temp->texture_id;
draw_car(car_width,car_length,car_x,car_y);

temp = temp->next;
}
}

void move_vehicles() {
VEHICLE* temp = head;
while(temp) {
temp->y = temp->y+10;
temp = temp->next;
}
current_y+=10;
}
void drawScene();

void *font = GLUT_BITMAP_TIMES_ROMAN_24;
void *fonts[] =
{
GLUT_BITMAP_9_BY_15,
GLUT_BITMAP_TIMES_ROMAN_10,
GLUT_BITMAP_TIMES_ROMAN_24
};


void specialKey(int key, int x, int y) {
switch (key) {
case 101: //UP arrow key
if(timedelay>0){
timedelay-=10;
}

break;
case 103: //DOWN arrow key
if(timedelay<500){
timedelay+=10;
}
break;

case 100: //LEFT arrow key
if(car_x>MAX_X/4){
car_x-=car_width;
}
break;

case 102: //RIGHT arrow key
if(car_x<(MAX_X/4-car_width+400)){
car_x+=car_width;
}
break;

}
}

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

void output(int x, int y, char *string)
{
int len, i;

glRasterPos2f(x, y);
len = (int) strlen(string);
for (i = 0; i < len; i++) {
glutBitmapCharacter(font, string[i]);
}
}

//Makes the image into a texture, and returns the id of the texture
GLuint loadTexture(Image* image) {
GLuint textureId;
glGenTextures(1, &textureId); //Make room for our texture
glBindTexture(GL_TEXTURE_2D, textureId); //Tell OpenGL which texture to edit
//Map the image to the texture
glTexImage2D(GL_TEXTURE_2D, //Always GL_TEXTURE_2D
0, //0 for now
GL_RGB, //Format OpenGL uses for image
image->width, image->height, //Width and height
0, //The border of the image
GL_RGB, //GL_RGB, because pixels are stored in RGB format
GL_UNSIGNED_BYTE, //GL_UNSIGNED_BYTE, because pixels are stored
//as unsigned numbers
image->pixels); //The actual pixel data
return textureId; //Returns the id of the texture
}



void initRendering() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LINE_STIPPLE);
glLineWidth(4);
Image* image = loadBMP("car3.bmp");
_textureId = loadTexture(image);
delete image;

image = loadBMP("car4.bmp");
_textureId1 = loadTexture(image);
delete image;

image = loadBMP("car5.bmp");
_textureId2 = loadTexture(image);
delete image;

image = loadBMP("car6.bmp");
_textureId3 = loadTexture(image);
delete image;

}

void handleResize(int w, int h) {
/*glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (float)w / (float)h, 1.0, 200.0);*/

glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, w, h, 0);
glMatrixMode(GL_MODELVIEW);
}

void draw_lanes() {

glLineStipple(1,0x00ff);
glBegin(GL_LINES);

for(int i=1; i<=3;i++) {
glVertex3f(rx+path_width+car_width*i, MAX_Y, 0);
glVertex3f(rx+path_width+car_width*i, 0, 0);
}

glEnd();

glLineStipple(1,0xffff);
}

void draw_footpath(int x,int y,int path_width) {
int cnt=25;
int bwidth = path_width-2;
int bheight = 40;
int yy=y;
int xx=x+2;

// Blocks on the foot path
for(int i=0; i<cnt; i++) {
glBegin(GL_POLYGON);
glVertex3f(xx,yy,0);
glVertex3f(xx+bwidth,yy,0);
glVertex3f(xx+bwidth,yy+bheight,0);
glVertex3f(xx,yy+bheight,0);
glEnd();
yy+=2*bheight;
}
}

void create_road() {

glColor3f(1.0f, 1.0f, 1.0f);

ry = MAX_Y;
// Lines on the side
glBegin(GL_LINES);
glVertex3f(rx, ry, 0);
glVertex3f(rx, 0, 0);
glVertex3f(rx+path_width, ry, 0);
glVertex3f(rx+path_width, 0, 0);

glVertex3f(rx+road_width, ry, 0);
glVertex3f(rx+road_width, 0, 0);
glVertex3f(rx+path_width+road_width, ry, 0);
glVertex3f(rx+path_width+road_width, 0, 0);

glEnd();

ry=-200;
move_cnt ++;
if (move_cnt==8) {
move_cnt = 0;
}
ry = ry + 10*move_cnt;

// Draw footpath on both the sides of the road
draw_footpath(rx,ry,path_width);
draw_footpath(rx+road_width,ry,path_width);

// Draw the lanes in the road
draw_lanes();

}

void draw_car(int length,int width,int x, int y) {

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, current_textureId);

//Bottom
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glColor3f(0.0f, 0.1f, 0.1f);

glBegin(GL_QUADS);

glTexCoord2f(0.0f, 0.0f);
glVertex3f(x, y, 0);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(x+length,y,0);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(x+length,y-width,0);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(x,y-width,0);

glEnd();

glBindTexture(GL_TEXTURE_2D,0);
}

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

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

GLfloat ambientLight[] = {0.2f, 0.2f, 0.2f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);

GLfloat directedLight[] = {0.7f, 0.7f, 0.7f, 1.0f};
GLfloat directedLightPos[] = {-10.0f, 15.0f, 20.0f, 0.0f};
glLightfv(GL_LIGHT0, GL_DIFFUSE, directedLight);
glLightfv(GL_LIGHT0, GL_POSITION, directedLightPos);

// Show the X and Y coordinate location of the mouse
glClear(GL_COLOR_BUFFER_BIT);

// Draw the main racing
current_textureId = _textureId;
draw_car(car_width,car_length,car_x+path_width,car_y);

// Create a road
create_road();

// Create new vehicle
create_vehicles();

// Move vehicles
move_vehicles();

// Draw the vehicles
draw_vehicles();

glutSwapBuffers();
}

//Called every 25 milliseconds
void update(int value) {

drawScene();

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

int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(MAX_X, MAX_Y);

glutCreateWindow("Car Game");
initRendering();

glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutSpecialFunc(specialKey);

glutReshapeFunc(handleResize);
glutTimerFunc(timedelay , update, 0);

glutMainLoop();
return 0;
}


2 comments:

  1. Dear Girish Lande,

    I'm trying to run the following two games from your blog:

    Brick Game part1
    CAR Game part-1

    I'm learning OpenGL (only new to it) and wondered if you had the relevant imageloader.h and .bmp files for the textures for the two games?

    Any help much appreciated.

    Thanks

    David Jones
    dj4487169@gmail.com

    ReplyDelete
  2. Dear Girish Lande,

    I'm also wondered to have access to your source code (including the imageloader.h and .bmp files for textures). Would you mind to send it to me?

    Thanks in advance!

    Wagner.
    wbarros@gmail.com

    ReplyDelete