헤더 위치 잘 맞추고 하면 실행되는 스네이크 게임.
넘나 심플한 것.
#include <glut.h>
#include <gl/gl.h>
#include <gl/GLU.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define SIZE 0.05
#define VELOCITY 0.1
#define RIGHT 1
#define LEFT 2
#define UP 3
#define DOWN 4
#define BESIDE_ROTATION 5
#define INNER_SIZE 0.04
#define COLOR 1.0, 1.0, 1.0
GLfloat DeltaX = 0.0;
GLfloat DeltaY = 0.0;
GLfloat NewDeltaX = 0.5;
GLfloat NewDeltaY = 0.0;
GLint ArrowKeyValue = GLUT_KEY_RIGHT;
GLfloat VertexList[100][4][2] = {};
GLint VertexAmount = 0;
int BoundaryTest();
void DrawHead();
void DrawBody();
void DrawNewHead();
void MyMouseMove(GLint X, GLint Y)
{
glutPostRedisplay();
}
void MyKeyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 'q': case 'Q':
//no break
exit(0);
default :
break;
}
glutPostRedisplay();
}
void MySpecialKeyboard(int key, int x, int y)
{
switch (key)
{
case GLUT_KEY_LEFT:
ArrowKeyValue = GLUT_KEY_LEFT;
break;
case GLUT_KEY_RIGHT:
ArrowKeyValue = GLUT_KEY_RIGHT;
break;
case GLUT_KEY_UP:
ArrowKeyValue = GLUT_KEY_UP;
break;
case GLUT_KEY_DOWN:
ArrowKeyValue = GLUT_KEY_DOWN;
break;
default:
break;
}
glutPostRedisplay();
}
void MyDisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
DrawHead();
DrawNewHead();
DrawBody();
glutSwapBuffers();
}
void MyTimer(int Value)
{
int i = 0;
float beforeVertex[8];
if (VertexAmount > 0)
{
beforeVertex[0] = VertexList[VertexAmount - 1][0][0];
beforeVertex[1] = VertexList[VertexAmount - 1][0][1];
beforeVertex[2] = VertexList[VertexAmount - 1][1][0];
beforeVertex[3] = VertexList[VertexAmount - 1][1][1];
beforeVertex[4] = VertexList[VertexAmount - 1][2][0];
beforeVertex[5] = VertexList[VertexAmount - 1][2][1];
beforeVertex[6] = VertexList[VertexAmount - 1][3][0];
beforeVertex[7] = VertexList[VertexAmount - 1][3][1];
}
for (i = VertexAmount; i > 0; i--)
{
if (i == 1)
{
VertexList[0][0][0] = DeltaX;
VertexList[0][0][1] = DeltaY;
VertexList[0][1][0] = DeltaX;
VertexList[0][1][1] = DeltaY;
VertexList[0][2][0] = DeltaX;
VertexList[0][2][1] = DeltaY;
VertexList[0][3][0] = DeltaX;
VertexList[0][3][1] = DeltaY;
}
else
{
VertexList[i - 1][0][0] = VertexList[i - 2][0][0];
VertexList[i - 1][0][1] = VertexList[i - 2][0][1];
VertexList[i - 1][1][0] = VertexList[i - 2][1][0];
VertexList[i - 1][1][1] = VertexList[i - 2][1][1];
VertexList[i - 1][2][0] = VertexList[i - 2][2][0];
VertexList[i - 1][2][1] = VertexList[i - 2][2][1];
VertexList[i - 1][3][0] = VertexList[i - 2][3][0];
VertexList[i - 1][3][1] = VertexList[i - 2][3][1];
}
}
switch (ArrowKeyValue)
{
case GLUT_KEY_LEFT:
DeltaX = DeltaX - VELOCITY;
break;
case GLUT_KEY_RIGHT:
DeltaX = DeltaX + VELOCITY;
break;
case GLUT_KEY_UP:
DeltaY = DeltaY + VELOCITY;
break;
case GLUT_KEY_DOWN:
DeltaY = DeltaY - VELOCITY;
break;
}
if (BoundaryTest() != 0)
{
VertexAmount++;
for (i = VertexAmount; i > 0; i--)
{
VertexList[i - 1][0][0] = VertexList[i - 2][0][0];
VertexList[i - 1][0][1] = VertexList[i - 2][0][1];
VertexList[i - 1][1][0] = VertexList[i - 2][1][0];
VertexList[i - 1][1][1] = VertexList[i - 2][1][1];
VertexList[i - 1][2][0] = VertexList[i - 2][2][0];
VertexList[i - 1][2][1] = VertexList[i - 2][2][1];
VertexList[i - 1][3][0] = VertexList[i - 2][3][0];
VertexList[i - 1][3][1] = VertexList[i - 2][3][1];
}
VertexList[0][0][0] = DeltaX;
VertexList[0][0][1] = DeltaY;
VertexList[0][1][0] = DeltaX;
VertexList[0][1][1] = DeltaY;
VertexList[0][2][0] = DeltaX;
VertexList[0][2][1] = DeltaY;
VertexList[0][3][0] = DeltaX;
VertexList[0][3][1] = DeltaY;
if (BoundaryTest() == BESIDE_ROTATION)
{
switch (ArrowKeyValue)
{
case GLUT_KEY_LEFT:
DeltaX = DeltaX - VELOCITY;
break;
case GLUT_KEY_RIGHT:
DeltaX = DeltaX + VELOCITY;
break;
case GLUT_KEY_UP:
DeltaY = DeltaY + VELOCITY;
break;
case GLUT_KEY_DOWN:
DeltaY = DeltaY - VELOCITY;
break;
}
}
else
{
DeltaX = NewDeltaX;
DeltaY = NewDeltaY;
}
NewDeltaX = (float)(rand() % 10) * 0.1;
NewDeltaY = (float)(rand() % 10) * 0.1;
}
glutPostRedisplay();
glutTimerFunc(1000, MyTimer, 1);
}
void MyReshpae(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(0, 0);
glutCreateWindow("Open GL Sample");
glClearColor(1.0, 1.0, 1.0, 1.0);
glutDisplayFunc(MyDisplay);
glutTimerFunc(40, MyTimer, 1);
glutKeyboardFunc(MyKeyboard);
glutSpecialFunc(MySpecialKeyboard);
glutMotionFunc(MyMouseMove);
glutReshapeFunc(MyReshpae);
glutMainLoop();
return 0;
}
void DrawHead()
{
glBegin(GL_POLYGON);
glColor3f(COLOR);
glVertex3f(-SIZE + DeltaX, -SIZE + DeltaY, 0.0);
glVertex3f(SIZE + DeltaX, -SIZE + DeltaY, 0.0);
glVertex3f(SIZE + DeltaX, SIZE + DeltaY, 0.0);
glVertex3f(-SIZE + DeltaX, SIZE + DeltaY, 0.0);
glEnd();
glBegin(GL_POLYGON);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(-INNER_SIZE + DeltaX, -INNER_SIZE + DeltaY, 0.0);
glVertex3f(INNER_SIZE + DeltaX, -INNER_SIZE + DeltaY, 0.0);
glVertex3f(INNER_SIZE + DeltaX, INNER_SIZE + DeltaY, 0.0);
glVertex3f(-INNER_SIZE + DeltaX, INNER_SIZE + DeltaY, 0.0);
glEnd();
}
void DrawNewHead()
{
glBegin(GL_POLYGON);
glColor3f(COLOR);
glVertex3f(-SIZE + NewDeltaX, -SIZE + NewDeltaY, 0.0);
glVertex3f(SIZE + NewDeltaX, -SIZE + NewDeltaY, 0.0);
glVertex3f(SIZE + NewDeltaX, SIZE + NewDeltaY, 0.0);
glVertex3f(-SIZE + NewDeltaX, SIZE + NewDeltaY, 0.0);
glEnd();
glBegin(GL_POLYGON);
glColor3f(0.0, 1.0, 0.0);
glVertex3f(-INNER_SIZE + NewDeltaX, -INNER_SIZE + NewDeltaY, 0.0);
glVertex3f(INNER_SIZE + NewDeltaX, -INNER_SIZE + NewDeltaY, 0.0);
glVertex3f(INNER_SIZE + NewDeltaX, INNER_SIZE + NewDeltaY, 0.0);
glVertex3f(-INNER_SIZE + NewDeltaX, INNER_SIZE + NewDeltaY, 0.0);
glEnd();
}
void DrawBody()
{
int i = 0;
for (i = 0; i < VertexAmount; i++)
{
glBegin(GL_POLYGON);
glColor3f(COLOR);
glVertex3f(-SIZE + VertexList[i][0][0], -SIZE + VertexList[i][0][1], 0.0);
glVertex3f(SIZE + VertexList[i][1][0], -SIZE + VertexList[i][1][1], 0.0);
glVertex3f(SIZE + VertexList[i][2][0], SIZE + VertexList[i][2][1], 0.0);
glVertex3f(-SIZE + VertexList[i][3][0], SIZE + VertexList[i][3][1], 0.0);
glEnd();
glBegin(GL_POLYGON);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(-INNER_SIZE + VertexList[i][0][0], -INNER_SIZE + VertexList[i][0][1], 0.0);
glVertex3f(INNER_SIZE + VertexList[i][1][0], -INNER_SIZE + VertexList[i][1][1], 0.0);
glVertex3f(INNER_SIZE + VertexList[i][2][0], INNER_SIZE + VertexList[i][2][1], 0.0);
glVertex3f(-INNER_SIZE + VertexList[i][3][0], INNER_SIZE + VertexList[i][3][1], 0.0);
glEnd();
}
}
int BoundaryTest()
{
int boundaryValue = 0;
//머리 오른쪽 == 새로운 물체 왼쪽
if ((roundf((SIZE + DeltaX) * 100) == roundf((-SIZE + NewDeltaX) * 100)) &&
(roundf((SIZE + DeltaY) * 100) == roundf((SIZE + NewDeltaY) * 100)) &&
(roundf((-SIZE + DeltaY) * 100) == roundf((-SIZE + NewDeltaY) * 100)) &&
(ArrowKeyValue == GLUT_KEY_RIGHT))
{
boundaryValue = RIGHT;
}
//머리 왼쪽 == 새로운 물체 오른쪽
else if ((roundf((-SIZE + DeltaX) * 100) == roundf((SIZE + NewDeltaX) * 100)) &&
(roundf((SIZE + DeltaY) * 100) == roundf((SIZE + NewDeltaY) * 100)) &&
(roundf((-SIZE + DeltaY) * 100) == roundf((-SIZE + NewDeltaY) * 100)) &&
(ArrowKeyValue == GLUT_KEY_LEFT))
{
boundaryValue = LEFT;
}
//머리 위쪽 == 새로운 물체 아래쪽
else if ((roundf((SIZE + DeltaY) * 100) == roundf((-SIZE + NewDeltaY) * 100)) &&
(roundf((SIZE + DeltaX) * 100) == roundf((SIZE + NewDeltaX) * 100)) &&
(roundf((-SIZE + DeltaX) * 100) == roundf((-SIZE + NewDeltaX) * 100)) &&
(ArrowKeyValue == GLUT_KEY_UP))
{
boundaryValue = UP;
}
//머리 아래쪽 == 새로운 물체 위쪽
else if ((roundf((- SIZE + DeltaY) * 100) == roundf((SIZE + NewDeltaY) * 100)) &&
(roundf((SIZE + DeltaX) * 100) == roundf((SIZE + NewDeltaX) * 100)) &&
(roundf((-SIZE + DeltaX) * 100) == roundf((-SIZE + NewDeltaX) * 100)) &&
(ArrowKeyValue == GLUT_KEY_DOWN))
{
boundaryValue = DOWN;
}
else if ((roundf((SIZE + DeltaY) * 100) == roundf((SIZE + NewDeltaY) * 100)) &&
(roundf((-SIZE + DeltaY) * 100) == roundf((-SIZE + NewDeltaY) * 100)) &&
(roundf((SIZE + DeltaX) * 100) == roundf((SIZE + NewDeltaX) * 100)) &&
(roundf((-SIZE + DeltaX) * 100) == roundf((-SIZE + NewDeltaX) * 100))
)
{
boundaryValue = BESIDE_ROTATION;
}
else
{
}
return boundaryValue;
}