작은 그래픽 라이브러리이다. 그래픽 과제를 진행하면서 X-window와 Cocoa에 대한 배경지식이 없어도 우리가 화면에 그래픽을 구현할 수 있도록 주어지는 그래픽 라이브러리이다.
주로 유닉스 계열 운영체제에서 사용되는 윈도우 시스템이다.
X-window 시스템을 활용해 화면에 마우스 및 키보드 같은 입력장치의 상호작용을 관리해 GUI 환경을 구현할 수 있다.
X-window는 우리가 평소에 쓰던 윈도우 GUI와는 다르게 네트워크 프로토콜 기반의 GUI이다.
웹과 비슷하게 클라이언트와 서버 모델을 기반으로 하고 있다.
마우스 이동 명령 요청(x-client) -> 이동 명령 받음(x-server) -> 명령 요청 결과 응답(장치 출력 or x-client에게 전달)
apple에서 ios, macOS 등의 운영체제 app 제작시 사용하는 프레임워크
**화면을 연결해주는 함수.**
void * mlx_init(void)
**화면에 x-window를 띄우는 함수이다. 가로 세로 및 창 제목을 구성해준다.**
void * mlx_new_window ( void mlx_ptr, int size_x, int size_y, char *title );
**키보드나 마우스의 입력을 기다리거나 창의 일부분을 렌더하는 함수.**
int mlx_loop ( void *mlx_ptr );
**mlx 포인터, 파일주소, 가로 및 세로 크기를 가져와 메모리에 올리고 메모리 주소를 반환한다.**
void *mlx_xpm_file_to_image(void *mlx_ptr, char *filename, int *width, int *height)
**좌표를 지정해서 x-window 화면에 띄워준다.**
int mlx_put_image_to_window(void *mlx_ptr, void *win_ptr, void *img_ptr, int x, int y);
.ber 확장자를 보면 2차원 배열로 구성하는게 맞겠다 사람의 관점에서는 싶지만, 1차원 배열로 구성한다고 해도 별 문제는 없다.
11.......11 로 끝나는 문자열이라고 해도 x의 크기를 미리 변수에 담아둔다면 즉 예를 들어 x의 크기를 5라고 알아둔다면 그걸 기점으로 파싱하면 되기 때문이다.
void download_map(char *filename, t_game *game)
{
int fd;
char *line;
fd = open(filename, O_RDONLY);
if (fd <= 0)
occur_error();
//1. GNL함수로 line변수에 값을 저장한다.
line = get_next_line(fd);
2. 스텝 및 x, y의 크기에 대해서도 초기화 한다.
game->step_cnt = 0;
game->y = 0;
game->x = ft_strlen(line) - 1;
3.game->str에 첫 번째로 읽은 문자열을 담는다.
game->str = utils_strdup(line);
4. leak 방지를 위해서 free
free(line);
while (line != 0)
{
5. GNL로 한 줄씩 읽을 때마다 y++을 함으로써
높이를 알아내고,
.ber의 다음 줄을 line에 계속 담아주며
game->str 에다가 읽어온 문자열을 담아준다.
game->y++;
line = get_next_line(fd);
if (line != 0)
game->str = utils_strjoin(game->str, line);
}
close(fd);
}
1. 함수에서 KEY가 활성화될 때마다 on_key_press 함수가 실행된다.
mlx_hook(game->win, KEY_RELEASED, 0, &on_key_press, game);
2. evt는 숫자로 들어오게 되는데 header 파일에서 선언한 상수를 통해 함수를 매칭시킨다.
int on_key_press(int evt, t_game *game)
{
if (evt == W)
{
key_w(game);
}
else if (evt == S)
{
key_s(game);
}
else if (evt == A)
{
key_a(game);
}
else if (evt == D)
{
key_d(game);
}
else if (evt == ESC)
{
exit(EXIT_SUCCESS);
}
printf("%d Step!\n", game->step_cnt);
return (0);
}
3. while문을 이용해 i 변수에 캐릭터의 위치를 담아준다.
키에 따라 x를 + or - 해줌으로써 위치 이동을 시켜준다.
그리고 나서 현재 위치를 타일로 바꿔주고, 다음 좌표를 'P'로 바꿔준 후 새롭게 맵을 렌더한다.
void key_w(t_game *game)
{
int i;
i = 0;
while (i++ < ft_strlen(game->str))
{
if (game->str[i] == 'P')
{
printf("i == %d \n", i);
break ;
}
}
if (game->str[i - game->x] == 'C')
{
printf("x == %d \n", game->x);
game->obj_cnt++;
}
if (game->str[i - game->x] == 'E' && game->total_obj == game->obj_cnt)
end_game(game);
else if (game->str[i - game->x] != '1' && game->str[i - game->x] != 'E')
{
game->str[i] = '0';
game->str[i - game->x] = 'P';
game->step_cnt++;
set_map(game);
}
}
1. 직사각형 예외처리
// x와 y의 값을 미리 구조체에 저장했기에 둘의 값을 곱하면 알 수 있다.
void validate_rectangle(t_game *game)
{
if (game->x * game->y != ft_strlen(game->str))
occur_error();
}
2. 벽 예외처리
// 첫 번째 조건문은 첫 번째 줄의 유효성을 검사한다.
// 세 번째 조건문은 마지막 줄의 유효성을 검사한다.
// 두 번째 조건문은 그 둘을 제외한 사이의 줄 유효성을 검사한다.
void validate_wall(t_game *game)
{
int i;
i = 0;
while (i < ft_strlen(game->str))
{
if (i < game->x)
{
if (game->str[i] != '1')
occur_error();
}
else if (i % game->x == 0 || i % game->x == i % game->x - 1)
{
if (game->str[i] != '1')
occur_error();
}
else if (i > ft_strlen(game->str) - game->x)
{
if (game->str[i] != '1')
occur_error();
}
i++;
}
}
3. 카운트 예외처리
// 도착지가 없거나 플레이어가 없거나 혹은 다수이거나 오브젝트가 없으면 에러를 발생시킨다.
void validate_count(t_game *game)
{
int i;
int end_point;
int player;
i = 0;
end_point = 0;
player = 0;
game->obj_cnt = 0;
game->total_obj = 0;
while (i++ < ft_strlen(game->str))
{
if (game->str[i] == 'E')
end_point++;
else if (game->str[i] == 'P')
player++;
else if (game->str[i] == 'C')
game->total_obj++;
}
if (end_point == 0 || player == 0 || player > 1 || game->total_obj == 0)
occur_error();
}