지난 포스팅에 이어짐
이제 user defined 함수들을 살펴보자.
5) void ofApp::drawPipe( )
//----------- Function for drawing pipe -----------
// consider : type of pipe, rotation, location
// pink pipe = a pipe which is waiting to be placed by user
// grey pipe = pipes already placed on the screen
void ofApp::drawPipe() {
if (currentP->pipe_type == 1) {
float x, y;
switch (currentP->rotation) {
case 1:
x = currentP->x;
y = currentP->y + 40;
ofSetColor(colorA, colorB, colorC);
ofDrawRectangle(x, y, 120, 40);
ofSetColor(colorA, colorD, colorE);
ofDrawRectangle(x + 105, y - 10, 15, 60);
break;
case 2:
x = currentP->x + 40;
y = currentP->y;
ofSetColor(colorA, colorB, colorC);
ofDrawRectangle(x, y, 40, 120);
ofSetColor(colorA, colorD, colorE);
ofDrawRectangle(x - 10, y + 105, 60, 15);
break;
case 3:
x = currentP->x;
y = currentP->y + 40;
ofSetColor(colorA, colorB, colorC);
ofDrawRectangle(x, y, 120, 40);
ofSetColor(colorA, colorD, colorE);
ofDrawRectangle(x, y - 10, 15, 60);
break;
case 4:
x = currentP->x + 40;
y = currentP->y;
ofSetColor(colorA, colorB, colorC);
ofDrawRectangle(x, y, 40, 120);
ofSetColor(colorA, colorD, colorE);
ofDrawRectangle(x - 10, y, 60, 15);
break;
}
}
else if (currentP->pipe_type == 2) {
float x, y;
switch (currentP->rotation) {
case 1:
x = currentP->x;
y = currentP->y + 40;
ofSetColor(colorA, colorB, colorC);
ofDrawRectangle(x, y, 40, 40);
ofDrawRectangle(x + 40, y, 40, 40);
ofDrawRectangle(x + 40, y + 40, 40, 40);
ofSetColor(colorA, colorD, colorE);
ofDrawRectangle(x + 30, y + 65, 60, 15);
break;
case 2:
x = currentP->x;
y = currentP->y + 40;
ofSetColor(colorA, colorB, colorC);
ofDrawRectangle(x, y, 40, 40);
ofDrawRectangle(x + 40, y, 40, 40);
ofDrawRectangle(x + 40, y - 40, 40, 40);
ofSetColor(colorA, colorD, colorE);
ofDrawRectangle(x, y - 10, 15, 60);
break;
case 3:
x = currentP->x + 40;
y = currentP->y;
ofSetColor(colorA, colorB, colorC);
ofDrawRectangle(x, y, 40, 40);
ofDrawRectangle(x, y + 40, 40, 40);
ofDrawRectangle(x + 40, y + 40, 40, 40);
ofSetColor(colorA, colorD, colorE);
ofDrawRectangle(x - 10, y, 60, 15);
break;
case 4:
x = currentP->x + 40;
y = currentP->y + 40;
ofSetColor(colorA, colorB, colorC);
ofDrawRectangle(x, y, 40, 40);
ofDrawRectangle(x + 40, y, 40, 40);
ofDrawRectangle(x, y + 40, 40, 40);
ofSetColor(colorA, colorD, colorE);
ofDrawRectangle(x + 65, y - 10, 15, 60);
break;
}
}
else if (currentP->pipe_type == 3) {
float x, y;
switch (currentP->rotation) {
case 1:
x = currentP->x;
y = currentP->y + 40;
ofSetColor(colorA, colorB, colorC);
ofDrawRectangle(x, y, 40, 40);
ofDrawRectangle(x + 40, y, 40, 40);
ofDrawRectangle(x + 40, y + 40, 40, 40);
ofSetColor(colorA, colorD, colorE);
ofDrawRectangle(x, y - 10, 15, 60);
break;
case 2:
x = currentP->x;
y = currentP->y + 40;
ofSetColor(colorA, colorB, colorC);
ofDrawRectangle(x, y, 40, 40);
ofDrawRectangle(x + 40, y, 40, 40);
ofDrawRectangle(x + 40, y - 40, 40, 40);
ofSetColor(colorA, colorD, colorE);
ofDrawRectangle(x + 30, y - 40, 60, 15);
break;
case 3:
x = currentP->x + 40;
y = currentP->y;
ofSetColor(colorA, colorB, colorC);
ofDrawRectangle(x, y, 40, 40);
ofDrawRectangle(x, y + 40, 40, 40);
ofDrawRectangle(x + 40, y + 40, 40, 40);
ofSetColor(colorA, colorD, colorE);
ofDrawRectangle(x + 65, y + 30, 15, 60);
break;
case 4:
x = currentP->x + 40;
y = currentP->y + 40;
ofSetColor(colorA, colorB, colorC);
ofDrawRectangle(x, y, 40, 40);
ofDrawRectangle(x + 40, y, 40, 40);
ofDrawRectangle(x, y + 40, 40, 40);
ofSetColor(colorA, colorD, colorE);
ofDrawRectangle(x - 10, y + 65, 60, 15);
break;
}
}
}
이번 포스팅의 user defined 코드들을 살펴보면 비로소 파이프 게임이 굴러가는 방식을 확인할 수 있다.
일단 drawPipe 함수는 파이프의 모양을 읽어 화면에 그리는 역할의 함수이다.
drawPipe 함수는 크게 3가지 파트로 나뉘어져 있으며, 각 파트는 다시 4가지 파트로 나뉜다.
파이프의 회전 각도나 파이프의 종류는 rotation과 pipe_type 변수 값을 통해 구별할 수 있다.
파이프의 종류는 총 3가지, 회전 각도는 총 4가지 이므로 drawPipe 함수는 3가지의 파이프의 종류에 대해 각각 4가지 의 roation 경우를 다룬다. 이는 코드를 보면 쉽게 이해할 수 있는데, 결과적으로 rotation 과 pipe_type 변수 값에 따라 다른 모양의 파이프가 화면에 표시되는 것이다.
현재 파이프는 핑크색으로, 이미 배치된 파이프는 회색으로 그려진다.
현재 파이프가 표시되는 위치는 파이프를 새롭게 배치할 때 마다 업데이트 되고,
이미 배치된 파이프의 위치 정보는 파이프 연결리스트에 저장되어 있어 draw 함수에서 해당 정보를 읽고 배치된 파이프를 모두 그린다.
7) void ofApp::addPath( )
//----------- Function for addning water nodes in water linked list -----------
// save every location water will go by : according to the pipes placed on the screen
// on every location the small blue circle will be drawn (water path)
void ofApp::addPath() {
if (currentP->pipe_type == 1) {
struct water *w;
w = (struct water*)malloc(sizeof(struct water));
switch (currentP->rotation) {
case 1:
w->x = currentP->x + 1; w->y = currentP->y + 60;
w->next = NULL;
endW->next = w; endW = w;
for (int i = 1; i < 120; i++) {
struct water *w;
w = (struct water*)malloc(sizeof(struct water));
w->x = endW->x + 1; w->y = endW->y;
w->next = NULL;
endW->next = w; endW = w;
}
pxNew = currentP->x + 120;
pyNew = currentP->y;
break;
case 2:
w->x = currentP->x + 60; w->y = currentP->y + 1;
w->next = NULL;
endW->next = w; endW = w;
for (int i = 1; i < 120; i++) {
struct water *w;
w = (struct water*)malloc(sizeof(struct water));
w->x = endW->x; w->y = endW->y + 1;
w->next = NULL;
endW->next = w; endW = w;
}
pxNew = currentP->x;
pyNew = currentP->y + 120;
break;
case 3:
w->x = currentP->x + 119; w->y = currentP->y + 60;
w->next = NULL;
endW->next = w; endW = w;
for (int i = 1; i < 120; i++) {
struct water *w;
w = (struct water*)malloc(sizeof(struct water));
w->x = endW->x - 1; w->y = endW->y;
w->next = NULL;
endW->next = w; endW = w;
}
pxNew = currentP->x - 120;
pyNew = currentP->y;
break;
case 4:
w->x = currentP->x + 60; w->y = currentP->y + 119;
w->next = NULL;
endW->next = w; endW = w;
for (int i = 1; i < 120; i++) {
struct water *w;
w = (struct water*)malloc(sizeof(struct water));
w->x = endW->x; w->y = endW->y - 1;
w->next = NULL;
endW->next = w; endW = w;
}
pxNew = currentP->x;
pyNew = currentP->y - 120;
break;
}
}
else if (currentP->pipe_type == 2) {
struct water *w;
w = (struct water*)malloc(sizeof(struct water));
switch (currentP->rotation) {
case 1:
w->x = currentP->x + 1; w->y = currentP->y + 60;
w->next = NULL;
endW->next = w; endW = w;
for (int i = 1; i < 60; i++) {
struct water *w;
w = (struct water*)malloc(sizeof(struct water));
w->x = endW->x + 1; w->y = endW->y;
w->next = NULL;
endW->next = w; endW = w;
}
for (int i = 1; i < 60; i++) {
struct water *w;
w = (struct water*)malloc(sizeof(struct water));
w->x = endW->x; w->y = endW->y + 1;
w->next = NULL;
endW->next = w; endW = w;
}
pxNew = currentP->x;
pyNew = currentP->y + 120;
break;
case 2:
w->x = currentP->x + 60; w->y = currentP->y + 1;
w->next = NULL;
endW->next = w; endW = w;
for (int i = 1; i < 60; i++) {
struct water *w;
w = (struct water*)malloc(sizeof(struct water));
w->x = endW->x; w->y = endW->y + 1;
w->next = NULL;
endW->next = w; endW = w;
}
for (int i = 1; i < 60; i++) {
struct water *w;
w = (struct water*)malloc(sizeof(struct water));
w->x = endW->x - 1; w->y = endW->y;
w->next = NULL;
endW->next = w; endW = w;
}
pxNew = currentP->x - 120;
pyNew = currentP->y;
break;
case 3:
w->x = currentP->x + 119; w->y = currentP->y + 60;
w->next = NULL;
endW->next = w; endW = w;
for (int i = 1; i < 60; i++) {
struct water *w;
w = (struct water*)malloc(sizeof(struct water));
w->x = endW->x - 1; w->y = endW->y;
w->next = NULL;
endW->next = w; endW = w;
}
for (int i = 1; i < 60; i++) {
struct water *w;
w = (struct water*)malloc(sizeof(struct water));
w->x = endW->x; w->y = endW->y - 1;
w->next = NULL;
endW->next = w; endW = w;
}
pxNew = currentP->x;
pyNew = currentP->y - 120;
break;
case 4:
w->x = currentP->x + 60; w->y = currentP->y + 119;
w->next = NULL;
endW->next = w; endW = w;
for (int i = 1; i < 60; i++) {
struct water *w;
w = (struct water*)malloc(sizeof(struct water));
w->x = endW->x; w->y = endW->y - 1;
w->next = NULL;
endW->next = w; endW = w;
}
for (int i = 1; i < 60; i++) {
struct water *w;
w = (struct water*)malloc(sizeof(struct water));
w->x = endW->x + 1; w->y = endW->y;
w->next = NULL;
endW->next = w; endW = w;
}
pxNew = currentP->x + 120;
pyNew = currentP->y;
break;
}
}
// 이어서
// 이어서
else if (currentP->pipe_type == 3) {
struct water *w;
w = (struct water*)malloc(sizeof(struct water));
switch (currentP->rotation) {
case 1:
w->x = currentP->x + 60; w->y = currentP->y + 119;
w->next = NULL;
endW->next = w; endW = w;
for (int i = 1; i < 60; i++) {
struct water *w;
w = (struct water*)malloc(sizeof(struct water));
w->x = endW->x; w->y = endW->y - 1;
w->next = NULL;
endW->next = w; endW = w;
}
for (int i = 1; i < 60; i++) {
struct water *w;
w = (struct water*)malloc(sizeof(struct water));
w->x = endW->x - 1; w->y = endW->y;
w->next = NULL;
endW->next = w; endW = w;
}
pxNew = currentP->x - 120;
pyNew = currentP->y;
break;
case 2:
w->x = currentP->x + 1; w->y = currentP->y + 60;
w->next = NULL;
endW->next = w; endW = w;
for (int i = 1; i < 60; i++) {
struct water *w;
w = (struct water*)malloc(sizeof(struct water));
w->x = endW->x + 1; w->y = endW->y;
w->next = NULL;
endW->next = w; endW = w;
}
for (int i = 1; i < 60; i++) {
struct water *w;
w = (struct water*)malloc(sizeof(struct water));
w->x = endW->x; w->y = endW->y - 1;
w->next = NULL;
endW->next = w; endW = w;
}
pxNew = currentP->x;
pyNew = currentP->y - 120;
break;
case 3:
w->x = currentP->x + 60; w->y = currentP->y + 1;
w->next = NULL;
endW->next = w; endW = w;
for (int i = 1; i < 60; i++) {
struct water *w;
w = (struct water*)malloc(sizeof(struct water));
w->x = endW->x; w->y = endW->y + 1;
w->next = NULL;
endW->next = w; endW = w;
}
for (int i = 1; i < 60; i++) {
struct water *w;
w = (struct water*)malloc(sizeof(struct water));
w->x = endW->x + 1; w->y = endW->y;
w->next = NULL;
endW->next = w; endW = w;
}
pxNew = currentP->x + 120;
pyNew = currentP->y;
break;
case 4:
w->x = currentP->x + 119; w->y = currentP->y + 60;
w->next = NULL;
endW->next = w; endW = w;
for (int i = 1; i < 60; i++) {
struct water *w;
w = (struct water*)malloc(sizeof(struct water));
w->x = endW->x - 1; w->y = endW->y;
w->next = NULL;
endW->next = w; endW = w;
}
for (int i = 1; i < 60; i++) {
struct water *w;
w = (struct water*)malloc(sizeof(struct water));
w->x = endW->x; w->y = endW->y + 1;
w->next = NULL;
endW->next = w; endW = w;
}
pxNew = currentP->x;
pyNew = currentP->y + 120;
break;
}
}
}
addPath 함수는 물줄기가 흘러가야 할 경로를 저장하는 역할을 수행한다. 새롭게 파이프를 배치할 때 마다 물줄기 연결리스트에 계속 경로가 추가되는데, 이때 '경로'라는 것은 파이프의 가운데 위치 경로를 의미한다.
연결리스트에 저장된 경로를 어디까지 읽어 화면에 표시할 것 인지를 시간이 지날수록 점점 늘려 나가면,
마치 물줄기가 파이프를 따라 흘러가는 듯한 모양새로 표현된다.
위 코드가 긴 이유는 현재 배치하는 파이프의 모양과 각도에 따라 모양 3가지, 각도 4가지 : 총 12가지의 경우의 수에 대한 경로를 저장하도록 코드를 작성했기 때문이다...
코드 자체는 단순한 switch/case문의 반복이므로, 코드에 대한 세세한 설명은 생략하도록 하겠다.
이렇게 게임의 모든 구현이 끝났다!
아쉬운 점은 함수를 적극적으로 이용했다면 코드의 길이를 지금보다 훨씬 단축시킬 수 있었을 것 같다는 점...
그럼 다음 포스팅에서 이 간단한 게임이 어떻게 실행되는지를 확인해보자.
'Project' 카테고리의 다른 글
[C++] OpenFrameworks로 파이프 게임 만들기(5) : 게임 실행 결과 (0) | 2022.08.24 |
---|---|
[C++] OpenFrameworks로 파이프 게임 만들기(3) : 파이프 게임 구현_1 (1) | 2022.08.24 |
[C++] OpenFrameworks로 파이프 게임 만들기(2) : 파이프 게임 설계 (0) | 2022.06.26 |
[C++] OpenFrameworks로 파이프 게임 만들기(1) : 기본 설정 (0) | 2022.06.26 |