Sunday, May 22, 2011

Brick Game part1

Hi, Here I am uploading game which i developed in openGL (motive was to kill the time on boring friday) This is very novice and still in the early in its life. This is work of just 4-5 hours. I wasted some of time just to figure out that the Image which I used for texture mapping needs to be of size 256X256 or some multiple of it. It's only after Kapil(one of my colleague) came for my rescue and we figured out the flaw. thanks Kapil! :) Once I could draw the wall of bricks i developed the logic on weekend and implemented it as first thing on monday morning. All I can say is it works! :) it can be made more efficient and more cool but I will leave that for some other day. You can download the code and make your own amendments to it. Its all free. thanks. :)


#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 m_x=0;
int m_y=0;
int brick_length=100,brick_width=30;

int ball_x=500;
int ball_y=500;
int radius = 20;

// BY default ball will go up
int x_dir = 1;
int y_dir = -1;
int base_y;
int base_x;
float move_mag = 5.0;

typedef struct brick {
int x;
int y;
int visible;
}BRICK;

BRICK BR[10][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 init_bricks() {

// Initialise the bricks
int x=100,y=50;

for(int row=0;row<10;row++) {
for(int column=0;column<10;column++) {
BRICK temp;
temp.visible = 1;
temp.x = (brick_length*column)+x;
temp.y = (brick_width*row)+y;
BR[row][column] = temp;
}
}

}

void move_ball() {
ball_x = ball_x + (move_mag*x_dir);
ball_y = ball_y + (move_mag*y_dir);
}

void change_y_dir() {
y_dir = -y_dir;
}
void change_x_dir() {
x_dir = -x_dir;
}
void change_both_dir() {
change_y_dir();
change_x_dir();
}

int crossed_x_limits() {
if((ball_x-radius)<=MIN_X) {
ball_x = MIN_X+radius;
return 1;
}
if((ball_x+radius)>=MAX_X) {
ball_x = MAX_X-radius;
return 1;
}
return 0;
}


int crossed_y_limits() {
if(ball_y-radius<=MIN_Y) {
ball_y = MIN_Y+radius;
return 1;
}
if(ball_y+radius>=MAX_Y) {
ball_y = MAX_Y-radius;
return 1;
}
return 0;
}
int hit_base() {

if (ball_x>=m_x-brick_length && ball_x<=m_x+brick_length) {
if((ball_y+radius)<=MAX_Y && (ball_y+radius)>=(MAX_Y-brick_width)) {
return 1;
}
}

return 0;
}


// the mouse callback function:
void mouse_move(int x, int y)
{
m_x = x;
m_y = y;

drawScene();
}

void specialKey(int key, int x, int y) {
switch (key) {
case 101: //UP arrow key
if (move_mag<radius-1) {
move_mag+=0.5;
}
break;
case 103: //DOWN arrow key
if (move_mag>1) {
move_mag-=0.5;
}
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
}

GLuint _textureId; //The id of the texture

void initRendering() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);

Image* image = loadBMP("br.bmp");
_textureId = 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 create_brick(int length,int width,int x, int y) {
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();
}



void drawCircle(float radius, float x1, float y1)
{
float angle = 0;
float x2,y2,cx,cy,fx,fy;
int cache = 0;
glBegin(GL_LINES);
for (angle = 0; angle < 360; angle+=25.0) {
float rad_angle = angle * 3.14 / 180;
x2 = x1+radius * sin((double)rad_angle);
y2 = y1+radius * cos((double)rad_angle);
if (cache) {
glVertex2f(cx,cy);
glVertex2f(x2,y2);
} else {
fx = x2;
fy = y2;
}
cache = 1;
cx = x2;
cy = y2;
}
glVertex2f(x2,y2);
glVertex2f(fx,fy);

glEnd();
}

void play_ball() {
move_ball();

if (crossed_x_limits()) {
change_x_dir();
} else if (crossed_y_limits()) {
change_y_dir();
} else {
// Do nothing
}
}

void detect_collision() {

if(hit_base()) {
change_y_dir();
return;
}

for(int row=0;row<10;row++) {
for(int column=0;column<10;column++) {
BRICK temp = BR[row][column];
if (temp.visible) {
int min_y = temp.y - brick_width;
int min_x = temp.x;
int max_x = temp.x + brick_length;
int max_y = temp.y ;

if ((ball_x+radius)>=min_x &&
(ball_x-radius)<=max_x &&
(ball_y+radius)>=min_y &&
(ball_y-radius)<=max_y) {
BR[row][column].visible = 0;
change_both_dir();
return;
}

}
}
}
}


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

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _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(1.0f, 0.2f, 0.2f);

// Draw the wall of bricks
int x=100,y=50;

for(int row=0;row<10;row++) {
for(int column=0;column<10;column++) {
if (BR[row][column].visible ==1) {
create_brick(
brick_length,
brick_width,
(brick_length*column)+x,
(brick_width*row)+y);
}
}
}

// Draw the moving support base
{
int x=m_x-brick_length,y=MAX_Y;
for(int row=0;row<1;row++) {
for(int column=0;column<2;column++) {
create_brick(
brick_length,
brick_width,
(brick_length*column)+x,
y-(brick_width*row));
}
}
}

// Draw the ball
play_ball();
drawCircle(radius,ball_x,ball_y);
detect_collision();

glutSwapBuffers();
}

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

drawScene();

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

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

glutCreateWindow("Texture demo");
initRendering();

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

glutReshapeFunc(handleResize);
glutMotionFunc(mouse_move);
glutPassiveMotionFunc(mouse_move);
glutTimerFunc(5 , update, 0);

glutMainLoop();
return 0;
}


1 comment:

  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