HetaJs

Tile Snap

3D던전에서 MiniMap표시용



Java Script

	var canvas = document.getElementById("ctx");
	var ctx = canvas.getContext("2d");
	var tileW = 40, tileH = 40;
	var mapW = 20, mapH = 20;	//지도 전체 크기
	
	// Stage에 들어간다.
	
	//a:65 w:87 d:68 s:83
	
	var keysDown = {
		left:false, 			
		up:false,
		right:false,
		down:false	
// 					37:false,
// 					38 : false,
// 					39:false,
// 					40:false
	};
	
	var lastFrameTime = 0;
	
	
	
	function Charactor(){
		this.tileFrom = [1,1];
		this.tileTo	 = [1,1];
		this.timeMoved = 0;
		this.dimensions = [30,30];	//캐릭터 픽셀.
		this.position = [45,45];	//top of this corner in map
		this.delayMove = 700;
	};
	Charactor.prototype.placeAt = function(x,y){
		this.tileFrom = [x,y];
		this.tileTo = [x,y];
		this.position = [
			((tileW*x)+(tileW-this.dimensions[0])/2),
			((tileH*y)+(tileH-this.dimensions[1])/2)
			];		//pixel positoin of charactor
	};
	Charactor.prototype.processMovement = function(t){
		if(this.tileFrom[0] == this.tileTo[0] &&
				this.tileFrom[1] == this.tileTo[1]){
			return false;
		}
		
		if((t-this.timeMoved)>=this.delayMove){
			this.placeAt(this.tileTo[0], this.tileTo[1]);
		}else{
			this.position[0] = (this.tileFrom[0] * tileW) +
			(tileW - this.dimensions[0])/2;
			this.position[1] = (this.tileFrom[1] * tileH) +
			(tileH - this.dimensions[1])/2;
			
			//x
			if(this.tileTo[0] != this.tileFrom[0]){
				var diff = (tileW /this.delayMove) * (t- this.timeMoved);
				this.position[0] += (this.tileTo[0] < this.tileFrom[0]?
						-diff : diff);
			}
			
			//y //실지 이동 
			if(this.tileTo[1] != this.tileFrom[1]){
				var diff = (tileH /this.delayMove) * (t- this.timeMoved);
				this.position[1] += (this.tileTo[1] < this.tileFrom[1]?
						-diff : diff);
			}
			
			
			this.position[0] = Math.round(this.position[0]);
			this.position[1] = Math.round(this.position[1]);
		}
		return true;
	};
	
	var player = new Charactor();
	
	
	//xy롤 이용해서 gameMap 배열 index를 알아낸다.
	function toIndex(x,y){
		return ( y * mapW + x);
	}
	
	
	window.addEventListener("keydown", function(e){
		//a:65 w:87 d:68 s:83
		if(e.keyCode == 65){
			keysDown['left'] = true;
		}else if(e.keyCode == 68){
			keysDown['right'] = true;
		}else if(e.keyCode == 87){
			keysDown['up'] = true;
		}else if(e.keyCode == 83){
			keysDown['down'] = true;
		}
	});
	
	window.addEventListener("keyup",function(e){
		if(e.keyCode == 65){
			keysDown['left'] = false;
		}else if(e.keyCode == 68){
			keysDown['right'] = false;
		}else if(e.keyCode == 87){
			keysDown['up'] = false;
		}else if(e.keyCode == 83){
			keysDown['down'] = false;
		}
	});
	
	
	
	
	
	//지도용.
	var currentSecond = 0, frameCount = 0, framesLastSecond = 0;
	
	var gameMap = [
		1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
		1,1,1,1,0,1,1,1,1,0,0,1,1,1,0,1,1,1,1,0,
		1,1,1,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,
		1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,0,
		0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,1,0,
		0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,1,0,1,0,
		0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,
		0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,
		0,1,1,1,0,1,1,1,1,0,0,1,1,1,0,1,1,1,1,0,
		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
		0,1,1,1,0,1,1,1,1,0,0,1,1,1,0,1,1,1,1,0,
		0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,
		0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,0,
		0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,1,0,
		0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,1,0,1,0,
		0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,
		0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,
		0,1,1,1,0,1,1,1,1,0,0,1,1,1,0,1,1,1,1,0,
		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	];
	
	var viewport = {
		screen:[0,0],
		startTile : [0,0],
		endTile : [0,0],
		offset : [0,0],
		update : function(px, py){
			this.offset[0] = Math.floor(this.screen[0]/2 - px);
			this.offset[1] = Math.floor(this.screen[1]/2 - py);
			
			var tile = [
				Math.floor(px/tileW),
				Math.floor(py/tileH)
			];
			
			this.startTile[0] = tile[0] - 1 - Math.ceil(this.screen[0]/2 / tileW);
			this.startTile[1] = tile[1] - 1 - Math.ceil(this.screen[1]/2 / tileH);
			if(this.startTile[0] < 0) this.startTile[0] = 0;
			if(this.startTile[1] < 0) this.startTile[1] = 0;
			
			
			
			this.endTile[0] = tile[0] +1 + Math.ceil(this.screen[0]/2 / tileW);
			this.endTile[1] = tile[1] +1 + Math.ceil(this.screen[1]/2 / tileH);
			if(this.endTile[0] >= mapW)	this.endTile[0] = mapW -1;
			if(this.endTile[1] >= mapH)	this.endTile[1] = mapH -1;
		}
	};
	
	//화면 세팅
	viewport.screen = [ canvas.width, canvas.height ];
	
	
	function draw(){
		
		if(ctx==null) return;
		
		//케릭터 이동용 프레임 시간 관리.
		var currentFrameTime = Date.now();
		var timeElapsed = currentFrameTime - lastFrameTime;
		
		
		//프레임 타임. 
		var sec = Math.floor(Date.now()/1000);
		if(sec != currentSecond){
			currentSecond = sec;
			framesLastSecond = frameCount;
			frameCount = 1;
		}else{
			frameCount++;
		}
		
		
		//플레이어 이동
		if(!player.processMovement(currentFrameTime)){
			if(keysDown['up'] && player.tileFrom[1] > 0
					&& gameMap[toIndex(player.tileFrom[0]),
						player.tileFrom[1]-1]==1){
						player.tileTo[1] -= 1;
			}else if(keysDown['down'] && player.tileFrom[1] < (mapH-1)
					&& gameMap[toIndex(player.tileFrom[0]),
						player.tileFrom[1]+1]==1){
						player.tileTo[1] += 1;
			}else if(keysDown['left'] && player.tileFrom[0] > 0
					&& gameMap[toIndex(player.tileFrom[0]-1),
						player.tileFrom[1]]==1){
						player.tileTo[0] -= 1;
			}else if(keysDown['right'] && player.tileFrom[0] < (mapW-1)
					&& gameMap[toIndex(player.tileFrom[0]+1),
						player.tileFrom[1]]==1){
						player.tileTo[0] += 1;
			}
						
			if(player.tileFrom[0] != player.tileTo[0] || player.tileFrom[1] != player.tileTo[1]){
				//x나 y를 이동중... 
				player.timeMoved = currentFrameTime;
			}
		}
		
		
		//카메라 업데이트 
		//TODO 플에이어가 구석쪽에 있는지를 체크 해야한다. 
		viewport.update( player.position[0] + player.dimensions[0]/2,
				player.position[1] + player.dimensions[1]/2
			);
		
		ctx.fillStyle = "#000000";
		ctx.fillRect(0,0, viewport.screen[0], viewport.screen[1]);
					//지도 그리기
// 					for(var y = 0; y< mapH; y++){
// 						for(var x = 0; x < mapW; x++){
		for(var y = viewport.startTile[1]; y<= viewport.endTile[1]; y++){
			for(var x = viewport.startTile[0]; x <= viewport.endTile[0]; x++){
				switch(gameMap[((y*mapW)+x)]){
				case 0:
					ctx.fillStyle = "#999999";
					break;
					
				default:
					ctx.fillStyle = "#eeeeee";
				}
				//ctx.fillRect(x*tileW, y*tileH, tileW, tileH);	//네모 그리기
				ctx.fillRect(viewport.offset[0] + x*tileW, 
						viewport.offset[1] + y*tileH, tileW, tileH);	//네모 그리기
			}
		}
		
		//캐릭터 그리기.
		ctx.fillStyle="#0000ff";
		//ctx.fillRect(player.position[0], player.position[1],player.dimensions[0],player.dimensions[1]);
		ctx.fillRect(viewport.offset[0] + player.position[0], viewport.offset[1] + player.position[1],
				player.dimensions[0],player.dimensions[1]);
		
		
		//
		ctx.fillStyle="#ff0000";
		ctx.fillText("FPS: " + framesLastSecond, 10, 20);
		
		//플레이어용.
		lastFrameTime = currentFrameTime;
		
		requestAnimationFrame(draw);
	}
	requestAnimationFrame(draw);