cub3D 구현과정

개발새발·2022년 4월 1일
1

42Cursus

목록 보기
13/29
post-thumbnail

Cub3D

1. Initialize

  • 항상 들고다닐 구조체(필요한 모든 정보를 담고 있음) 내부의 변수들 0으로 초기화
  • Map 정보 받을 linked list 생성, 초기화
  • buf, texture 배열 생성, 초기화

 

2. Parse

2-1. map.cub 예시

NO ./textures/NO.xpm
SO ./textures/SO.xpm
WE ./textures/WE.xpm
EA ./textures/EA.xpm

F 127, 127, 127
C 135, 206, 235

        111111111111111111111111
        1000000000110000000000001
        1011000001110000001000001
        100100000000000000000001
111111111011000001110000000000001
100000000011000001110111101111111
11110111111111011100000010001
11110111111111011101010010001
11000000110101011100000010001
10001000000000001100000010001
10000000000000001101010010001
11000001110101011111011110N0111
11110111 1110101 101111010001
11111111 1111111 111111111111

2-2. map.cub 규칙

Texture

  • 뱡향은 반드시 NO, SO, WE, EA 로 시작하는 총 4개의 .xpm파일경로만 명시되어 있어야 한다.
  • 방향(동서남북)과 xpm파일경로는 공백으로 구분된다.

Color

  • F(floor), C(ceiling)로 시작하는 두 가지의 색 정보만 주어져야 한다.
  • 0이상 255이하의 정수 3개(R,G,B)가 ,로 구분되어 제공된다.
  • 3개의 정수이기 때문에 ,는 2개만 존재해야 하며, 정수와 정수 사이에 공백의 유무와 개수는 상관없다.
  • Texture와 마찬가지로 F 또는 C와 색 정보는 공백으로 구분된다.

Map

  • 0 : 빈 공간
  • 1 : 벽
  • 공백 : 존재하지 않는 공간
  • N, S, W or E : 플레이어의 초기 위치 및 시점
  • 위 4가지 요소 이외의 정보가 있다면 유효하지 않은 map이다.
  • map은 벽으로 둘러쌓여 있어야 한다.
  • map 정보는 파일의 가장 마지막에 있어야 한다.
  • 플레이어의 위치 정보(N, S, W or E)는 하나만 존재해야 한다.
  • 플레이어의 위치 기준 동서남북엔 0 또는 1만 올 수 있다.
  • 공백 기준 동서남북엔 공백 또는 1만 올 수 있다.
    -> 공백은 오직 1하고만 맞닿을 수 있다.

2-3. 인자 유효성 검사

  • 프로그램 실행 형식 : ./cub3D map.cub
  • 전달 인자가 2개가 아니면(argc != 2) Error 발생시킨다.
  • 두 번째 인자는 반드시 .cub확장자여야 한다.

2-4. Parse .cub

  • .cub 파일 open()하고 gnl로 한 줄씩 받아오면서 Texture(NO, SO, EA, WE), Color(F, C), Map 정보를 차례대로 받아온다.
    • Texture : NO ./path_to_the_north_texture 형식이 맞으면 ft_split()으로 path만 가져와서 해당 파일 open()하고 mlx_xpm_file_to_image()mlx_get_data_addr()를 통해 texture 배열에 저장한다. (SO, EA, WE도 마찬가지) 총 4개의 texture 정보(동서남북)를 받아야한다.
    • Color : Floor, Ceiling 각각 0이상 255이하의 3개의 정수(R, G, B)가 쉼표 2개로 잘 구분되어 있다면 shift 연산을 사용해(T << 24 | R << 16 | G << 8 | B) 0xTTRRGGBB 형식으로 변환하여 저장한다. 총 2개의 color 정보(천장, 바닥)을 받아야한다.
    • Map : 한 줄 단위로 유효한 map인지 확인한다.
      • 테두리가 벽(1)으로 둘러 쌓여있는지
      • 0, 1, 공백, pos(플레이어의 초기 위치 및 시선)로만 이루어져 있는지
      • pos정보는 하나만 있는지
      • 나머지 정보는 배열에 옮겨 담고 확인
      • map의 가로 최댓값, 세로 최댓값 구하기
      • map의 정보를 linked list에 저장

 

3. Map 옮겨담기

  • map의 가로 최댓값 x 세로 최댓값 크기의 int형 이중 배열 생성, 초기화
  • 한 줄 단위로 list에 있는 map을 배열로 복사, 뒤에 남는 부분은 공백으로 초기화
  • map 유효성 검사 : 0공백, pos공백은 맞닿을 수 없다.
  • pos 정보(N, S, W or E)에 따라 player의 초기 위치 벡터, 방향 벡터, 카메라 평면 초기화

 

4. mlx_hook 설정

mlx_hook(info.win, KEY_EVENT_PRESS, 0, &key_press, &info);

  • ESC key 입력 들어오면 메모리 해제 후 프로그램 종료
  • W, A, S, D key 입력 들어오면 key flag 1로 설정

mlx_hook(info.win, KEY_EVENT_RELEASE, 0, &key_release, &info);

  • ESC key 입력 들어오면 메모리 해제 후 프로그램 종료
  • W, A, S, D key 입력 끊기면 key flag 0으로 설정

mlx_hook(info.win, KEY_EVENT_EXIT, 0, &exit_press, &info);

  • 마우스로 빨간색 x버튼 누르면 메모리 해제 후 프로그램 종료

mlx_loop_hook(info.mlx, &main_loop, &info);

  • Raycasting으로 계산되어 저장된 이미지 정보를 mlx_put_image_to_window() 함수로 창에 띄운다.
  • Raycasting 원리
  • key press로 입력된 player 위치 이동 반영

실행 시 초기 화면

profile
블록체인 개발 어때요

0개의 댓글