2015-01-11 3 views
1

게임의 전체지도를 메모리에로드하려고 시도했을 때 원하는 것보다 조금 더 커졌습니다. 지도를 여러 조각으로 나눠 넣으려고합니다. 내 게임의지도는 쉼표로 구분됩니다. 지도 문자열의 일부 샘플 : "0, 0, 45, 32, 3, 0, 0,"n 번째 문자와 다른 n 번째 문자 사이의 문자열 추출

현재 다음을 사용하고 있지만 9 초 (내지도가 큽니다)가 걸립니다.

String[] mapArr = map.split(", "); 
short[] groundLayer = new short[chunkWidth * chunkHeight]; 
//code that fills in the groundLayer array 

플레이어가 한 방향으로 너무 멀리 걸 으면 9 초 동안 기다리면 작동하지 않습니다.

내 생각 엔 'map String'에서 쉼표 (int firstComma)에서 쉼표 (int lastComma)로 부분 문자열을 처리하는 것이 었습니다.

firstComma = characterX + (characterY * mapWidth); 
lastComma = firstComma + (chunkWidth * chunkHeight); 

그런 다음 결과 하위 문자열 만 분할합니다 (","). 성능이 현명한 좋은 생각입니까?

이와 같은 작업을 수행하는 가장 효율적인 방법은 무엇입니까? substring, regex, indexOf, 뭔가 다른가요? 어떤 도움이라도 대단히 감사 할 것입니다.


편집 아래에서 더 컨텍스트 제공 :

내지도는 여러 레이어로 구성되어 있습니다 그리고 나는 내보낼/그릴 '타일'를 사용합니다. 다음은 파일을 읽고 짧은 배열로 저장하는 방법입니다. 오히려 전체지도 문자열을 분할보다 내가 문자 Y. 여기

try { 
    String map = readFile("res/images/tiles/MyFirstMap-building-p.json"); 
    String[] strArr = map.split(", "); 

    buildingLayer = new short[chunkWidth * chunkHeight]; 
    short arrayIndex = 0; 
    for(short y = 0; y < chunkHeight; y++) { 
     for(short x = 0; x < chunkWidth; x++) { 
      //get the absolute position of the cell 
      short cellX = (short) (characterX + x - chunkWidth/2); 
      short cellY = (short) (characterY + y - chunkHeight/2); 
      if(cellX >= 0 && cellX < mapWidth && cellY >= 0 && cellY < mapHeight) { //within bounds 
       buildingLayer[arrayIndex] = Short.parseShort(strArr[cellX + (cellY * mapWidth)]); 
      } else { //out of bounds, put down a placeholder 
       buildingLayer[arrayIndex] = 0; 
      } 
      arrayIndex++; 
     } 
    } 
} catch (IOException e) { 
    logger.fatal("ReadMapFile(building)", e); 
    JOptionPane.showMessageDialog(theDesktop, getStringChecked("message_file_locks") + "\n\n" + e.getMessage(), getStringChecked("message_error"), JOptionPane.ERROR_MESSAGE); 
    System.exit(1); 
} 


private static String readFile(String path) throws IOException { 
    FileInputStream stream = new FileInputStream(new File(path)); 
    try { 
     FileChannel fc = stream.getChannel(); 
     MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()); 
     return Charset.defaultCharset().decode(bb).toString(); 
    } 
    finally { 
     stream.close(); 
    } 
} 
+0

무작위 액세스 파일은 어떻습니까? 당신은 그 안에있는 각 블록의 위치를 ​​계산할 것이고 그것을 읽을 것입니다. 메모리에 모든 것을로드 할 필요가 없습니다. – MightyPork

+3

정말로 큰 데이터를 저장한다면 왜 그것을 문자열로 저장합니까? 지도에 바이너리 형식과 같은 것을 만들면 모든 것이 훨씬 효율적입니다. 이렇게하면 불필요한 문자열 오버 헤드가 아니라 실제로 필요한 데이터 만 저장하고 (데이터를 계산할 수 있습니다). – MinecraftShamrock

+0

잘 그것은 다음과 같은 형식입니다 ... 0, 0, 3, 0, 2, ... 분할을 사용하여 직접 짧은 배열로 추출 할 수 있습니까? – KisnardOnline

답변

0

에 문자 X 만 분할을 시도하고 나는 (I 단순 목적으로 루프 로직을 많이 제거)와 함께 갔다 솔루션입니다. 의견에 도움을 주신 @Elliott Frisch에게 감사드립니다.

private static short[] scanMapFile(String path, int[] leftChunkSides, int[] rightChunkSides) throws FileNotFoundException { 
    Scanner scanner = new Scanner(new File(path)); 
    scanner.useDelimiter(", "); 

    short[] tmpMap = new short[chunkWidth * chunkHeight]; 
    int count = 0; 

    while(scanner.hasNext()){ 
     tmpMap[count] = scanner.nextShort();  
     count++; 
    } 

    scanner.close(); 
    return tmpMap; 
} 
관련 문제