Lordofpomelo 소스 코드 분석 (1): World 초기 화 된 읽 기 지도 설정

모든 일 에는 출발점 이 있 습 니 다. 우리 먼저 World. init 부터 시작 합 시다!
// Configure for area server
app.configure('production|development', 'area', function(){
	app.filter(pomelo.filters.serial());
	app.before(playerFilter());

	var areaId = app.get('curServer').area;
	if(!areaId || areaId < 0) {
		throw new Error('load area config failed');
	}
	world.init(dataApi.area.all());
	area.init(dataApi.area.findById(areaId));
});

이 코드 는 lordofpomelo 의 game - server 에 있 는 app. js 파일 입 니 다. 이 World. init (dataApi. area. all () 를 먼저 보 겠 습 니 다. 호출 된 것 은... / app / domain / World. js 파일 의 init 방법 입 니 다. 코드 는 다음 과 같 습 니 다.
exp.init = function(areasConfig){
	//Init areas
	for(var key in areasConfig){
		//init map
		var areaConfig = areasConfig[key];
		areaConfig.weightMap = false;
		maps[areaConfig.id] = new Map(areaConfig);
	}
};

내용 이 간단 합 니 다. 들 어 오 는 매개 변 수 는 모든 area 서버 입 니 다. lordofomelo 에 기본적으로 3 개의 area 서버 가 설치 되 어 있 습 니 다. 각각 게임 의 3 개의 지도 에 대응 하여 World 를 초기 화 할 때 한 번 씩 순환 하여 area 의 map 를 초기 화 합 니 다. 여 기 는 maps [areConfig. id] = new Map (area Config) 을 호출 합 니 다.다음은 맵 의 구조 방법 에 들 어 갑 니 다. 대응 하 는 파일 은... / app / domain / map / map. js 입 니 다.
/**
 * The data structure for map in the area
 */
var Map = function(opts) {
	this.mapPath = process.cwd() + opts.path;
	this.map = null;
	this.weightMap = null;
	this.name = opts.name;

	this.init(opts);
};

우선 this. mapPath 는 첫 번 째 지 도 를 가 져 온 프로필 로. / config / map / desert. json 에 있 습 니 다.이름 만 봐 도 알 아 맞 힐 수 있 는 사막의 지도 다.this. name 은 바로 desert 입 니 다. 이 어 this. init (opts) 방법 을 수행 합 니 다.
/**
 * Init game map
 * @param {Object} opts
 * @api private
 */
Map.prototype.init = function(opts) {
	var weightMap = opts.weightMap || false;
	var map = require(this.mapPath);
	if(!map) {
		logger.error('Load map failed! ');
	} else {
		this.configMap(map);
		this.id = opts.id;
		this.width = opts.width;
		this.height = opts.height;
		this.tileW = 20;
		this.tileH = 20;
		this.rectW = Math.ceil(this.width/this.tileW);
		this.rectH = Math.ceil(this.height/this.tileH);

		this.pathCache = new PathCache({limit:1000});
		this.pfinder = buildFinder(this);

		if(weightMap) {
			//Use cache map first
			var path = process.cwd() + '/tmp/map.json';
			var maps = fs.existsSync(path)?require(path) : {};

			if(!!maps[this.id]){
				this.collisions = maps[this.id].collisions;
				this.weightMap = this.getWeightMap(this.collisions);
			}else{
				this.initWeightMap();
				this.initCollisons();
				maps[this.id] = {version : Date.now(), collisions : this.collisions};
				fs.writeFileSync(path, JSON.stringify(maps));
			}

		}
	}
};

이 코드 는 비교적 길 으 니 조급해 하지 말고 천천히 봅 시다.우선 var map = require (this. mapPath);사실은 앞의 지도 프로필 을 읽 는 것 입 니 다.그리고 이 this. configMap (map);
Map.prototype.configMap = function(map){
	this.map = {};
	var layers = map.layers;
	for(var i = 0; i < layers.length; i++){
		var layer = layers[i];
		if(layer.type === 'objectgroup'){
			this.map[layer.name] = configObjectGroup(layer.objects);
		}
	}
};

이것 은 복잡 하지 않 습 니 다. 바로 설정 중의 layers 를 읽 는 것 입 니 다. 이 안의 첫 번 째 지 도 는 모두 5 개의 layer 가 있 는데 그것 이 바로 desert, birth, mob, npc, collision 입 니 다. 이름 을 봐 도 알 수 있 습 니 다. 바로 배경 바닥, 출생지, 괴물, npc 와 장애물 5 층 입 니 다. 그 중에서 네 개 는 모두 object group 유형 에 속 하기 때문에 this. map [layer. name] = configObject Group 으로 호출 됩 니 다.(layer. objects) 이 문장 은 코드 를 계속 봅 니 다.
function configObjectGroup(objs){
	for(var i = 0; i < objs.length; i++){
		objs[i] = configProps(objs[i]);
	}

	return objs;
}

layer 에 있 는 object 를 하나씩 순환 한 다음 configProps (obbs [i]) 를 호출 합 니 다.
function configProps(obj){
	if(!!obj && !!obj.properties){
		for(var key in obj.properties){
			obj[key] = obj.properties[key];
		}

		delete obj.properties;
	}

	return obj;
}

이 안 은 모든 obj 의 속성 을 읽 고 상층 으로 돌아 가 하나의 배열 을 형성 하여 this. map [layer. name] 이 변수 에 저장 합 니 다.
자, 소스 코드 가 많 으 니 천천히 하 세 요. 이 장 은 여기까지 입 니 다.
여러분 안녕 히 계 세 요.

좋은 웹페이지 즐겨찾기