+1
-1
@@ -31,7 +31,7 @@
|
||||
data-content-width="640"
|
||||
data-content-height="1136"
|
||||
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">
|
||||
</div>
|
||||
<script>
|
||||
|
||||
Vendored
+441
-14
@@ -252,6 +252,7 @@ declare module es {
|
||||
declare module es {
|
||||
class Core extends egret.DisplayObjectContainer {
|
||||
static emitter: Emitter<CoreEvents>;
|
||||
static debugRenderEndabled: boolean;
|
||||
static graphicsDevice: GraphicsDevice;
|
||||
static content: ContentManager;
|
||||
static _instance: Core;
|
||||
@@ -701,6 +702,58 @@ declare module es {
|
||||
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 {
|
||||
interface ITriggerListener {
|
||||
onTriggerEnter(other: Collider, local: Collider): any;
|
||||
@@ -763,6 +816,7 @@ declare module es {
|
||||
constructor();
|
||||
width: number;
|
||||
height: number;
|
||||
createBoxRect(x: number, y: number, width: number, height: number): BoxCollider;
|
||||
setSize(width: number, height: number): this;
|
||||
setWidth(width: number): BoxCollider;
|
||||
setHeight(height: number): void;
|
||||
@@ -944,6 +998,7 @@ declare module es {
|
||||
}
|
||||
declare class ObjectUtils {
|
||||
static clone<T>(p: any, c?: T): T;
|
||||
static elements(p: {}): any[];
|
||||
}
|
||||
declare module es {
|
||||
interface IRenderable {
|
||||
@@ -1200,6 +1255,7 @@ declare module es {
|
||||
static readonly Epsilon: number;
|
||||
static readonly Rad2Deg: number;
|
||||
static readonly Deg2Rad: number;
|
||||
static readonly PiOver2: number;
|
||||
static toDegrees(radians: number): number;
|
||||
static toRadians(degrees: 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 clamp01(value: number): number;
|
||||
static angleBetweenVectors(from: Vector2, to: Vector2): number;
|
||||
static incrementWithWrap(t: number, length: number): number;
|
||||
}
|
||||
}
|
||||
declare module es {
|
||||
@@ -1490,6 +1547,336 @@ declare module es {
|
||||
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 {
|
||||
static bubbleSort(ary: number[]): void;
|
||||
static insertionSort(ary: number[]): void;
|
||||
@@ -1505,15 +1892,28 @@ declare class ArrayUtils {
|
||||
static equals(ary1: number[], ary2: number[]): Boolean;
|
||||
static insert(ary: any[], index: number, value: any): any;
|
||||
}
|
||||
declare class Base64Utils {
|
||||
private static _keyNum;
|
||||
private static _keyStr;
|
||||
private static _keyAll;
|
||||
static encode: (input: any) => string;
|
||||
static decode(input: any, isNotStr?: boolean): string;
|
||||
private static _utf8_encode;
|
||||
private static _utf8_decode;
|
||||
private static getConfKey;
|
||||
declare module es {
|
||||
class Base64Utils {
|
||||
private static _keyStr;
|
||||
static readonly nativeBase64: boolean;
|
||||
static decode(input: string): string;
|
||||
static encode(input: string): string;
|
||||
static decodeBase64AsArray(input: string, bytes: number): Uint32Array;
|
||||
static decompress(data: string, decoded: any, compression: string): any;
|
||||
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 {
|
||||
class ContentManager {
|
||||
@@ -1524,14 +1924,16 @@ declare module es {
|
||||
}
|
||||
declare module es {
|
||||
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;
|
||||
}
|
||||
}
|
||||
declare module es {
|
||||
class EdgeExt {
|
||||
static oppositeEdge(self: Edge): Edge;
|
||||
static isHorizontal(self: Edge): boolean;
|
||||
static isVertical(self: Edge): boolean;
|
||||
}
|
||||
}
|
||||
declare module es {
|
||||
class FuncPack {
|
||||
func: Function;
|
||||
@@ -1546,6 +1948,19 @@ declare module es {
|
||||
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 {
|
||||
class GlobalManager {
|
||||
_enabled: boolean;
|
||||
@@ -1715,7 +2130,19 @@ declare class RandomUtils {
|
||||
}
|
||||
declare module es {
|
||||
class RectangleExt {
|
||||
static getSide(rect: Rectangle, edge: Edge): number;
|
||||
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 {
|
||||
|
||||
+1890
-165
File diff suppressed because it is too large
Load Diff
Vendored
+1
-1
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
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
],
|
||||
@@ -145,6 +145,16 @@
|
||||
"url": "assets/isometric_grass_and_water.png",
|
||||
"type": "image",
|
||||
"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
@@ -10,27 +10,32 @@ module scene {
|
||||
}
|
||||
|
||||
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"));
|
||||
this.createEntityAsync("bg").then(bg => {
|
||||
bg.addComponent(new component.PlayerController());
|
||||
bg.addComponent(new es.Mover());
|
||||
let spriteRenderer = bg.addComponent(new es.ScrollingSpriteRenderer(sprite));
|
||||
spriteRenderer.setRenderLayer(4);
|
||||
spriteRenderer.scrollX = -30;
|
||||
let spriteRenderer = bg.addComponent(new es.ScrollingSpriteRenderer(sprite)).setRenderLayer(0);
|
||||
// spriteRenderer.scrollX = -30;
|
||||
// bg.addComponent(new es.BoxCollider());
|
||||
|
||||
this.camera.follow(bg, es.CameraStyle.lockOn);
|
||||
});
|
||||
|
||||
es.Core.debugRenderEndabled = true;
|
||||
// // bg.addComponent(new es.SpriteRenderer()).setSprite(sprite).setColor(0xff0000);
|
||||
|
||||
|
||||
for (let i = 0; i < 20; i++) {
|
||||
let sprite = new es.Sprite(RES.getRes("checkbox_select_disabled_png"));
|
||||
let player2 = this.createEntity("bg");
|
||||
player2.addComponent(new es.SpriteRenderer()).setSprite(sprite).setRenderLayer(i);
|
||||
player2.position = new es.Vector2(30 * i, 30 * i);
|
||||
// player2.addComponent(new es.BoxCollider());
|
||||
}
|
||||
// for (let i = 0; i < 20; i++) {
|
||||
// let sprite = new es.Sprite(RES.getRes("checkbox_select_disabled_png"));
|
||||
// let player2 = this.createEntity("bg");
|
||||
// player2.addComponent(new es.SpriteRenderer()).setSprite(sprite).setRenderLayer(i);
|
||||
// player2.position = new es.Vector2(30 * i, 30 * i);
|
||||
// // player2.addComponent(new es.BoxCollider());
|
||||
// }
|
||||
|
||||
|
||||
let pool = new es.ComponentPool<component.SimplePooled>(component.SimplePooled);
|
||||
|
||||
@@ -37,7 +37,7 @@ egret_native.egretStart = function () {
|
||||
contentWidth: 640,
|
||||
contentHeight: 1136,
|
||||
showPaintRect: false,
|
||||
showFPS: false,
|
||||
showFPS: true,
|
||||
fpsStyles: "x:0,y:0,size:12,textColor:0xffffff,bgAlpha:0.9",
|
||||
showLog: false,
|
||||
logFilter: "",
|
||||
|
||||
Vendored
+441
-14
@@ -252,6 +252,7 @@ declare module es {
|
||||
declare module es {
|
||||
class Core extends egret.DisplayObjectContainer {
|
||||
static emitter: Emitter<CoreEvents>;
|
||||
static debugRenderEndabled: boolean;
|
||||
static graphicsDevice: GraphicsDevice;
|
||||
static content: ContentManager;
|
||||
static _instance: Core;
|
||||
@@ -701,6 +702,58 @@ declare module es {
|
||||
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 {
|
||||
interface ITriggerListener {
|
||||
onTriggerEnter(other: Collider, local: Collider): any;
|
||||
@@ -763,6 +816,7 @@ declare module es {
|
||||
constructor();
|
||||
width: number;
|
||||
height: number;
|
||||
createBoxRect(x: number, y: number, width: number, height: number): BoxCollider;
|
||||
setSize(width: number, height: number): this;
|
||||
setWidth(width: number): BoxCollider;
|
||||
setHeight(height: number): void;
|
||||
@@ -944,6 +998,7 @@ declare module es {
|
||||
}
|
||||
declare class ObjectUtils {
|
||||
static clone<T>(p: any, c?: T): T;
|
||||
static elements(p: {}): any[];
|
||||
}
|
||||
declare module es {
|
||||
interface IRenderable {
|
||||
@@ -1200,6 +1255,7 @@ declare module es {
|
||||
static readonly Epsilon: number;
|
||||
static readonly Rad2Deg: number;
|
||||
static readonly Deg2Rad: number;
|
||||
static readonly PiOver2: number;
|
||||
static toDegrees(radians: number): number;
|
||||
static toRadians(degrees: 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 clamp01(value: number): number;
|
||||
static angleBetweenVectors(from: Vector2, to: Vector2): number;
|
||||
static incrementWithWrap(t: number, length: number): number;
|
||||
}
|
||||
}
|
||||
declare module es {
|
||||
@@ -1490,6 +1547,336 @@ declare module es {
|
||||
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 {
|
||||
static bubbleSort(ary: number[]): void;
|
||||
static insertionSort(ary: number[]): void;
|
||||
@@ -1505,15 +1892,28 @@ declare class ArrayUtils {
|
||||
static equals(ary1: number[], ary2: number[]): Boolean;
|
||||
static insert(ary: any[], index: number, value: any): any;
|
||||
}
|
||||
declare class Base64Utils {
|
||||
private static _keyNum;
|
||||
private static _keyStr;
|
||||
private static _keyAll;
|
||||
static encode: (input: any) => string;
|
||||
static decode(input: any, isNotStr?: boolean): string;
|
||||
private static _utf8_encode;
|
||||
private static _utf8_decode;
|
||||
private static getConfKey;
|
||||
declare module es {
|
||||
class Base64Utils {
|
||||
private static _keyStr;
|
||||
static readonly nativeBase64: boolean;
|
||||
static decode(input: string): string;
|
||||
static encode(input: string): string;
|
||||
static decodeBase64AsArray(input: string, bytes: number): Uint32Array;
|
||||
static decompress(data: string, decoded: any, compression: string): any;
|
||||
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 {
|
||||
class ContentManager {
|
||||
@@ -1524,14 +1924,16 @@ declare module es {
|
||||
}
|
||||
declare module es {
|
||||
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;
|
||||
}
|
||||
}
|
||||
declare module es {
|
||||
class EdgeExt {
|
||||
static oppositeEdge(self: Edge): Edge;
|
||||
static isHorizontal(self: Edge): boolean;
|
||||
static isVertical(self: Edge): boolean;
|
||||
}
|
||||
}
|
||||
declare module es {
|
||||
class FuncPack {
|
||||
func: Function;
|
||||
@@ -1546,6 +1948,19 @@ declare module es {
|
||||
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 {
|
||||
class GlobalManager {
|
||||
_enabled: boolean;
|
||||
@@ -1715,7 +2130,19 @@ declare class RandomUtils {
|
||||
}
|
||||
declare module es {
|
||||
class RectangleExt {
|
||||
static getSide(rect: Rectangle, edge: Edge): number;
|
||||
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 {
|
||||
|
||||
+1890
-165
File diff suppressed because it is too large
Load Diff
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -28,13 +28,13 @@ module es {
|
||||
public draw(shape: egret.Shape): boolean {
|
||||
switch (this.drawType) {
|
||||
case DebugDrawType.line:
|
||||
DrawUtils.drawLine(shape, this.start, this.end, this.color);
|
||||
// DrawUtils.drawLine(shape, this.start, this.end, this.color);
|
||||
break;
|
||||
case DebugDrawType.hollowRectangle:
|
||||
DrawUtils.drawHollowRect(shape, this.rectangle, this.color);
|
||||
// DrawUtils.drawHollowRect(shape, this.rectangle, this.color);
|
||||
break;
|
||||
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;
|
||||
case DebugDrawType.text:
|
||||
break;
|
||||
|
||||
@@ -28,6 +28,20 @@ module es {
|
||||
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的大小
|
||||
* @param width
|
||||
|
||||
@@ -162,11 +162,13 @@ module es {
|
||||
* 进行状态同步
|
||||
*/
|
||||
public sync(camera: Camera) {
|
||||
this.displayObject.x = 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.displayObject.scaleX = this.entity.scale.x;
|
||||
this.displayObject.scaleY = this.entity.scale.y;
|
||||
this.displayObject.rotation = this.entity.rotation;
|
||||
let afterPos = new Vector2(this.entity.position.x + this.localOffset.x - camera.position.x + camera.origin.x,
|
||||
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;
|
||||
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() {
|
||||
|
||||
@@ -123,8 +123,10 @@ module es {
|
||||
public render(camera: Camera) {
|
||||
this.sync(camera);
|
||||
|
||||
this.displayObject.x = 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;
|
||||
let afterPos = new Vector2(this.entity.position.x + this.localOffset.x - camera.position.x + camera.origin.x,
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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是在基于重力的平铺地图中移动对象的助手。
|
||||
* 它要求它所在的实体有一个BoxCollider。BoxCollider将与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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,10 @@ module es {
|
||||
* 核心发射器。只发出核心级别的事件
|
||||
*/
|
||||
public static emitter: Emitter<CoreEvents>;
|
||||
/**
|
||||
* 是否启用调试渲染
|
||||
*/
|
||||
public static debugRenderEndabled = false;
|
||||
/**
|
||||
* 全局访问图形设备
|
||||
*/
|
||||
|
||||
@@ -16,4 +16,19 @@ class ObjectUtils {
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,10 @@ module es {
|
||||
public static readonly Epsilon: number = 0.00001;
|
||||
public static readonly Rad2Deg = 57.29578;
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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[];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
module es {
|
||||
export interface ITmxLayer {
|
||||
offsetX: number;
|
||||
offsetY: number;
|
||||
opacity: number;
|
||||
visible: boolean;
|
||||
properties: Map<string, string>;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>;
|
||||
|
||||
/**
|
||||
* 当我们有一个图像tileset,tile可以是任何大小,所以我们记录的最大大小来剔除
|
||||
*/
|
||||
public maxTileWidth: number;
|
||||
|
||||
/**
|
||||
* 当我们有一个图像tileset,tile可以是任何大小,所以我们记录的最大大小来剔除
|
||||
*/
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
module es {
|
||||
export class TmxUtils {
|
||||
/**
|
||||
* 解码
|
||||
* @param data 数据
|
||||
* @param encoding 编码方式 目前暂时只支持XML、base64(无压缩)、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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+121
-111
@@ -1,124 +1,134 @@
|
||||
class Base64Utils {
|
||||
private static _keyNum = "0123456789+/";
|
||||
private static _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
private static _keyAll = Base64Utils._keyNum + Base64Utils._keyStr;
|
||||
/**
|
||||
* 加密
|
||||
* @param input
|
||||
*/
|
||||
public static encode = function (input) {
|
||||
let output = "";
|
||||
let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
|
||||
let i = 0;
|
||||
input = this._utf8_encode(input);
|
||||
while (i < input.length) {
|
||||
chr1 = input.charCodeAt(i++);
|
||||
chr2 = input.charCodeAt(i++);
|
||||
chr3 = input.charCodeAt(i++);
|
||||
enc1 = chr1 >> 2;
|
||||
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
|
||||
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
|
||||
enc4 = chr3 & 63;
|
||||
if (isNaN(chr2)) {
|
||||
enc3 = enc4 = 64;
|
||||
} else if (isNaN(chr3)) {
|
||||
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;
|
||||
};
|
||||
module es{
|
||||
export class Base64Utils {
|
||||
private static _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||
|
||||
/**
|
||||
* 解码
|
||||
* @param input
|
||||
* @param isNotStr
|
||||
*/
|
||||
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);
|
||||
/**
|
||||
* 判断是否原生支持Base64位解析
|
||||
*/
|
||||
static get nativeBase64() {
|
||||
return (typeof (window.atob) === "function");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 解码
|
||||
* @param input
|
||||
*/
|
||||
static decode(input:string): string {
|
||||
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
|
||||
|
||||
if (this.nativeBase64) {
|
||||
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) {
|
||||
chr1 = input.charCodeAt(i++);
|
||||
chr2 = input.charCodeAt(i++);
|
||||
chr3 = input.charCodeAt(i++);
|
||||
|
||||
enc1 = chr1 >> 2;
|
||||
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
|
||||
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
|
||||
enc4 = chr3 & 63;
|
||||
|
||||
if (isNaN(chr2)) {
|
||||
enc3 = enc4 = 64;
|
||||
} else if (isNaN(chr3)) {
|
||||
enc4 = 64;
|
||||
}
|
||||
|
||||
output.push(this._keyStr.charAt(enc1));
|
||||
output.push(this._keyStr.charAt(enc2));
|
||||
output.push(this._keyStr.charAt(enc3));
|
||||
output.push(this._keyStr.charAt(enc4));
|
||||
}
|
||||
|
||||
output = output.join("");
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 解析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);
|
||||
|
||||
if (enc4 != 64) {
|
||||
if (chr3 == 0) {
|
||||
if (isNotStr) output = output + String.fromCharCode(chr3);
|
||||
} else {
|
||||
output = output + String.fromCharCode(chr3);
|
||||
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 ar;
|
||||
}
|
||||
output = this._utf8_decode(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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂时不支持
|
||||
* @param data
|
||||
* @param decoded
|
||||
* @param compression
|
||||
* @private
|
||||
*/
|
||||
static decompress(data: string, decoded: any, compression: string): any {
|
||||
throw new Error("GZIP/ZLIB compressed TMX Tile Map not supported!");
|
||||
}
|
||||
return utftext;
|
||||
}
|
||||
|
||||
private static _utf8_decode(utftext) {
|
||||
let string = "";
|
||||
let i = 0;
|
||||
let c = 0;
|
||||
let c1 = 0;
|
||||
let c2 = 0;
|
||||
let c3 = 0;
|
||||
while (i < utftext.length) {
|
||||
c = utftext.charCodeAt(i);
|
||||
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;
|
||||
/**
|
||||
* 解析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;
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
private static getConfKey(key): string {
|
||||
return key.slice(1, key.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,50 +1,6 @@
|
||||
module es {
|
||||
/** 各种辅助方法来辅助绘图 */
|
||||
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 {
|
||||
let colorMatrix = [
|
||||
1, 0, 0, 0, 0,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
module es {
|
||||
export enum Edge {
|
||||
top,
|
||||
bottom,
|
||||
left,
|
||||
right
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,23 @@
|
||||
module es {
|
||||
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
|
||||
@@ -15,5 +33,65 @@ module es {
|
||||
result.height = Math.max(first.bottom, result.bottom) - result.y;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
module es {
|
||||
/**
|
||||
* 管理数值的简单助手类。它存储值,直到累计的总数大于1。一旦超过1,该值将在调用update时添加到amount中。
|
||||
*/
|
||||
export class SubpixelNumber {
|
||||
public remainder: number;
|
||||
|
||||
/**
|
||||
* 以amount递增余数,将值截断为int,存储新的余数并将amount设置为当前值。
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user