티스토리 뷰
/***********************
* inclues
***********************/
#include <gl/glut.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <stdlib.h> //rand(), srand()
#include <time.h> //time()
/***********************
* macro definition
***********************/
#define randomize() srand((int)time(NULL)) // srand 초기화하는 매크로
#define random(n) rand()%(n) // 0 부터 n-1까지 임의의 수를 얻는 매크로
/********************************************
* the global variable
*
* 위에서 떨어지는 도형을 1번 도형
* 정지한 상태의 도형을 2번 도형이라고 한다.
*********************************************/
GLfloat Line_X = -0.7; // 1번 도형의 좌표값을 저장한다.
GLfloat Line_Y = 0.0;
GLfloat TargetX; // 2번 도형의 좌표값을 저장한다.
GLfloat TargetY;
GLfloat Center[2]; // 1번, 2번 도형의 중심 좌표값을 저장한다.
GLfloat Level = 0.01; // 1번 도형의 속도를 저장한다.
GLint ShapeNow; // 1번 도형의 현재 모양의 상태를 저장한다. 0이면 사각형, 1이면 삼각형
GLint MovingShape; // 1번 도형의 모양 상태를 저장한다. 0이면 사각형, 1이면 삼각형
GLint TargetShape; // 2번 도형의 모양 상태를 저장한다. 0이면 사각형, 1이면 삼각형
GLfloat Pause; // 1번 도형의 떨어지는 속도를 임시로 저장한다.
GLfloat Counter = 3.2f; // 1번 도형의 떨어질때의 카운터를 저장한다.
GLfloat Red, Green, Blue; // glColor3f() 파라미터
GLint ColorIndex; // 색깔을 결정하는 배열 인덱스
/********************************************
* PALETTE[9][3]
*
* 9가지 색깔을 9 * 3 배열로 저장한다.
*********************************************/
unsigned char PALETTE[9][3] = {
{ 0, 255, 255 }, // CYAN
{ 0, 255, 0 }, // GREEN
{ 0, 0, 255 }, // BLUE
{ 255, 0, 0 }, // RED
{ 255, 190, 0 }, // Orange
{ 255, 255, 0 }, // YELLOW
{ 255, 0, 255 }, // PURPLE
{ 190, 0, 255 }, // Violet
{ 0, 0, 0 }, // BLACK
};
/********************************************
* Color
*
* 색깔을 초기화 하는 함수
*********************************************/
void Color()
{
Red = PALETTE[ColorIndex][0] / 255.0f;
Green = PALETTE[ColorIndex][1] / 255.0f;
Blue = PALETTE[ColorIndex][2] / 255.0f;
glColor3f(Red, Green, Blue);
}
/********************************************
* Target Square : 사각형
*
* 2번 도형의 색깔과 모양, 좌표를 설정한다.
*********************************************/
void TargetSquare( )
{
Color();
glBegin(GL_LINE_LOOP);
glVertex3f(TargetX, TargetY+0.2, 0.0);
glVertex3f(TargetX+0.2, TargetY+0.2, 0.0);
glVertex3f(TargetX+0.2, TargetY-0.0, 0.0);
glVertex3f(TargetX, TargetY-0.0, 0.0);
glEnd( );
}
/********************************************
* Target Triangle : 삼각형
*
* 2번 도형의 색깔과 모양, 좌표를 설정한다.
*********************************************/
void TargetTriangle( )
{
Color();
glBegin(GL_LINE_LOOP);
glVertex3f(TargetX, TargetY, 0.0);
glVertex3f(TargetX + 0.2, TargetY, 0.0);
glVertex3f(TargetX + 0.1, TargetY +0.2, 0.0);
glEnd( );
}
/********************************************
* Moving Square : 사각형
*
* 1번 도형의 색깔과 모양, 좌표를 설정한다.
*********************************************/
void MovingSquare( )
{
glClear(GL_COLOR_BUFFER_BIT);
Color();
/* Square Coordinates(x, y)*/
glBegin(GL_POLYGON);
glVertex3f(-0.1 + Line_X, 1.7 - Line_Y, 0.0);
glVertex3f( 0.1 + Line_X, 1.7 - Line_Y, 0.0);
glVertex3f( 0.1 + Line_X, 1.5 - Line_Y, 0.0);
glVertex3f(-0.1 + Line_X, 1.5 - Line_Y, 0.0);
glEnd( );
ShapeNow = 0; // 현재 떨어지는 도형이 사각형(0)임을 기억한다.
if(TargetShape == 0) TargetSquare(); // Random()에서 TargetShape을 가져와
else if(TargetShape == 1) TargetTriangle(); // 0이면 사각형, 1이면 삼각형으로 2번 도형을 그린다.
Center[0] = (-0.1 + Line_X)+0.1; // 도형의 중심 좌표중 x 좌표를 기억한다.
glFlush( );
}
/********************************************
* Moving Triangle : 삼각형
*
* 1번 도형의 색깔과 모양, 좌표를 설정한다.
*********************************************/
void MovingTriangle( )
{
glClear(GL_COLOR_BUFFER_BIT);
Color();
/* Triangle Coordinates(x, y)*/
glBegin(GL_POLYGON);
glVertex3f(-0.1 + Line_X, 1.7 - Line_Y, 0.0);
glVertex3f( 0.1 + Line_X, 1.7 - Line_Y, 0.0);
glVertex3f( 0.0 + Line_X, 1.9 - Line_Y, 0.0);
glEnd( );
ShapeNow = 1; // 현재 떨어지는 도형이 삼각형(1)임을 기억한다.
if(TargetShape == 0) TargetSquare();
else if(TargetShape == 1) TargetTriangle();
Center[1] = 0.0 + Line_X;
glFlush( );
}
/********************************************
* Reshape
*
*
*********************************************/
void Reshape(int NewWidth, int NewHeight)
{
glViewport(0, 0, 600, 600);
GLfloat WidthFactor = (GLfloat)500 / (GLfloat)400;
GLfloat HeightFactor = (GLfloat)NewHeight / (GLfloat)400;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0 * WidthFactor, 1.0 * WidthFactor,
-1.0 * HeightFactor, 1.0 * HeightFactor, -1.0, 1.0);
}
/********************************************
* Random
*
* 1번, 2번 도형의 모양, 2번 도형의 좌표를 얻는다.
*********************************************/
void Random()
{
randomize(); // srand()를 사용하기 위해 시간으로 난수를 초기화 한다.
TargetX = random(20)%(13-2)+2; // 2번 도형의 좌표를 난수를 이용해서 얻는다.
TargetY = random(20)%(15-8)+8; // 8부터 15까지 임의의 수를 받는다.
MovingShape = random(50) % 2; // 1번 도형의 모양을 임의의 수로 얻는다.
TargetShape = random(50) % 2; // 2번 도형의 모양을 임의의 수로 얻는다.
TargetX = (-TargetX) * 0.1; // 2번 도형의 좌표를 생성한다.
TargetY = (-TargetY) * 0.1;
switch (MovingShape) // 1번 도형의 모양을 결정
{
case 0:
glutDisplayFunc(MovingSquare);
break;
case 1:
glutDisplayFunc(MovingTriangle);
break;
}
}
/********************************************
* Timer
*
* 1번, 2번 도형의 모양, 2번 도형의 좌표를 얻는다.
*********************************************/
void Timer(int Value)
{
/* 도형을 맞추면 사라지는 조건 */
if(Line_Y < Counter)
{
Line_Y = Line_Y + Level;
if(TargetShape == ShapeNow)
{
if((TargetX-0.02 < Center[0]) & (Center[0] < TargetX+0.2-0.02)) // 사각형이 사라지는 조건
{
Counter = 1.53-TargetY;
}
if((TargetX-0.02 < Center[1]) & (Center[1] < TargetX+0.2-0.02)) // 삼각형이 사라지는 조건
{
Counter = 1.7-TargetY;
}
}
else Counter = 3.2f;
}
else
{
/* reset */
Line_Y = 0.0; Line_X = -0.7;
Random();
TargetShape= random(9) % 2;
/* color reset*/
if(ColorIndex >= 8) ColorIndex = 0;
else ColorIndex = ColorIndex + 1;
}
glutPostRedisplay( );
glutTimerFunc(30, Timer, 1);
}
void SpecialKey(int KeyPressed, int x, int y)
{
switch (KeyPressed)
{
case GLUT_KEY_LEFT:
Line_X = Line_X - 0.05; // move left
break;
case GLUT_KEY_RIGHT:
Line_X = Line_X + 0.05; // move right
break;
case GLUT_KEY_DOWN:
Line_Y = Line_Y + 0.03; // move down
break;
}
}
void GeneralKey(unsigned char KeyPressed, int x, int y)
{
switch (KeyPressed)
{
case '1': // 1 : Square
if(ShapeNow == 1) // Triangle ?
{
glutDisplayFunc(MovingSquare);
Line_Y = Line_Y - 0.1; // coordinates error control
}
break;
case '2': // 2 : Triangl
if(ShapeNow == 0) // Square ?
{
glutDisplayFunc(MovingTriangle);
Line_Y = Line_Y + 0.1; // coordinates error control
}
break;
case 32:
if(Level != 0.00)
{
Pause = Level; // Drop Speed
Level = 0.00; // Stop!
}
else
{
Level = Pause; // Restarting Drop
}
break;
case 'q':
case 81: // ASCII Code : 'Q'
case 27: // ASCII Code : ESCcape
exit(0); // Exit The Program
}
}
void MainMenu(int entryID)
{
if(entryID == 1) Level = 0.01; //speed control
else if(entryID == 2) Level = 0.02;
else if(entryID == 3) Level = 0.03;
else if(entryID == 4) Level = 0.06;
}
/***********************
* main
***********************/
int main(int argc, char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(300, 600);
glutInitWindowPosition(0, 0);
glutCreateWindow("MyTarget!!");
glClearColor (1.0, 1.0, 1.0, 1.0);
/* Start the main loop*/
Random();
/* Reshape, Timer Callback*/
glutReshapeFunc(Reshape);
glutTimerFunc(40, Timer, 1);
/* Menu Callback */
GLint MainMenuID = glutCreateMenu(MainMenu);
glutAttachMenu(GLUT_RIGHT_BUTTON);
/* Menu Output*/
glutAddMenuEntry("Level 1", 1);
glutAddMenuEntry("Level 2", 2);
glutAddMenuEntry("Level 3", 3);
glutAddMenuEntry("Level 4", 4);
/* Keyboard Callback*/
glutSpecialFunc(SpecialKey);
glutKeyboardFunc(GeneralKey);
glutMainLoop( );
return 0;
}
void boom()
{
glColor3f(1.0,0.0,0.0)
glBegin(GL_POLYGON)
glVertex3f(
}