没有生成rpg游戏地图的HTML5画布视口



我正在学习一些在线示例,并试图了解如何将HTML5游戏组合在一起。

我已经掌握了一些基本知识,比如游戏循环,以及分离更新和渲染逻辑。

我现在可以从瓷砖集生成地图,并渲染一个可以四处走动并在其移动时为其精灵设置动画的角色。

我一直在努力解决角色移动时视口跟随角色的方式。它基本上是工作的,相机会跟随它——然而,它对生成的地图有一个非常奇怪的影响。

到目前为止,代码相当长,但我已经创建了一个当前工作方式的JSFiddle,它说明了我遇到的问题。可以使用箭头键移动角色。

jsFiddle当前问题

jsFiddle的代码

顺便说一句,我注意到如果角色走进左上角,似乎没问题

生成地图的代码是:

tileSize=game.currentMap.tileset.tileWidth;

if (player.x >= (game.viewport.x / 2)) r = Math.floor(player.x - ((map.width * map.tileset.tileWidth) / 2))
for (r = Math.floor(game.viewport.x / map.tileset.tileWidth); r < Math.floor(game.viewport.x / map.tileset.tileWidth) + canvas.width / map.tileset.tileWidth + 1; r++) {
for (c = Math.floor(game.viewport.y / map.tileset.tileHeight); c < Math.floor(game.viewport.y / map.tileset.tileHeight) + canvas.height / map.tileset.tileHeight + 1; c++) {
var tile = ground[r][c];
var tileRow = (tile / game.currentMap.tileset.tilesInImgRow) | 0; // Bitwise OR operation
var tileCol = (tile % game.currentMap.tileset.tilesInImgRow) | 0;
ctx.drawImage(
game.currentMap.tileset.image, (tileCol * tileSize), (tileRow * tileSize),
tileSize,
tileSize, (c * tileSize) - game.viewport.x, (r * tileSize) - game.viewport.y,
tileSize,
tileSize);
tile = layer1[r][c];
tileRow = (tile / game.currentMap.tileset.tilesInImgRow) | 0;
tileCol = (tile % game.currentMap.tileset.tilesInImgRow) | 0;
ctx.drawImage(
game.currentMap.tileset.image, (tileCol * tileSize), (tileRow * tileSize),
tileSize,
tileSize, (c * tileSize) - game.viewport.x, (r * tileSize) - game.viewport.y,
tileSize,
tileSize);

}
}

然而,当我从其他资源中研究代码时,我有点不确定问题是由这个函数还是由生成和更新视口的函数引起的。

有什么建议吗?

更新

调整视口的代码,使角色在地图边缘附近时不再停留在视口的中心:

if (game.viewport.x <= 0) dX = player.x;
else if (game.viewport.x >= game.currentMap.tileset.tileWidth * game.currentMap.width - canvas.width) dX = player.x - game.viewport.x;
else dX = Math.round(canvas.width / 2 - player.width / 2);
if (game.viewport.y <= 0) dY = player.y;
else if (game.viewport.y >= game.currentMap.tileset.tileHeight * game.currentMap.height - canvas.height) dY = player.y - game.viewport.y;
else dY = Math.round(canvas.height / 2 - player.height / 2);

当角色移动时更新视口的代码:

if (player.x + player.width / 2 < canvas.width / 2) {
game.viewport.x = 0;
} else if (player.x + canvas.width / 2 + player.width / 2 >= map.tileset.tileWidth * map.width) {
game.viewport.x = map.tileset.tileWidth * map.width - canvas.width;
} else {
game.viewport.x = Math.floor(player.x - (canvas.width / 2 - player.width / 2));
}

if (player.y + player.height / 2 < canvas.height / 2) {
game.viewport.y = 0;
} else if (player.y + canvas.height / 2 + player.height / 2 >= map.tileset.tileHeight * map.height) {
game.viewport.y = map.tileset.tileHeight * map.height - canvas.height;
} else {
game.viewport.y = Math.floor(player.y - (canvas.height / 2 - player.height / 2));
}

视口最初使用以下内容设置:

var game = {
images: 0,
imagesLoaded: 0,
backgroundColor: '#000',
viewport: {
x: Math.floor(player.x - (canvas.width / 2 - playerSpriteSize / 2)),
y: Math.floor(player.y - (canvas.height / 2 - playerSpriteSize / 2))
},
currentMap: map,
fps: 0,
lastfps: 0,
fpsTimer: 0

}

好吧,在玩了几天代码并喝了很多杯咖啡之后,我设法解决了我自己的问题,我想我会与其他有类似问题的人分享这个问题。

更新视口的代码很好,问题是分配给视口的初始值以及迭代贴图x和y平铺的方式。

在游戏变量中,我将视口更改为:

viewport: {
x: Math.floor(player.x - (canvas.width / 2)),
y: Math.floor(player.y - (canvas.height / 2))
},

然后在drawMap功能中:

for (r = 0; r < map.rowTileCount; r++) {
for (c = 0; c < map.colTileCount; c++) {

通过这种方式,我们总是生成完整的地图(这可能不必要地使用额外的资源,但我们总是可以稍后回来再看一遍),然后我们在画布上只画出其中的一部分,这正是我想要的。

http://jsfiddle.net/zdMSx/6/

最新更新