格式化图像精灵的多维数组

Formatting a multidimensional array of image sprites

本文关键字:数组 图像 精灵 格式化      更新时间:2023-09-26

我正在制作一个为游戏加载精灵的函数,但我不太确定如何做到这一点。我仍在摸索javascript和OOP,所以我有点迷失了方向。我需要根据精灵所在的精灵表和精灵表中精灵位置对应的索引来选择精灵。我想用一个字母和一个数字来指代精灵表的XY位置。类似于Tile("A", 132);的子画面将是512x512像素,包含每个32x32像素大的子画面,使得多个画面的每张画面总共有256个子画面。以下是我目前所拥有的:

function Tileset(Spritesheet, Index){
    this.Spritesheet=Spritesheet;
    this.Index=Index;
    this.SpritesheetList=["TilesetA.png","TilesetB.png","TilesetC.png"];
    this.Tile=Image;
    this.LoadTiles = function(){
        for (sheet in SpritesheetList){
            var dummyImage= new Image;
            dummyImage.src=this.SpritesheetList[sheet];
            SpritesheetList[sheet]=[];
            for (var Y=0; Y<16; Y++){
                for (var X=0; X<16; X++){
                    this.SpritesheetList[sheet][Y*16 + X]=dummyImage.getSubimage(X*32, Y*32, 32, 32);
                };
            };
        };
        return this.SpritesheetList[Spritesheet][Index];
    };
    return this.SpritesheetList[Spritesheet][Index];
};

您的代码中存在一些问题。我不知道你是否使用了任何库,但如果瓦片的大小是32x32像素,那么getSubimage的最后两个参数应该是32。

您还应该尝试只加载一次磁贴,而不是每次访问磁贴时都加载。

我对您的代码进行了一些重构,使其更加面向对象和可重用。

function Tileset(spritesheetImages) {
    this.spritesheetImages = spritesheetImages;
    this.spritesheetList   = {};
}
Tileset.prototype.loadTiles =  function() {
    for (var i = 0, len = this.spritesheetImages.length; i < len; i++) {
        var image = new Image();
        image.src = this.spritesheetImages[i];
        this.spritesheetList[this.spritesheetImages[i]] = [];
        for (var y = 0; y < 16; y++) {
            for (var x = 0; x < 16; x++) {
                this.spritesheetList[this.spritesheetImages[i]].push(image.getSubimage(x*16, y*16, 32, 32));
            }
        }
    }
};
Tileset.prototype.getTile = function(spritesheetImage, tileIndex) {
    return this.spritesheetList[spritesheetImage][tileIndex];
};
var tileset = new Tileset(["TilesetA.png","TilesetB.png","TilesetC.png"]);
tileset.loadTiles();
tileset.getTile("TilesetA.png", 132);

现在你可以在需要的时候创建一个tilemap。我使用了原型方法,因为这样函数就不会随每个实例复制。希望这就是你的意图。

编辑

要添加新的精灵表图像,您可以使用此方法

Tileset.prototype.addSpritesheetImage = function(spritesheetImage) {
    var image = new Image();
    image.src = spritesheetImage;
    this.spritesheetList[spritesheetImage] = [];
    for (var y = 0; y < 16; y++) {
        for (var x = 0; x < 16; x++) {
            this.spritesheetList[spritesheetImage].push(image.getSubimage(x*16, y*16, 32, 32));
        }
    }
};

如果您想使用精灵表索引,您可以将getTile方法更改为

Tileset.prototype.getTile = function(spritesheetIndex, tileIndex) {
    return this.spritesheetList[Object.keys(this.spritesheetList)[spritesheetIndex]][tileIndex];
};