Files
esengine/source/src/Tiled/Layer.ts

175 lines
6.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
module es {
export class TmxLayer implements ITmxLayer {
public map: TmxMap;
public name: string;
public opacity: number;
public offsetX: number;
public offsetY: number;
public properties: Map<string, string>;
public visible: boolean;
public get offset(): Vector2 {
return new Vector2(this.offsetX, this.offsetY);
}
/**
* 这一层tile的宽度。对于固定大小的地图始终与地图宽度相同。
*/
public width: number;
/**
* 这一层的tile高度。对于固定大小的地图始终与地图高度相同。
*/
public height: number;
public tiles: TmxLayerTile[];
/**
* 回带有gid的TmxLayerTile。这是一个慢查询所以要缓存它
* @param gid
*/
public getTileWithGid(gid: number){
for (let i = 0; i < this.tiles.length; i ++){
if (this.tiles[i] && this.tiles[i].gid == gid)
return this.tiles[i];
}
return null;
}
/**
* 获取x/y坐标处的TmxLayerTile。注意这些是平铺坐标而不是世界坐标!
* @param x
* @param y
*/
public getTile(x: number, y: number): TmxLayerTile {
return this.tiles[x + y * this.width];
}
/**
* 返回平铺空间中的矩形列表,其中任何非空平铺组合为边界区域
*/
public getCollisionRectangles(): Rectangle[] {
let checkedIndexes = [];
let rectangles = [];
let startCol = -1;
let index = -1;
for (let y = 0; y < this.map.height; y ++){
for (let x = 0; x< this.map.width; x ++){
index = y * this.map.width + x;
let tile = this.getTile(x, y);
if (tile && !checkedIndexes[index]){
if (startCol < 0)
startCol = x;
checkedIndexes[index] = true;
}else if(tile || checkedIndexes[index]){
if (startCol >= 0){
rectangles.push(this.findBoundsRect(startCol, x, y, checkedIndexes));
startCol = -1;
}
}
}
if (startCol >= 0){
rectangles.push(this.findBoundsRect(startCol, this.map.width, y, checkedIndexes));
startCol = -1;
}
}
return rectangles;
}
/**
* 在startX和endX之间的tile周围找到最大的边界矩形从startY开始尽可能向下
* @param startX
* @param endX
* @param startY
* @param checkedIndexes
*/
public findBoundsRect(startX: number, endX: number, startY: number, checkedIndexes?: boolean[]){
let index = -1;
for (let y = startY + 1; y < this.map.height; y ++){
for (let x = startX; x < endX; x ++){
index = y * this.map.width + x;
let tile = this.getTile(x, y);
if (tile || checkedIndexes[index]){
// 再次将我们到目前为止在这一行中访问过的所有内容设置为false因为它不会包含在矩形中应该再次进行检查
for (let _x = startX; _x < x; _x++){
index = y * this.map.width + _x;
checkedIndexes[index] = false;
}
return new Rectangle(startX * this.map.tileWidth, startY * this.map.tileHeight,
(endX - startX) * this.map.tileWidth, (y - startY) * this.map.tileHeight);
}
checkedIndexes[index] = true;
}
}
return new Rectangle(startX * this.map.tileWidth, startY * this.map.tileHeight,
(endX - startX) * this.map.tileWidth, (this.map.height - startY) * this.map.tileHeight);
}
}
export class TmxLayerTile {
public static readonly FLIPPED_HORIZONTALLY_FLAG = 0x80000000;
public static readonly FLIPPED_VERTICALLY_FLAG = 0x40000000;
public static readonly FLIPPED_DIAGONALLY_FLAG = 0x20000000;
public tileset: TmxTileset;
public gid: number;
public x: number;
public y: number;
public get position(): Vector2{
return new Vector2(this.x, this.y);
}
public horizontalFlip: boolean;
public verticalFlip: boolean;
public diagonalFlip: boolean;
public _tilesetTileIndex?: number;
/**
* 获取此TmxLayerTile(如果存在)的TmxTilesetTile
* TmxTilesetTile只存在于动态的tiles和带有附加属性的tiles中。
*/
public get tilesetTile(): TmxTilesetTile {
if (this._tilesetTileIndex == undefined){
this._tilesetTileIndex = -1;
if (this.tileset.firstGid <= this.gid){
let tilesetTile = this.tileset.tiles.get(this.gid - this.tileset.firstGid);
if (tilesetTile){
this._tilesetTileIndex = this.gid - this.tileset.firstGid;
}
}
}
if (this._tilesetTileIndex < 0)
return null;
return this.tileset.tiles.get(this._tilesetTileIndex);
}
constructor(map: TmxMap, id: number, x: number, y: number){
this.x = x;
this.y = y;
let rawGid = id;
// 扫描平铺反转位标志
let flip: boolean;
flip = (rawGid & TmxLayerTile.FLIPPED_HORIZONTALLY_FLAG) != 0;
this.horizontalFlip = flip;
flip = (rawGid & TmxLayerTile.FLIPPED_VERTICALLY_FLAG) != 0;
this.verticalFlip = flip;
flip = (rawGid & TmxLayerTile.FLIPPED_DIAGONALLY_FLAG) != 0;
this.diagonalFlip = flip;
// 零位标志
rawGid &= ~(TmxLayerTile.FLIPPED_HORIZONTALLY_FLAG | TmxLayerTile.FLIPPED_VERTICALLY_FLAG | TmxLayerTile.FLIPPED_DIAGONALLY_FLAG);
// 将GID保存
this.gid = rawGid;
this.tileset = map.getTilesetForTileGid(this.gid);
}
}
}