mlx_hook은 window가 유지되는 동안 event가 발생하면 callback함수를 실행하는 함수입니다.
#define KEY_PRESS 2
#define EXIT_BUTTON 17
mlx_hook(game.win_ptr, KEY_PRESS, 0, &key_press, &game);
mlx_hook(game.win_ptr, EXIT_BUTTON, 0, &exit_game, &game);
mlx_hook의 두번째와 세번째 인자는 각각 x_event와 x_mask 값입니다.
X11/X.h을 참조하여 x_event와 x_mask에 대한 값을 알 수 있습니다.
mac os x에서는 mask값은 사용하지 않기 때문에 인자로 0을 넣어줍니다.
문서를 참고하여 event 값을 알아냅니다.
키를 입력 받았을때 실행할 callback함수와 종료상황일때 실행할 callback함수를 인자로 넣어줍니다.
mlx_hook에 등록된 callback함수는 아래와 같습니다.
int key_press(int keycode, t_game *game)
{
if (keycode == KEY_ESC)
// esc키를 눌렀을때
exit(0);
else if (!game->player.key_block)
// 플레이어가 이동을 완료했을때만
{
if (keycode == KEY_W)
move_dir(game, &(game->player), DIR_N);
else if (keycode == KEY_A)
{
move_dir(game, &(game->player), DIR_W);
game->player.look = DIR_W;
}
else if (keycode == KEY_S)
move_dir(game, &(game->player), DIR_S);
else if (keycode == KEY_D)
{
move_dir(game, &(game->player), DIR_E);
game->player.look = DIR_E;
}
}
return (0);
}
키가 입력되었다면 해당 keycode(macOS 키코드)를 인자로 받을 수 있습니다.
move_dir함수로 방향에 맞게 플레이어를 이동시켜 줍니다.
void move_dir(t_game *game, t_spr *sprite, int dir)
{
sprite->x0 = sprite->x;
sprite->y0 = sprite->y;
// 플레이어의 현재 좌표를 업데이트 해줌
sprite->dir = dir; //진행방향
if (!is_collision(game, sprite, dir))
// 진행방향에 벽이 있다면 움직일 수 없음
{
sprite->move = TRUE;
if (sprite == &(game->player))
game->step_cnt++;
}
else
sprite->move = FALSE;
sprite->walk = TRUE;
}
현재 플레이어가 서있는 좌표를 (x0, y0)에 업데이트해줍니다. (자세한 내용은 렌더링 부분에서 설명합니다.)
sprite->dir = dir
키입력에 맞게 진행하고자 하는 방향을 설정합니다.
입력받은 방향에 장애물이 있는지 확인하는 함수입니다.
int is_collision(t_game *game, t_spr *sprite, int dir)
{
int x;
int y;
char c;
x = game->vector[dir].x;
y = game->vector[dir].y;
c = game->map.pos[sprite->y + y][sprite->x + x];
if (c == '1')
return (1);
else if (c == 'E' && game->coin_num < game->map.c_cnt)
return (1);
return (0);
}
game->vector는 (x, y)방향을 나타내는 벡터를 의미합니다.
예를 들어 vector[DIR_EAST]는 (1, 0)입니다.
c는 플레이어가 가고자 하는 좌표입니다.
c에 장애물이 있는지 확인합니다.
장애물이 있다면 sprite->move = False가 됩니다.
sprite->walk는 장애물에 막혀 이동하지 못할 때에도 움직이는 애니메이션은 그려주기 위해 사용합니다.
walk와 move가 모두 true일때는 좌표를 옮기며 걷는 모션도 표현되지만,
walk만 true일 경우는 제자리에서 걷는 모션만 표현됩니다.
window 왼쪽 상단의 빨간 버튼을 누르면 프로그램을 종료하는 함수를 호출하도록 합니다.
mlx_hook(game.win_ptr, EXIT_BUTTON, 0, &exit_game, &game);