rendered paste body/*
Bounce by kecebongsoft (http://kecebongsoft.wordpress.com)
*/
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
#define WINDOW_MODE GLFW_WINDOW
#define GAME_STATE_INIT_DEVICE 1
#define GAME_STATE_INIT_LEVEL 2
#define GAME_STATE_GAMEPLAY 3
#define GAME_STATE_EXIT 4
#define DISPLAY_LIST_CUBE 1
#include <GL/glfw.h>
#include <GL/glu.h>
#include <GL/glut.h>
//#include <GL/glx.h>
#include <GL/glutils.cpp>
#include <stdio.h> // Header file for standard file i/o.
#include <math.h>
#include <cstdlib>
#include <vector>
struct Ball{
GLfloat pos[3];
GLfloat angle[3];
GLfloat max[3];
GLfloat min[3];
float speed;
float maxspeed;
float yspeed;
float gravity;
GLUquadric* quad;
};
int gameState = GAME_STATE_INIT_DEVICE;
std::vector<std::vector<int> > levelmap; // Holds array of map (tileset)
GLuint cubetexture[3];
GLuint balltexture[3];
Ball ball;
GLfloat vcamera[3];
GLfloat LightAmbient[]= { 0.2f, 0.2f, 0.2f, 0.0f };
GLfloat LightDiffuse[]= { 1.5f,1.5f, 1.5f, 0.0f };
GLfloat LightPosition[]= { 50.0f, 5.0f, -5.0f, 1.0f };
// tmp vars :
float angle,x,y,z;
float max(float x, float y){
return x>y?x:y;
}
float min(float x, float y){
return x<y?x:y;
}
void terminate(int exitcode) {
glfwTerminate();
exit(exitcode);
}
bool initWindow() {
if (glfwInit() != GL_TRUE) {
return false;
}
if (glfwOpenWindow(WINDOW_WIDTH, WINDOW_HEIGHT, 5, 6, 5, 0, 32, 0, WINDOW_MODE) != GL_TRUE) {
return false;
}
glfwSetWindowTitle("Tuing Tuing");
return true;
}
bool initGeometry() {
// Build Cube
glNewList(DISPLAY_LIST_CUBE, GL_COMPILE);
glBegin(GL_QUADS); // Start Drawing The Cub
// Front Face (note that the texture's corners have to match the quad's corners)
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f);
glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Texture and Quad
// Back Face
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f);
glVertex3f( 1.0f, -1.0f, -1.0f); // Bottom Left Of The Texture and Quad
// Top Face
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f);
glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
// Bottom Face
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f);
glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
// Right face
glTexCoord2f(1.0f, 0.0f);
glVertex3f( 1.0f, -1.0f, -1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f);
glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
// Left Face
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
glEnd(); // Done Drawing The Quad
glEndList();
return true;
}
bool initTextures() {
LoadGLTextures("crate.bmp",(GLuint*)&cubetexture);
LoadGLTextures("ball.bmp",(GLuint*)&balltexture);
return true;
}
bool initGraphic() {
printf("Initializing graphic...\n");
glfwSwapInterval(0);
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // Setup The Ambient Light
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light
glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // Position The Light
glEnable(GL_LIGHT1); // Enable Light One
glEnable(GL_LIGHTING);
glDepthFunc(GL_LESS);
glShadeModel(GL_SMOOTH);
glLoadIdentity();
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
glMatrixMode(GL_PROJECTION);
gluPerspective(45.0f,(GLfloat)WINDOW_WIDTH/(GLfloat)WINDOW_HEIGHT,0.1f,100.0f);
gluLookAt(0,0,-20,20,0,20,0,1,0);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glMatrixMode(GL_MODELVIEW);
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glClearDepth(1.0);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
initGeometry();
initTextures();
return true;
}
bool loadLevel() {
printf("Initializing level...\n");
FILE *txtlevel;
char line[255];
txtlevel = fopen("level1.dat","rt");
levelmap.clear();
levelmap.push_back(std::vector<int>());
int row,col, startcol, startrow;
row=col=0;
while (fgets(line, 2, txtlevel)) {
if (line[0]!='\n') {
levelmap[levelmap.size()-1].push_back(atoi(line));
if(atoi(line)==9){
startrow = row;
startcol = col;
}
col++;
} else {
levelmap.push_back(std::vector<int>());
col=0;
row++;
}
}
fclose(txtlevel);
std::reverse(levelmap.begin(), levelmap.end());
for(int i=0;i<levelmap.size();i++){
if(levelmap[i].size()<=0){
levelmap.erase(levelmap.begin()+i);
}
}
for(int i=0;i<levelmap.size();i++){
std::reverse(levelmap[i].begin(), levelmap[i].end());
}
startrow = levelmap.size() - startrow;
startcol = levelmap[0].size() - startcol;
ball.pos[0] = startcol * 2;
ball.pos[1] = startrow * 2;
printf("Rows : %d\nCols : %d\n", levelmap.size(), levelmap[1].size());
return true;
}
bool initLevel() {
loadLevel();
ball.quad = gluNewQuadric();
gluQuadricTexture(ball.quad, true);
ball.maxspeed = 0.15;
ball.speed = 0;
//ball.pos[0] = 10;
//ball.pos[1] = 10;
ball.gravity = 0.003;
z = -15;
return true;
}
void input() {
if (getKey(GLFW_KEY_ESC)) {
gameState = GAME_STATE_EXIT;
}
if (getKey(GLFW_KEY_UP)) {
if(ball.pos[1]==ball.min[1]){ball.yspeed = 0.18;}
}
if (getKey(GLFW_KEY_LEFT)) {
ball.speed = min(ball.speed+0.001, ball.maxspeed);
}
if (getKey(GLFW_KEY_RIGHT)){
ball.speed = max(ball.speed-0.001, -ball.maxspeed);
}
if (getKey(GLFW_KEY_PAGEUP)){
z+=0.025f;
}
if (getKey(GLFW_KEY_PAGEDOWN)){
z-=0.025f;
}
}
void updateBall(){
int row, col;
if(ball.speed>0){
ball.speed-=0.00025;
}
if(ball.speed<0){
ball.speed+=0.00025;
}
ball.pos[0]+=ball.speed;
ball.pos[1]+=ball.yspeed;
ball.yspeed-=ball.gravity;
ball.angle[2]+=(ball.speed * -45);
row = (int)floorf((ball.pos[1] + 1) / 2);
col= (int)floorf((ball.pos[0] + 1) / 2);
if(row<levelmap.size() && col<levelmap[0].size()){
if(levelmap[row][col]==1){
}
if(levelmap[row][col]==0){
int i;
i = col-1;
while(levelmap[row][i]!=1 && i>=0){
i--;
}
ball.min[0] = ((GLfloat)i * 2) + 2;
i = col+1;
while(levelmap[row][i]!=1 && (int)i<levelmap[row].size()){
i++;
}
ball.max[0] = ((GLfloat)i * 2) - 2;
i = row-1;
while(levelmap[i][col]!=1 && i>=0){
i--;
}
ball.min[1] = ((GLfloat)i * 2) + 1.8;
i = row+1;
while(levelmap[i][col]!=1 && (int)i<levelmap.size()){
i++;
}
ball.max[1] = ((GLfloat)i * 2) - 1.8;
}
}
if(ball.pos[0]>ball.max[0]){
ball.pos[0] = ball.max[0];
ball.speed*=-1;
ball.speed+=0.015;
ball.speed=0;
}
if(ball.pos[0]<ball.min[0]){
ball.pos[0] = ball.min[0];
ball.speed*=-1;
ball.speed-=0.015;
ball.speed=0;
}
if(ball.pos[1]>ball.max[1]){
ball.pos[1] = ball.max[1];
ball.yspeed*=-1;
}
if(ball.pos[1]<ball.min[1]){
ball.pos[1] = ball.min[1];
ball.yspeed*=-1;
//if(ball.yspeed>0){
ball.yspeed-=0.08;
//}
}
}
void update() {
x += (ball.pos[0] - x) / 50;
y += (ball.pos[1] - y) / 30;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
gluPerspective(45.0f,(GLfloat)WINDOW_WIDTH/(GLfloat)WINDOW_HEIGHT,0.1f,100.0f);
gluLookAt(x,y+6,z,x,y+1,0,0,1,0);
//gluLookAt(x,y,z,x,y,0,0,1,0);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glMatrixMode(GL_MODELVIEW);
updateBall();
}
void drawMap(){
for(int i=0;i<levelmap.size();i++){
for(int j=0;j<levelmap[i].size();j++){
glLoadIdentity();
switch(levelmap[i][j]){
case 0:
break;
case 1:
glBindTexture(GL_TEXTURE_2D, cubetexture[2]);
glTranslatef((float)j * 2, (float)i * 2, 0.0f);
glCallList(DISPLAY_LIST_CUBE);
break;
}
}
}
}
void drawBall(){
glLoadIdentity();
GLfloat lightpos[]= { ball.pos[0] + 2, ball.pos[1] + 2, 0.0f, 1.0f };
GLfloat lightpos2[]= { ball.pos[0] - 2, ball.pos[1] - 2, -2.0f, 1.0f };
GLfloat lightpos3[]= { ball.pos[0] - 1, ball.pos[1] + 1, -2.0f, 1.0f };
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // Setup The Ambient Light
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light
glLightfv(GL_LIGHT1, GL_POSITION,lightpos); // Position The Light
glEnable(GL_LIGHT1); // Enable Light One
glLightfv(GL_LIGHT2, GL_AMBIENT, LightAmbient); // Setup The Ambient Light
glLightfv(GL_LIGHT2, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light
glLightfv(GL_LIGHT2, GL_POSITION,lightpos2); // Position The Light
glEnable(GL_LIGHT2);
glLightfv(GL_LIGHT3, GL_AMBIENT, LightAmbient); // Setup The Ambient Light
glLightfv(GL_LIGHT3, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light
glLightfv(GL_LIGHT3, GL_POSITION,lightpos3); // Position The Light
glEnable(GL_LIGHT3);
glLoadIdentity();
glTranslatef(ball.pos[0], ball.pos[1], ball.pos[2]);
glRotatef(ball.angle[0], 1.0f, 0.0f, 0.0f);
glRotatef(ball.angle[1], 0.0f, 1.0f, 0.0f);
glRotatef(ball.angle[2], 0.0f, 0.0f, 1.0f);
glBindTexture(GL_TEXTURE_2D, balltexture[2]);
gluSphere(ball.quad, 1, 25, 25);
}
void draw() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawMap();
drawBall();
glfwSwapBuffers();
}
void gameplay() {
static double lasttick = 0;
static double tick = 0;
tick = glfwGetTime();
if(tick-lasttick>0.0006){
// Wait for ticks
input();
update();
lasttick = glfwGetTime();
}
// Don't wait for ticks
draw();
}
bool gameLoop() {
switch (gameState) {
case GAME_STATE_INIT_DEVICE:
if (initGraphic()) {
gameState = GAME_STATE_INIT_LEVEL;
} else {
gameState = GAME_STATE_EXIT;
}
break;
case GAME_STATE_INIT_LEVEL:
if (initLevel()) {
gameState = GAME_STATE_GAMEPLAY;
} else {
gameState = GAME_STATE_EXIT;
}
break;
case GAME_STATE_GAMEPLAY:
gameplay();
break;
case GAME_STATE_EXIT:
return false;
break;
}
return true;
}
int main() {
initWindow();
while (gameLoop()) {
}
terminate(0);
return 0;
}