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;
}