42Seoul - so_long

devicii·2022년 5월 2일
0

42

목록 보기
5/8
post-thumbnail

선행지식

1. minilibX ?

작은 그래픽 라이브러리이다. 그래픽 과제를 진행하면서 X-windowCocoa에 대한 배경지식이 없어도 우리가 화면에 그래픽을 구현할 수 있도록 주어지는 그래픽 라이브러리이다.

- X-window

주로 유닉스 계열 운영체제에서 사용되는 윈도우 시스템이다.
X-window 시스템을 활용해 화면에 마우스 및 키보드 같은 입력장치의 상호작용을 관리해 GUI 환경을 구현할 수 있다.

  • X-window는 우리가 평소에 쓰던 윈도우 GUI와는 다르게 네트워크 프로토콜 기반의 GUI이다.

  • 웹과 비슷하게 클라이언트와 서버 모델을 기반으로 하고 있다.

    	마우스 이동 명령 요청(x-client) -> 이동 명령 받음(x-server) -> 명령 요청 결과 응답(장치 출력 or  x-client에게 전달)

- Cocoa

apple에서 ios, macOS  등의 운영체제 app  제작시 사용하는 프레임워크

함수

mlx_init

**화면을 연결해주는 함수.**

void * mlx_init(void)

mlx_new_window

**화면에 x-window를 띄우는 함수이다. 가로 세로 및 창 제목을 구성해준다.**

void * mlx_new_window ( void mlx_ptr, int size_x, int size_y, char *title );

mlx_loop

 **키보드나 마우스의 입력을 기다리거나 창의 일부분을 렌더하는 함수.**

int mlx_loop ( void *mlx_ptr );

mlx_xpm_file_to_image

**mlx 포인터, 파일주소, 가로 및 세로 크기를 가져와 메모리에 올리고 메모리 주소를 반환한다.**

void *mlx_xpm_file_to_image(void *mlx_ptr, char *filename, int *width, int *height)

mlx_put_image_to_window

**좌표를 지정해서 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();
}

참고자료

youjeon님 so_long 정리글

M1으로 minilibx 사용하는 법

profile
Life is a long journey. But code Should be short :)

0개의 댓글