4

我正在努力在谷歌上找到我的问题的答案,所以认为 id post。

我只使用 html5、javascript 和 jquery 构建了一个自上而下的基于瓷砖的 rpg 游戏。

我已经在数组中设置了图像。我已经在一个数组中设置了我的地图,然后循环遍历它以在屏幕上显示图块。

我希望在画布上显示一个 750px x 600px 的大地图部分,当玩家移动到 4 个边界之一时,地图将更新并显示地图的下一部分,或者如果没有可用的地图保持原样。

我将如何实现这个?

如果您不明白我在问什么,请尝试更好地解释:p,但这是我的代码:

$(document).ready(function(){

var canvas = $("#TBG");
var context = canvas.get(0).getContext("2d");

var canvasWidth = canvas.width();
var canvasHeight = canvas.height();

//Player Controls -------------------------------------------------------------------------
$(window).keydown(function(e){
   var keyCode = e.keyCode;
    if (keyCode == arrowRight){
        Player.moveRight = true;
    }
    else if (keyCode == arrowLeft){
        Player.moveLeft = true;
    }
    else if (keyCode == arrowUp){
        Player.moveUp = true;
    }
    else if (keyCode == arrowDown) {
        Player.moveDown = true;
    }
});
$(window).keyup(function(e){
    var keyCode = e.keyCode;
    if (keyCode == arrowRight){
        Player.moveRight = false;
    }
    else if (keyCode == arrowLeft){
        Player.moveLeft = false;
    }
    else if (keyCode == arrowUp){
        Player.moveUp = false;
    }
    else if (keyCode == arrowDown) {
        Player.moveDown = false;
    }
});

function player() {

    this.x = 100;
    this.y = 100;
    this.vX = 0;
    this.vY = 0;

    var moveRight = false;
    var moveLeft = false;
    var moveUp = false;
    var moveDown = false;
}

var Player = new player();

var arrowLeft = 37;
var arrowUp = 38;
var arrowRight = 39;
var arrowDown = 40;

//End Player controls ------------------------------------------------------------------------------

//Map initialisation -------------------------------------------------------------------------------------

var images = new Array(3);

images[0] = new Image();
images[0].src = "images/player.png";

images[1] = new Image();
images[1].src = "images/wall.png";

images[2] = new Image();
images[2].src = "images/grass.png";

images[3] = new Image();
images[3].src = "images/floor.png";

var tileMap = [
    [3,1,3,3,3,3,3,3,3,3],
    [3,1,1,2,2,2,2,2,2,3],
    [3,1,1,1,2,2,2,2,2,3],
    [3,2,1,1,1,2,2,2,2,3],
    [3,2,2,1,1,1,2,2,2,3],
    [3,2,2,2,1,1,1,1,1,3],
    [3,2,2,2,2,1,1,1,1,3],
    [3,2,2,2,2,1,1,1,1,3],
    [3,2,2,2,2,1,1,1,1,3],
    [3,3,3,3,3,3,3,3,3,3]
];

//Animate Loop -------------------------------------------------------------------------------------------
function animate () {

    context.clearRect(0,0,canvasWidth,canvasHeight);

    Player.vX = 0;
    Player.vY = 0;

    //Player Animation
    if (Player.moveRight) {
        Player.vX =2;
    };
    if (Player.moveUp) {
        Player.vY = -2;
    };
    if (Player.moveDown) {
        Player.vY = 2;
    };
    if (Player.moveLeft) {
        Player.vX = -2;
    };

    Player.x += Player.vX;
    Player.y += Player.vY;

    if (Player.x < 0){
        Player.x = 0;
        Player.vX *= -2;
    }
    else if (Player.x + 64 > canvasWidth) {
        Player.x = canvasWidth - 64;
        Player.vX *= -2;
    };
    if (Player.y < 0){
        Player.y = 0;
        Player.vY *= -2;
    }
    else if (Player.y + 64 > canvasHeight) {
        Player.y = canvasWidth - 64;
        Player.vY *= -2;
    };

    for (var i = 0; i < 10; i++) {
        for (var j = 0; j < 10; j++){

            var tileId = tileMap[i][j];
            var tileWidth = 32;
            var tileHeight = 32;

            context.drawImage(images[tileId],i * tileWidth, j * tileHeight);
        }

    }
    context.drawImage(images[0], Player.x, Player.y);

    setTimeout(animate, 0);
}
// End Loop ------------------------------------------------------------------------------------------------

animate();

});

我不擅长 Javascript,但学习并了解有关编程的大量知识。

提前谢谢汤姆

4

2 回答 2

2

好吧,实际上并没有特定的方法来做到这一点(就像活动开发中的任何事情一样),但也许我可以提供一些帮助,因为我也在创建一个以地板为中心的活动。地板层并没有真正的独特之处。这只是给图表的一个短语,可以相互填充。你甚至可以在你的整个活动中参与其中,但你可以看到它是如何执行的。如果有一个 5X5 的草坪位置,并且您想在上面放一个灌木,那么在分区之间您只会看到资格是什么颜色,因为您更改了之前的草坪地板。有些人通过包括另一部分来定位灌木来处理这个问题。这样第一部分上面就有草坪,灌木看起来就像在上面。您可能必须对几个实际的植物使用多个级别才能获得您想要的影响。就个人而言,我的活动中可能只有一层楼。这将是主要风景的东西草坪,灰尘等。然后我将有一个项目部分,我将有预先制作的对象(可以是植物,花朵,坏人,房屋等),我的电机将带他们角色并弄清楚如何描绘它们。

对于初学者来说,你可以让你的个性与显示器的侧面发生冲突。例如,为了与显示的其余部分发生冲突,您将检查表演者的 x 位置是否小于 0,如果是,则将其设置为 0。

接下来,您将希望能够在显示屏上绘制地板。您可以使用整数范围来表示平面图。不同的图形表示您必须绘制不同的地板设计。所以一个 3X3 范围的 '0' 将是一张象征 3X3 线草坪地板的地图,而 '1' 可能是水或其他东西。您可以从文本/二进制计算机文件或 XML 计算机文件或其他东西中获取这些数字。由于您正在考虑 XML,因此它通常只是一种用于购买详细信息的人类可读的方式。XML 细节实际上并没有做任何事情(在某种意义上),这取决于您的系统来理解它。

另一个建议是,由于您使用的是 SFML,您可以使用“视图”来移动摄影机。查看 SFML 网页了解如何使用它们。

现在为我最好的建议。我的发布相对无法解释,但我描述的所有内容都受到 Chip Gravelyn 的地板电机指南的保护。它以 C# 发布,他在开发楼层经理方面做了很多事情,但您仍然可以将他的事情实施到您的 C++/SFML 活动中。在线查找“NIckGravelyn”。com。

于 2012-11-09T19:24:18.480 回答
2

你快到了!我最近在我自己的游戏的平铺渲染器中实现了类似的东西。

在这个循环中:

for (var i = 0; i < 10; i++) {
    for (var j = 0; j < 10; j++) {
        var tileId = tileMap[i][j];
        var tileWidth = 32;
        var tileHeight = 32;

        context.drawImage(images[tileId],i * tileWidth, j * tileHeight);
    }
}

您需要将相机“居中”。在我的游戏中,每次玩家移动时,我都会以他们的位置为中心,但你可以随心所欲地这样做。您可以在绘图时通过对世界坐标应用偏移来使相机居中:

for (var i = 0; i < 10; i++) {
    for (var j = 0; j < 10; j++) {
        var tileId = tileMap[i + yOffset][j + xOffset] || tileIdForEmptyCell;
        var tileWidth = 32;
        var tileHeight = 32;

        context.drawImage(images[tileId],i * tileWidth, j * tileHeight);
    }
}

在您的代码中, i 和 j 代表您的屏幕平铺坐标,它们永远不会改变。要“移动”世界,您只需对世界坐标应用偏移量,该坐标用于执行对瓦片地图的查找。

您必须考虑地图何时结束,这就是该|| tileIdForEmptyCell位的作用。

于 2012-11-09T19:28:15.670 回答