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);