javascript - 使用 JavaScript 创建 2d 平台

标签 javascript jquery function html5-canvas game-engine

我正在使用 EaselJS 开发一款 HTML5 Canvas 游戏,并且编写了一个函数,该函数允许我仅通过设置一个或多个图像、大小和位置来创建“ block ”。

我所说的“ block ”是指:

this is a block this is a block compound by 9 blocks this is a block compound by 9 blocks using the second method

我使用两种方法来执行此操作:

第一种方法:

通过这种方法, block 是在我设置的位置内的可用空间中随机使用图像创建的。

第二种方法:

这些 block 是在我设置的位置内创建的,使用左上角、顶部、右上角、左侧、中心、右侧、左下角、底部和右下角的特定图像,并且这些部分中的每一部分都可以有多个图像(因此系统使用随机图像来避免多次重复同一图像)。

好的,但是问题出在哪里?

此函数使用无数 77(与碰撞检测相关的部分算上131行)! 我知道有一种更好的方法可以做到这一点,这将比现在花费大约一半或更少的行数,但我不知道该怎么做,当有人向我展示时,我将使用 我的余生都以“正确的方式”。 你能帮我吗?

我想要什么:

使用更少线条的一种可能方法是使用单一“方法”,该方法允许我创建由 9 个或更多图像复合的 block 复合的 block (我只是不知道该怎么做它,我知道这很难理解。尝试想象第三张图片被使用了 9 次)。 //这部分问题切中主题!

请注意,这个问题不是主观的,因为这里的目标是使用更少的行,并且我没有使用 EaselJS 标签,因为这个问题不是 EaselJS 特定的,任何具有 JavaScript 知识的人都可以回答我。

这是我难以置信的大 JavaScript 函数:

var Graphic = function (src, blockWidth, blockHeight) {
    return {
        createBlockAt: function (x, y, blockGroupWidth, blockGroupHeight, clsdir, alpha) {
            for (var blockY = 0; blockY < blockGroupHeight / blockHeight; blockY++) {
                for (var blockX = 0; blockX < blockGroupWidth / blockWidth; blockX++) {

                    var obj = new createjs.Bitmap(src[Math.floor(Math.random() * src.length)]);

                    obj.width = blockWidth;
                    obj.height = blockHeight;
                    if (typeof alpha !== 'undefined') {
                        obj.alpha = alpha; // While debugging this can be used to check if a block was made over another block.
                    }

                    obj.x = Math.round(x + (blockWidth * blockX));
                    obj.y = Math.round(y + (blockHeight * blockY));

                    stage.addChild(obj);
                }
            }
        }
    }
}
var complexBlock = function (topLeft, topCenter, topRight, middleLeft, middleCenter, middleRight, bottomLeft, bottomCenter, bottomRight, blockWidth, blockHeight) {
    return {
        createBlockAt: function (x, y, blockGroupWidth, blockGroupHeight, clsdir, alpha) {
            for (var blockY = 0; blockY < blockGroupHeight / blockHeight; blockY++) {
                for (var blockX = 0; blockX < blockGroupWidth / blockWidth; blockX++) {
                    if (blockY == 0 && blockX == 0) {
                        var obj = new createjs.Bitmap(topLeft[Math.floor(Math.random() * topLeft.length)]);
                    }
                    if (blockY == 0 && blockX != 0 && blockX != (blockGroupWidth / blockWidth - 1)) {
                        var obj = new createjs.Bitmap(topCenter[Math.floor(Math.random() * topCenter.length)]);
                    }
                    if (blockY == 0 && blockX == (blockGroupWidth / blockWidth - 1)) {
                        var obj = new createjs.Bitmap(topRight[Math.floor(Math.random() * topRight.length)]);
                    }

                    if (blockY != 0 && blockY != (blockGroupHeight / blockHeight - 1) && blockX == 0) {
                        var obj = new createjs.Bitmap(middleLeft[Math.floor(Math.random() * middleLeft.length)]);
                    }
                    if (blockY != 0 && blockY != (blockGroupHeight / blockHeight - 1) && blockX != 0 && blockX != (blockGroupWidth / blockWidth - 1)) {
                        var obj = new createjs.Bitmap(middleCenter[Math.floor(Math.random() * middleCenter.length)]);
                    }
                    if (blockY != 0 && blockY != (blockGroupHeight / blockHeight - 1) && blockX == (blockGroupWidth / blockWidth - 1)) {
                        var obj = new createjs.Bitmap(middleRight[Math.floor(Math.random() * middleRight.length)]);
                    }

                    if (blockY == (blockGroupHeight / blockHeight - 1) && blockX == 0) {
                        var obj = new createjs.Bitmap(bottomLeft[Math.floor(Math.random() * bottomLeft.length)]);
                    }
                    if (blockY == (blockGroupHeight / blockHeight - 1) && blockX != 0 && blockX != (blockGroupWidth / blockWidth - 1)) {
                        var obj = new createjs.Bitmap(bottomCenter[Math.floor(Math.random() * bottomCenter.length)]);
                    }
                    if (blockY == (blockGroupHeight / blockHeight - 1) && blockX == (blockGroupWidth / blockWidth - 1)) {
                        var obj = new createjs.Bitmap(bottomRight[Math.floor(Math.random() * bottomRight.length)]);
                    }

                    obj.width = blockWidth;
                    obj.height = blockHeight;
                    if (typeof alpha !== 'undefined') {
                        obj.alpha = alpha; // While debugging this can be used to check if a block was made over another block.
                    }

                    obj.x = Math.round(x + (blockWidth * blockX));
                    obj.y = Math.round(y + (blockHeight * blockY));

                    stage.addChild(obj);
                }
            }
        }
    }
}

var bigDirt = complexBlock(["http://i.imgur.com/DLwZMwJ.png"], ["http://i.imgur.com/UJn3Mtb.png"], ["http://i.imgur.com/AC2GFM2.png"], ["http://i.imgur.com/iH6wFj0.png"], ["http://i.imgur.com/wDSNzyc.png", "http://i.imgur.com/NUPhXaa.png"], ["http://i.imgur.com/b9vCjrO.png"], ["http://i.imgur.com/hNumqPG.png"], ["http://i.imgur.com/zXvJECc.png"], ["http://i.imgur.com/Whp7EuL.png"], 40, 40);

bigDirt.createBlockAt(0, 0, 40*3, 40*3);

好吧...这里有很多代码,我该如何测试?

我们开始吧:JSFiddle

最佳答案

在给定九个可能的分支的情况下,我没有看到减少行数的简单方法,但您可以大大减少代码中的重复:

function randomImage(arr) {
    return new createjs.Bitmap(arr[Math.floor(Math.random() * arr.length)]);
}

if (blockY == 0 && blockX == 0) {
    var obj = randomImage(topLeft);
} // etc

回复:九个可能的分支,您应该注意它们是互斥的,因此应该使用 else if 而不是仅仅 if,而且它们也很自然三人一组,表明它们应该嵌套。

编辑事实上,有一种方法可以大大减少函数的大小。请注意,对于 X 和 Y,各有三个选项(总共九个)。可以根据二维查找表对您想要的图像数组进行编码:

var blocksHigh = blockGroupHeight / blockHeight;
var blocksWide = blockGroupWidth / blockWidth;
var blockSelector = [
    [topLeft, topCenter, topRight],
    [middleLeft, middleCenter, middleRight],
    [bottomLeft, bottomCenter, bottomRight]
];

for (var blockY = 0; blockY < blocksHigh; blockY++) {
    var blockSY = (blockY == 0) ? 0 : blockY < (blocksHigh - 1) ? 1 : 2;
    for (var blockX = 0; blockX < blocksWide; blockX++) {
        var blockSX = (blockY == 0) ? 0 : blockY < (blocksWide - 1) ? 1 : 2;
        var array = blockSelector[blockSY][blockSX];
        var obj = randomImage(array);

        ...
     }
}

请注意循环外部的 blocksHighblocksWide 的定义,以减少昂贵的重复除法运算。

参见http://jsfiddle.net/alnitak/Kpj3E/

关于javascript - 使用 JavaScript 创建 2d 平台,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23826694/

相关文章:

javascript - 使用 jQuery 从下拉列表中获取选定的文本

javascript - 向 firebase : data. Push() 发送数据不是函数

python - python参数实际上是参数的别名吗?

ios - 完成 block 似乎被忽略

javascript - 露天批量上传带有 xml 元数据的图像

javascript - 从 Dart 调用我的 JavaScript

javascript - 如何使用 JavaScript 检测用户的 IP 地址?

javascript - 使用矩形选择框选择 SVG 元素在缩放期间不起作用 : d3. js

javascript - jQuery 分区可见性隐藏不起作用

javascript - 从函数中获取变量的值