저는 플레이어 주변의 미니지도로 브라우저 게임을 만들고 있습니다. 다른 플레이어가있는 곳을 추적하고 누군가가 움직일 때마다이 미니 맵을 업데이트해야합니다. 나는 이것을 NodeJS와 CouchDB에서 구현하고있다. 내 디자인은 다음과 같습니다 :NodeJS에서 "sleep"을 에뮬레이트하려면 어떻게해야합니까?
나는 모든 변화하는 게임 데이터에 대한 데이터베이스를 가지고 있습니다. 이 데이터베이스에는 2 차원 배열의 기본지도 데이터가 들어있는 문서가 있는데이 격자의 각 사각형은이 배열의 요소로 표시됩니다. 여러 사용자가지도를 동시에 움직일 수 있었기 때문에 다른 사용자가 글을 쓰고있는 것처럼 읽을 수 없도록하는 방법이 필요했습니다 (많은 사용자가 읽는다면 잘못된 정보를 얻을 수 있습니다. 단일 문서 작성). 나는이 데이터베이스에서 개별 사각형을 나타내는 별도의 문서를 가지기로 결정했으며, 각 문서에는 해당 사각형이 "켜져"있는 플레이어와 해당 사각형과 관련된 다른 데이터가 있습니다. 기본적으로지도 문서는 정사각형 문서의 조회 테이블로만 사용됩니다. 이를 통해 전체 맵 문서를 다시 작성하지 않고도 단일 문서를 변경하고 동시 읽기 및 쓰기 문제를 해결할 수 있습니다.
그러나 내 문제는 사용자가 참조 용으로 사용할 수있는 미니 맵을 가져와야한다는 것입니다. 이 미니지도에는 주변 사각형의 문서가 있습니다. 이후이 모든 것을 동시에 필요로하기 때문에 데이터베이스에서 9 개의 사각형을 모두 가져 와서 단일 아약스 응답으로 반환한다고 생각했습니다. 내 문제는 내가 할 IO를 차단하는 양을 줄이는 것입니다. 지금 당장 데이터베이스에서 필요한 사각형을 요청하는 중첩 루프가 있습니다.
var miniMap = new Array();
var keyMap = new Object();
var numDone = 0;
for(i = position.y - 1, y = 0; i < position.y + 1 && i < map.length; i++, y++){
miniMap[i] = new Array();
for(v = position.x - 1, x = 0; v < position.x + 1 && v < map.length; v++, x++){
keyMap[map[i][v].id] = {'x': x, 'y': y};
gameDB.getDoc(map[i][v].id, function(er, doc){
var tPos = keyMap[doc._id];
miniMap[tPos.y][tPos.x] = doc;
numDone++;
});
}
}
내 문제,하지만 그 getDoc 비 차단, 그래서는 미니 맵에 광장 데이터를 설정할 때 나도 몰라 : 여기에 내 코드에서 보면 (위치 및지도가 전달됩니다)입니다 . 나는이 같은 일을 생각 :
while(numDone < 9){
sleep(10);
}
callback(miniMap);
이 CouchDB를 내 모든 데이터를 받고 완료하지만, 자바 스크립트가 슬립 기능을 가지고 있지 않을 때까지 내가 기다릴 수있게된다. 내가 찾은 가장 가까운 것은 setTimeout이지만, 그것은 또한 블로킹이 아니므로 CouchDB가 내 데이터를 가져 오는 것을 끝내기에는 타임 아웃을 위해 선택한 시간이 충분하다는 것을 100 % 확신 할 수는 없습니다.
기본적으로 나는 조건을 갖고 그것을 테스트 한 다음 조건이 거짓 일 경우 다시 이벤트 스택으로 반환하려고합니다. 이것은 내가이 일을 할 수있는 더 좋은 방법이 있나요 ... 꽤 끔찍한 보인다
function testCallback(data, condition, callback){
if(data < condition){
setTimeout(function(){
testCallback(data, condition, callback);
}, 10);
}else{
callback(data);
}
}
: 내가 생각 유일한 해결책은 같은 것을 할 것 재귀의 setTimeout 콜백을 가지고 있었다? 이 접근법을 포기하고 업데이트 된 데이터를 얻기 위해 여러 아약스 호출이 있어야만합니까? 차단 접근 방법을 선택해야합니까? 이 여러 노드 프로세스를 실행하는 데 필요하지 않는 한 나는 게임에 대해 잘 모르겠지만, 그것을
function getMiniMap(....., callback) { // supply the callback that sends the data
var miniMap = new Array();
var keyMap = new Object();
var numDone = 0;
...
numDone++;
if (numDone === 9) { // as soon as everything has been collected...
callback(miniMap); // ... call the send callback and supply it the miniMap
}
});
}
}
}
아, 그리고 당신의 데이터베이스 모델 정말 나쁜 :
지도 부분을 잘못하고 있다고 가정합니다. 모든 것을 데이터베이스 대신 메모리에 보관하는 것이 확실히 쉬운 방법 일 것입니다. 나는 내가 맵핑 문서에 모든 것을 넣고 재부팅 할 필요가있을 때만 상태를 저장할 것이라고 생각한다. 도와 주셔서 감사합니다!! – tjameson
[Redis] (http://redis.io/)도 확인하십시오. redis-server를 시작한 다음 노드에 redis 모듈을 사용합니다. 문자열 키와 json 객체를주고 BAM은 모든 자식과 데이터를 저장합니다. 그것을로드하고 키를 사용하여 객체로 메모리에 다시 가져옵니다. – BigOmega
Redis 또는 이와 같은 상태 정보 유형에 대한 관계형 데이터 스토어 대신 [Firebase] (http://firebase.com)를 사용할 수도 있습니다. Firebase는 상태를 실시간으로 모든 연결된 클라이언트와 동기화합니다. 그것은 귀하의 응용 프로그램 유형을 위해 설계되었습니다. – DrFriedParts