javascript 2d数组tile map srcolling

时间:2018-01-20 11:26:58

标签: javascript arrays scroll

我已经搜索了好几个星期,但却找不到合适的教程 让我们说我们有一个800x800的画布。

<canvas id='draw' width=800 height=800></canvas>

我们有一个瓦片地图(0将是方形障碍,1将是空气)。

var tileMap = [ [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
                [0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
                [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] 
]

如何使地图滚动,以便每当玩家移动时只能看到3x3的正方形? 例如:

canvas screen-->           [0,0,0]
                           [0,1,1]      <-- just this part to be seen
                           [0,0,0]         

当玩家移动时:

canvas screen-->           [0,0,0]
                           [1,1,1]     <-- now this part will be seen
                           [0,0,0]

那么如何让瓷砖地图移动以给出玩家正在移动的错觉?

2 个答案:

答案 0 :(得分:0)

不应修改

tileMap,而是创建一个表示当前视图中心的对象,例如播放器并在您的显示功能中使用它。只要您想滚动查看移动中心

&#13;
&#13;
var tileMap = [ [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
                [0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
                [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] 
]


var hero = {
	position: {
  	x: 0,
    y: 1
  }
};

const air = 1;
const barrier = 0;

display(hero,tileMap);

// move player instead of scrolling data
// tileMap is untouched
hero.position.x += 3;

display(hero,tileMap);

// use player position to display only portion of map
function display(player,map) {
		var result = [
    	"",
      "",
      ""
    ];
    
    for(var y = 0, i = player.position.y - 1; y < 3; i++,y++) {
    		if (i >= 0 && i < map.length) {
        	  for(var x = 0, j = player.position.x - 1; x < 3; j++,x++) {
                if ( j >= 0 && j < map[i].length) {
                		result[y] += map[i][j] + ",";
                }
                else {
                	// outside map only ait
                	result[y] += air+ ",";
                }
            }
        }
        else {
        	// outside map only ait
        	result[y] += air +","+ air +","+air+",";
        }
    }
    console.log(result);
}
&#13;
&#13;
&#13;

答案 1 :(得分:0)

你没有解释你的数组是如何与你的画布和动画相关的 - 所以一个明确的猜测就是你只关心你的数组。

您需要相机 viewMap位置和尺寸值所指示的视口阵列 cam
在下面的示例中,它的锚点是左/上(您可能希望稍后更改逻辑以使用中心/中心,而不是您)。

  • 在键盘事件中,更改相机x y位置并防止超出地图边界
  • 填充您的viewMap数组并打印出来:

var tileMap = [
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
  [0, 1, 4, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 8, 8, 1, 0],
  [0, 6, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 9, 9, 1, 0],
  [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
];

var cam = {
  x: 0,
  y: 0,
  width: 3,
  height: 3
};

// Create empty 2D viewMap of viewport
var viewMap = [];
for (var i = 0; i < cam.height; i++) viewMap[i] = new Array(cam.width);


function tileViewport() {
  for (var y = 0; y < cam.height; y++)
    for (var x = 0; x < cam.width; x++)
      viewMap[y][x] = tileMap[y + cam.y][x + cam.x];
  // PRINT
  console.clear(); console.log(viewMap.map(a => a.join(" ")).join("\n"))
}

document.body.addEventListener("keydown", function(e) {
  var key = e.which;
  
  if( /^(37|38|39|40|)$/.test(key) ) e.preventDefault(); // prevent browser default stuff
  
  if (key === 38) --cam.y;
  if (key === 40) ++cam.y;
  if (key === 37) --cam.x;
  if (key === 39) ++cam.x;

  // Fix movement to tileMap area boundary
  cam.y = Math.max(0, Math.min(cam.y, tileMap.length - cam.height));
  cam.x = Math.max(0, Math.min(cam.x, tileMap[0].length - cam.width));

  tileViewport();
});

// INITIALIZE
tileViewport();
Click here and user your keyboard arrows!

既然以上工作正常,您可以:

  • 使用新的viewMap数组
  • 为障碍物行为添加逻辑
  • 为您的画布预取新的图块
  • 根据动作为画布设置动画