[예제]갤러그 만들기
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<time.h>
#include<Windows.h>
#define KEY_UP (256+72)
#define KEY_DOWN (256+80)
#define KEY_LEFT (256+75)
#define KEY_RIGHT (256+77)
#define KEY_SPACE 32
#define TARGET 5
void TargetCreate(int*, int*);
void gotoxy(int, int);
void PUnitRender(int, int);
void BulletReady(int*, int*, int *);
void BulletMove(int*, int*, int *);
void ClearXY(int*, int*);
int GetKey();
int Log(int*, int*, int*);
int t_x[TARGET], t_y[TARGET];
int score = 0;
void main()
{
int u_x = 20, u_y = 30;// 이건 유저의 위치
system("mode CON COLS=150 LINES=40"); //명령프롬포트 크기창
srand((unsigned)time(0)); // 랜덤을 현재시간 받아와서 랜덤성(불특정성) 강하게 만들어줌
for (int i = 0; i<TARGET; i++) // i = 0 부터 4까지 증가하면서 총 다섯번 반복하라.
{
t_x[i] = rand() % 20 + 10; // 타겟의 위치 지정 x축 10 ~ 29
t_y[i] = rand() % 10 + 10; // 타겟의 위치 지정 y축 10 ~ 19
}
TargetCreate(t_x, t_y); // 타겟 생성 함수 ( 아래쪽에 정의돼있다 )
while (1) // 무한반복
{
PUnitRender(u_x, u_y); // 유저 생성 함수
BulletReady(&u_x, &u_y, &score); // 총알 준비 함수, 근데 왜 굳이 해당 변수의 주솟값을 함수의 파라미터로 넣었을까?
// -> 그것은 외부 함수에서 접근해올 때 해당 변수가 지역변수이기때문에 수정(변화)이 안된다.
// 하지만 해당 변수의 메모리 주솟값에 직접 다가가서, 값의 내용을 변화시킨다면 변화가 된다.
// 여기서 변수의 주솟값을 함수의 파라미터로 넣은이유도 그런 이유에서다.
Log(&score, &u_x, &u_y); // 스코어와 유저위치 - 변수의 주솟값을 매개변수로 받은것으로 보아 변수값을 수시로 변화를 줄것임을 암시
}
}
int Log(int *sc, int * x, int* y) // 로그함수.. 스코어와 유저위치의 주솟값을 받는 함수가 되겠지.
{
gotoxy(50, 6); //
printf("score : %d\n\n", *sc); // 스코어의 주솟값 앞에 *를 붙여서 해당 값의 내용을 출력해낸다. (스코어는 수시로 변할 것이다)
gotoxy(50, 8); //
printf("User X : %d Y: %d\n\n", *x, *y); // X의 위치와 Y의 위치를 출력한다 .(X위치와 Y위치는 수시로 변할 것이다)
for (int i = 0; i<TARGET; i++) // 0 부터 4까지 증가하면서 총 5번 반복한다.
{
gotoxy(50, 10 + (i * 2)); //
printf("TARGET %d : X : %d Y : %d ", i, t_x[i], t_y[i]); // 타겟의 위치를 출력한다. (이 부분들은 고정 된 값들일 것이다)
}
return 0;
}
void BulletReady(int *x, int *y, int *sc) // 총알 준비 함수 ( 매개변수에 들어가는 값이 변할 수 있겠구나 )
{
int sel; // sel 변수는 GetKey();를 담을 변수가 될 것
sel = GetKey(); //
switch (sel) // switch 함수
{
case KEY_UP:
break;
case KEY_DOWN:
break;
case KEY_LEFT:
if ((*x) != 2) // x의 위치가 2가 아니라면
(*x)--; // 1만큼 왼쪽으로 가라. 그러니까 2라면은 아무런 움직임을 주지 않았다.
break;
case KEY_RIGHT:
if ((*x) != 100) // x의 위치가 100이라면
(*x)++; // 1만큼 오른쪽으로 가라. 그러니까 100이라면 아무런 움직임을 주지 않았다.
break;
case KEY_SPACE:
BulletMove(x, y, sc); // 스페이스바를 입력받았을 땐, 미사일 함수 출력 이게 이미 지금 위에서 보면 알다시피, BulletReady 함수에서 받을 때 주솟값으로 받았기때문에
// 여기서도 x,y,sc는 u_x의 주솟값을 의미한다. u_x의 내용은 포인터의 영향을 받는 순간부터 수시로 변할 수 있다.
}
}
void BulletMove(int *x, int *y, int *sc) // 미사일 함수를 짜보자. ( 매개변수에 들어가는 값의 변화가 있을 수 있겠구나 )
{
int hi = *y; // hi 라는 곳에 *(y주솟값) 그러니까 y값의 내용을 담는다. 왜 굳이 hi라는 새변수를 가져왔을까.. 아래의 ClearXY함수 매개변수에서 주솟값으로 이용하기위해
while (hi--) // 이것이 1 줄어든다.
{
Sleep(20); // 잠시 멈추어라
gotoxy(*x, hi); // x값의 내용, hi라는 곳으로 이동하라
printf("1"); //1 이라는 값으로 미사일 표시
if (*x == t_x[0] && hi == t_y[0]) // x값의 내용이 타겟의 x값과 같고, y값의 내용이 타겟의 y값과 같다면
*sc = *sc + 10; // 스코어가 10 올라갑니다.
if (*x == t_x[1] && hi == t_y[1]) // x값의 내용이 타겟의 x값과 같고, y값의 내용이 타겟의 y값과 같다면
*sc = *sc + 10; // 스코어가 10 올라갑니다.
if (*x == t_x[2] && hi == t_y[2]) // x값의 내용이 타겟의 x값과 같고, y값의 내용이 타겟의 y값과 같다면
*sc = *sc + 10; // 스코어가 10 올라갑니다.
if (*x == t_x[3] && hi == t_y[3]) // x값의 내용이 타겟의 x값과 같고, y값의 내용이 타겟의 y값과 같다면
*sc = *sc + 10; // 스코어가 10 올라갑니다.
if (*x == t_x[4] && hi == t_y[4]) // x값의 내용이 타겟의 x값과 같고, y값의 내용이 타겟의 y값과 같다면
*sc = *sc + 10; // 스코어가 10 올라갑니다.
ClearXY(x, &hi); // x 는 u_x
}
}
void ClearXY(int *x, int *y) // 총알이 날아간 흔적을 지우는 함수
{
gotoxy(*x, (*y) + 1); // x값은 유지되고, y의 값이 +1 되며 그 값을 지운다.
printf(" ");
}
int GetKey()
{
int keyinfo = _getch();
if (keyinfo == 0 || keyinfo == 224)
{
keyinfo = 256 + _getch();
}
return keyinfo;
}
void PUnitRender(int x, int y) // 비행기 생성함수
{
int ran[][3] = {
{ 0,1,0 },
{ 2,3,4 },
{ 5,0,5 } };
for (int i = 0; i<3; i++)
{
gotoxy(x, y + i);
for (int j = 0; j<3; j++)
{
switch (ran[i][j])
{
case 0:
printf(" ");
break;
case 1:
printf("△");
break;
case 2:
printf("◁");
break;
case 3:
printf("■");
break;
case 4:
printf("▷");
break;
case 5:
printf("@");
break;
}
}
printf("\n");
}
}
void TargetCreate(int* x, int* y)
{
for (int i = 0; i<TARGET; i++)
{
gotoxy(*(x + i), *(y + i)); // (x + 1) 라고하면 *(&x[1])와 같다.
printf("*");
}
}
void gotoxy(int x, int y)
{
COORD Pos;
Pos.X = x;
Pos.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Pos);
}