[cub3d](8)미니맵 크기, 위치 설정기능 추가하기



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로 고정하였습니다.

< 왼쪽위 >

collision col-line

< 오른쪽위 >

collision row-line

< 왼쪽아래 >

collision col-line

< 오른쪽아래 >

collision row-line




© 2021.02. by kirim

Powered by kkrim