1️⃣ 목표
- 미니맵의 크기와 위치를 임의로 바꿀 수 있게 하는 것이 목표입니다.
- 추후에 구현할 3D이미지를 위해서 왠만하면 기존의 변수의 값이 변경되지 않도록 구현할 계획입니다. (사실 변수값들이 변경되어도 3D케스팅함수를 그에 맞춰서 구현하면되긴합니다만 필요할때만 스케일값을 조절하는쪽이 더 깔끔할 것같습니다.)
2️⃣ 이전 미니맵 배율구현과 바뀐 점
- 예전에 미니맵을 처음구현 했을때 오른쪽 아래에 고정되어 출력되도록 구현한적이 있습니다.
- 단순히 main.c파일에서 다음과 같이
mlx_new_image함수
를 이용하여 가로, 세로의 크기를 MINI_SCALE값을 곱한 크기로 생성되도록 만들었습니다. - 미니맵의 위치는
mlx_put_image_to_window
함수를 이용하여 이미지를 출력할때 위치를 지정해주어 그려주도록 만들었습니다.
god->img.ptr = mlx_new_image(god->mlx, (int)(MINI_SCALE * WINDOW_WIDTH), (int)(MINI_SCALE * WINDOW_HEIGHT));
mlx_put_image_to_window(god->mlx, god->win, img->ptr, (int)(WINDOW_WIDTH * (1 - MINI_SCALE)), (int)(WINDOW_HEIGHT * (1 - MINI_SCALE)));
- 하지만
god->img.ptr
는 미니맵뿐마아니라 추후에 구현할 3D케스팅화면까지도 출력해주어야 합니다. - 그렇기때문에 다음과 같이
mlx
의 창 크기에 맞춰서 생성해 주었습니다.
god->img.ptr = mlx_new_image(god->mlx, WINDOW_WIDTH, WINDOW_HEIGHT);
mlx_put_image_to_window(god->mlx, god->win, img->ptr, 0, 0);
mlx
해상도를 그대록 사용하여 img
포인터의 data
를 만들기 때문에 mlx_put_image_to_window함수
는 (0, 0)의 위치부터 출력해줘도 됩니다.- 그 대신에 애초에
img의 data
를 설정할때 위치 좌표를 지정하여 색이 설정되는 방식으로 구현을 바꿔주었습니다.
3️⃣ 미니맵의 배율과 위치를 케스팅하기
(1) 필요한 매크로 구현
/* Kinds of MAP_LOCATION */
# define LEFTUP_MAP (1)
# define LEFTDOWN_MAP (2)
# define RIGHTUP_MAP (3)
# define RIGHTDOWN_MAP (4)
# define MAP_LOCATION (LEFTDOWN_MAP)
# define MINIMAP_SCALE (0.5)
- 미니맵의 위치는 화면의 모서리 네곳이 될 수 있도록 종류를 매크로로 지정했습니다.
MAP_LOCATION
매크로에 원하는 위치의 값을 넣으면 설정이 가능하도록 했습니다.
(2) setting_map_location구현
void setting_map_location(int *x, int *y, int x2, int y2)
{
if (MAP_LOCATION == LEFTUP_MAP)
{
*x = (int)(MINIMAP_SCALE * x2);
*y = (int)(MINIMAP_SCALE * y2);
}
else if (MAP_LOCATION == LEFTDOWN_MAP)
{
*x = (int)(MINIMAP_SCALE * x2);
*y = (int)((1 - MINIMAP_SCALE) * TILE_SIZE * MAP_NUM_ROWS + MINIMAP_SCALE * y2);
}
else if (MAP_LOCATION == RIGHTUP_MAP)
{
*x = (int)((1 - MINIMAP_SCALE) * TILE_SIZE * MAP_NUM_COLS + MINIMAP_SCALE * x2);
*y = (int)(MINIMAP_SCALE * y2);
}
else if (MAP_LOCATION == RIGHTDOWN_MAP)
{
*x = (int)((1 - MINIMAP_SCALE) * TILE_SIZE * MAP_NUM_COLS + MINIMAP_SCALE * x2);
*y = (int)((1 - MINIMAP_SCALE) * TILE_SIZE * MAP_NUM_ROWS + MINIMAP_SCALE * y2);
}
}
- (1)번에서 만들어준 매크로값에 따라 변수가 설정되는 함수 입니다.
4️⃣ setting_map_location함수 적용하기
(1) 미니맵그리는 함수에 사용
void fill_squares(t_img *img, int x, int y, int color)
{
int i;
int j;
setting_map_location(&x, &y, x, y);
j = 0;
while (j < (int)(MINIMAP_SCALE * TILE_SIZE))
{
i = 0;
while (i < (int)(MINIMAP_SCALE * TILE_SIZE))
{
img->data[(int)(WINDOW_WIDTH) * (y + j) + (x + i)] = color;
i++;
}
j++;
}
}
setting_map_location함수
는 보통 img->data
변수에 색을 지정해주기 직전에 사용됩니다.
(2) player그리는 함수에 사용
int draw_player(t_god *god, t_player *player, t_img *img)
{
int x;
int y;
setting_map_location(&x, &y, player->x, player->y);
update_player(god);
for (int row = -(player->thickness) / 2; row <= (player->thickness) / 2; row++)
{
for (int col = -(player->thickness) / 2; col <= (player->thickness) / 2; col++)
{
img->data[WINDOW_WIDTH * (y + row) + (x + col)] = 0x0000FF;
}
}
draw_ray(god);
mlx_put_image_to_window(god->mlx, god->win, img->ptr, 0, 0);
return (0);
}
- 위에서도 역시
img->data
에 색을 적용하기 직전에 사용됐습니다. player->x, player->y
의 변수의 원본이 변경되지않고 새로운 변수(x, y)에 지정하여 사용했습니다.
(3) 광선(ray)그리는 함수에 사용
void draw_line(t_god *god, double dx, double dy)
{
double ray_x;
double ray_y;
int x;
int y;
double max_value;
ray_x = god->player.x;
ray_y = god->player.y;
max_value = fmax(fabs(dx), fabs(dy));
dx /= max_value;
dy /= max_value;
while (1)
{
if (!is_wall(ray_x, ray_y))
{
setting_map_location(&x, &y, ray_x, ray_y);
god->img.data[WINDOW_WIDTH * y + x] = 0xFF0000;
}
else
break;
ray_x += dx;
ray_y += dy;
}
}
draw_line함수
에서 dx, dy변수는 함수 내부에서 계산되었습니다. 하지만 setting_map_location
에 사용될 변수를 위하여 계산된 인자로 받도록 바꿔주었습니다.
5️⃣ 미니맵 출력해보기
MINIMAP_SCALE
의 값은 0.4
로 고정하였습니다.
< 왼쪽위 >
< 오른쪽위 >
< 왼쪽아래 >
< 오른쪽아래 >