#28 新增tiledMapRenderer用于渲染tiledmap

This commit is contained in:
yhh
2020-08-12 18:08:12 +08:00
parent 167ef03df6
commit e5805960e0
14 changed files with 1402 additions and 2 deletions

View File

@@ -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

View File

@@ -0,0 +1,135 @@
module es {
export class TiledMapRenderer extends RenderableComponent{
public tiledMap: TmxMap;
public physicsLayer: number = 1 << 0;
/**
* 如果空,所有层将被渲染
*/
public layerIndicesToRender: number[];
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;
if (collisionLayerName){
this.collisionLayer = tiledMap.tileLayers.get(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.get(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) {
if (!this.layerIndicesToRender){
TiledRendering.renderMap(this.tiledMap, Vector2.add(this.entity.transform.position, this._localOffset),
this.transform.scale, this.renderLayer);
}else{
for (let i = 0; i < this.tiledMap.layers.size; i ++){
if (this.tiledMap.layers.get(i.toString()).visible && this.layerIndicesToRender.contains(i))
TiledRendering.renderLayer(this.tiledMap.layers.get(i.toString()), Vector2.add(this.entity.transform.position, this._localOffset),
this.transform.scale, this.renderLayer);
}
}
}
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;
}
}
}