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

411 lines
21 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
module es {
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.getBounds().width - obj.textField.width) / 2 + obj.shape.getBounds().x;
obj.textField.y = pos.y - obj.textField.height - 5 + obj.shape.getBounds().y;
}else{
obj.textField.x = pos.x + (obj.width - obj.textField.width) / 2;
obj.textField.y = pos.y - obj.textField.height - 5;
}
obj.textField.background = true;
obj.textField.backgroundColor = 0xa0a0a4;
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:
this.renderTilesetTile(objGroup, obj, container, pos, scale, debugRender);
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 ++){
if (i == 0){
obj.shape.graphics.moveTo(points[i].x, points[i].y);
}else{
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;
}
}
}
private static renderTilesetTile(objGroup: es.TmxObjectGroup, obj, container: egret.DisplayObjectContainer, pos, scale: es.Vector2, debugRender) {
let tileset = objGroup.map.getTilesetForTileGid(obj.tile.gid);
let sourceRect = tileset.tileRegions.get(obj.tile.gid);
if (container) {
if (tileset.image) {
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);
}
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);
tileset.image.texture.x = pos.x;
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;
}
tileset.image.texture.anchorOffsetX = 0;
tileset.image.texture.anchorOffsetY = 0;
debugRender(obj, pos);
} else {
let tilesetTile = tileset.tiles.get(obj.tile.gid);
let texture: egret.Texture = tilesetTile.image.bitmap.getTexture(`${obj.tile.gid}`);
if (!texture) {
texture = tilesetTile.image.bitmap.createTexture(`${obj.tile.gid}`, sourceRect.x, sourceRect.y, sourceRect.width, sourceRect.height);
}
pos.y -= obj.height;
tilesetTile.image.texture = new Bitmap(texture);
container.addChild(tilesetTile.image.texture);
tilesetTile.image.texture.width = obj.width;
tilesetTile.image.texture.height = obj.height;
tilesetTile.image.texture.x = pos.x;
tilesetTile.image.texture.y = pos.y;
if (obj.tile.verticalFlip && obj.tile.horizontalFlip) {
tilesetTile.image.texture.scaleX = -1;
tilesetTile.image.texture.scaleY = -1;
} else if (obj.tile.verticalFlip) {
tilesetTile.image.texture.scaleX = scale.x;
tilesetTile.image.texture.scaleY = -1;
} else if (obj.tile.horizontalFlip) {
tilesetTile.image.texture.scaleX = -1;
tilesetTile.image.texture.scaleY = scale.y;
} else {
tilesetTile.image.texture.scaleX = scale.x;
tilesetTile.image.texture.scaleY = scale.y;
}
tilesetTile.image.texture.anchorOffsetX = 0;
tilesetTile.image.texture.anchorOffsetY = 0;
}
}
}
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];
}
}
}
}
}