2009-06-22 4 views
3

프로젝트 용 RPG 게임을 완성하려하지만 게임 맵을 만드는 방법을 모릅니다. 그래픽 일 필요는 없지만 전체 맵과 각 타일의 코드가 정확해야합니다.Java로지도를 생성하는 방법은 무엇입니까?

지금까지, 나는 연결된 모든 타일을 포함하는 ArrayList를 사용하여 비 매트릭 맵을 (교수의 요청에 따라) 만드는 것에 대해 생각했습니다.

public abstract class Casella { 
/** 
* @uml.property name="tabellone" 
* @uml.associationEnd multiplicity="(1 1)" inverse="casella:Tabellone" 
* @uml.association name="contains" 
*/ 

private int id; 
private boolean free = true; 
private List adjacent; 
private List items; 
private Tabellone tabellone = null; 

public void in(){ 
    free = false; 
} 

public void out(){ 
    free = true; 
} 

} 

이 코드는 하나의 타일 (확장하는 클래스가 3 개)에 대한 코드입니다. 나는 함께 모이고지도를 만드는 방법에 대해서는 아직 모른다.

감사합니다.

+0

이 게임이 무엇인지, 그리고 어떤 종류의지도에 대해 더 자세히 설명해 주시겠습니까? 흥미로운 장소가 포함 된 세계지도? – akarnokd

+0

지도는 모든 게임마다 생성됩니다. 그것은 단지 하나의 레벨이고 모든 세포는 3 가지 종류 (도시, 언덕, 평야) 중 하나가 될 수 있습니다. 각 셀에는 4 가지 종류 중 하나 인 항목 (클래스 항목)도 포함될 수 있습니다. 캐릭터는 1 턴에 1 타일을 움직입니다. – Gurzo

답변

1

나는 이것을 adjacency 목록을 사용하여 관리했다. 각 셀에는 인접 셀의 인덱스가 포함 된 ArrayList가 있습니다. 이러한 인덱스는 셀의 Map ArrayList에있는 셀이 갖는 인덱스입니다.

http://en.wikipedia.org/wiki/Adjacency_list

9

구현을 시작하지 않으려면지도 사용 방법부터 시작하십시오. 그러면 구현 방법에 대한 제약이 생깁니다. 예 :

지도를 그릴 때 어떻게 접근합니까? 좌표로? 또는 "타일 X에서 서쪽으로"가면됩니까?

[편집] 나는 RPG 게임의 메인 루프부터 시작하는 것이 좋습니다. 문자/토큰을 어딘가에 배치해야합니다 (예 : 타일과 관련성이 있어야합니다).

그런 다음 문자를 이동해야합니다. 캐릭터는 현재 타일 (상대, 아이템, 타입)을 검사 할 수 있어야합니다. 어떻게 움직일 수 있는지 알 수있는 방법이 필요합니다 (즉, 오른쪽에 벽이 있습니까?)

이렇게하면 게임의 다른 객체를 렌더링하는 서비스 인지도에 대한 인터페이스가 제공됩니다. 인터페이스가 제공해야하는 것에 대한 아이디어가 있다면지도 (데이터 구조)를 구현하는 방법을 알 수 있어야합니다.

맵을 생성하는 데는 난수 생성기와 "상식"을 사용하십시오. 인접한 타일을보십시오 : 그들이 모두 도시 일 때이 타일은 아마도 도시 일 것입니다. 평원과 동일합니다. 언덕은 단 하나 품목이고, 빈번하지 않습니다.

이 코드를 실행하여 작동하는지 확인하려면 ASCII ("C", "P"lain, "H"ill)로 맵을 인쇄하십시오.

+0

나는 그것에 대해 전혀 모른다. 모든 타일에는 고유 한 ID가 있으므로이 작업을 수행하는 방식에는 코드가 필요하지 않다고 생각합니다. 하지만 아마도 좌표를 사용하는 것이 더 낫습니다. 정말 모르겠습니다 ... =/ 제안 사항이 있으십니까? – Gurzo

+1

이것은 시작하는 법을 모르는 이유입니다. 아직 앉아 있지 않아도 수업을 듣고 앉아야합니다. –

+0

당신은 좌표를 필요로하지 않을 것입니다. 그렇지 않으면 어떤 식 으로든 서로 관련이없는 게임 타일을 가지고있을 것입니다. 체스 보드를 생각해보십시오 : 모든 타일 (사각형)은 특정 좌표를 가지며, 그 사이의 관계는 잘 알려져 있고 고정되어 있습니다. – GalacticCowboy

0

타일 기반 맵인 경우 각 룸은 인접한 룸과 고정 된 관계를 갖습니다. 좌표가 걱정되지 않아도됩니다 (타일이 사각형이면 단순 할 수도 있지만). 그러나 방향에 대해 걱정할 필요가 있습니다.

타일이 사각형 인 경우 기수 방향 (n, s, e, w) 만 있으면됩니다. 헥스 타일이라면 1 ~ 6 번 출구 번호를 지정할 수 있습니다 (아마도 정적 최종 상수로). 그런 다음 각각의 인접한 타일은 그 출구와 함께이 타일에 링크 될 수 있습니다.

+0

헥스 타일 아이디어가 내가 찾고 있었던 것일 수 있습니다. 따라서 직각지도는 생성되지 않습니다 (교수가 그런지도를 원하지 않기 때문에). 그런 것을 어떻게 생성합니까? – Gurzo

0

Aaron에 의해 말했듯이, 먼저지도 좌표가 어떻게 될지 결정해야합니다.

그러나 X-Y-Z 좌표계에 구속되지 않습니다. 예를 들어 각 타일은지도의 다른 타일과 연결될 수 있습니다. 그것은 모두 당신이 그것을 어떻게 만들고 싶은가에 달려 있습니다.

당신은 RPG 게임을 제작하고 있다고 말하면, 캐릭터를 둘러싸고있는 지형을 잘 볼 수 있어야합니다. 다중 레벨인가? 캐릭터가 한 타일에서 다른 타일로 어떻게 이동합니까? 그 움직임이 한 방향일까요?

게임용지도를 디자인 할 때 문자 그대로 수십개의 질문이 있습니다.

코딩을 시작하기 전에 우선 잘 계획해야합니다.

+0

매우 간단한 RPG입니다. 하나의지도, 모든 상대를지도에서 죽이고 승리하십시오. 레벨 업은 아니지만 새로운 아이템을 얻을 수 있습니다. 무브먼트는 1 턴에 1 타일이 될 수 있습니다. – Gurzo

1

이 프로젝트에서 속도 나 메모리가 큰 관심사입니까? 그렇지 않다면 왜 2D 배열을 사용하지 않습니까? 이 개념화하기 쉬운

뭔가 여기에서

Casella map [][] = new Casella[xSize][ySize]; 

처럼, 단지 각 셀지도 타일 인 엑셀 스프레드 시트로 사진.

가는 길은 괜찮습니다. 때로는 약간의 개념화가 어렵습니다. 인접한 타일 목록이 있습니다. 따라서지도를 만들 때 어딘가에서 시작하고, 아마도 왼쪽 상단에서 시작하여 거기에서부터 시작하십시오.

지도를 설정하고 가장자리 항목을 결정하는 데 도움이되도록 중첩 된 for 루프를 사용할 수 있습니다.

for(int i = 0; i < XSIZE ; ++i) 
    for(int j = 0; j < YSIZE ; ++j) 
     if(j==0) //found left edge (i.e. no adjacent ones to the left) 
     if(j==(YSIZE)) //found right edge (you get the picture) 

가장자리를 루프를 사용하고 검사 점, 당신이해야합니다 가장자리 제외하고 각 타일 위, 아래, 뒤쪽으로 연결하고 전달 할 필요가하려고하는 것입니다 중 2 3 대신에 3 개의 링크가 있습니다.

+2

비고 : 당신은 결코 j == YSIZE를 얻지 못할 것입니다. 당신은 j == YSIZE - 1을 의미합니까? – akarnokd

+0

실험실 프로젝트이기 때문에 속도 나 메모리는 중요하지 않습니다. 배열을 사용하는 것이 이상적이며 쉬운 방법이지만, 교수는 직사각형 (매트릭스 기반) 맵을 원하지 않습니다.어쨌든, 내가 다른 길을 가지지 않으면 나는 아마 이것에 충실 할 것이고 너무 많이 신경 쓰지 않기를 바랄 것이다. – Gurzo

+0

감사합니다 kd304, 놓친 :) – amischiefr

3

매트릭스를 사용하지 않고 이와 같이 맵을 생성하려면 수정 된 너비 우선 검색 알고리즘을 사용하여 가운데 타일부터 시작하여 바깥쪽으로 맵을 채우는 것이 좋습니다. 우선, 인접한 타일 목록보다 조금 더 나은 것이 필요할 것입니다. 다음 타일을 저장하는 각 방향에 대해 하나씩 4 개의 변수를 가질 수 있습니다.

private Tabellone up = null; 
private Tabellone down = null; 
private Tabellone left = null; 
private Tabellone right = null; 

우리는 가장 가운데 타일로 시작한다고 가정 해 봅시다. 이제 방향의 몇 가지가 null인지 파악하고 각 방향에 대해 새 Tablellone 객체를 만들고이 현재 객체의 각 변수를 설정하고 생성 된 객체에서 적절한 반대 변수를 설정해야합니다. . 이 타일에 방향을 모두 작성하면

Tabellone adj = new Tabellone(); 
up = adj; 
adj.setDown(this); 

, 당신은 당신이 만든 다른 타일 중 하나를 선택하고 동일한 작업을 수행합니다. 이것은 너비 우선 탐색 알고리즘이 들어오는 곳입니다. 큐를 사용하여 생성 한 각 타일을 통과하고 길 찾기를 채울 수 있습니다. 알고리즘을 중지 시키려면 생성하려는 타일 수에 제한을 설정하고 카운터를 사용하여 생성 된 타일 수를 추적하십시오.

int count = 0; 
ArrayList<Tabellone> queue = new ArrayList<Tabellone>() 
queue.add(/*center tile*/); 
while (count < 100) { //if we want 100 tiles 
    //take out the center tile from the beginning of the array list, create a tile for each direction and add those tiles to the array list, then increment count by 1. 
} 

참고 : 당신이 사각형을 원한다면, 당신은뿐만 아니라 각각의 대각선 방향에 대한 변수가 필요 것, 다이아몬드 모양의 맵을 생성합니다 약자로이 알고리즘.

물론, 이것이 당신이 원하는 것보다 조금 복잡해 보인다면, 저는 좌표계를 추천 할 것입니다.

+0

아, 이거 야! 내가 제대로 작동하는지 지금 확인해 볼께! – Gurzo

+0

나는 이것을 시도했지만 여전히 질문이있다. 생성주기에는 무엇을 넣어야합니까? 나는 그것에 대해 생각해 봤지만 정확한 코드를 찾을 수는 없다. 그런 다음 인접한 타일을 다음과 같이 설정하는 방법을 만들었습니다. public void setUp (Casella tile) { \t \t up = tile; \t \t tile.setDown (this); \t} 그래서 타일을 놓치지 않고 한 번에 두 타일 사이의 링크를 설정합니다. 지도를 만들 때 어떤 도움이 필요합니까? – Gurzo

+0

setUp을 호출 할 때마다 ArrayList에 설정 한 타일을 넣어야합니다. 그런 다음 ArrayList에서 첫 번째 타일을 제거하고 동일한 작업 만 수행하면됩니다. – AlbertoPL

1

코드는 실제로 기능 요구 사항이 아니므로 정확하게 게임 /지도에 대해 알지 못해 정확한 것을 말하기 어렵습니다.

X 타일이 있고 순서가 인접하지 않은 맵을 사용한다고 가정하면 비 매트릭 솔루션이 가장 좋습니다. 일반적인 해결책은 비대칭 인접성을위한 인접성 목록 또는 대칭성을위한 인접성 목록을 사용하는 그래프처럼 모델링하는 것입니다 인접. 만약 당신이 입사 목록을 사용한다면 당신은 가장자리가 연결되어있는 꼭지점을 포함하는 가장자리 객체가 필요합니다. 인접 목록을 사용한다면 multimap을 사용하는 것이 좋습니다.

주문한 인접성이있는 비 매트 리 솔루션을 원한다면 AlbertoPL에 대한 해결책이 있습니다.

너비가 넓고 Y 타일이 길고 서로 옆에있는 타일이 인접하여 타일이 최대 4 개 및 최소 2 개 인접 타일을 가질 수 있다고 가정하면 매트릭스를 사용하여 타일로 이루어지며 매트릭 인접성에 의한 인접성을 나타냅니다. 그 생각은지도 [Y] [X]가지도 [Y + 1] [X]와 인접하고지도 [Y] [X + 1]와 반대입니다. 타일 [Y + 1] [X + 1]이 타일 [Y] [X]에 인접한 경우이 솔루션은 최대 6 및 최소 3 타일 인접성에 적합 할 수도 있습니다. 이것은지도를 쉽게 파싱 할 수 있으며 2 차원이므로 자연스럽게 모델링 할 수 있습니다. 단점은 타일이 설정되면 매트릭스를 변경하지 않고 인접성을 변경할 수 없다는 것입니다. 이 교수님이 제안한 바가 아니므로 직접하고 싶지는 않을 수도 있습니다. 그러나 (정적 인) 순서가 있으면이 방법이 가장 쉽습니다.

+0

처음 아이디어는 인접성 목록을 사용하는 것이 었습니다. 지금 나는 알베르토의 길을 만들려고 노력하고있다. 나는 당신의 방법을 이해 했으니, 감사합니다!^_^ – Gurzo

2

벽, 버기와 지역 모든 벽, 버기 게임의 영역을 개최한다 특수 컨테이너입니다.

private String level = 
      " ######\n" 
     + " ## #\n" 
     + " ##$ #\n" 
     + " #### $##\n" 
     + " ## $ $ #\n" 
     + "#### # ## # ######\n" 
     + "## # ## ##### ..#\n" 
     + "## $ $   ..#\n" 
     + "###### ### #@## ..#\n" 
     + " ##  #########\n" 
     + " ########\n"; 

이것은 게임 레벨입니다. 공간을 제외하고는 5 자입니다. 해시 (#)는 벽을 의미합니다. 달러 ($)는 이동할 상자를 나타냅니다. 점 (.) 문자는 상자를 이동해야하는 장소를 나타냅니다. 문자 (@)는 sokoban입니다. 그리고 마침내 개행 문자 (\ n)는 새로운 행을 시작합니다.

+0

내가 이것을 처음 보았을 때, 나는 nPush (http://npush.sourceforge.net) –

관련 문제