Code:
#include <stdio.h>
#include <time.h>
#include <windows.h>
#include <gl/glut.h>
#define UP 1
#define Down 2
#define LEFT 3
#define RIGHT 4
// Variabile de stare
GLint lvl = 1;
GLint points = 0;
GLint size = 0;
GLbyte gameOver = true;
GLbyte EnableLight = true;
// Variabilele la vierme
GLint bodyPos[2][100] = {{}};
GLint _x = 5;
GLint _z = 10;
GLint _oldX[2] = {};
GLint _oldZ[2] = {};
GLbyte direction = 0;
// Variabile la mancare
GLint _bx = 0;
GLint _bz = 0;
// Variabile de ecran
GLint _w = 800;
GLint _h = 550;
GLint _Giw = 0;
GLint _Gih = 0;
GLint _Gfw = 150;
GLint _Gfh = 150;
//Variabile pentru unghiul camerei
static GLfloat view_rotx=45.0F ;
static GLfloat view_roty=0.0F ;
static GLfloat view_rotz=0.0F ;
static GLfloat headRotation=90.0F ;
static GLfloat zoom=-300.0F ;
// Variabile pentru FPS
DWORD g_dwLastFPS = 0;
int g_nFPS = 0, g_nFrames = 0;
//Configurarea Luminii
void initLight()
{
//Adaugam lumina ambientala
GLfloat ambientColor[] = {0.3f, 0.4f, 0.8f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor);
//Lumina pozitionata
GLfloat lightColor0[] = {0.5f, 0.5f, 0.5f, 1.0f};
GLfloat lightPos0[] = {4.0f, 0.0f, 8.0f, 1.0f};
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos0);
//Adaugam lumina directa
GLfloat lightColor1[] = {0.5f, 0.2f, 0.2f, 1.0f};
//Vine din directia (-1, 0.5, 0.5)
GLfloat lightPos1[] = {-1.0f, 0.5f, 0.5f, 0.0f};
glLightfv(GL_LIGHT1, GL_DIFFUSE, lightColor1);
glLightfv(GL_LIGHT1, GL_POSITION, lightPos1);
}
//Initializarea primelor configuratii
void Initialize(void)
{
glEnable(GL_DEPTH_TEST);
glClearColor(0.7f, 0.9f, 0.3f,0.7f); //Schimbam culoarea "cerului" intr-un...verde sau ce o fi iesit pe aici
if(EnableLight){
glEnable(GL_COLOR_MATERIAL); //Dam enable la culoare
glEnable(GL_LIGHTING); //Dam enable la lumina
glEnable(GL_LIGHT0); //Dam enable la lumina #0
glEnable(GL_LIGHT1); //Dam enable la lumina #1
glEnable(GL_NORMALIZE); //Automatizarea normalizarii normalelor
}
}
//Redimensionarea ferestrei
void resize (int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (double)w / (double)h, 1, 800.0);
}
void Write(char *string){//Scriem un string pe ecran
while(*string)
glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *string++);
}
//Aceasta functie va intoarce obiectele in functie de unghi
void ManipulateViewAngle() {
glRotatef(view_rotx,1.0,0.0,0.0);//Intoarcem in jurul la axa X
glRotatef(view_roty,0.0,1.0,0.0);//Intoarcem in jurul la axa Y
glRotatef(view_rotz,0.0,0.0,1.0);//Intoarcem in jurul la axa Z
}
//Resetam dimensiunea la vierme si locatia lui(sau sa ii zicem mai bine "joc nou" HAHA HIHI HEHE HOHO)
void Reset(){
_x = 5;
_z = 10;
direction = 0;
lvl = 1;
points = 0;
size = 0;
gameOver = false;
view_rotx=45.0F ;
view_roty=0.0F ;
view_rotz=0.0F ;
headRotation=90.0F ;
zoom=-300.0F ;
}
//WELCOOOOOMEEEE SCREEEEEENNNN YUPYYY
void WelcomeScreen(){
char tmp_str[40];
glColor3f(1, 0, 0);
glRasterPos2f(0, 20);
Write("Snake 3D");
glColor3f(0, 0, 1);
glRasterPos2f(0, 10);
Write("Marin Alexandru Radu");
glColor3f(0, 0, 1);
glRasterPos2f(0, 0);
Write("Apasati 'n' pentru joc nou.");
}
void DrawSnake(){
int i;
//Desenam capul si suprafata
glPushMatrix();
ManipulateViewAngle();
//Suprafata de marshaluire a sarpelui
glPushMatrix();
glColor3f(0.5f, 0.0f, 1.0f);
glTranslatef(75.0, -16.0, 75.0);
glScalef(155,5.0,155);
glutSolidCube(1);
glPopMatrix();
//HEAD OF THE WORM
glColor3f(1.0,0.0,0.0);//Culoare..
glTranslatef(_x,-10.0,_z);//Ii dam locatia in functie de _x si _z
glScalef(0.5,0.5,0.5);
glutSolidSphere(10,20,20);//Ii facem capul mai tuguiat(o sfera putin mai mare decat celalte sfere)
glRotatef(headRotation, 0.0, 1.0, 0.0);
glColor3f(1.0,1.0,0.0);
glTranslatef(0,0.0,6.0);
glScalef(0.8,1.0,1.0);
glutSolidCone(10,10,20,20);
glColor3f(0,0,0);
glTranslatef(-4.0,10.0,0.0);
glScalef(0.3,0.3,0.3);
glutSolidSphere(10,20,20);
glTranslatef(26.0,0.0,0.0);
glutSolidSphere(10,20,20);
glPopMatrix();
//Desenarea corpului
for(i=0; i<size; i++){//Loop-ul va da lungimea corpului si va desena sfere
glPushMatrix();
ManipulateViewAngle();
glTranslatef(bodyPos[0][i],-10.0,bodyPos[1][i]);//Localizarea sferelor
glColor3f(0.8,0.4,0.4);
glScalef(0.5,0.5,0.5);
glutSolidSphere(7,20,20);
glPopMatrix();
}
}
void DrawFood()
{
//Desenam sferele AKA mancarea pentru vierme
glPushMatrix();
ManipulateViewAngle();
glTranslatef(_bx,-10.0,_bz);
glColor3f(0.8, 0.4, 0.4);//MEMO "SCHIMBA CULOAREA LA MANCARE CA ESTE FOARTE ENERVANTA ASA!!!!!!!"
glScalef(0.5,0.5,0.5);
glutSolidSphere(7,20,20);
glPopMatrix();
}
void GameStatus(){
char tmp_str[40];
// Vom face un "status" al jocului ce il vom afisa pe ecran
glColor3f(0, 0, 0);
glRasterPos2f(5, 50);
sprintf(tmp_str, "Nivel: %d Puncte: %d", lvl, points);
Write(tmp_str);
}
//Generam numere aleatoare pentru locatia mancarii viermelui
int RandomNumber(int high, int low)
{
return (rand() % (high-low))+low;
}
//Generam noua mancare pentru vierme
void newFood(){
time_t seconds;
time(&seconds);
srand((unsigned int) seconds);
_bx = RandomNumber(_Gfw-_Giw, _Giw+10);
_bz = RandomNumber(_Gfh-_Gih, _Gih+10);
}
//Functie de calcul FPS
void getFPS(){
char tmp_str[40];
if( GetTickCount() - g_dwLastFPS >= 1000 ) // Cand a trecut o secunda...
{
g_dwLastFPS = GetTickCount(); // Updatam variabila de timp
g_nFPS = g_nFrames; // Salvam FPS
g_nFrames = 0; // Resetam FPS
}
g_nFrames++;
glRasterPos2f(75, 50);
sprintf(tmp_str, "FPS: %d", g_nFPS);
Write(tmp_str);
glRasterPos2f(50, 60);
sprintf(tmp_str, "Poz X: %d Poz Z: %d", _x, _z);//Afisam pozitia X si Z
Write(tmp_str);
}
//Functia de "accidentare"
bool collision(){
int i;
for(i=0; i<size; i++){
if((bodyPos[0][i] == _x && bodyPos[1][i] == _z) ||
((bodyPos[0][i] >= _x) && (bodyPos[0][i] <= _x + 5) && (bodyPos[1][i] >= _z) && (bodyPos[1][i] <= _z + 5)) ||
((bodyPos[0][i] <= _x) && (bodyPos[0][i] >= _x - 5) && (bodyPos[1][i] <= _z) && (bodyPos[1][i] >= _z - 5)) ||
((bodyPos[0][i] <= _x) && (bodyPos[0][i] >= _x - 5) && (bodyPos[1][i] >= _z) && (bodyPos[1][i] <= _z + 5)) ||
((bodyPos[0][i] >= _x) && (bodyPos[0][i] <= _x + 5) && (bodyPos[1][i] <= _z) && (bodyPos[1][i] >= _z - 5)))
return true;
}
return false;
}
//Functie pentru miscarea sarpelui in functie de directie
//Putin logic,dar vom folosi tastatura (old school: sus,jos,dreapta,stanga)
void Run(int value){
int i;
_oldX[1] = _x;
_oldZ[1] = _z;
switch(direction){
case RIGHT:
headRotation =90;
_x += 6;
if(_x > _Gfw-2) _x = _Giw-1;//Daca viermele se duce intr-o margine,aici il vom face sa "apara" in partea cealalta (no walls)
break;
case LEFT:
headRotation =-90;
_x -= 6;
if(_x < 0) _x = _Gfw-2;//Acelasi lucru ca mai sus
break;
case UP:
headRotation =0;
_z += 6;
if(_z > _Gfh-2) _z = _Gih-1;//Acelasi lucru ca mai sus
break;
case Down:
headRotation =180;
_z -= 6;
if(_z < 2) _z = _Gfh-2;//Acelasi lucru ca mai sus
break;
}
//Verificat daca s-a papat singur,IF DAAAA,atunci GAME OVER
if(collision()) gameOver = true;
//Vedem daca viermele isi mananca mancarea (verificam X si Y)
// Daca da crestem numarul de puncte,marimea viermelui si creeam o sfera (mancare YUM YUM) noua
if((_x == _bx && _z == _bz) ||
((_x >= _bx) && (_x <= _bx + 4) && (_z >= _bz) && (_z <= _bz + 4)) ||
((_x <= _bx) && (_x >= _bx - 4) && (_z <= _bz) && (_z >= _bz - 4)) ||
((_x <= _bx) && (_x >= _bx - 4) && (_z >= _bz) && (_z <= _bz + 4)) ||
((_x >= _bx) && (_x <= _bx + 4) && (_z <= _bz) && (_z >= _bz - 4))){
points++;
if(points < 100) size++;
if(points%5 == 0 && lvl < 15) lvl++;
newFood();
}
for(i = 0; i<size; i++){// Salvam pozitiile partilor corpului la "el vierme"
_oldX[0] = _oldX[1];
_oldZ[0] = _oldZ[1];
_oldX[1] = bodyPos[0][i];
_oldZ[1] = bodyPos[1][i];
bodyPos[0][i] = _oldX[0];
bodyPos[1][i] = _oldZ[0];
}
//Setam timpul
glutTimerFunc(130-lvl*4, Run, 0);
}
void Display(void){//Draw Function
//Golire ecran
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if(EnableLight) initLight();
glTranslatef (-60.0, 40.0, zoom);
//Daca "Game over" e adavarat,naspa,daca nu continuam jocul.
if(!gameOver){
GameStatus();
DrawFood();
DrawSnake();
}
else
WelcomeScreen();
getFPS();
// Updatam ecranul
glutPostRedisplay();
glutSwapBuffers();
}
void Special(int key, int x, int y){
switch(key){
case GLUT_KEY_RIGHT :
if(direction != LEFT)
direction = RIGHT;
break;
case GLUT_KEY_LEFT :
if(direction != RIGHT)
direction = LEFT;
break;
case GLUT_KEY_UP :
if(direction != UP)
direction = Down;
break;
case GLUT_KEY_DOWN :
if(direction != Down)
direction = UP;
break;
}
}
void keyboard (unsigned char key, int x, int y)//Functii de baza pt miscarea viermelui
{
switch (key) {
//Toate rotatiile viermelui peste unghiurile X, Y, Z
case 'x' : view_rotx +=2 ;
glutPostRedisplay();
break;
case 'X' : view_rotx -=2 ;
glutPostRedisplay();
break;
case 'y' : view_roty +=2 ;
glutPostRedisplay();
break;
case 'Y' : view_roty -=2 ;
glutPostRedisplay();
break;
case 'z' : view_rotz +=2 ;
glutPostRedisplay();
break;
case 'Z' : view_rotz -=2 ;
glutPostRedisplay();
break;
case 'a' : size++ ;//Functie ascunsa pentru utilizator (HAHA HIHI HEHE HOHO) cu care putem sa facem marimea sarpelui mai mare
glutPostRedisplay();
break;
case 'A' : size-- ;//Functie ascunsa pentru utilizator (HAHA HIHI HEHE HOHO) cu care putem sa facem marimea sarpelui mai mica
glutPostRedisplay();
break;
case '+' : zoom++ ;//Functie ascunsa pentru utilizator (HAHA HIHI HEHE HOHO) cu care putem sa facem zoom inspre plansa
glutPostRedisplay();
break;
case '-' : zoom-- ;//Functie ascunsa pentru utilizator (HAHA HIHI HEHE HOHO) cu care putem sa facem zoom mai departe de plansa (O facem miica mica mica)
glutPostRedisplay();
break;
case 'n' : Reset() ;//Functie de reset,care noi il mintim pe utilizator ca este de fapt pentru inceperea jocului (HAHA HIHI HEHE HOHO)
glutPostRedisplay();
break;
//ESC pentru a iesi.
case 27:
exit(0);
break;
default:
break;
}
}
int main(void){
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(_w,_h);
glutInitWindowPosition(80,80);
glutCreateWindow("Snake Game ");
glutSpecialFunc(Special);
glutKeyboardFunc(keyboard);
glutDisplayFunc(Display);
glutReshapeFunc(resize);
newFood();
Run(0);
Initialize();
glutMainLoop();
}
The problem is that i am trying to change the camera mode to follow the head object.The problem is that i've find the function gluLookAt(),but i don't understand what variables to put in there.