Merge pull request #27 from esengine/develop_tiled

tiled 支持
This commit is contained in:
YHH
2020-08-15 22:01:37 +08:00
committed by GitHub
43 changed files with 8637 additions and 539 deletions
+1 -1
View File
@@ -31,7 +31,7 @@
data-content-width="640" data-content-width="640"
data-content-height="1136" data-content-height="1136"
data-multi-fingered="2" data-multi-fingered="2"
data-show-fps="false" data-show-log="false" data-show-fps="true" data-show-log="false"
data-show-fps-style="x:0,y:0,size:12,textColor:0xffffff,bgAlpha:0.9"> data-show-fps-style="x:0,y:0,size:12,textColor:0xffffff,bgAlpha:0.9">
</div> </div>
<script> <script>
+440 -13
View File
@@ -252,6 +252,7 @@ declare module es {
declare module es { declare module es {
class Core extends egret.DisplayObjectContainer { class Core extends egret.DisplayObjectContainer {
static emitter: Emitter<CoreEvents>; static emitter: Emitter<CoreEvents>;
static debugRenderEndabled: boolean;
static graphicsDevice: GraphicsDevice; static graphicsDevice: GraphicsDevice;
static content: ContentManager; static content: ContentManager;
static _instance: Core; static _instance: Core;
@@ -701,6 +702,58 @@ declare module es {
stop(): void; stop(): void;
} }
} }
declare module es {
class CollisionState {
right: boolean;
left: boolean;
above: boolean;
below: boolean;
becameGroundedThisFrame: boolean;
wasGroundedLastFrame: boolean;
isGroundedOnOnewayPlatform: boolean;
slopAngle: number;
readonly hasCollision: boolean;
_movementRemainderX: SubpixelNumber;
_movementRemainderY: SubpixelNumber;
reset(): void;
toString(): string;
}
class TiledMapMover extends Component {
colliderHorizontalInset: number;
colliderVerticalInset: number;
_boxColliderBounds: Rectangle;
constructor();
testCollisions(motion: Vector2, boxColliderBounds: Rectangle, collisionState: CollisionState): void;
testMapCollision(collisionRect: Rectangle, direction: Edge, collisionState: CollisionState, collisionResponse: number): void;
collisionRectForSide(side: Edge, motion: number): Rectangle;
}
}
declare module es {
class TiledMapRenderer extends RenderableComponent {
tiledMap: TmxMap;
physicsLayer: number;
layerIndicesToRender: number[];
private toContainer;
readonly width: number;
readonly height: number;
collisionLayer: TmxLayer;
_shouldCreateColliders: boolean;
_colliders: Collider[];
constructor(tiledMap: TmxMap, collisionLayerName?: string, shouldCreateColliders?: boolean);
setLayerToRender(layerName: string): void;
setLayersToRender(...layerNames: string[]): void;
private getLayerIndex;
getRowAtWorldPosition(yPos: number): number;
getColumnAtWorldPosition(xPos: number): number;
onEntityTransformChanged(comp: transform.Component): void;
onAddedToEntity(): void;
onRemovedFromEntity(): void;
update(): void;
render(camera: es.Camera): void;
addColliders(): void;
removeColliders(): void;
}
}
declare module es { declare module es {
interface ITriggerListener { interface ITriggerListener {
onTriggerEnter(other: Collider, local: Collider): any; onTriggerEnter(other: Collider, local: Collider): any;
@@ -763,6 +816,7 @@ declare module es {
constructor(); constructor();
width: number; width: number;
height: number; height: number;
createBoxRect(x: number, y: number, width: number, height: number): BoxCollider;
setSize(width: number, height: number): this; setSize(width: number, height: number): this;
setWidth(width: number): BoxCollider; setWidth(width: number): BoxCollider;
setHeight(height: number): void; setHeight(height: number): void;
@@ -944,6 +998,7 @@ declare module es {
} }
declare class ObjectUtils { declare class ObjectUtils {
static clone<T>(p: any, c?: T): T; static clone<T>(p: any, c?: T): T;
static elements(p: {}): any[];
} }
declare module es { declare module es {
interface IRenderable { interface IRenderable {
@@ -1200,6 +1255,7 @@ declare module es {
static readonly Epsilon: number; static readonly Epsilon: number;
static readonly Rad2Deg: number; static readonly Rad2Deg: number;
static readonly Deg2Rad: number; static readonly Deg2Rad: number;
static readonly PiOver2: number;
static toDegrees(radians: number): number; static toDegrees(radians: number): number;
static toRadians(degrees: number): number; static toRadians(degrees: number): number;
static map(value: number, leftMin: number, leftMax: number, rightMin: number, rightMax: number): number; static map(value: number, leftMin: number, leftMax: number, rightMin: number, rightMax: number): number;
@@ -1209,6 +1265,7 @@ declare module es {
static isEven(value: number): boolean; static isEven(value: number): boolean;
static clamp01(value: number): number; static clamp01(value: number): number;
static angleBetweenVectors(from: Vector2, to: Vector2): number; static angleBetweenVectors(from: Vector2, to: Vector2): number;
static incrementWithWrap(t: number, length: number): number;
} }
} }
declare module es { declare module es {
@@ -1490,6 +1547,336 @@ declare module es {
reset(): void; reset(): void;
} }
} }
declare module es {
class TmxGroup implements ITmxLayer {
map: TmxMap;
offsetX: number;
offsetY: number;
opacity: number;
properties: Map<string, string>;
visible: boolean;
name: string;
layers: ITmxLayer[];
tileLayers: TmxLayer[];
objectGroups: TmxObjectGroup[];
imageLayers: TmxImageLayer[];
groups: TmxGroup[];
}
}
declare module es {
interface ITmxLayer {
offsetX: number;
offsetY: number;
opacity: number;
visible: boolean;
properties: Map<string, string>;
}
}
declare module es {
class TmxImageLayer implements ITmxLayer {
map: TmxMap;
name: string;
offsetX: number;
offsetY: number;
opacity: number;
properties: Map<string, string>;
visible: boolean;
width?: number;
height?: number;
image: TmxImage;
}
}
declare module es {
class TmxLayer implements ITmxLayer {
map: TmxMap;
name: string;
opacity: number;
offsetX: number;
offsetY: number;
properties: Map<string, string>;
visible: boolean;
readonly offset: Vector2;
width: number;
height: number;
tiles: TmxLayerTile[];
getTileWithGid(gid: number): TmxLayerTile;
getTile(x: number, y: number): TmxLayerTile;
getCollisionRectangles(): Rectangle[];
findBoundsRect(startX: number, endX: number, startY: number, checkedIndexes?: boolean[]): Rectangle;
}
class TmxLayerTile {
static readonly FLIPPED_HORIZONTALLY_FLAG: number;
static readonly FLIPPED_VERTICALLY_FLAG: number;
tileset: TmxTileset;
gid: number;
x: number;
y: number;
readonly position: Vector2;
horizontalFlip: boolean;
verticalFlip: boolean;
_tilesetTileIndex?: number;
readonly tilesetTile: TmxTilesetTile;
constructor(map: TmxMap, id: number, x: number, y: number);
}
}
declare module es {
class TmxDocument {
tmxDirectory: string;
constructor();
}
interface ITmxElement {
name: string;
}
class TmxImage {
texture: egret.Bitmap;
bitmap: egret.SpriteSheet;
source: string;
format: string;
data: any;
trans: number;
width: number;
height: number;
dispose(): void;
}
}
declare module es {
class TmxMap extends TmxDocument {
version: string;
tiledVersion: string;
width: number;
height: number;
readonly worldWidth: number;
readonly worldHeight: number;
tileWidth: number;
tileHeight: number;
hexSideLength?: number;
orientation: OrientationType;
staggerAxis: StaggerAxisType;
staggerIndex: StaggerIndexType;
renderOrder: RenderOrderType;
backgroundColor: number;
nextObjectID?: number;
layers: ITmxLayer[];
tilesets: TmxTileset[];
tileLayers: TmxLayer[];
objectGroups: TmxObjectGroup[];
imageLayers: TmxImageLayer[];
groups: TmxGroup[];
properties: Map<string, string>;
maxTileWidth: number;
maxTileHeight: number;
readonly requiresLargeTileCulling: boolean;
getTilesetForTileGid(gid: number): TmxTileset;
worldToTilePositionX(x: number, clampToTilemapBounds?: boolean): number;
worldToTilePositionY(y: number, clampToTilemapBounds?: boolean): number;
getLayer(name: string): ITmxLayer;
update(): void;
_isDisposed: any;
dispose(disposing?: boolean): void;
}
enum OrientationType {
unknown = 0,
orthogonal = 1,
isometric = 2,
staggered = 3,
hexagonal = 4
}
enum StaggerAxisType {
x = 0,
y = 1
}
enum StaggerIndexType {
odd = 0,
even = 1
}
enum RenderOrderType {
rightDown = 0,
rightUp = 1,
leftDown = 2,
leftUp = 3
}
}
declare module es {
class TmxObjectGroup implements ITmxLayer {
map: TmxMap;
name: string;
opacity: number;
visible: boolean;
offsetX: number;
offsetY: number;
color: number;
drawOrder: DrawOrderType;
objects: TmxObject[];
properties: Map<string, string>;
}
class TmxObject implements ITmxElement {
id: number;
name: string;
shape: egret.Shape;
textField: egret.TextField;
objectType: TmxObjectType;
type: string;
x: number;
y: number;
width: number;
height: number;
rotation: number;
tile: TmxLayerTile;
visible: boolean;
text: TmxText;
points: Vector2[];
properties: Map<string, string>;
constructor();
}
class TmxText {
fontFamily: string;
pixelSize: number;
wrap: boolean;
color: number;
bold: boolean;
italic: boolean;
underline: boolean;
strikeout: boolean;
kerning: boolean;
alignment: TmxAlignment;
value: string;
}
class TmxAlignment {
horizontal: TmxHorizontalAlignment;
vertical: TmxVerticalAlignment;
}
enum TmxObjectType {
basic = 0,
point = 1,
tile = 2,
ellipse = 3,
polygon = 4,
polyline = 5,
text = 6
}
enum DrawOrderType {
unkownOrder = -1,
TopDown = 0,
IndexOrder = 1
}
enum TmxHorizontalAlignment {
left = 0,
center = 1,
right = 2,
justify = 3
}
enum TmxVerticalAlignment {
top = 0,
center = 1,
bottom = 2
}
}
declare module es {
class TiledMapLoader {
static loadTmxMap(map: TmxMap, filePath: string): Promise<TmxMap>;
static loadTmxMapData(map: TmxMap, xMap: any): Promise<TmxMap>;
static parseLayers(container: any, xEle: any, map: TmxMap, width: number, height: number): Promise<void>;
static loadTmxGroup(group: TmxGroup, map: TmxMap, xGroup: any, width: number, height: number): TmxGroup;
static loadTmxImageLayer(layer: TmxImageLayer, map: TmxMap, xImageLayer: any): Promise<TmxImageLayer>;
static loadTmxLayer(layer: TmxLayer, map: TmxMap, xLayer: any, width: number, height: number): TmxLayer;
private static updateMaxTileSizes;
static parseOrientationType(type: string): OrientationType;
static parseStaggerAxisType(type: string): StaggerAxisType;
static parseStaggerIndexType(type: string): StaggerIndexType;
static parseRenderOrderType(type: string): RenderOrderType;
static parsePropertyDict(prop: any): Map<string, string>;
static parseTmxTileset(map: TmxMap, xTileset: any): Promise<TmxTileset>;
static loadTmxTileset(tileset: TmxTileset, map: TmxMap, xTileset: any, firstGid: number): Promise<TmxTileset>;
static loadTmxTilesetTile(tile: TmxTilesetTile, tileset: TmxTileset, xTile: any, terrains: TmxTerrain[]): Promise<TmxTilesetTile>;
static loadTmxAnimationFrame(frame: TmxAnimationFrame, xFrame: any): TmxAnimationFrame;
static loadTmxObjectGroup(group: TmxObjectGroup, map: TmxMap, xObjectGroup: any): TmxObjectGroup;
static loadTmxObject(obj: TmxObject, map: TmxMap, xObject: any): TmxObject;
static loadTmxText(text: TmxText, xText: any): TmxText;
static loadTmxAlignment(alignment: TmxAlignment, xText: any): TmxAlignment;
static parsePoints(xPoints: any): any[];
static parsePoint(pt: {
x: number;
y: number;
}): Vector2;
static parseTmxTerrain(xTerrain: any): TmxTerrain;
static parseTmxTileOffset(xTileOffset: any): TmxTileOffset;
static loadTmxImage(image: TmxImage, xImage: any): Promise<TmxImage>;
}
}
declare module es {
class TiledRendering {
static renderMap(map: TmxMap, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, layerDepth: number): void;
static renderLayer(layer: TmxLayer, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, layerDepth: number): void;
static renderLayerRenderCamera(layer: ITmxLayer, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, layerDepth: number, camerClipBounds: Rectangle): void;
static renderLayerCamera(layer: TmxLayer, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, layerDepth: number, camerClipBounds: Rectangle): void;
static renderImageLayer(layer: TmxImageLayer, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, layerDepth: number): void;
static renderObjectGroup(objGroup: TmxObjectGroup, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, layerDepth: number): void;
static renderGroup(group: TmxGroup, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, layerDepth: number): void;
static renderTile(tile: TmxLayerTile, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, tileWidth: number, tileHeight: number, color: egret.ColorMatrixFilter, layerDepth: number): void;
}
}
declare module es {
class TmxTileset extends TmxDocument implements ITmxElement {
map: TmxMap;
firstGid: number;
name: any;
tileWidth: number;
tileHeight: number;
spacing: number;
margin: number;
columns?: number;
tileCount?: number;
tiles: Map<number, TmxTilesetTile>;
tileOffset: TmxTileOffset;
properties: Map<string, string>;
image: TmxImage;
terrains: TmxTerrain[];
tileRegions: Map<number, Rectangle>;
update(): void;
}
class TmxTileOffset {
x: number;
y: number;
}
class TmxTerrain implements ITmxElement {
name: any;
tile: number;
properties: Map<string, string>;
}
}
declare module es {
class TmxTilesetTile {
tileset: TmxTileset;
id: number;
terrainEdges: TmxTerrain[];
probability: number;
type: string;
properties: Map<string, string>;
image: TmxImage;
objectGroups: TmxObjectGroup[];
animationFrames: TmxAnimationFrame[];
readonly currentAnimationFrameGid: number;
_animationElapsedTime: number;
_animationCurrentFrame: number;
isDestructable: boolean;
isSlope: boolean;
isOneWayPlatform: boolean;
slopeTopLeft: number;
slopeTopRight: number;
processProperties(): void;
updateAnimatedTiles(): void;
}
class TmxAnimationFrame {
gid: number;
duration: number;
}
}
declare module es {
class TmxUtils {
static decode(data: any, encoding: any, compression: string): Array<number>;
static color16ToUnit($color: string): number;
}
}
declare class ArrayUtils { declare class ArrayUtils {
static bubbleSort(ary: number[]): void; static bubbleSort(ary: number[]): void;
static insertionSort(ary: number[]): void; static insertionSort(ary: number[]): void;
@@ -1505,15 +1892,28 @@ declare class ArrayUtils {
static equals(ary1: number[], ary2: number[]): Boolean; static equals(ary1: number[], ary2: number[]): Boolean;
static insert(ary: any[], index: number, value: any): any; static insert(ary: any[], index: number, value: any): any;
} }
declare class Base64Utils { declare module es {
private static _keyNum; class Base64Utils {
private static _keyStr; private static _keyStr;
private static _keyAll; static readonly nativeBase64: boolean;
static encode: (input: any) => string; static decode(input: string): string;
static decode(input: any, isNotStr?: boolean): string; static encode(input: string): string;
private static _utf8_encode; static decodeBase64AsArray(input: string, bytes: number): Uint32Array;
private static _utf8_decode; static decompress(data: string, decoded: any, compression: string): any;
private static getConfKey; static decodeCSV(input: string): Array<number>;
}
}
declare module es {
class Color {
private _packedValue;
constructor(r: number, g: number, b: number, alpha: number);
b: number;
g: number;
r: number;
a: number;
packedValue: number;
equals(other: Color): boolean;
}
} }
declare module es { declare module es {
class ContentManager { class ContentManager {
@@ -1524,14 +1924,16 @@ declare module es {
} }
declare module es { declare module es {
class DrawUtils { class DrawUtils {
static drawLine(shape: egret.Shape, start: Vector2, end: Vector2, color: number, thickness?: number): void;
static drawLineAngle(shape: egret.Shape, start: Vector2, radians: number, length: number, color: number, thickness?: number): void;
static drawHollowRect(shape: egret.Shape, rect: Rectangle, color: number, thickness?: number): void;
static drawHollowRectR(shape: egret.Shape, x: number, y: number, width: number, height: number, color: number, thickness?: number): void;
static drawPixel(shape: egret.Shape, position: Vector2, color: number, size?: number): void;
static getColorMatrix(color: number): egret.ColorMatrixFilter; static getColorMatrix(color: number): egret.ColorMatrixFilter;
} }
} }
declare module es {
class EdgeExt {
static oppositeEdge(self: Edge): Edge;
static isHorizontal(self: Edge): boolean;
static isVertical(self: Edge): boolean;
}
}
declare module es { declare module es {
class FuncPack { class FuncPack {
func: Function; func: Function;
@@ -1546,6 +1948,19 @@ declare module es {
emit(eventType: T, data?: any): void; emit(eventType: T, data?: any): void;
} }
} }
declare module es {
enum Edge {
top = 0,
bottom = 1,
left = 2,
right = 3
}
}
declare module es {
class Enumerable {
static repeat<T>(element: T, count: number): any[];
}
}
declare module es { declare module es {
class GlobalManager { class GlobalManager {
_enabled: boolean; _enabled: boolean;
@@ -1715,7 +2130,19 @@ declare class RandomUtils {
} }
declare module es { declare module es {
class RectangleExt { class RectangleExt {
static getSide(rect: Rectangle, edge: Edge): number;
static union(first: Rectangle, point: Vector2): Rectangle; static union(first: Rectangle, point: Vector2): Rectangle;
static getHalfRect(rect: Rectangle, edge: Edge): Rectangle;
static getRectEdgePortion(rect: Rectangle, edge: Edge, size?: number): Rectangle;
static expandSide(rect: Rectangle, edge: Edge, amount: number): void;
static contract(rect: Rectangle, horizontalAmount: any, verticalAmount: any): void;
}
}
declare module es {
class SubpixelNumber {
remainder: number;
update(amount: number): number;
reset(): void;
} }
} }
declare module es { declare module es {
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

@@ -0,0 +1,345 @@
{ "height":25,
"infinite":false,
"layers":[
{
"data":[24, 24, 23, 11, 19, 19, 12, 23, 24, 24, 23, 7, 2, 2, 1, 4, 2, 2, 3, 4, 4, 1, 3, 4, 1, 24, 23, 23, 14, 3, 3, 8, 12, 24, 24, 18, 4, 1, 3, 1, 3, 3, 4, 4, 1, 3, 1, 4, 3, 4, 11, 15, 15, 7, 1, 4, 3, 20, 23, 11, 7, 2, 1, 3, 1, 3, 4, 4, 3, 2, 2, 3, 4, 2, 1, 18, 4, 3, 2, 2, 4, 3, 8, 12, 18, 2, 4, 4, 3, 3, 1, 4, 2, 1, 4, 4, 4, 1, 1, 1, 14, 2, 1, 4, 2, 1, 4, 2, 8, 7, 5, 17, 6, 3, 3, 3, 4, 3, 4, 4, 3, 2, 4, 3, 4, 10, 6, 2, 1, 4, 4, 1, 3, 4, 3, 8, 12, 10, 6, 2, 1, 1, 1, 1, 2, 1, 4, 2, 1, 1, 24, 18, 1, 2, 4, 3, 3, 5, 6, 5, 13, 9, 11, 7, 3, 4, 1, 3, 1, 3, 4, 2, 4, 4, 4, 24, 14, 4, 2, 5, 6, 2, 8, 22, 9, 23, 24, 10, 6, 2, 1, 3, 1, 5, 6, 2, 3, 4, 4, 2, 19, 7, 3, 1, 8, 7, 4, 1, 8, 12, 24, 23, 23, 10, 17, 6, 3, 1, 8, 7, 1, 3, 3, 3, 1, 1, 2, 4, 2, 2, 3, 3, 4, 3, 20, 24, 23, 23, 23, 23, 18, 2, 2, 3, 1, 4, 4, 1, 1, 1, 3, 3, 5, 13, 6, 1, 2, 2, 5, 9, 23, 23, 24, 23, 24, 14, 1, 3, 1, 1, 3, 3, 4, 4, 4, 2, 4, 16, 24, 10, 6, 2, 4, 20, 23, 23, 24, 23, 23, 24, 14, 2, 4, 2, 4, 5, 6, 4, 3, 1, 3, 1, 20, 23, 24, 10, 6, 3, 8, 12, 24, 23, 23, 23, 24, 14, 1, 2, 1, 5, 9, 18, 4, 3, 4, 4, 2, 8, 12, 23, 24, 18, 4, 3, 16, 24, 24, 24, 23, 24, 18, 1, 3, 1, 16, 24, 14, 1, 3, 2, 4, 1, 2, 8, 12, 24, 14, 4, 1, 8, 15, 12, 24, 23, 11, 7, 2, 1, 2, 16, 23, 18, 1, 4, 2, 3, 4, 3, 2, 8, 19, 7, 2, 2, 3, 3, 8, 15, 19, 7, 3, 1, 2, 5, 9, 24, 14, 1, 2, 3, 2, 2, 1, 4, 4, 1, 2, 5, 6, 2, 2, 2, 1, 3, 4, 3, 5, 13, 9, 24, 24, 18, 4, 3, 4, 1, 4, 1, 3, 2, 5, 13, 9, 14, 3, 1, 3, 2, 4, 4, 5, 21, 19, 12, 24, 11, 7, 1, 2, 3, 2, 1, 3, 3, 3, 20, 23, 24, 18, 4, 4, 2, 3, 1, 1, 8, 7, 5, 9, 23, 18, 1, 3, 4, 2, 4, 2, 4, 1, 2, 8, 15, 19, 7, 4, 5, 6, 4, 2, 4, 5, 17, 9, 23, 11, 22, 13, 6, 4, 1, 3, 2, 2, 4, 4, 3, 2, 1, 4, 2, 8, 7, 4, 2, 3, 16, 24, 23, 11, 7, 16, 23, 18, 3, 1, 1, 3, 1, 2, 3, 3, 3, 4, 2, 1, 3, 2, 3, 4, 3, 8, 15, 15, 7, 4, 8, 19, 7, 3, 4, 1, 2, 3, 4, 1, 3, 4, 4, 4, 1, 4, 4, 3, 2, 3, 4, 1, 2, 4, 2, 1, 2, 2, 4, 1, 4, 2, 3, 2, 1, 4, 2, 2, 1, 2, 2, 2, 4, 3, 3, 2, 3, 3, 2, 3, 2, 4, 1, 3, 1, 1, 1, 1, 4, 1, 3, 3, 2, 1, 4, 2, 1, 3, 1, 3, 3, 4, 3, 4, 2, 1, 2, 3, 1, 1],
"height":25,
"id":1,
"name":"Tile Layer 1",
"opacity":1,
"type":"tilelayer",
"visible":true,
"width":25,
"x":0,
"y":0
}],
"nextlayerid":2,
"nextobjectid":1,
"orientation":"isometric",
"renderorder":"right-down",
"tiledversion":"1.2.1",
"tileheight":32,
"tilesets":[
{
"columns":4,
"firstgid":1,
"grid":
{
"height":32,
"orientation":"isometric",
"width":64
},
"image":"isometric_grass_and_water.png",
"imageheight":384,
"imagewidth":256,
"margin":0,
"name":"isometric_grass_and_water",
"spacing":0,
"terrains":[
{
"name":"Grass",
"tile":0
},
{
"name":"Water",
"tile":22
}],
"tilecount":24,
"tileheight":64,
"tileoffset":
{
"x":0,
"y":16
},
"tiles":[
{
"id":0,
"terrain":[0, 0, 0, 0]
},
{
"id":1,
"terrain":[0, 0, 0, 0]
},
{
"id":2,
"terrain":[0, 0, 0, 0]
},
{
"id":3,
"terrain":[0, 0, 0, 0]
},
{
"id":4,
"terrain":[0, 0, 0, 1]
},
{
"id":5,
"terrain":[0, 0, 1, 0]
},
{
"id":6,
"terrain":[1, 0, 0, 0]
},
{
"id":7,
"terrain":[0, 1, 0, 0]
},
{
"id":8,
"terrain":[0, 1, 1, 1]
},
{
"id":9,
"terrain":[1, 0, 1, 1]
},
{
"id":10,
"terrain":[1, 1, 1, 0]
},
{
"id":11,
"terrain":[1, 1, 0, 1]
},
{
"id":12,
"terrain":[0, 0, 1, 1]
},
{
"id":13,
"terrain":[1, 0, 1, 0]
},
{
"id":14,
"terrain":[1, 1, 0, 0]
},
{
"id":15,
"terrain":[0, 1, 0, 1]
},
{
"id":16,
"terrain":[0, 0, 1, 1]
},
{
"id":17,
"terrain":[1, 0, 1, 0]
},
{
"id":18,
"terrain":[1, 1, 0, 0]
},
{
"id":19,
"terrain":[0, 1, 0, 1]
},
{
"id":20,
"terrain":[0, 1, 1, 0]
},
{
"id":21,
"terrain":[1, 0, 0, 1]
},
{
"id":22,
"terrain":[1, 1, 1, 1]
},
{
"id":23,
"terrain":[1, 1, 1, 1]
}],
"tilewidth":64,
"wangsets":[
{
"cornercolors":[
{
"color":"#8ab022",
"name":"Grass",
"probability":1,
"tile":0
},
{
"color":"#378dc2",
"name":"Water",
"probability":1,
"tile":23
}],
"edgecolors":[],
"name":"Grass and Water",
"tile":15,
"wangtiles":[
{
"dflip":false,
"hflip":false,
"tileid":0,
"vflip":false,
"wangid":[0, 1, 0, 1, 0, 1, 0, 1]
},
{
"dflip":false,
"hflip":false,
"tileid":1,
"vflip":false,
"wangid":[0, 1, 0, 1, 0, 1, 0, 1]
},
{
"dflip":false,
"hflip":false,
"tileid":2,
"vflip":false,
"wangid":[0, 1, 0, 1, 0, 1, 0, 1]
},
{
"dflip":false,
"hflip":false,
"tileid":3,
"vflip":false,
"wangid":[0, 1, 0, 1, 0, 1, 0, 1]
},
{
"dflip":false,
"hflip":false,
"tileid":4,
"vflip":false,
"wangid":[0, 1, 0, 2, 0, 1, 0, 1]
},
{
"dflip":false,
"hflip":false,
"tileid":5,
"vflip":false,
"wangid":[0, 1, 0, 1, 0, 2, 0, 1]
},
{
"dflip":false,
"hflip":false,
"tileid":6,
"vflip":false,
"wangid":[0, 1, 0, 1, 0, 1, 0, 2]
},
{
"dflip":false,
"hflip":false,
"tileid":7,
"vflip":false,
"wangid":[0, 2, 0, 1, 0, 1, 0, 1]
},
{
"dflip":false,
"hflip":false,
"tileid":8,
"vflip":false,
"wangid":[0, 2, 0, 2, 0, 2, 0, 1]
},
{
"dflip":false,
"hflip":false,
"tileid":9,
"vflip":false,
"wangid":[0, 1, 0, 2, 0, 2, 0, 2]
},
{
"dflip":false,
"hflip":false,
"tileid":10,
"vflip":false,
"wangid":[0, 2, 0, 1, 0, 2, 0, 2]
},
{
"dflip":false,
"hflip":false,
"tileid":11,
"vflip":false,
"wangid":[0, 2, 0, 2, 0, 1, 0, 2]
},
{
"dflip":false,
"hflip":false,
"tileid":12,
"vflip":false,
"wangid":[0, 1, 0, 2, 0, 2, 0, 1]
},
{
"dflip":false,
"hflip":false,
"tileid":13,
"vflip":false,
"wangid":[0, 1, 0, 1, 0, 2, 0, 2]
},
{
"dflip":false,
"hflip":false,
"tileid":14,
"vflip":false,
"wangid":[0, 2, 0, 1, 0, 1, 0, 2]
},
{
"dflip":false,
"hflip":false,
"tileid":15,
"vflip":false,
"wangid":[0, 2, 0, 2, 0, 1, 0, 1]
},
{
"dflip":false,
"hflip":false,
"tileid":16,
"vflip":false,
"wangid":[0, 1, 0, 2, 0, 2, 0, 1]
},
{
"dflip":false,
"hflip":false,
"tileid":17,
"vflip":false,
"wangid":[0, 1, 0, 1, 0, 2, 0, 2]
},
{
"dflip":false,
"hflip":false,
"tileid":18,
"vflip":false,
"wangid":[0, 2, 0, 1, 0, 1, 0, 2]
},
{
"dflip":false,
"hflip":false,
"tileid":19,
"vflip":false,
"wangid":[0, 2, 0, 2, 0, 1, 0, 1]
},
{
"dflip":false,
"hflip":false,
"tileid":20,
"vflip":false,
"wangid":[0, 2, 0, 1, 0, 2, 0, 1]
},
{
"dflip":false,
"hflip":false,
"tileid":21,
"vflip":false,
"wangid":[0, 1, 0, 2, 0, 1, 0, 2]
},
{
"dflip":false,
"hflip":false,
"tileid":22,
"vflip":false,
"wangid":[0, 2, 0, 2, 0, 2, 0, 2]
},
{
"dflip":false,
"hflip":false,
"tileid":23,
"vflip":false,
"wangid":[0, 2, 0, 2, 0, 2, 0, 2]
}]
}]
}],
"tilewidth":64,
"type":"map",
"version":1.2,
"width":25
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

File diff suppressed because one or more lines are too long
+11 -1
View File
@@ -1,7 +1,7 @@
{ {
"groups": [ "groups": [
{ {
"keys": "checkbox_select_disabled_png,checkbox_select_down_png,checkbox_select_up_png,checkbox_unselect_png,selected_png,border_png,header_png,radiobutton_select_disabled_png,radiobutton_select_down_png,radiobutton_select_up_png,radiobutton_unselect_png,roundthumb_png,thumb_png,track_png,tracklight_png,handle_png,off_png,on_png,button_down_png,button_up_png,thumb_pb_png,track_pb_png,track_sb_png,bg_jpg,egret_icon_png,description_json", "keys": "checkbox_select_disabled_png,checkbox_select_down_png,checkbox_select_up_png,checkbox_unselect_png,selected_png,border_png,header_png,radiobutton_select_disabled_png,radiobutton_select_down_png,radiobutton_select_up_png,radiobutton_unselect_png,roundthumb_png,thumb_png,track_png,tracklight_png,handle_png,off_png,on_png,button_down_png,button_up_png,thumb_pb_png,track_pb_png,track_sb_png,bg_jpg,egret_icon_png,description_json,isometric_grass_and_water_json,orthogonal-outside_json",
"name": "preload" "name": "preload"
} }
], ],
@@ -145,6 +145,16 @@
"url": "assets/isometric_grass_and_water.png", "url": "assets/isometric_grass_and_water.png",
"type": "image", "type": "image",
"name": "isometric_grass_and_water_png" "name": "isometric_grass_and_water_png"
},
{
"url": "assets/000010000.img.json",
"type": "json",
"name": "000010000.img_json"
},
{
"url": "assets/orthogonal-outside.json",
"type": "json",
"name": "orthogonal-outside_json"
} }
] ]
} }
+16 -11
View File
@@ -10,27 +10,32 @@ module scene {
} }
public async onStart() { public async onStart() {
let mapData = await es.TiledMapLoader.loadTmxMap(new es.TmxMap(), "orthogonal-outside_json");
let map = this.createEntity("map");
let tiledMap = map.addComponent(new es.TiledMapRenderer(mapData)).setRenderLayer(1);
console.log(mapData);
let sprite = new es.Sprite(RES.getRes("checkbox_select_disabled_png")); let sprite = new es.Sprite(RES.getRes("checkbox_select_disabled_png"));
this.createEntityAsync("bg").then(bg => { this.createEntityAsync("bg").then(bg => {
bg.addComponent(new component.PlayerController()); bg.addComponent(new component.PlayerController());
bg.addComponent(new es.Mover()); bg.addComponent(new es.Mover());
let spriteRenderer = bg.addComponent(new es.ScrollingSpriteRenderer(sprite)); let spriteRenderer = bg.addComponent(new es.ScrollingSpriteRenderer(sprite)).setRenderLayer(0);
spriteRenderer.setRenderLayer(4); // spriteRenderer.scrollX = -30;
spriteRenderer.scrollX = -30;
// bg.addComponent(new es.BoxCollider()); // bg.addComponent(new es.BoxCollider());
this.camera.follow(bg, es.CameraStyle.lockOn); this.camera.follow(bg, es.CameraStyle.lockOn);
}); });
es.Core.debugRenderEndabled = true;
// // bg.addComponent(new es.SpriteRenderer()).setSprite(sprite).setColor(0xff0000); // // bg.addComponent(new es.SpriteRenderer()).setSprite(sprite).setColor(0xff0000);
// for (let i = 0; i < 20; i++) {
for (let i = 0; i < 20; i++) { // let sprite = new es.Sprite(RES.getRes("checkbox_select_disabled_png"));
let sprite = new es.Sprite(RES.getRes("checkbox_select_disabled_png")); // let player2 = this.createEntity("bg");
let player2 = this.createEntity("bg"); // player2.addComponent(new es.SpriteRenderer()).setSprite(sprite).setRenderLayer(i);
player2.addComponent(new es.SpriteRenderer()).setSprite(sprite).setRenderLayer(i); // player2.position = new es.Vector2(30 * i, 30 * i);
player2.position = new es.Vector2(30 * i, 30 * i); // // player2.addComponent(new es.BoxCollider());
// player2.addComponent(new es.BoxCollider()); // }
}
let pool = new es.ComponentPool<component.SimplePooled>(component.SimplePooled); let pool = new es.ComponentPool<component.SimplePooled>(component.SimplePooled);
+1 -1
View File
@@ -37,7 +37,7 @@ egret_native.egretStart = function () {
contentWidth: 640, contentWidth: 640,
contentHeight: 1136, contentHeight: 1136,
showPaintRect: false, showPaintRect: false,
showFPS: false, showFPS: true,
fpsStyles: "x:0,y:0,size:12,textColor:0xffffff,bgAlpha:0.9", fpsStyles: "x:0,y:0,size:12,textColor:0xffffff,bgAlpha:0.9",
showLog: false, showLog: false,
logFilter: "", logFilter: "",
+440 -13
View File
@@ -252,6 +252,7 @@ declare module es {
declare module es { declare module es {
class Core extends egret.DisplayObjectContainer { class Core extends egret.DisplayObjectContainer {
static emitter: Emitter<CoreEvents>; static emitter: Emitter<CoreEvents>;
static debugRenderEndabled: boolean;
static graphicsDevice: GraphicsDevice; static graphicsDevice: GraphicsDevice;
static content: ContentManager; static content: ContentManager;
static _instance: Core; static _instance: Core;
@@ -701,6 +702,58 @@ declare module es {
stop(): void; stop(): void;
} }
} }
declare module es {
class CollisionState {
right: boolean;
left: boolean;
above: boolean;
below: boolean;
becameGroundedThisFrame: boolean;
wasGroundedLastFrame: boolean;
isGroundedOnOnewayPlatform: boolean;
slopAngle: number;
readonly hasCollision: boolean;
_movementRemainderX: SubpixelNumber;
_movementRemainderY: SubpixelNumber;
reset(): void;
toString(): string;
}
class TiledMapMover extends Component {
colliderHorizontalInset: number;
colliderVerticalInset: number;
_boxColliderBounds: Rectangle;
constructor();
testCollisions(motion: Vector2, boxColliderBounds: Rectangle, collisionState: CollisionState): void;
testMapCollision(collisionRect: Rectangle, direction: Edge, collisionState: CollisionState, collisionResponse: number): void;
collisionRectForSide(side: Edge, motion: number): Rectangle;
}
}
declare module es {
class TiledMapRenderer extends RenderableComponent {
tiledMap: TmxMap;
physicsLayer: number;
layerIndicesToRender: number[];
private toContainer;
readonly width: number;
readonly height: number;
collisionLayer: TmxLayer;
_shouldCreateColliders: boolean;
_colliders: Collider[];
constructor(tiledMap: TmxMap, collisionLayerName?: string, shouldCreateColliders?: boolean);
setLayerToRender(layerName: string): void;
setLayersToRender(...layerNames: string[]): void;
private getLayerIndex;
getRowAtWorldPosition(yPos: number): number;
getColumnAtWorldPosition(xPos: number): number;
onEntityTransformChanged(comp: transform.Component): void;
onAddedToEntity(): void;
onRemovedFromEntity(): void;
update(): void;
render(camera: es.Camera): void;
addColliders(): void;
removeColliders(): void;
}
}
declare module es { declare module es {
interface ITriggerListener { interface ITriggerListener {
onTriggerEnter(other: Collider, local: Collider): any; onTriggerEnter(other: Collider, local: Collider): any;
@@ -763,6 +816,7 @@ declare module es {
constructor(); constructor();
width: number; width: number;
height: number; height: number;
createBoxRect(x: number, y: number, width: number, height: number): BoxCollider;
setSize(width: number, height: number): this; setSize(width: number, height: number): this;
setWidth(width: number): BoxCollider; setWidth(width: number): BoxCollider;
setHeight(height: number): void; setHeight(height: number): void;
@@ -944,6 +998,7 @@ declare module es {
} }
declare class ObjectUtils { declare class ObjectUtils {
static clone<T>(p: any, c?: T): T; static clone<T>(p: any, c?: T): T;
static elements(p: {}): any[];
} }
declare module es { declare module es {
interface IRenderable { interface IRenderable {
@@ -1200,6 +1255,7 @@ declare module es {
static readonly Epsilon: number; static readonly Epsilon: number;
static readonly Rad2Deg: number; static readonly Rad2Deg: number;
static readonly Deg2Rad: number; static readonly Deg2Rad: number;
static readonly PiOver2: number;
static toDegrees(radians: number): number; static toDegrees(radians: number): number;
static toRadians(degrees: number): number; static toRadians(degrees: number): number;
static map(value: number, leftMin: number, leftMax: number, rightMin: number, rightMax: number): number; static map(value: number, leftMin: number, leftMax: number, rightMin: number, rightMax: number): number;
@@ -1209,6 +1265,7 @@ declare module es {
static isEven(value: number): boolean; static isEven(value: number): boolean;
static clamp01(value: number): number; static clamp01(value: number): number;
static angleBetweenVectors(from: Vector2, to: Vector2): number; static angleBetweenVectors(from: Vector2, to: Vector2): number;
static incrementWithWrap(t: number, length: number): number;
} }
} }
declare module es { declare module es {
@@ -1490,6 +1547,336 @@ declare module es {
reset(): void; reset(): void;
} }
} }
declare module es {
class TmxGroup implements ITmxLayer {
map: TmxMap;
offsetX: number;
offsetY: number;
opacity: number;
properties: Map<string, string>;
visible: boolean;
name: string;
layers: ITmxLayer[];
tileLayers: TmxLayer[];
objectGroups: TmxObjectGroup[];
imageLayers: TmxImageLayer[];
groups: TmxGroup[];
}
}
declare module es {
interface ITmxLayer {
offsetX: number;
offsetY: number;
opacity: number;
visible: boolean;
properties: Map<string, string>;
}
}
declare module es {
class TmxImageLayer implements ITmxLayer {
map: TmxMap;
name: string;
offsetX: number;
offsetY: number;
opacity: number;
properties: Map<string, string>;
visible: boolean;
width?: number;
height?: number;
image: TmxImage;
}
}
declare module es {
class TmxLayer implements ITmxLayer {
map: TmxMap;
name: string;
opacity: number;
offsetX: number;
offsetY: number;
properties: Map<string, string>;
visible: boolean;
readonly offset: Vector2;
width: number;
height: number;
tiles: TmxLayerTile[];
getTileWithGid(gid: number): TmxLayerTile;
getTile(x: number, y: number): TmxLayerTile;
getCollisionRectangles(): Rectangle[];
findBoundsRect(startX: number, endX: number, startY: number, checkedIndexes?: boolean[]): Rectangle;
}
class TmxLayerTile {
static readonly FLIPPED_HORIZONTALLY_FLAG: number;
static readonly FLIPPED_VERTICALLY_FLAG: number;
tileset: TmxTileset;
gid: number;
x: number;
y: number;
readonly position: Vector2;
horizontalFlip: boolean;
verticalFlip: boolean;
_tilesetTileIndex?: number;
readonly tilesetTile: TmxTilesetTile;
constructor(map: TmxMap, id: number, x: number, y: number);
}
}
declare module es {
class TmxDocument {
tmxDirectory: string;
constructor();
}
interface ITmxElement {
name: string;
}
class TmxImage {
texture: egret.Bitmap;
bitmap: egret.SpriteSheet;
source: string;
format: string;
data: any;
trans: number;
width: number;
height: number;
dispose(): void;
}
}
declare module es {
class TmxMap extends TmxDocument {
version: string;
tiledVersion: string;
width: number;
height: number;
readonly worldWidth: number;
readonly worldHeight: number;
tileWidth: number;
tileHeight: number;
hexSideLength?: number;
orientation: OrientationType;
staggerAxis: StaggerAxisType;
staggerIndex: StaggerIndexType;
renderOrder: RenderOrderType;
backgroundColor: number;
nextObjectID?: number;
layers: ITmxLayer[];
tilesets: TmxTileset[];
tileLayers: TmxLayer[];
objectGroups: TmxObjectGroup[];
imageLayers: TmxImageLayer[];
groups: TmxGroup[];
properties: Map<string, string>;
maxTileWidth: number;
maxTileHeight: number;
readonly requiresLargeTileCulling: boolean;
getTilesetForTileGid(gid: number): TmxTileset;
worldToTilePositionX(x: number, clampToTilemapBounds?: boolean): number;
worldToTilePositionY(y: number, clampToTilemapBounds?: boolean): number;
getLayer(name: string): ITmxLayer;
update(): void;
_isDisposed: any;
dispose(disposing?: boolean): void;
}
enum OrientationType {
unknown = 0,
orthogonal = 1,
isometric = 2,
staggered = 3,
hexagonal = 4
}
enum StaggerAxisType {
x = 0,
y = 1
}
enum StaggerIndexType {
odd = 0,
even = 1
}
enum RenderOrderType {
rightDown = 0,
rightUp = 1,
leftDown = 2,
leftUp = 3
}
}
declare module es {
class TmxObjectGroup implements ITmxLayer {
map: TmxMap;
name: string;
opacity: number;
visible: boolean;
offsetX: number;
offsetY: number;
color: number;
drawOrder: DrawOrderType;
objects: TmxObject[];
properties: Map<string, string>;
}
class TmxObject implements ITmxElement {
id: number;
name: string;
shape: egret.Shape;
textField: egret.TextField;
objectType: TmxObjectType;
type: string;
x: number;
y: number;
width: number;
height: number;
rotation: number;
tile: TmxLayerTile;
visible: boolean;
text: TmxText;
points: Vector2[];
properties: Map<string, string>;
constructor();
}
class TmxText {
fontFamily: string;
pixelSize: number;
wrap: boolean;
color: number;
bold: boolean;
italic: boolean;
underline: boolean;
strikeout: boolean;
kerning: boolean;
alignment: TmxAlignment;
value: string;
}
class TmxAlignment {
horizontal: TmxHorizontalAlignment;
vertical: TmxVerticalAlignment;
}
enum TmxObjectType {
basic = 0,
point = 1,
tile = 2,
ellipse = 3,
polygon = 4,
polyline = 5,
text = 6
}
enum DrawOrderType {
unkownOrder = -1,
TopDown = 0,
IndexOrder = 1
}
enum TmxHorizontalAlignment {
left = 0,
center = 1,
right = 2,
justify = 3
}
enum TmxVerticalAlignment {
top = 0,
center = 1,
bottom = 2
}
}
declare module es {
class TiledMapLoader {
static loadTmxMap(map: TmxMap, filePath: string): Promise<TmxMap>;
static loadTmxMapData(map: TmxMap, xMap: any): Promise<TmxMap>;
static parseLayers(container: any, xEle: any, map: TmxMap, width: number, height: number): Promise<void>;
static loadTmxGroup(group: TmxGroup, map: TmxMap, xGroup: any, width: number, height: number): TmxGroup;
static loadTmxImageLayer(layer: TmxImageLayer, map: TmxMap, xImageLayer: any): Promise<TmxImageLayer>;
static loadTmxLayer(layer: TmxLayer, map: TmxMap, xLayer: any, width: number, height: number): TmxLayer;
private static updateMaxTileSizes;
static parseOrientationType(type: string): OrientationType;
static parseStaggerAxisType(type: string): StaggerAxisType;
static parseStaggerIndexType(type: string): StaggerIndexType;
static parseRenderOrderType(type: string): RenderOrderType;
static parsePropertyDict(prop: any): Map<string, string>;
static parseTmxTileset(map: TmxMap, xTileset: any): Promise<TmxTileset>;
static loadTmxTileset(tileset: TmxTileset, map: TmxMap, xTileset: any, firstGid: number): Promise<TmxTileset>;
static loadTmxTilesetTile(tile: TmxTilesetTile, tileset: TmxTileset, xTile: any, terrains: TmxTerrain[]): Promise<TmxTilesetTile>;
static loadTmxAnimationFrame(frame: TmxAnimationFrame, xFrame: any): TmxAnimationFrame;
static loadTmxObjectGroup(group: TmxObjectGroup, map: TmxMap, xObjectGroup: any): TmxObjectGroup;
static loadTmxObject(obj: TmxObject, map: TmxMap, xObject: any): TmxObject;
static loadTmxText(text: TmxText, xText: any): TmxText;
static loadTmxAlignment(alignment: TmxAlignment, xText: any): TmxAlignment;
static parsePoints(xPoints: any): any[];
static parsePoint(pt: {
x: number;
y: number;
}): Vector2;
static parseTmxTerrain(xTerrain: any): TmxTerrain;
static parseTmxTileOffset(xTileOffset: any): TmxTileOffset;
static loadTmxImage(image: TmxImage, xImage: any): Promise<TmxImage>;
}
}
declare module es {
class TiledRendering {
static renderMap(map: TmxMap, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, layerDepth: number): void;
static renderLayer(layer: TmxLayer, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, layerDepth: number): void;
static renderLayerRenderCamera(layer: ITmxLayer, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, layerDepth: number, camerClipBounds: Rectangle): void;
static renderLayerCamera(layer: TmxLayer, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, layerDepth: number, camerClipBounds: Rectangle): void;
static renderImageLayer(layer: TmxImageLayer, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, layerDepth: number): void;
static renderObjectGroup(objGroup: TmxObjectGroup, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, layerDepth: number): void;
static renderGroup(group: TmxGroup, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, layerDepth: number): void;
static renderTile(tile: TmxLayerTile, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, tileWidth: number, tileHeight: number, color: egret.ColorMatrixFilter, layerDepth: number): void;
}
}
declare module es {
class TmxTileset extends TmxDocument implements ITmxElement {
map: TmxMap;
firstGid: number;
name: any;
tileWidth: number;
tileHeight: number;
spacing: number;
margin: number;
columns?: number;
tileCount?: number;
tiles: Map<number, TmxTilesetTile>;
tileOffset: TmxTileOffset;
properties: Map<string, string>;
image: TmxImage;
terrains: TmxTerrain[];
tileRegions: Map<number, Rectangle>;
update(): void;
}
class TmxTileOffset {
x: number;
y: number;
}
class TmxTerrain implements ITmxElement {
name: any;
tile: number;
properties: Map<string, string>;
}
}
declare module es {
class TmxTilesetTile {
tileset: TmxTileset;
id: number;
terrainEdges: TmxTerrain[];
probability: number;
type: string;
properties: Map<string, string>;
image: TmxImage;
objectGroups: TmxObjectGroup[];
animationFrames: TmxAnimationFrame[];
readonly currentAnimationFrameGid: number;
_animationElapsedTime: number;
_animationCurrentFrame: number;
isDestructable: boolean;
isSlope: boolean;
isOneWayPlatform: boolean;
slopeTopLeft: number;
slopeTopRight: number;
processProperties(): void;
updateAnimatedTiles(): void;
}
class TmxAnimationFrame {
gid: number;
duration: number;
}
}
declare module es {
class TmxUtils {
static decode(data: any, encoding: any, compression: string): Array<number>;
static color16ToUnit($color: string): number;
}
}
declare class ArrayUtils { declare class ArrayUtils {
static bubbleSort(ary: number[]): void; static bubbleSort(ary: number[]): void;
static insertionSort(ary: number[]): void; static insertionSort(ary: number[]): void;
@@ -1505,15 +1892,28 @@ declare class ArrayUtils {
static equals(ary1: number[], ary2: number[]): Boolean; static equals(ary1: number[], ary2: number[]): Boolean;
static insert(ary: any[], index: number, value: any): any; static insert(ary: any[], index: number, value: any): any;
} }
declare class Base64Utils { declare module es {
private static _keyNum; class Base64Utils {
private static _keyStr; private static _keyStr;
private static _keyAll; static readonly nativeBase64: boolean;
static encode: (input: any) => string; static decode(input: string): string;
static decode(input: any, isNotStr?: boolean): string; static encode(input: string): string;
private static _utf8_encode; static decodeBase64AsArray(input: string, bytes: number): Uint32Array;
private static _utf8_decode; static decompress(data: string, decoded: any, compression: string): any;
private static getConfKey; static decodeCSV(input: string): Array<number>;
}
}
declare module es {
class Color {
private _packedValue;
constructor(r: number, g: number, b: number, alpha: number);
b: number;
g: number;
r: number;
a: number;
packedValue: number;
equals(other: Color): boolean;
}
} }
declare module es { declare module es {
class ContentManager { class ContentManager {
@@ -1524,14 +1924,16 @@ declare module es {
} }
declare module es { declare module es {
class DrawUtils { class DrawUtils {
static drawLine(shape: egret.Shape, start: Vector2, end: Vector2, color: number, thickness?: number): void;
static drawLineAngle(shape: egret.Shape, start: Vector2, radians: number, length: number, color: number, thickness?: number): void;
static drawHollowRect(shape: egret.Shape, rect: Rectangle, color: number, thickness?: number): void;
static drawHollowRectR(shape: egret.Shape, x: number, y: number, width: number, height: number, color: number, thickness?: number): void;
static drawPixel(shape: egret.Shape, position: Vector2, color: number, size?: number): void;
static getColorMatrix(color: number): egret.ColorMatrixFilter; static getColorMatrix(color: number): egret.ColorMatrixFilter;
} }
} }
declare module es {
class EdgeExt {
static oppositeEdge(self: Edge): Edge;
static isHorizontal(self: Edge): boolean;
static isVertical(self: Edge): boolean;
}
}
declare module es { declare module es {
class FuncPack { class FuncPack {
func: Function; func: Function;
@@ -1546,6 +1948,19 @@ declare module es {
emit(eventType: T, data?: any): void; emit(eventType: T, data?: any): void;
} }
} }
declare module es {
enum Edge {
top = 0,
bottom = 1,
left = 2,
right = 3
}
}
declare module es {
class Enumerable {
static repeat<T>(element: T, count: number): any[];
}
}
declare module es { declare module es {
class GlobalManager { class GlobalManager {
_enabled: boolean; _enabled: boolean;
@@ -1715,7 +2130,19 @@ declare class RandomUtils {
} }
declare module es { declare module es {
class RectangleExt { class RectangleExt {
static getSide(rect: Rectangle, edge: Edge): number;
static union(first: Rectangle, point: Vector2): Rectangle; static union(first: Rectangle, point: Vector2): Rectangle;
static getHalfRect(rect: Rectangle, edge: Edge): Rectangle;
static getRectEdgePortion(rect: Rectangle, edge: Edge, size?: number): Rectangle;
static expandSide(rect: Rectangle, edge: Edge, amount: number): void;
static contract(rect: Rectangle, horizontalAmount: any, verticalAmount: any): void;
}
}
declare module es {
class SubpixelNumber {
remainder: number;
update(amount: number): number;
reset(): void;
} }
} }
declare module es { declare module es {
+1863 -138
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
File diff suppressed because one or more lines are too long
+3 -3
View File
@@ -28,13 +28,13 @@ module es {
public draw(shape: egret.Shape): boolean { public draw(shape: egret.Shape): boolean {
switch (this.drawType) { switch (this.drawType) {
case DebugDrawType.line: case DebugDrawType.line:
DrawUtils.drawLine(shape, this.start, this.end, this.color); // DrawUtils.drawLine(shape, this.start, this.end, this.color);
break; break;
case DebugDrawType.hollowRectangle: case DebugDrawType.hollowRectangle:
DrawUtils.drawHollowRect(shape, this.rectangle, this.color); // DrawUtils.drawHollowRect(shape, this.rectangle, this.color);
break; break;
case DebugDrawType.pixel: case DebugDrawType.pixel:
DrawUtils.drawPixel(shape, new Vector2(this.x, this.y), this.color, this.size); // DrawUtils.drawPixel(shape, new Vector2(this.x, this.y), this.color, this.size);
break; break;
case DebugDrawType.text: case DebugDrawType.text:
break; break;
@@ -28,6 +28,20 @@ module es {
this.setHeight(value); this.setHeight(value);
} }
/**
* BoxCollider并使用x/y组件作为localOffset
* @param x
* @param y
* @param width
* @param height
*/
public createBoxRect(x: number, y: number, width: number, height: number): BoxCollider{
this._localOffset = new Vector2(x + width / 2, y + width / 2);
this.shape = new Box(width, height);
this._colliderRequiresAutoSizing = false;
return this;
}
/** /**
* BoxCollider的大小 * BoxCollider的大小
* @param width * @param width
@@ -162,11 +162,13 @@ module es {
* *
*/ */
public sync(camera: Camera) { public sync(camera: Camera) {
this.displayObject.x = this.entity.position.x + this.localOffset.x - camera.position.x + camera.origin.x; let afterPos = new Vector2(this.entity.position.x + this.localOffset.x - camera.position.x + camera.origin.x,
this.displayObject.y = this.entity.position.y + this.localOffset.y - camera.position.y + camera.origin.y; this.entity.position.y + this.localOffset.y - camera.position.y + camera.origin.y);
this.displayObject.scaleX = this.entity.scale.x; if (this.displayObject.x != afterPos.x) this.displayObject.x = afterPos.x;
this.displayObject.scaleY = this.entity.scale.y; if (this.displayObject.y != afterPos.y) this.displayObject.y = afterPos.y;
this.displayObject.rotation = this.entity.rotation; if (this.displayObject.scaleX != this.entity.scale.x) this.displayObject.scaleX = this.entity.scale.x;
if (this.displayObject.scaleY != this.entity.scale.y) this.displayObject.scaleY = this.entity.scale.y;
if (this.displayObject.rotation != this.entity.rotation) this.displayObject.rotation = this.entity.rotation;
} }
public toString() { public toString() {
+4 -2
View File
@@ -123,8 +123,10 @@ module es {
public render(camera: Camera) { public render(camera: Camera) {
this.sync(camera); this.sync(camera);
this.displayObject.x = this.entity.position.x + this.localOffset.x - camera.position.x + camera.origin.x; let afterPos = new Vector2(this.entity.position.x + this.localOffset.x - camera.position.x + camera.origin.x,
this.displayObject.y = this.entity.position.y + this.localOffset.y - camera.position.y + camera.origin.y; this.entity.position.y + this.localOffset.y - camera.position.y + camera.origin.y);
if (this.displayObject.x != afterPos.x) this.displayObject.x = afterPos.x;
if (this.displayObject.y != afterPos.y) this.displayObject.y = afterPos.y;
} }
} }
} }
+131
View File
@@ -0,0 +1,131 @@
module es {
/**
*
*/
export class CollisionState {
public right: boolean;
public left: boolean;
public above: boolean;
public below: boolean;
public becameGroundedThisFrame: boolean;
public wasGroundedLastFrame: boolean;
public isGroundedOnOnewayPlatform: boolean;
public slopAngle: number;
public get hasCollision(): boolean {
return this.below || this.right || this.left || this.above;
}
public _movementRemainderX: SubpixelNumber;
public _movementRemainderY: SubpixelNumber;
public reset() {
this.becameGroundedThisFrame = this.isGroundedOnOnewayPlatform = this.right = this.left = this.above = this.below = false;
this.slopAngle = 0;
}
public toString() {
return `[CollisionState] r: ${this.right}, l: ${this.left}, a: ${this.above}, b: ${this.below}, angle: ${this.slopAngle}, wasGroundedLastFrame: ${this.wasGroundedLastFrame}, becameGroundedThisFrame: ${this.becameGroundedThisFrame}`;
}
}
/**
* TiledMapMover是在基于重力的平铺地图中移动对象的助手
* BoxColliderBoxCollider将与colliderHorizontal/VerticalInset用于所有碰撞检测
*
* Transform向下移动1个像素并调用CollisionState.clearLastGroundTile来跳过平台
*/
export class TiledMapMover extends Component {
/**
* BoxCollider将根据水平面上的嵌入缩小
*/
public colliderHorizontalInset = 2;
/**
* BoxCollider将根据该嵌入缩小
*/
public colliderVerticalInset = 6;
/**
*
*/
public _boxColliderBounds: Rectangle;
constructor() {
super();
}
/**
*
* @param motion
* @param boxColliderBounds
* @param collisionState
*/
public testCollisions(motion: Vector2, boxColliderBounds: Rectangle, collisionState: CollisionState) {
this._boxColliderBounds = boxColliderBounds;
// 保存我们当前的接地状态,我们将用于wasGroundedLastFrame和becameGroundedThisFrame
collisionState.wasGroundedLastFrame = collisionState.below;
// 重置碰撞状态
collisionState.reset();
// 获取圆角值用于我们的实际检测
let motionX = motion.x;
let motionY = motion.y;
// 首先,检查水平方向中的移动
if (motionX != 0){
let direction = motionX > 0 ? Edge.right : Edge.left;
let sweptBounds = this.collisionRectForSide(direction, motionX);
let collisionResponse: number = 0;
if (this.testMapCollision(sweptBounds, direction, collisionState, collisionResponse)){
motion.x = collisionResponse - RectangleExt.getSide(boxColliderBounds, direction);
collisionState.left = direction == Edge.left;
collisionState.right = direction == Edge.right;
collisionState._movementRemainderX.reset();
}else{
collisionState.left = false;
collisionState.right = false;
}
}
}
public testMapCollision(collisionRect: Rectangle, direction: Edge, collisionState: CollisionState, collisionResponse: number){
let side = EdgeExt.oppositeEdge(direction);
let perpindicularPosition = EdgeExt.isVertical(side) ? collisionRect.center.x : collisionRect.center.y;
let leadingPosition = RectangleExt.getSide(collisionRect, direction);
let shouldTestSlopes = EdgeExt.isVertical(side);
}
/**
*
* @param side
* @param motion
*/
public collisionRectForSide(side: Edge, motion: number){
let bounds: Rectangle;
// 对于水平碰撞检查,我们只使用一个条块作为边界。Vertical得到矩形的一半,就可以正确地向上推,
// 当相交的斜率,忽略以进行水平移动。
if (EdgeExt.isHorizontal(side)){
bounds = RectangleExt.getRectEdgePortion(this._boxColliderBounds, side);
}else {
bounds = RectangleExt.getHalfRect(this._boxColliderBounds, side);
}
// 我们水平收缩用于垂直移动,垂直收缩用于水平移动
if (EdgeExt.isVertical(side)){
RectangleExt.contract(bounds, this.colliderHorizontalInset, 0);
}else {
RectangleExt.contract(bounds, 0, this.colliderVerticalInset);
}
// 最后在移动方向上扩展边
RectangleExt.expandSide(bounds, side, motion);
return bounds;
}
}
}
@@ -0,0 +1,146 @@
module es {
export class TiledMapRenderer extends RenderableComponent {
public tiledMap: TmxMap;
public physicsLayer: number = 1 << 0;
/**
*
*/
public layerIndicesToRender: number[];
private toContainer: boolean = false;
public get width() {
return this.tiledMap.width * this.tiledMap.tileWidth;
}
public get height() {
return this.tiledMap.height * this.tiledMap.tileHeight;
}
public collisionLayer: TmxLayer;
public _shouldCreateColliders: boolean;
public _colliders: Collider[];
constructor(tiledMap: TmxMap, collisionLayerName: string = null, shouldCreateColliders: boolean = true) {
super();
this.tiledMap = tiledMap;
this._shouldCreateColliders = shouldCreateColliders;
this.displayObject = new egret.DisplayObjectContainer();
if (collisionLayerName) {
this.collisionLayer = tiledMap.tileLayers[collisionLayerName];
}
}
/**
*
* @param layerName
*/
public setLayerToRender(layerName: string) {
this.layerIndicesToRender = [];
this.layerIndicesToRender[0] = this.getLayerIndex(layerName);
}
/**
* layerIndicesToRender
* @param layerNames
*/
public setLayersToRender(...layerNames: string[]) {
this.layerIndicesToRender = [];
for (let i = 0; i < layerNames.length; i++)
this.layerIndicesToRender[i] = this.getLayerIndex(layerNames[i]);
}
private getLayerIndex(layerName: string) {
let index = 0;
let layerType = this.tiledMap.getLayer(layerName);
for (let layer in this.tiledMap.layers) {
if (this.tiledMap.layers.hasOwnProperty(layer) &&
this.tiledMap.layers[layer] == layerType) {
return index;
}
}
return -1;
}
public getRowAtWorldPosition(yPos: number): number {
yPos -= this.entity.transform.position.y + this._localOffset.y;
return this.tiledMap.worldToTilePositionY(yPos);
}
public getColumnAtWorldPosition(xPos: number): number {
xPos -= this.entity.transform.position.x + this._localOffset.x;
return this.tiledMap.worldToTilePositionX(xPos);
}
public onEntityTransformChanged(comp: transform.Component) {
// 这里我们只处理位置变化。平铺地图不能缩放
if (this._shouldCreateColliders && comp == transform.Component.position) {
this.removeColliders();
this.addColliders();
}
}
public onAddedToEntity() {
this.addColliders();
}
public onRemovedFromEntity() {
this.removeColliders();
}
public update() {
this.tiledMap.update();
}
public render(camera: es.Camera) {
this.sync(camera);
if (!this.layerIndicesToRender) {
TiledRendering.renderMap(this.tiledMap, !this.toContainer ? this.displayObject as egret.DisplayObjectContainer : null, Vector2.add(this.entity.transform.position, this._localOffset),
this.transform.scale, this.renderLayer);
} else {
for (let i = 0; i < this.tiledMap.layers.length; i++) {
if (this.tiledMap.layers[i].visible && this.layerIndicesToRender.contains(i))
TiledRendering.renderLayerRenderCamera(this.tiledMap.layers[i] as TmxLayer, !this.toContainer ? this.displayObject as egret.DisplayObjectContainer : null, Vector2.add(this.entity.transform.position, this._localOffset),
this.transform.scale, this.renderLayer, camera.bounds);
}
}
if (!this.toContainer){
this.displayObject.cacheAsBitmap = true;
this.toContainer = true;
}
}
public addColliders() {
if (!this.collisionLayer || !this._shouldCreateColliders)
return;
// 获取冲突层及其冲突的矩形
let collisionRects = this.collisionLayer.getCollisionRectangles();
// 为我们收到的矩形创建碰撞器
this._colliders = [];
for (let i = 0; i < collisionRects.length; i++) {
let collider = new BoxCollider().createBoxRect(collisionRects[i].x + this._localOffset.x,
collisionRects[i].y + this._localOffset.y, collisionRects[i].width, collisionRects[i].height);
collider.physicsLayer = this.physicsLayer;
collider.entity = this.entity;
this._colliders[i] = collider;
Physics.addCollider(collider);
}
}
public removeColliders() {
if (this._colliders == null)
return;
for (let collider of this._colliders) {
Physics.removeCollider(collider);
}
this._colliders = null;
}
}
}
+4
View File
@@ -7,6 +7,10 @@ module es {
* *
*/ */
public static emitter: Emitter<CoreEvents>; public static emitter: Emitter<CoreEvents>;
/**
*
*/
public static debugRenderEndabled = false;
/** /**
* 访 * 访
*/ */
+15
View File
@@ -16,4 +16,19 @@ class ObjectUtils {
} }
return c; return c;
} }
public static elements(p: {}){
let c = [];
for (let i in p){
if (Array.isArray(p[i])){
for (let v of p[i]){
c.push(v);
}
}else{
c.push(p[i]);
}
}
return c;
}
} }
+17
View File
@@ -3,6 +3,10 @@ module es {
public static readonly Epsilon: number = 0.00001; public static readonly Epsilon: number = 0.00001;
public static readonly Rad2Deg = 57.29578; public static readonly Rad2Deg = 57.29578;
public static readonly Deg2Rad = 0.0174532924; public static readonly Deg2Rad = 0.0174532924;
/**
* pi除以2的值(1.57079637)
*/
public static readonly PiOver2 = Math.PI / 2;
/** /**
* *
@@ -76,5 +80,18 @@ module es {
public static angleBetweenVectors(from: Vector2, to: Vector2) { public static angleBetweenVectors(from: Vector2, to: Vector2) {
return Math.atan2(to.y - from.y, to.x - from.x); return Math.atan2(to.y - from.y, to.x - from.x);
} }
/**
* t并确保它总是大于或等于0并且小于长度
* @param t
* @param length
*/
public static incrementWithWrap(t: number, length: number){
t ++;
if (t == length)
return 0;
return t;
}
} }
} }
+16
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: ITmxLayer[];
public tileLayers: TmxLayer[];
public objectGroups: TmxObjectGroup[];
public imageLayers: TmxImageLayer[];
public groups: TmxGroup[];
}
}
+9
View File
@@ -0,0 +1,9 @@
module es {
export interface ITmxLayer {
offsetX: number;
offsetY: number;
opacity: number;
visible: boolean;
properties: Map<string, string>;
}
}
+15
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;
}
}
+175
View File
@@ -0,0 +1,175 @@
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);
// 将GID保存
this.gid = rawGid;
this.tileset = map.getTilesetForTileGid(this.gid);
}
}
}
+146
View File
@@ -0,0 +1,146 @@
///<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: ITmxLayer[];
public tilesets: TmxTileset[];
public tileLayers: TmxLayer[];
public objectGroups: TmxObjectGroup[];
public imageLayers: TmxImageLayer[];
public groups: 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.length - 1; i >= 0; i --){
if (this.tilesets[i].firstGid <= gid)
return this.tilesets[i];
}
console.error(`tile gid${gid}未在任何tileset中找到`);
}
/**
* tilemap边界
* @param x
* @param clampToTilemapBounds
*/
public worldToTilePositionX(x: number, clampToTilemapBounds = true){
let tileX = Math.floor(x / this.tileWidth);
if (!clampToTilemapBounds)
return tileX;
return MathHelper.clamp(tileX, 0, this.width - 1);
}
/**
* tilemap边界
* @param y
* @param clampToTilemapBounds
*/
public worldToTilePositionY(y: number, clampToTilemapBounds = true){
let tileY = Math.floor(y / this.tileHeight);
if (!clampToTilemapBounds)
return tileY;
return MathHelper.clamp(tileY, 0, this.height - 1);
}
/**
*
* @param name
*/
public getLayer(name: string): ITmxLayer {
return this.layers[name];
}
/**
* 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
}
}
+86
View File
@@ -0,0 +1,86 @@
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: TmxObject[];
public properties: Map<string, string>;
}
export class TmxObject implements ITmxElement {
public id: number;
public name: string;
public shape: egret.Shape;
public textField: egret.TextField;
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;
public points: Vector2[];
public properties: Map<string, string>;
constructor(){
this.shape = new egret.Shape();
this.textField = new egret.TextField();
}
}
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
}
}
+59
View File
@@ -0,0 +1,59 @@
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.Bitmap;
public bitmap: egret.SpriteSheet;
public source: string;
public format: string;
public data: any;
public trans: number;
public width: number;
public height: number;
public dispose(){
if (this.bitmap){
this.bitmap.dispose();
this.bitmap = null;
}
}
}
}
+534
View File
@@ -0,0 +1,534 @@
module es {
import Bitmap = egret.Bitmap;
export class TiledMapLoader {
public static loadTmxMap(map: TmxMap, filePath: string) {
let xMap = RES.getRes(filePath);
return this.loadTmxMapData(map, xMap);
}
public static async loadTmxMapData(map: TmxMap, xMap: any) {
map.version = xMap["version"];
map.tiledVersion = xMap["tiledversion"];
map.width = xMap["width"];
map.height = xMap["height"];
map.tileWidth = xMap["tilewidth"];
map.tileHeight = xMap["tileheight"];
map.hexSideLength = xMap["hexsidelength"];
map.orientation = this.parseOrientationType(xMap["orientation"]);
map.staggerAxis = this.parseStaggerAxisType(xMap["staggeraxis"]);
map.staggerIndex = this.parseStaggerIndexType(xMap["staggerindex"]);
map.renderOrder = this.parseRenderOrderType(xMap["renderorder"]);
map.nextObjectID = xMap["nextobjectid"];
map.backgroundColor = TmxUtils.color16ToUnit(xMap["color"]);
map.properties = this.parsePropertyDict(xMap["properties"]);
// 我们保持记录的最大瓷砖大小的情况下,图像tileset随机大小
map.maxTileWidth = map.tileWidth;
map.maxTileHeight = map.tileHeight;
map.tilesets = [];
for (let e of xMap["tilesets"]) {
let tileset = await this.parseTmxTileset(map, e);
map.tilesets.push(tileset);
this.updateMaxTileSizes(tileset);
}
map.layers = [];
map.tileLayers = [];
map.objectGroups = [];
map.imageLayers = [];
map.groups = [];
this.parseLayers(map, xMap, map, map.width, map.height);
return map;
}
/**
* xEle中的所有层
* @param container
* @param xEle
* @param map
* @param width
* @param height
*/
public static async parseLayers(container: any, xEle: any, map: TmxMap, width: number, height: number) {
for (let e of ObjectUtils.elements(xEle).where(x => {
return x.type == "tilelayer" || x.type == "objectgroup" || x.type == "imagelayer" || x.type == "group"
})) {
let layer: ITmxLayer;
switch (e.type) {
case "tilelayer":
let tileLayer = this.loadTmxLayer(new TmxLayer(), map, e, width, height);
layer = tileLayer;
if (container instanceof TmxMap || container instanceof TmxGroup)
container.tileLayers.push(tileLayer);
break;
case "objectgroup":
let objectgroup = this.loadTmxObjectGroup(new TmxObjectGroup(), map, e);
layer = objectgroup;
if (container instanceof TmxMap || container instanceof TmxGroup)
container.objectGroups.push(objectgroup);
break;
case "imagelayer":
let imagelayer = await this.loadTmxImageLayer(new TmxImageLayer(), map, e);
layer = imagelayer;
if (container instanceof TmxMap || container instanceof TmxGroup)
container.imageLayers.push(imagelayer);
break;
case "group":
let newGroup = this.loadTmxGroup(new TmxGroup(), map, e, width, height);
layer = newGroup;
if (container instanceof TmxMap || container instanceof TmxGroup)
container.groups.push(newGroup);
break;
default:
throw new Error("无效的操作");
}
if (container instanceof TmxMap || container instanceof TmxGroup)
container.layers.push(layer);
}
}
public static loadTmxGroup(group: TmxGroup, map: TmxMap, xGroup: any, width: number, height: number) {
group.map = map;
group.name = xGroup["name"] != undefined ? xGroup["name"] : "";
group.opacity = xGroup["opacity"] != undefined ? xGroup["opacity"] : 1;
group.visible = xGroup["visible"] != undefined ? xGroup["visible"] : true;
group.offsetX = xGroup["offsetx"] != undefined ? xGroup["offsetx"] : 0;
group.offsetY = xGroup["offsety"] != undefined ? xGroup["offsety"] : 0;
group.properties = this.parsePropertyDict(xGroup["properties"]);
group.layers = [];
group.tileLayers = [];
group.objectGroups = [];
group.imageLayers = [];
group.groups = [];
this.parseLayers(group, xGroup, map, width, height);
return group;
}
public static async loadTmxImageLayer(layer: TmxImageLayer, map: TmxMap, xImageLayer: any) {
layer.map = map;
layer.name = xImageLayer["name"];
layer.width = xImageLayer["width"];
layer.height = xImageLayer["height"];
layer.visible = xImageLayer["visible"] != undefined ? xImageLayer["visible"] : true;
layer.opacity = xImageLayer["opacity"] != undefined ? xImageLayer["opacity"] : 1;
layer.offsetX = xImageLayer["offsetx"] != undefined ? xImageLayer["offsetx"] : 0;
layer.offsetY = xImageLayer["offsety"] != undefined ? xImageLayer["offsety"] : 0;
let xImage = xImageLayer["image"];
if (xImage) {
layer.image = await this.loadTmxImage(new TmxImage(), xImage);
}
layer.properties = this.parsePropertyDict(xImageLayer["properties"]);
return layer;
}
public static loadTmxLayer(layer: TmxLayer, map: TmxMap, xLayer: any, width: number, height: number) {
layer.map = map;
layer.name = xLayer["name"];
layer.opacity = xLayer["opacity"] != undefined ? xLayer["opacity"] : 1;
layer.visible = xLayer["visible"] != undefined ? xLayer["visible"] : true;
layer.offsetX = xLayer["offsetx"] != undefined ? xLayer["offsetx"] : 0;
layer.offsetY = xLayer["offsety"] != undefined ? xLayer["offsety"] : 0;
// TODO: 传入的宽度/高度是否与TMX层?
layer.width = xLayer["width"];
layer.height = xLayer["height"];
let xData = xLayer["data"];
let encoding = xData["encoding"] != undefined ? xData["encoding"] : "csv";
layer.tiles = new Array<TmxLayerTile>(width * height);
if (encoding == "base64") {
let br = TmxUtils.decode(xData.toString(), encoding, xData["compression"]);
let index = 0;
for (let j = 0; j < height; j++) {
for (let i = 0; i < width; i++) {
let gid = br[index];
layer.tiles[index++] = gid != 0 ? new TmxLayerTile(map, gid, i, j) : null;
}
}
} else if (encoding == "csv") {
// let csvData = TmxUtils.decode(xData.toString(), encoding, xData["compression"]);
let k = 0;
for (let s of xData) {
let gid = s;
let x = k % width;
let y = k / width;
layer.tiles[k++] = gid != 0 ? new TmxLayerTile(map, gid, x, y) : null;
}
} else if (!encoding) {
let k = 0;
for (let e of xData["tile"]) {
let gid = e["gid"] != undefined ? e["gid"] : 0;
let x = k % width;
let y = k / width;
layer.tiles[k++] = gid != 0 ? new TmxLayerTile(map, gid, x, y) : null;
}
} else {
throw new Error("TmxLayer:未知编码");
}
layer.properties = TiledMapLoader.parsePropertyDict(xLayer["properties"]);
return layer;
}
private static updateMaxTileSizes(tileset: TmxTileset) {
// 必须迭代字典,因为tile.gid可以是任意顺序的的任何数字
tileset.tiles.forEach(tile => {
if (tile.image) {
if (tile.image.width > tileset.map.maxTileWidth)
tileset.map.maxTileWidth = tile.image.width;
if (tile.image.height > tileset.map.maxTileHeight)
tileset.map.maxTileHeight = tile.image.height;
}
});
tileset.tileRegions.forEach(region => {
let width = region.width;
let height = region.height;
if (width > tileset.map.maxTileWidth) tileset.map.maxTileWidth = width;
if (width > tileset.map.maxTileHeight) tileset.map.maxTileHeight = height;
});
}
public static parseOrientationType(type: string) {
if (type == "unknown")
return OrientationType.unknown;
if (type == "orthogonal")
return OrientationType.orthogonal;
if (type == "isometric")
return OrientationType.isometric;
if (type == "staggered")
return OrientationType.staggered;
if (type == "hexagonal")
return OrientationType.hexagonal;
return OrientationType.unknown;
}
public static parseStaggerAxisType(type: string) {
if (type == "y")
return StaggerAxisType.y;
return StaggerAxisType.x;
}
public static parseStaggerIndexType(type: string) {
if (type == "even")
return StaggerIndexType.even;
return StaggerIndexType.odd;
}
public static parseRenderOrderType(type: string) {
if (type == "right-up")
return RenderOrderType.rightUp;
if (type == "left-down")
return RenderOrderType.leftDown;
if (type == "left-up")
return RenderOrderType.leftUp;
return RenderOrderType.rightDown;
}
public static parsePropertyDict(prop) {
if (!prop)
return null;
let dict = new Map<string, string>();
for (let p of prop) {
let pname = p["name"];
let valueAttr = p["value"];
if (p["type"] == "color")
dict.set(pname, TmxUtils.color16ToUnit(valueAttr).toString());
else
dict.set(pname, valueAttr);
}
return dict;
}
public static async parseTmxTileset(map: TmxMap, xTileset: any) {
// firstgid总是在TMX中,而不是在TSX中
let xFirstGid = xTileset["firstgid"];
let firstGid = xFirstGid;
let source = xTileset["image"];
// 如果是嵌入式TmxTileset,即不是外部的,source将为null
if (!source) {
source = "resource/assets/" + source;
// 其他所有内容都在TSX文件中
let xDocTileset = await RES.getResByUrl(source, null, this, RES.ResourceItem.TYPE_IMAGE);
let tileset = this.loadTmxTileset(new TmxTileset(), map, xDocTileset["tileset"], firstGid);
return tileset;
}
return this.loadTmxTileset(new TmxTileset(), map, xTileset, firstGid);
}
public static async loadTmxTileset(tileset: TmxTileset, map: TmxMap, xTileset: any,
firstGid: number) {
tileset.map = map;
tileset.firstGid = firstGid;
tileset.name = xTileset["name"];
tileset.tileWidth = xTileset["tilewidth"];
tileset.tileHeight = xTileset["tileheight"];
tileset.spacing = xTileset["spacing"] != undefined ? xTileset["spacing"] : 0;
tileset.margin = xTileset["margin"] != undefined ? xTileset["margin"] : 0;
tileset.columns = xTileset["columns"];
tileset.tileCount = xTileset["tilecount"];
tileset.tileOffset = this.parseTmxTileOffset(xTileset["tileoffset"]);
let xImage = xTileset["image"];
if (xImage)
tileset.image = await this.loadTmxImage(new TmxImage(), xTileset);
tileset.terrains = [];
if (xTileset["terrains"])
for (let e of xTileset["terrains"])
tileset.terrains.push(this.parseTmxTerrain(e));
tileset.tiles = new Map<number, TmxTilesetTile>();
for (let xTile of xTileset["tiles"]) {
let tile = await this.loadTmxTilesetTile(new TmxTilesetTile(), tileset, xTile, tileset.terrains);
tileset.tiles.set(tile.id, tile);
}
tileset.properties = this.parsePropertyDict(xTileset["properties"]);
// 缓存我们的源矩形为每个瓷砖,所以我们不必每次我们渲染计算他们。
// 如果我们有一个image,这是一个普通的tileset,否则它是一个image tileset
tileset.tileRegions = new Map<number, Rectangle>();
if (tileset.image && tileset.image.bitmap) {
let id = firstGid;
for (let y = tileset.margin; y < tileset.image.height - tileset.margin; y += tileset.tileHeight + tileset.spacing) {
let column = 0;
for (let x = tileset.margin; x < tileset.image.width - tileset.margin; x += tileset.tileWidth + tileset.spacing) {
tileset.tileRegions.set(id++, new Rectangle(x, y, tileset.tileWidth, tileset.tileHeight));
if (++column >= tileset.columns)
break;
}
}
} else {
tileset.tiles.forEach(tile => {
tileset.tileRegions.set(firstGid + tile.id, new Rectangle(0, 0, tile.image.width, tile.image.height));
});
}
return tileset;
}
public static async loadTmxTilesetTile(tile: TmxTilesetTile, tileset: TmxTileset, xTile: any, terrains: TmxTerrain[]) {
tile.tileset = tileset;
tile.id = xTile["id"];
let strTerrain = xTile["terrain"];
if (strTerrain){
tile.terrainEdges = new Array(4);
let index = 0;
for (let v of strTerrain){
let edge: TmxTerrain = terrains[v];
tile.terrainEdges[index ++] = edge;
}
}
tile.probability = xTile["probability"] != undefined ? xTile["probability"] : 1;
tile.type = xTile["type"];
let xImage = xTile["image"];
if (xImage) {
tile.image = await this.loadTmxImage(new TmxImage(), xImage);
}
tile.objectGroups = [];
if (xTile["objectgroup"])
for (let e of xTile["objectgroup"])
tile.objectGroups.push(this.loadTmxObjectGroup(new TmxObjectGroup(), tileset.map, e));
tile.animationFrames = [];
if (xTile["animation"]) {
for (let e of xTile["animation"]["frame"])
tile.animationFrames.push(this.loadTmxAnimationFrame(new TmxAnimationFrame(), e));
}
tile.properties = this.parsePropertyDict(xTile["properties"]);
if (tile.properties)
tile.processProperties();
return tile;
}
public static loadTmxAnimationFrame(frame: TmxAnimationFrame, xFrame: any) {
frame.gid = xFrame["tileid"];
frame.duration = xFrame["duration"] / 1000;
return frame;
}
public static loadTmxObjectGroup(group: TmxObjectGroup, map: TmxMap, xObjectGroup: any) {
group.map = map;
group.name = xObjectGroup["name"] != undefined ? xObjectGroup["name"] : "";
group.color = TmxUtils.color16ToUnit(xObjectGroup["color"]);
group.opacity = xObjectGroup["opacity"] != undefined ? xObjectGroup["opacity"] : 1;
group.visible = xObjectGroup["visible"] != undefined ? xObjectGroup["visible"] : true;
group.offsetX = xObjectGroup["offsetx"] != undefined ? xObjectGroup["offsetx"] : 0;
group.offsetY = xObjectGroup["offsety"] != undefined ? xObjectGroup["offsety"] : 0;
let drawOrderDict = new Map<string, DrawOrderType>();
drawOrderDict.set("unknown", DrawOrderType.unkownOrder);
drawOrderDict.set("topdown", DrawOrderType.IndexOrder);
drawOrderDict.set("index", DrawOrderType.TopDown);
let drawOrderValue = xObjectGroup["draworder"];
if (drawOrderValue)
group.drawOrder = drawOrderDict.get(drawOrderValue);
group.objects = [];
for (let e of xObjectGroup["objects"])
group.objects.push(this.loadTmxObject(new TmxObject(), map, e));
group.properties = this.parsePropertyDict(xObjectGroup["properties"]);
return group;
}
public static loadTmxObject(obj: TmxObject, map: TmxMap, xObject: any) {
obj.id = xObject["id"] != undefined ? xObject["id"] : 0;
obj.name = xObject["name"] != undefined ? xObject["name"] : "";
obj.x = xObject["x"];
obj.y = xObject["y"];
obj.width = xObject["width"] != undefined ? xObject["width"] : 0;
obj.height = xObject["height"] != undefined ? xObject["height"] : 0;
obj.type = xObject["type"] != undefined ? xObject["type"] : "";
obj.visible = xObject["visible"] != undefined ? xObject["visible"] : true;
obj.rotation = xObject["rotation"] != undefined ? xObject["rotation"] : 0;
// 评估对象类型并分配适当的内容
let xGid = xObject["gid"];
let xEllipse = xObject["ellipse"];
let xPolygon = xObject["polygon"];
let xPolyline = xObject["polyline"];
let xText = xObject["text"];
let xPoint = xObject["point"];
if (xGid) {
obj.tile = new TmxLayerTile(map, xGid, Math.round(obj.x), Math.round(obj.y));
obj.objectType = TmxObjectType.tile;
} else if (xEllipse) {
obj.objectType = TmxObjectType.ellipse;
} else if (xPolygon) {
obj.points = this.parsePoints(xPolygon);
obj.objectType = TmxObjectType.polygon;
} else if (xPolyline) {
obj.points = this.parsePoints(xPolyline);
obj.objectType = TmxObjectType.polyline;
} else if (xText) {
obj.text = this.loadTmxText(new TmxText(), xText);
obj.objectType = TmxObjectType.text;
} else if (xPoint) {
obj.objectType = TmxObjectType.point;
} else {
obj.objectType = TmxObjectType.basic;
}
obj.properties = this.parsePropertyDict(xObject["properties"]);
return obj;
}
public static loadTmxText(text: TmxText, xText: any) {
text.fontFamily = xText["fontfamily"] != undefined ? xText["fontfamily"] : "sans-serif";
text.pixelSize = xText["pixelsize"] != undefined ? xText["pixelsize"] : 16;
text.wrap = xText["wrap"] != undefined ? xText["wrap"] : false;
text.color = TmxUtils.color16ToUnit(xText["color"]);
text.bold = xText["bold"] ? xText["bold"] : false;
text.italic = xText["italic"] ? xText["italic"] : false;
text.underline = xText["underline"] ? xText["underline"] : false;
text.strikeout = xText["strikeout"] ? xText["strikeout"] : false;
text.kerning = xText["kerning"] ? xText["kerning"] : true;
text.alignment = this.loadTmxAlignment(new TmxAlignment(), xText);
text.value = xText;
return text;
}
public static loadTmxAlignment(alignment: TmxAlignment, xText: any) {
function firstLetterToUpperCase(str: string) {
if (!str || str == "")
return str;
return str[0].toString().toUpperCase() + str.substr(1);
}
let xHorizontal = xText["halign"] != undefined ? xText["halign"] : "left";
alignment.horizontal = TmxHorizontalAlignment[firstLetterToUpperCase(xHorizontal)];
let xVertical = xText["valign"] != undefined ? xText["valign"] : "top";
alignment.vertical = TmxVerticalAlignment[firstLetterToUpperCase((xVertical))];
return alignment;
}
public static parsePoints(xPoints: any) {
let points = [];
let index = 0;
for (let s of xPoints)
points[index++] = this.parsePoint(s);
return points;
}
public static parsePoint(pt: {x: number, y: number}) {
return new Vector2(pt.x, pt.y);
}
public static parseTmxTerrain(xTerrain: any) {
let terrain = new TmxTerrain();
terrain.name = xTerrain["name"];
terrain.tile = xTerrain["tile"];
terrain.properties = this.parsePropertyDict(xTerrain["properties"]);
return terrain;
}
public static parseTmxTileOffset(xTileOffset: any) {
let tmxTileOffset = new TmxTileOffset();
if (!xTileOffset) {
tmxTileOffset.x = 0;
tmxTileOffset.y = 0;
return tmxTileOffset;
}
tmxTileOffset.x = xTileOffset["x"];
tmxTileOffset.y = xTileOffset["y"];
return tmxTileOffset;
}
public static async loadTmxImage(image: TmxImage, xImage: any) {
let xSource = xImage["image"];
if (xSource) {
image.source = "resource/assets/" + xSource;
image.bitmap = new egret.SpriteSheet(await RES.getResByUrl(image.source, null, this, RES.ResourceItem.TYPE_IMAGE));
} else {
image.format = xImage["format"];
let xData = xImage["data"];
image.data = TmxUtils.decode(xData, xData["encoding"], xData["compression"]);
}
image.trans = TmxUtils.color16ToUnit(xImage["trans"]);
image.width = xImage["imagewidth"] != undefined ? xImage["imagewidth"] : 0;
image.height = xImage["imageheight"] != undefined ? xImage["imageheight"] : 0;
return image;
}
}
}
+373
View File
@@ -0,0 +1,373 @@
module es {
import Bitmap = egret.Bitmap;
export class TiledRendering {
public static renderMap(map: TmxMap, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, layerDepth: number) {
map.layers.forEach(layer => {
if (layer instanceof TmxLayer && layer.visible) {
this.renderLayer(layer, container, position, scale, layerDepth);
} else if (layer instanceof TmxImageLayer && layer.visible) {
this.renderImageLayer(layer, container, position, scale, layerDepth);
} else if (layer instanceof TmxGroup && layer.visible) {
this.renderGroup(layer, container, position, scale, layerDepth);
} else if (layer instanceof TmxObjectGroup && layer.visible) {
this.renderObjectGroup(layer, container, position, scale, layerDepth);
}
});
}
public static renderLayer(layer: TmxLayer, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, layerDepth: number) {
if (!layer.visible)
return;
let tileWidth = layer.map.tileWidth * scale.x;
let tileHeight = layer.map.tileHeight * scale.y;
let color = DrawUtils.getColorMatrix(0xFFFFFF);
for (let i = 0; i < layer.tiles.length; i++) {
let tile = layer.tiles[i];
if (!tile)
continue;
this.renderTile(tile, container, position, scale, tileWidth, tileHeight, color, layerDepth);
}
}
public static renderLayerRenderCamera(layer: ITmxLayer, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, layerDepth: number, camerClipBounds: Rectangle){
if (layer instanceof TmxLayer && layer.visible) {
this.renderLayerCamera(layer, container, position, scale, layerDepth, camerClipBounds);
} else if (layer instanceof TmxImageLayer && layer.visible) {
this.renderImageLayer(layer, container, position, scale, layerDepth);
} else if (layer instanceof TmxGroup && layer.visible) {
this.renderGroup(layer, container, position, scale, layerDepth);
} else if (layer instanceof TmxObjectGroup && layer.visible) {
this.renderObjectGroup(layer, container, position, scale, layerDepth);
}
}
public static renderLayerCamera(layer: TmxLayer, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, layerDepth: number, camerClipBounds: Rectangle){
if (!layer.visible)
return;
position = position.add(layer.offset);
camerClipBounds.location = camerClipBounds.location.subtract(position);
let tileWidth = layer.map.tileWidth * scale.x;
let tileHeight = layer.map.tileHeight * scale.y;
let minX, minY, maxX, maxY = 0;
if (layer.map.requiresLargeTileCulling){
minX = layer.map.worldToTilePositionX(camerClipBounds.left - (layer.map.maxTileWidth * scale.x - tileWidth));
minY = layer.map.worldToTilePositionY(camerClipBounds.top - (layer.map.maxTileHeight * scale.y - tileHeight));
maxX = layer.map.worldToTilePositionX(camerClipBounds.right + (layer.map.maxTileWidth * scale.x - tileWidth));
maxY = layer.map.worldToTilePositionY(camerClipBounds.bottom + (layer.map.maxTileHeight * scale.y - tileHeight));
}else{
minX = layer.map.worldToTilePositionX(camerClipBounds.left);
minY = layer.map.worldToTilePositionY(camerClipBounds.top);
maxX = layer.map.worldToTilePositionX(camerClipBounds.right);
maxY = layer.map.worldToTilePositionY(camerClipBounds.bottom);
}
let color = DrawUtils.getColorMatrix(0xFFFFFF);
for (let y = minY; y <= maxY; y ++){
for (let x = minX; x <= maxX; x ++){
let tile = layer.getTile(x, y);
if (tile)
this.renderTile(tile, container, position, scale, tileWidth, tileHeight, color, layerDepth);
}
}
}
public static renderImageLayer(layer: TmxImageLayer, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, layerDepth: number) {
if (!layer.visible)
return;
let color = DrawUtils.getColorMatrix(0xFFFFFF);
let pos = Vector2.add(position, new Vector2(layer.offsetX, layer.offsetY).multiply(scale));
if (!layer.image.texture.parent)
container.addChild(layer.image.texture);
layer.image.texture.x = pos.x;
layer.image.texture.y = pos.y;
layer.image.texture.scaleX = scale.x;
layer.image.texture.scaleY = scale.y;
layer.image.texture.filters = [color];
}
public static renderObjectGroup(objGroup: TmxObjectGroup, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, layerDepth: number) {
if (!objGroup.visible)
return;
function debugRender(obj: TmxObject, pos: Vector2){
if (!container)
return;
if (!Core.debugRenderEndabled)
return;
if (!obj.textField.parent && obj.name){
obj.textField.text = obj.name;
obj.textField.size = 12;
obj.textField.fontFamily = "sans-serif";
if (obj.shape){
obj.textField.x = pos.x + (obj.shape.width - obj.textField.width) / 2;
obj.textField.y = pos.y - obj.textField.height - 5;
}else{
obj.textField.x = pos.x + (obj.width - obj.textField.width) / 2;
obj.textField.y = pos.y - obj.textField.height - 5;
}
obj.textField.textColor = 0xffffff;
container.addChild(obj.textField);
}
}
for (let object in objGroup.objects) {
let obj = objGroup.objects[object];
if (!obj.visible)
continue;
// 如果我们不调试渲染,我们只渲染平铺块和文本类型
if (!Core.debugRenderEndabled) {
if (obj.objectType != TmxObjectType.tile && obj.objectType != TmxObjectType.text)
continue;
}
let pos = Vector2.add(position, new Vector2(obj.x, obj.y).multiply(scale));
switch (obj.objectType) {
case TmxObjectType.basic:
if (!obj.shape.parent){
obj.shape.x = obj.x;
obj.shape.y = obj.y;
container.addChild(obj.shape);
}
obj.shape.graphics.clear();
obj.shape.graphics.lineStyle(1, 0xa0a0a4);
obj.shape.graphics.beginFill(0x979798, 0.5);
obj.shape.graphics.drawRect(0, 0, obj.width * scale.x, obj.height * scale.y);
obj.shape.graphics.endFill();
debugRender(obj, pos);
break;
case TmxObjectType.point:
let size = objGroup.map.tileWidth * 0.5;
pos.x -= size * 0.5;
pos.y -= size * 0.5;
if (!obj.shape.parent){
obj.shape.x = pos.x;
obj.shape.y = pos.y;
container.addChild(obj.shape);
}
obj.shape.graphics.clear();
obj.shape.graphics.lineStyle(1, 0xa0a0a4);
obj.shape.graphics.beginFill(0x979798, 0.5);
obj.shape.graphics.drawCircle(0, 0, 1);
obj.shape.graphics.endFill();
debugRender(obj, pos);
break;
case TmxObjectType.tile:
let tileset = objGroup.map.getTilesetForTileGid(obj.tile.gid);
let sourceRect = tileset.tileRegions.get(obj.tile.gid);
if (obj.tile.horizontalFlip && obj.tile.verticalFlip) {
pos.x += tileset.tileHeight + (sourceRect.height * scale.y - tileset.tileHeight);
pos.y -= (sourceRect.width * scale.x - tileset.tileWidth);
}
else if (obj.tile.horizontalFlip) {
pos.x += tileset.tileWidth + (sourceRect.height * scale.y - tileset.tileHeight);
}
else if (obj.tile.verticalFlip) {
pos.y += (tileset.tileWidth - sourceRect.width * scale.x);
}
else {
pos.y += (tileset.tileHeight - sourceRect.height * scale.y);
}
if (container){
let texture: egret.Texture = tileset.image.bitmap.getTexture(`${obj.tile.gid}`);
if (!texture) {
texture = tileset.image.bitmap.createTexture(`${obj.tile.gid}`, sourceRect.x, sourceRect.y, sourceRect.width, sourceRect.height);
}
tileset.image.texture = new Bitmap(texture);
container.addChild(tileset.image.texture);
if (tileset.image.texture.x != pos.x) tileset.image.texture.x = pos.x;
if (tileset.image.texture.y != pos.y) tileset.image.texture.y = pos.y;
if (obj.tile.verticalFlip && obj.tile.horizontalFlip){
tileset.image.texture.scaleX = -1;
tileset.image.texture.scaleY = -1;
}else if (obj.tile.verticalFlip){
tileset.image.texture.scaleX = scale.x;
tileset.image.texture.scaleY = -1;
}else if(obj.tile.horizontalFlip){
tileset.image.texture.scaleX = -1;
tileset.image.texture.scaleY = scale.y;
}else{
tileset.image.texture.scaleX = scale.x;
tileset.image.texture.scaleY = scale.y;
}
if (tileset.image.texture.anchorOffsetX != 0) tileset.image.texture.anchorOffsetX = 0;
if (tileset.image.texture.anchorOffsetY != 0) tileset.image.texture.anchorOffsetY = 0;
}
debugRender(obj, pos);
break;
case TmxObjectType.ellipse:
pos = new Vector2(obj.x + obj.width * 0.5, obj.y + obj.height * 0.5).multiply(scale);
if (!obj.shape.parent){
obj.shape.x = pos.x;
obj.shape.y = pos.y;
container.addChild(obj.shape);
}
obj.shape.graphics.clear();
obj.shape.graphics.lineStyle(1, 0xa0a0a4);
obj.shape.graphics.beginFill(0x979798, 0.5);
obj.shape.graphics.drawCircle(0, 0, obj.width * 0.5);
obj.shape.graphics.endFill();
debugRender(obj, pos);
break;
case TmxObjectType.polygon:
case TmxObjectType.polyline:
let points: Vector2[] = [];
for (let i = 0; i < obj.points.length; i++)
points[i] = Vector2.multiply(obj.points[i], scale);
if (!obj.shape.parent && points.length > 0){
obj.shape.x = pos.x;
obj.shape.y = pos.y;
container.addChild(obj.shape);
}
obj.shape.graphics.clear();
obj.shape.graphics.lineStyle(1, 0xa0a0a4);
for (let i = 0; i < points.length; i ++){
obj.shape.graphics.lineTo(points[i].x, points[i].y);
}
obj.shape.graphics.endFill();
debugRender(obj, pos);
break;
case TmxObjectType.text:
if (!obj.textField.parent){
obj.textField.x = pos.x;
obj.textField.y = pos.y;
container.addChild(obj.textField);
}
obj.textField.text = obj.text.value;
obj.textField.textColor = obj.text.color;
obj.textField.bold = obj.text.bold != undefined ? obj.text.bold : false;
obj.textField.italic = obj.text.italic != undefined ? obj.text.italic : false;
obj.textField.size = obj.text.pixelSize;
obj.textField.fontFamily = obj.text.fontFamily;
break;
default:
break;
}
}
}
public static renderGroup(group: TmxGroup, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, layerDepth: number) {
if (!group.visible)
return;
group.layers.forEach(layer => {
if (layer instanceof TmxGroup) {
this.renderGroup(layer, container, position, scale, layerDepth);
}
if (layer instanceof TmxObjectGroup) {
this.renderObjectGroup(layer, container, position, scale, layerDepth);
}
if (layer instanceof TmxLayer) {
this.renderLayer(layer, container, position, scale, layerDepth);
}
if (layer instanceof TmxImageLayer) {
this.renderImageLayer(layer, container, position, scale, layerDepth);
}
});
}
public static renderTile(tile: TmxLayerTile, container: egret.DisplayObjectContainer, position: Vector2, scale: Vector2, tileWidth: number, tileHeight: number, color: egret.ColorMatrixFilter, layerDepth: number) {
let gid = tile.gid;
// 动画tiles(以及来自图像tile的tiles)将位于Tileset本身内,位于单独的TmxTilesetTile对象中,不要与我们在此循环中处理的TmxLayerTiles混淆
let tilesetTile = tile.tilesetTile;
if (tilesetTile && tilesetTile.animationFrames.length > 0)
gid = tilesetTile.currentAnimationFrameGid;
let sourceRect = tile.tileset.tileRegions.get(gid);
// 对于y位置,我们需要考虑瓦片是否大于瓦片的高度和移位。
// tiled使用左下角的坐标系统,而egret则使用左上角的坐标系统
let tx = Math.floor(tile.x) * tileWidth;
let ty = Math.floor(tile.y) * tileHeight;
let rotation = 0;
if (tile.horizontalFlip && tile.verticalFlip) {
tx += tileHeight + (sourceRect.height * scale.y - tileHeight);
ty -= (sourceRect.width * scale.x - tileWidth);
} else if (tile.horizontalFlip) {
tx += tileWidth + (sourceRect.height * scale.y - tileHeight);
} else if (tile.verticalFlip) {
ty += (tileWidth - sourceRect.width * scale.x);
} else {
ty += (tileHeight - sourceRect.height * scale.y);
}
let pos = new Vector2(tx, ty).add(position);
if (tile.tileset.image) {
if (container){
let texture: egret.Texture = tile.tileset.image.bitmap.getTexture(`${gid}`);
if (!texture) {
texture = tile.tileset.image.bitmap.createTexture(`${gid}`, sourceRect.x, sourceRect.y, sourceRect.width, sourceRect.height);
}
tile.tileset.image.texture = new Bitmap(texture);
container.addChild(tile.tileset.image.texture);
if (tile.tileset.image.texture.x != pos.x) tile.tileset.image.texture.x = pos.x;
if (tile.tileset.image.texture.y != pos.y) tile.tileset.image.texture.y = pos.y;
if (tile.verticalFlip && tile.horizontalFlip){
tile.tileset.image.texture.scaleX = -1;
tile.tileset.image.texture.scaleY = -1;
}else if (tile.verticalFlip){
tile.tileset.image.texture.scaleX = scale.x;
tile.tileset.image.texture.scaleY = -1;
}else if(tile.horizontalFlip){
tile.tileset.image.texture.scaleX = -1;
tile.tileset.image.texture.scaleY = scale.y;
}else{
tile.tileset.image.texture.scaleX = scale.x;
tile.tileset.image.texture.scaleY = scale.y;
}
if (tile.tileset.image.texture.rotation != rotation) tile.tileset.image.texture.rotation = rotation;
if (tile.tileset.image.texture.anchorOffsetX != 0) tile.tileset.image.texture.anchorOffsetX = 0;
if (tile.tileset.image.texture.anchorOffsetY != 0) tile.tileset.image.texture.anchorOffsetY = 0;
}
// tile.tileset.image.texture.filters = [color];
} else {
if (tilesetTile.image.texture) {
if (!tilesetTile.image.bitmap.getTexture(gid.toString())) {
tilesetTile.image.texture = new Bitmap(tilesetTile.image.bitmap.createTexture(gid.toString(), sourceRect.x, sourceRect.y, sourceRect.width, sourceRect.height));
container.addChild(tilesetTile.image.texture);
}
tilesetTile.image.texture.x = pos.x;
tilesetTile.image.texture.y = pos.y;
tilesetTile.image.texture.scaleX = scale.x;
tilesetTile.image.texture.scaleY = scale.y;
tilesetTile.image.texture.rotation = rotation;
tilesetTile.image.texture.anchorOffsetX = 0;
tilesetTile.image.texture.anchorOffsetY = 0;
tilesetTile.image.texture.filters = [color];
}
}
}
}
}
+39
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: 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>;
}
}
+79
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: 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;
}
}
+49
View File
@@ -0,0 +1,49 @@
module es {
export class TmxUtils {
/**
*
* @param data
* @param encoding XMLbase64()csv解析
* @param compression
* @returns
*
* @version Egret 3.0.3
*/
static decode(data: any, encoding: any, compression: string): Array<number> {
compression = compression || "none";
encoding = encoding || "none";
switch (encoding) {
case "base64":
var decoded = Base64Utils.decodeBase64AsArray(data, 4);
return (compression === "none") ? decoded : Base64Utils.decompress(data, decoded, compression);
case "csv":
return Base64Utils.decodeCSV(data);
case "none":
var datas: Array<number> = [];
for (var i: number = 0; i < data.length; i++) {
datas[i] = +data[i].gid;
}
return datas;
default:
throw new Error("未定义的编码:" + encoding);
}
}
/**
* "#"16,"#ff0000""0xff0000"
* @param $color
* @returns 16
* @version Egret 3.0.3
*/
static color16ToUnit($color:string): number {
if (!$color)
return 0xFFFFFF;
var colorStr: string = "0x" + $color.slice(1);
return parseInt(colorStr, 16);
}
}
}
+104 -94
View File
@@ -1,124 +1,134 @@
class Base64Utils { module es{
private static _keyNum = "0123456789+/"; export class Base64Utils {
private static _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; private static _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
private static _keyAll = Base64Utils._keyNum + Base64Utils._keyStr;
/** /**
* * Base64位解析
*/
static get nativeBase64() {
return (typeof (window.atob) === "function");
}
/**
*
* @param input * @param input
*/ */
public static encode = function (input) { static decode(input:string): string {
let output = ""; input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
let i = 0; if (this.nativeBase64) {
input = this._utf8_encode(input); return window.atob(input);
} else {
var output: any = [], chr1: number, chr2: number, chr3: number, enc1: number, enc2: number, enc3: number, enc4: number, i: number = 0;
while (i < input.length) {
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output.push(String.fromCharCode(chr1));
if (enc3 !== 64) {
output.push(String.fromCharCode(chr2));
}
if (enc4 !== 64) {
output.push(String.fromCharCode(chr3));
}
}
output = output.join("");
return output;
}
}
/**
*
* @param input
*/
static encode(input:string): string {
input = input.replace(/\r\n/g, "\n");
if (this.nativeBase64) {
window.btoa(input);
} else {
var output: any = [], chr1: number, chr2: number, chr3: number, enc1: number, enc2: number, enc3: number, enc4: number, i: number = 0;
while (i < input.length) { while (i < input.length) {
chr1 = input.charCodeAt(i++); chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++); chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++); chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2; enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63; enc4 = chr3 & 63;
if (isNaN(chr2)) { if (isNaN(chr2)) {
enc3 = enc4 = 64; enc3 = enc4 = 64;
} else if (isNaN(chr3)) { } else if (isNaN(chr3)) {
enc4 = 64; enc4 = 64;
} }
output = output +
this._keyAll.charAt(enc1) + this._keyAll.charAt(enc2) +
this._keyAll.charAt(enc3) + this._keyAll.charAt(enc4);
}
return this._keyStr.charAt(Math.floor((Math.random() * this._keyStr.length))) + output;
};
/** output.push(this._keyStr.charAt(enc1));
* output.push(this._keyStr.charAt(enc2));
* @param input output.push(this._keyStr.charAt(enc3));
* @param isNotStr output.push(this._keyStr.charAt(enc4));
*/
public static decode(input, isNotStr: boolean = true) {
let output = "";
let chr1, chr2, chr3;
let enc1, enc2, enc3, enc4;
let i = 0;
input = this.getConfKey(input);
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = this._keyAll.indexOf(input.charAt(i++));
enc2 = this._keyAll.indexOf(input.charAt(i++));
enc3 = this._keyAll.indexOf(input.charAt(i++));
enc4 = this._keyAll.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
if (chr2 == 0) {
if (isNotStr) output = output + String.fromCharCode(chr2);
} else {
output = output + String.fromCharCode(chr2);
}
} }
if (enc4 != 64) { output = output.join("");
if (chr3 == 0) {
if (isNotStr) output = output + String.fromCharCode(chr3);
} else {
output = output + String.fromCharCode(chr3);
}
}
}
output = this._utf8_decode(output);
return output; return output;
} }
private static _utf8_encode(string) {
string = string.replace(/\r\n/g, "\n");
let utftext = "";
for (let n = 0; n < string.length; n++) {
let c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
} }
/**
* Base64格式数据
* @param input
* @param bytes
*/
static decodeBase64AsArray(input: string, bytes: number): Uint32Array {
bytes = bytes || 1;
var dec = Base64Utils.decode(input), i, j, len;
var ar: Uint32Array = new Uint32Array(dec.length / bytes);
for (i = 0, len = dec.length / bytes; i < len; i++) {
ar[i] = 0;
for (j = bytes - 1; j >= 0; --j) {
ar[i] += dec.charCodeAt((i * bytes) + j) << (j << 3);
} }
return utftext; }
return ar;
} }
private static _utf8_decode(utftext) { /**
let string = ""; *
let i = 0; * @param data
let c = 0; * @param decoded
let c1 = 0; * @param compression
let c2 = 0; * @private
let c3 = 0; */
while (i < utftext.length) { static decompress(data: string, decoded: any, compression: string): any {
c = utftext.charCodeAt(i); throw new Error("GZIP/ZLIB compressed TMX Tile Map not supported!");
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if ((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i + 1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utftext.charCodeAt(i + 1);
c3 = utftext.charCodeAt(i + 2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
} }
private static getConfKey(key): string { /**
return key.slice(1, key.length); * csv数据
* @param input
*/
static decodeCSV(input: string): Array<number> {
var entries: Array<any> = input.replace("\n", "").trim().split(",");
var result:Array<number> = [];
for (var i:number = 0; i < entries.length; i++) {
result.push(+entries[i]);
}
return result;
}
} }
} }
+68
View File
@@ -0,0 +1,68 @@
module es {
export class Color {
/**
* RGBA
*/
private _packedValue: number;
/**
* 绿alpha值的标量构造RGBA颜色
*/
constructor(r: number, g: number,b: number, alpha: number){
if (((r | g |b | alpha) & 0xFFFFFF00) != 0){
let clampedR = MathHelper.clamp(r, 0, 255);
let clampedG = MathHelper.clamp(g, 0, 255);
let clampedB = MathHelper.clamp(b, 0, 255);
let clampedA = MathHelper.clamp(alpha, 0, 255);
this._packedValue = (clampedA << 24) | (clampedB << 16) | (clampedG << 8) | (clampedR);
}else{
this._packedValue = (alpha << 24 ) | (b << 16) | (g << 8) | r;
}
}
public get b(){
return this._packedValue >> 16;
}
public set b(value: number){
this._packedValue = (this._packedValue & 0xff00ffff) | (value << 16);
}
public get g(){
return this._packedValue >> 8;
}
public set g(value: number){
this._packedValue = (this._packedValue & 0xffff00ff) | (value << 8)
}
public get r(){
return this._packedValue;
}
public set r(value: number){
this._packedValue = (this._packedValue & 0xffffff00) | value;
}
public get a(){
return this._packedValue >> 24;
}
public set a(value: number){
this._packedValue = (this._packedValue & 0x00ffffff) | (value << 24);
}
public get packedValue(){
return this._packedValue;
}
public set packedValue(value: number){
this._packedValue = value;
}
public equals(other: Color):boolean{
return this._packedValue == other._packedValue;
}
}
}
-44
View File
@@ -1,50 +1,6 @@
module es { module es {
/** 各种辅助方法来辅助绘图 */ /** 各种辅助方法来辅助绘图 */
export class DrawUtils { export class DrawUtils {
public static drawLine(shape: egret.Shape, start: Vector2, end: Vector2, color: number, thickness: number = 1) {
this.drawLineAngle(shape, start, MathHelper.angleBetweenVectors(start, end), Vector2.distance(start, end), color, thickness);
}
public static drawLineAngle(shape: egret.Shape, start: Vector2, radians: number, length: number, color: number, thickness = 1) {
shape.graphics.beginFill(color);
shape.graphics.drawRect(start.x, start.y, 1, 1);
shape.graphics.endFill();
shape.scaleX = length;
shape.scaleY = thickness;
shape.$anchorOffsetX = 0;
shape.$anchorOffsetY = 0;
shape.rotation = radians;
}
public static drawHollowRect(shape: egret.Shape, rect: Rectangle, color: number, thickness = 1) {
this.drawHollowRectR(shape, rect.x, rect.y, rect.width, rect.height, color, thickness);
}
public static drawHollowRectR(shape: egret.Shape, x: number, y: number, width: number, height: number, color: number, thickness = 1) {
let tl = new Vector2(x, y).round();
let tr = new Vector2(x + width, y).round();
let br = new Vector2(x + width, y + height).round();
let bl = new Vector2(x, y + height).round();
this.drawLine(shape, tl, tr, color, thickness);
this.drawLine(shape, tr, br, color, thickness);
this.drawLine(shape, br, bl, color, thickness);
this.drawLine(shape, bl, tl, color, thickness);
}
public static drawPixel(shape: egret.Shape, position: Vector2, color: number, size: number = 1) {
let destRect = new Rectangle(position.x, position.y, size, size);
if (size != 1) {
destRect.x -= size * 0.5;
destRect.y -= size * 0.5;
}
shape.graphics.beginFill(color);
shape.graphics.drawRect(destRect.x, destRect.y, destRect.width, destRect.height);
shape.graphics.endFill();
}
public static getColorMatrix(color: number): egret.ColorMatrixFilter { public static getColorMatrix(color: number): egret.ColorMatrixFilter {
let colorMatrix = [ let colorMatrix = [
1, 0, 0, 0, 0, 1, 0, 0, 0, 0,
+32
View File
@@ -0,0 +1,32 @@
module es {
export class EdgeExt {
public static oppositeEdge(self: Edge) {
switch (self) {
case Edge.bottom:
return Edge.top;
case Edge.top:
return Edge.bottom;
case Edge.left:
return Edge.right;
case Edge.right:
return Edge.left;
}
}
/**
* true
* @param self
*/
public static isHorizontal(self: Edge): boolean{
return self == Edge.right || self == Edge.left;
}
/**
* true
* @param self
*/
public static isVertical(self: Edge): boolean {
return self == Edge.top || self == Edge.bottom;
}
}
}
+8
View File
@@ -0,0 +1,8 @@
module es {
export enum Edge {
top,
bottom,
left,
right
}
}
+16
View File
@@ -0,0 +1,16 @@
module es {
export class Enumerable {
/**
*
* @param element
* @param count
*/
public static repeat<T>(element: T, count: number){
let result = [];
while (count--) {
result.push(element)
}
return result;
}
}
}
+78
View File
@@ -1,5 +1,23 @@
module es { module es {
export class RectangleExt { export class RectangleExt {
/**
*
* @param rect
* @param edge
*/
public static getSide(rect: Rectangle, edge: Edge) {
switch (edge) {
case Edge.top:
return rect.top;
case Edge.bottom:
return rect.bottom;
case es.Edge.left:
return rect.left;
case Edge.right:
return rect.right;
}
}
/** /**
* *
* @param first * @param first
@@ -15,5 +33,65 @@ module es {
result.height = Math.max(first.bottom, result.bottom) - result.y; result.height = Math.max(first.bottom, result.bottom) - result.y;
return result; return result;
} }
public static getHalfRect(rect: Rectangle, edge: Edge) {
switch (edge) {
case Edge.top:
return new Rectangle(rect.x, rect.y, rect.width, rect.height / 2);
case Edge.bottom:
return new Rectangle(rect.x, rect.y + rect.height / 2, rect.width, rect.height / 2);
case Edge.left:
return new Rectangle(rect.x, rect.y, rect.width / 2, rect.height);
case Edge.right:
return new Rectangle(rect.x + rect.width / 2, rect.y, rect.width / 2, rect.height);
}
}
/**
* /
* @param rect
* @param edge
* @param size
*/
public static getRectEdgePortion(rect: Rectangle, edge: Edge, size: number = 1) {
switch (edge) {
case es.Edge.top:
return new Rectangle(rect.x, rect.y, rect.width, size);
case Edge.bottom:
return new Rectangle(rect.x, rect.y + rect.height - size, rect.width, size);
case Edge.left:
return new Rectangle(rect.x, rect.y, size, rect.height);
case Edge.right:
return new Rectangle(rect.x + rect.width - size, rect.y, size, rect.height);
}
}
public static expandSide(rect: Rectangle, edge: Edge, amount: number) {
amount = Math.abs(amount);
switch (edge) {
case Edge.top:
rect.y -= amount;
rect.height += amount;
break;
case es.Edge.bottom:
rect.height += amount;
break;
case Edge.left:
rect.x -= amount;
rect.width += amount;
break;
case Edge.right:
rect.width += amount;
break;
}
}
public static contract(rect: Rectangle, horizontalAmount, verticalAmount) {
rect.x += horizontalAmount;
rect.y += verticalAmount;
rect.width -= horizontalAmount * 2;
rect.height -= verticalAmount * 2;
}
} }
} }
+27
View File
@@ -0,0 +1,27 @@
module es {
/**
* 11update时添加到amount中
*/
export class SubpixelNumber {
public remainder: number;
/**
* amount递增余数intamount设置为当前值
* @param amount
*/
public update(amount: number){
this.remainder += amount;
let motion = Math.trunc(this.remainder);
this.remainder -= motion;
return motion;
}
/**
* 0
*
*/
public reset(){
this.remainder = 0;
}
}
}