tiled 基本数据

This commit is contained in:
yhh
2020-08-12 12:16:35 +08:00
parent c89ed25d8a
commit 167ef03df6
24 changed files with 2625 additions and 3 deletions

16
source/src/Tiled/Group.ts Normal file
View File

@@ -0,0 +1,16 @@
module es {
export class TmxGroup implements ITmxLayer{
public map: TmxMap;
public offsetX: number;
public offsetY: number;
public opacity: number;
public properties: Map<string, string>;
public visible: boolean;
public name: string;
public layers: TmxList<any>;
public tileLayers: TmxList<TmxLayer>;
public objectGroups: TmxList<TmxObjectGroup>;
public imageLayers: TmxList<TmxImageLayer>;
public groups: TmxList<TmxGroup>;
}
}

View File

@@ -0,0 +1,9 @@
module es {
export interface ITmxLayer {
offsetX: number;
offsetY: number;
opacity: number;
visible: boolean;
properties: Map<string, string>;
}
}

View File

@@ -0,0 +1,15 @@
module es {
export class TmxImageLayer implements ITmxLayer {
public map: TmxMap;
public name: string;
public offsetX: number;
public offsetY: number;
public opacity: number;
public properties: Map<string, string>;
public visible: boolean;
public width?: number;
public height?: number;
public image: TmxImage;
}
}

100
source/src/Tiled/Layer.ts Normal file
View File

@@ -0,0 +1,100 @@
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;
}
}
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);
}
}
}

114
source/src/Tiled/Map.ts Normal file
View File

@@ -0,0 +1,114 @@
///<reference path="./TiledCore.ts" />
module es {
export class TmxMap extends TmxDocument {
public version: string;
public tiledVersion: string;
public width: number;
public height: number;
public get worldWidth(){
return this.width * this.tileWidth;
}
public get worldHeight(){
return this.height * this.tileHeight;
}
public tileWidth: number;
public tileHeight: number;
public hexSideLength?: number;
public orientation: OrientationType;
public staggerAxis: StaggerAxisType;
public staggerIndex: StaggerIndexType;
public renderOrder: RenderOrderType;
public backgroundColor: number;
public nextObjectID?: number;
/**
* 包含所有的ITmxLayers不管它们的具体类型是什么。
* 注意TmxGroup中的层将不在此列表中。TmxGroup管理自己的层列表。
*/
public layers: TmxList<any>;
public tilesets: TmxList<TmxTileset>;
public tileLayers: TmxList<TmxLayer>;
public objectGroups: TmxList<TmxObjectGroup>;
public imageLayers: TmxList<TmxImageLayer>;
public groups: TmxList<TmxGroup>;
public properties: Map<string, string>;
/**
* 当我们有一个图像tilesettile可以是任何大小所以我们记录的最大大小来剔除
*/
public maxTileWidth: number;
/**
* 当我们有一个图像tilesettile可以是任何大小所以我们记录的最大大小来剔除
*/
public maxTileHeight: number;
/**
* 此地图是否具有需要非默认平铺大小的特殊剔除
*/
public get requiresLargeTileCulling(): boolean {
return this.maxTileHeight > this.tileHeight || this.maxTileWidth > this.tileWidth;
}
/**
* 获取给定tileId的tile tileset
* @param gid
*/
public getTilesetForTileGid(gid: number): TmxTileset {
if (gid == 0)
return null;
for (let i = this.tilesets.size - 1; i >= 0; i --){
if (this.tilesets.get(i.toString()).firstGid <= gid)
return this.tilesets.get(i.toString());
}
console.error(`tile gid${gid}未在任何tileset中找到`);
}
/**
* 更新他们的动画tile
*/
public update(){
this.tilesets.forEach(tileset => {tileset.update();});
}
public _isDisposed;
public dispose(disposing: boolean = true){
if (!this._isDisposed){
if (disposing){
this.tilesets.forEach(tileset => {if (tileset.image) tileset.image.dispose()});
this.imageLayers.forEach(layer => {if (layer.image) layer.image.dispose();});
}
this._isDisposed = true;
}
}
}
export enum OrientationType {
unknown,
orthogonal,
isometric,
staggered,
hexagonal
}
export enum StaggerAxisType {
x,
y
}
export enum StaggerIndexType {
odd,
even
}
export enum RenderOrderType {
rightDown,
rightUp,
leftDown,
leftUp
}
}

View File

@@ -0,0 +1,77 @@
module es {
export class TmxObjectGroup implements ITmxLayer {
public map: TmxMap;
public name: string;
public opacity: number;
public visible: boolean;
public offsetX: number;
public offsetY: number;
public color: number;
public drawOrder: DrawOrderType;
public objects: TmxList<TmxObject>;
public properties: Map<string, string>;
}
export class TmxObject implements ITmxElement {
public id: number;
public name: string;
public objectType: TmxObjectType;
public type: string;
public x: number;
public y: number;
public width: number;
public height: number;
public rotation: number;
public tile: TmxLayerTile;
public visible: boolean;
public text: TmxText;
}
export class TmxText {
public fontFamily: string;
public pixelSize: number;
public wrap: boolean;
public color: number;
public bold: boolean;
public italic: boolean;
public underline: boolean;
public strikeout: boolean;
public kerning: boolean;
public alignment: TmxAlignment;
public value: string;
}
export class TmxAlignment {
public horizontal: TmxHorizontalAlignment;
public vertical: TmxVerticalAlignment;
}
export enum TmxObjectType {
basic,
point,
tile,
ellipse,
polygon,
polyline,
text
}
export enum DrawOrderType {
unkownOrder = -1,
TopDown,
IndexOrder
}
export enum TmxHorizontalAlignment {
left,
center,
right,
justify
}
export enum TmxVerticalAlignment {
top,
center,
bottom
}
}

View File

@@ -0,0 +1,58 @@
module es {
export class TmxDocument {
public TmxDirectory: string;
constructor(){
this.TmxDirectory = "";
}
}
export interface ITmxElement {
name: string;
}
export class TmxList<T extends ITmxElement> extends Map<string, T>{
public _nameCount: Map<string, number> = new Map<string, number>();
public add(t: T){
let tName = t.name;
// 通过附加数字重命名重复的条目
if (this.has(tName))
this._nameCount.set(tName, this._nameCount.get(tName) + 1);
else
this._nameCount.set(tName, 0);
}
protected getKeyForItem(item: T): string {
let name = item.name;
let count = this._nameCount.get(name);
let dupes = 0;
// 对于重复的键,附加一个计数器。对于病理情况,插入下划线以确保唯一性
while (this.has(name)){
name = name + Enumerable.repeat("_", dupes).toString() + count.toString();
dupes ++;
}
return name;
}
}
export class TmxImage {
public texture: egret.Texture;
public source: string;
public format: string;
public data: any;
public trans: number;
public width: number;
public height: number;
public dispose(){
if (this.texture){
this.texture.dispose();
this.texture = null;
}
}
}
}

View File

@@ -0,0 +1,39 @@
module es {
export class TmxTileset extends TmxDocument implements ITmxElement {
public map: TmxMap;
public firstGid: number;
public name;
public tileWidth: number;
public tileHeight: number;
public spacing: number;
public margin: number;
public columns?: number;
public tileCount?: number;
public tiles: Map<number, TmxTilesetTile>;
public tileOffset: TmxTileOffset;
public properties: Map<string, string>;
public image: TmxImage;
public terrains: TmxList<TmxTerrain>;
/**
* 为每个块缓存源矩形
*/
public tileRegions: Map<number, Rectangle>;
public update(){
this.tiles.forEach(value => {
value.updateAnimatedTiles();
});
}
}
export class TmxTileOffset {
public x: number;
public y: number;
}
export class TmxTerrain implements ITmxElement {
public name;
public tile: number;
public properties: Map<string, string>;
}
}

View File

@@ -0,0 +1,79 @@
module es {
export class TmxTilesetTile {
public tileset: TmxTileset;
public id: number;
public terrainEdges: TmxTerrain[];
public probability: number;
public type: string;
public properties: Map<string, string>;
public image: TmxImage;
public objectGroups: TmxList<TmxObjectGroup>;
public animationFrames: TmxAnimationFrame[];
// TODO: 为什么动画瓷砖需要添加firstGid
public get currentAnimationFrameGid(){
return this.animationFrames[this._animationCurrentFrame].gid + this.tileset.firstGid;
}
public _animationElapsedTime: number;
public _animationCurrentFrame: number;
/**
* 返回“engine:isDestructable”属性的值(如果属性字典中存在)
*/
public isDestructable: boolean;
/**
* 返回“engine:isSlope”属性的值(如果存在于属性字典中)
*/
public isSlope: boolean;
/**
* 返回“engine:isOneWayPlatform”属性的值(如果存在于属性字典中)
*/
public isOneWayPlatform: boolean;
/**
* 返回“engine:slopeTopLeft”属性的值(如果存在于属性字典中)
*/
public slopeTopLeft: number;
/**
* 如果属性字典中存在“engine:slopeTopRight”属性则返回该属性的值
*/
public slopeTopRight: number;
public processProperties(){
let value: string;
value = this.properties.get("engine.isDestructable");
if (value)
this.isDestructable = Boolean(value);
value = this.properties.get("engine:isSlope");
if (value)
this.isSlope = Boolean(value);
value = this.properties.get("engine:isOneWayPlatform");
if (value)
this.isOneWayPlatform = Boolean(value);
value = this.properties.get("engine:slopeTopLeft");
if (value)
this.slopeTopLeft = Number(value);
value = this.properties.get("engine:slopeTopRight");
if (value)
this.slopeTopRight = Number(value);
}
public updateAnimatedTiles(){
if (this.animationFrames.length == 0)
return;
this._animationElapsedTime += Time.deltaTime;
if (this._animationElapsedTime > this.animationFrames[this._animationCurrentFrame].duration){
this._animationCurrentFrame = MathHelper.incrementWithWrap(this._animationCurrentFrame, this.animationFrames.length);
this._animationElapsedTime = 0;
}
}
}
export class TmxAnimationFrame {
public gid: number;
public duration: number;
}
}