Minecraft와 같은 블록 세계를 다루는 방법


9

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

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


2
마인 크래프트는 한꺼번에 청크 (Chunks)라고하는 상당히 큰 큐브로 세상을로드합니다. 정확한 세부 정보를 잘 모르겠습니다. Minecraft 소스는 어떻게 된지 살펴보고 싶다면 쉽게 잡을 수 있습니다.
ratbum

마인 크래프트 위키 : minecraftwiki.net/wiki/Chunk
tom van green

이미 Minecraft의 덩어리에 대해 알고 있었지만 어쨌든 감사합니다.
danijar

이 블로그의 범위에 맞지 않는 복잡한 질문입니다.

답변:


9

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 개의 새로운 청크를 완전히로드 할 수 있도록 만드십시오.


감사합니다! MMO를 위해 클라이언트를 작성하고 있기 때문에 AI에 대해서는 아무것도 없습니다. NPC 계산은 서버에서 수행합니다. 한 가지 추가 사항 : 그래픽 엔진에는 "다른 모든 불투명 블록으로 완전히 둘러싸여 있지 않은 모든 블록"이 필요하지는 않습니다. 동굴이 있다면 플레이어는 중요하지 않은 것을 볼 수 없습니다. ;-)
danijar

2
플레이어가 볼 수없는 동굴에 대하여 ... 동굴이 완전히 막혔는지 판단하는 것보다 단지 동굴을 그리는 데 성능이 덜 사용되는 것 같습니다. 그리고 동굴을 그리지 않으면 블록을 제거하면 한 덩어리가 아닌 여러 덩어리에 대한 메시를 다시 생성해야합니다. 동굴을 배제하는 방법을 찾는 것이 좋을 것입니다. 나는 그것을 효율적으로 수행 할 수있는 방법을 생각할 수 없습니다 : D.
Thomas Marnell

3

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

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

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

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

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

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

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


3
마칭 큐브는 복셀 시각화에 관한 것입니다. 그리고 Minecraft는 그것을 사용하지도 않습니다. 그것은 단지 큐브를 그립니다. 바로 Marching Cubes 가하지 않는 것입니다.
Nicol Bolas

설명해 주셔서 감사합니다! 나는 전에 Voxels에 대해 들어 본 적이 없으며 내 프로젝트에 매우 중요합니다. 그러나 지금 질문이 남아 있습니다.
danijar

각 요소 에이 청크의 복셀 배열이 포함 된 니어 청크 배열을 만드는 것을 이해합니다. 그러나 플레이어가 세계에서 움직일 때 청크 배열 변경을 처리해야합니다. 저장 파일에서 필요한 청크를 읽어야합니까? 아니면 메모리에 보관하는 좋은 방법이 있습니까?
danijar

2
@danijar 약간의 사소한, 픽셀은 "picture element"의 약자이며, voxel은 "volume element"와 같은 방식으로 형성됩니다. 그것은 중요한 것이 아니지만, 복셀이라는 용어를 듣지 못했기 때문에 그것이 당신에게 흥미로울 수 있다고 생각했습니다.
Daniel Carlsson

1

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.