我有一个二维数组,横向为30,纵向为20。但是视口只显示15列和10行。我的游戏最初就是这样的,我一直在尝试实现下面这种效果:
这是我的fiddle链接:http://jsfiddle.net/sTr7q/
我有一个二维数组,横向为30,纵向为20。但是视口只显示15列和10行。我的游戏最初就是这样的,我一直在尝试实现下面这种效果:
这是我的fiddle链接:http://jsfiddle.net/sTr7q/
我为您创建了一个基本视口:
您需要跟踪视口的X和Y(vX,vY),表示您在整个世界中的位置。我还将视口宽度和高度保留为变量,而不是硬编码。
您可以使用箭头键更改视口X和Y,这将滚动地图,仅绘制正确的瓦片。
希望有所帮助!如果您有任何问题,请告诉我!
编辑:视口随玩家移动的示例:http://jsfiddle.net/kmHZt/10/
var canvas, context, board, imageObj, tiles, board, display;
var NUM_OF_TILES = 2;
// viewport
var vX = 0,
vY = 0,
vWidth = 15,
vHeight = 10;
var playerX = 0,
playerY = 0;
var worldWidth = 29,
worldHeight = 19;
function loadMap(map) {
if (map == 1) {
return [[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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0], [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0], [0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 0], [0, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 0], [0, 1, 1, 2, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 0], [0, 1, 1, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 1, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 0], [0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 0], [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0], [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]];
}
}
$(document).ready(function() {
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
canvas.tabIndex = 0;
canvas.focus();
canvas.addEventListener('keydown', function(e) {
console.log(e);
var key = null;
switch (e.which) {
case 37:
// Left
if (playerX > 0) playerX--;
break;
case 38:
// Up
if (playerY > 0) playerY--;
break;
case 39:
// Right
if (playerX < worldWidth) playerX++;
break;
case 40:
// Down
if (playerY < worldHeight) playerY++;
break;
}
// Okay! The player is done moving, now we have to determine the "best" viewport.
// Ideally the viewport centers the player,
// but if its too close to an edge we'll have to deal with that edge
vX = playerX - Math.floor(0.5 * vWidth);
if (vX < 0) vX = 0;
if (vX+vWidth > worldWidth) vX = worldWidth - vWidth;
vY = playerY - Math.floor(0.5 * vHeight);
if (vY < 0) vY = 0;
if (vY+vHeight > worldHeight) vY = worldHeight - vHeight;
draw();
}, false);
var board = [];
canvas.width = 512;
canvas.height = 352;
board = loadMap(1);
imageObj = new Image();
tiles = [];
var loadedImagesCount = 0;
for (x = 0; x <= NUM_OF_TILES; x++) {
var imageObj = new Image(); // new instance for each image
imageObj.src = "http://mystikrpg.com/canvas/img/tiles/t" + x + ".png";
imageObj.onload = function() {
// console.log("Added tile ... "+loadedImagesCount);
loadedImagesCount++;
if (loadedImagesCount == NUM_OF_TILES) {
// Onces all tiles are loaded ...
// We paint the map
draw();
}
};
tiles.push(imageObj);
}
function draw() {
context.clearRect(0,0,canvas.width, canvas.height);
for (y = 0; y <= vHeight; y++) {
for (x = 0; x <= vWidth; x++) {
theX = x * 32;
theY = y * 32;
context.drawImage(tiles[board[y+vY][x+vX]], theX, theY, 32, 32);
}
}
context.fillStyle = 'red';
context.fillRect((playerX-vX)*32, (playerY-vY)*32, 32, 32);
}
});