태그 보관물: c++

c++

Minecraft와 같은 블록 세계를 다루는 방법 블록 세계로 간단한

Minecraft와 같은 블록 세계로 간단한 게임을 만들고 싶습니다. 내 이론적 질문은 재생 중에이 블록 정보를 처리하는 가장 좋은 방법은 무엇입니까? 내 첫 번째 아이디어는 거대한 배열이지만 메모리가 부족하다고 생각합니다. 어쩌면 나는 플레이어 근처에 블록을로드해야합니다.

파일에서 필요한 블록 정보로드와 메모리에서 필요한 정보 만 보유하는 것을 어떻게 처리 할 수 ​​있습니까?



답변

Minecraft와 같은 블록으로 게임에 대한 데이터를 저장하는 몇 가지 방법이 있습니다.

내가 마인 크래프트가하는 방식은 16x16x256 청크에서 세상을 깨뜨리는 것입니다. 플레이어가 게임을 시작할 때 플레이어 주위의 청크가 메모리에로드 된 다음 걸 으면 백그라운드 스레드가 더 많이로드됩니다. : 여기 쇼가 비디오입니다 http://www.youtube.com/watch?v=oR_ZdJH9eho은 .

또 다른 방법은 세상을 옥트리로 나누는 것입니다. Michael Goodfellow는이 데이터 구조로 큐브 세계를 구현하는 방법에 대한 블로그 ( http://www.sea-of-memes.com/LetsCode1/LetsCode1.html)를 작성했습니다 . Octree는 압축 기능을 제공하기 때문에 좋지만 Array를 사용하는 것이 조금 더 어려울 것입니다.

“메모리에 필요한 것만 유지하는 방법” “필요한”항목을 요청해야하기 때문에 조금 더 어렵습니다. 환경과 상호 작용하는 AI로 세계의 다른 지역에 살고있는 NPC가 있다면 더 많은 세계가 메모리에 있어야합니다. 복셀 세계 데이터는 매우 빠르게 커질 수 있으므로 가능한 한 적은 양의 메모리를 유지하는 것이 가장 좋습니다. (IE, 플레이어 근처에 NPC 만 있습니다).

그래픽 엔진은 다른 불투명 블록으로 완전히 둘러싸이지 않은 모든 블록을 “필요”합니다. 월드를 렌더링하는 일반적인 방법은 모든 보이는 블록의 정점을 포함하는 단일 메시를 만드는 것입니다. 65,536 블록 (Minecraft 크기 청크)에 대해 draw 메서드를 한 번만 호출하기 때문에 그리기가 훨씬 빠릅니다. 그래픽 엔진은이 메시를 빌드해야하므로 일반적으로 청크의 모든 큐브를 알아야합니다. 이것이 Minecraft의 바닥을 볼 때 많은 세계가 보이지 않는 이유입니다. 모든 6면에 둘러싸인 모든 블록을 건너 뛰기 때문입니다. Minecraft는 동일한 종류의 질감의 가로면을 질감이 반복되는 한 상자에 결합하여 정점 수를 줄입니다.

내 조언은 16x16x256 덩어리와 함께하는 것입니다. 메시 및 게임 로직 (충돌 감지, 블록 추가 / 제거 등)을 구축하기 때문에 빠른 반복 및 편집이 필요하므로 Array에 저장하십시오. 그런 다음 플레이어 주위의 원 안에 가능한 많은 청크를로드하십시오. 더 나은 또는 나쁜 컴퓨터를 위해 청크 수를 늘리거나 줄입니다.

청크의 로딩은 성능에 큰 타격을 줄 수 있으므로 시간이 지남에 따라 실행되는 스레드에 넣으십시오. 플레이어가 청크의 한쪽 끝에서 다른 쪽 끝으로 걸어가는 동안 3 개의 새로운 청크를 완전히로드 할 수 있도록 만드십시오.


답변

나는 그것을 설명하는 가장 좋은 방법이 없을 수도 있지만 시도 할 것입니다.

더 효율적으로 만드는 방법을 이해하는 가장 좋은 방법은 복셀을 이해하는 것입니다. Minecraft는 복셀 기반이며 구 등 대신 큐브를 사용합니다.

기본적으로 복셀은 동적으로 볼륨을 변경할 수 있고 볼륨이 변경 될 때 모양도 변할 수있는 3D 모양입니다. 청크는 X x X x 복셀 세트입니다. 예를 들어 16x16x16 복셀을 가진 청크를 가질 수 있고 X 개의 청크를 가질 수 있습니다. 플레이어가 청크에서 N보다 멀리 떨어져 있으면 계산에 포함시키지 않는 거리가 설정됩니다. 이것은 클리핑 거리와 비슷하지만 각 청크에도 적용해야합니다. 이런 식으로, 당신은 항상 3×3 덩어리 세트의 중앙 덩어리에 플레이어를 가질 수 있도록 가질 수 있습니다.

여러분이 가진 것은 개별 복셀을 처리하는 클래스입니다. 우리는 그것을 Voxel_cl이라고 부릅니다. 그런 다음 Chunk_cl이라는 복셀 덩어리를 처리하는 클래스가 있습니다. 그런 다음 복셀을 생성하는 모든 청크를 생성하는 World_cl이라는 월드 클래스가 있습니다.

이제는 모든 것의 거대한 배열 대신 언제든지 9 개의 덩어리가 배열되고 덩어리 클래스에는 4096 개의 복셀 배열이 있습니다.

이것은 매우 간단한 설명입니다. 나는 현재 복셀을 사용하여 무언가를 연구하고 있으므로 입력을 던질 것이라고 생각했습니다 =-)

복셀에 대한 자세한 내용은 http://en.wikipedia.org/wiki/Marching_cubes를 확인하십시오 .


답변

렌더러는 보이는 표면 만 렌더링하는 반면, 컴퓨터는 백그라운드에서 블록 데이터를 처리하는 반면 렌더러는 보이는 것과 만 작동합니다. 8×8 청크는 다루기가 더 쉬울 것입니다.


답변