import ConfigManager from "../../../engines/configs/ConfigManager"; import MathUtils from "../../../engines/utils/MathUtils"; import GameController from "./GameController"; /** * 圆内多边形 */ export default class InCirclePolygon { /** * 中心点 */ center:cc.Vec3; /** * 中心点的高度 */ centerHeight:number; /** * 外角 */ outAngle:number; /** * 内角角度 */ private angle:number; /** * 内角数量 */ private count:number; /** * 边长 */ private side:number; private helfSide:number; /** * 长度 */ private length:number; /** * X轴的数据范围 */ minX:number; maxX:number; /** * 物理数据 */ private physicsData:number[][]; private physicsTileSize:cc.Vec2; private physicsSize:cc.Vec2; /** * 多边形数据 */ private polygon:cc.Node; private polygonTiles:cc.Rect[]; polygonTileAngles:number[]; /** * 圆内多边形 * @param side 边长 * @param count 内角数量 * @param length 长度 * @param circumradius 外接圆半径 * @param physicsData 物理数据 */ constructor(polygon:cc.Node){ this.polygon=polygon; this.side=GameController.single.levelConfig.side; this.helfSide=this.side*0.5; this.count=GameController.single.levelConfig.count; this.angle=360/this.count; this.length=GameController.single.levelConfig.length; //物理数据 let jsonAsset:cc.JsonAsset=ConfigManager.single.GetConfig(GameController.single.levelConfig.physicsConfig); let config:any=jsonAsset.json; //展开 this.minX=0 this.maxX=this.count*this.side; this.InitPolygonTiles(); //计算中心点高度 this.center=new cc.Vec3(); this.centerHeight=MathUtils.InCirclePolygonCentre(this.side,this.angle); this.physicsData=config.data; //物理块大小 this.physicsTileSize=new cc.Vec2(); this.physicsTileSize.x=this.centerHeight*Math.tanh(MathUtils.angle2Radian(config.angleInterval*0.5))*2; this.physicsTileSize.y=config.tileHeight; //物理块索引空间大小 this.physicsSize=new cc.Vec2(); this.physicsSize.x=this.physicsData[0].length; this.physicsSize.y=this.physicsData.length; this.outAngle=180-(90-this.angle*0.5)*2; } private InitPolygonTiles():void{ //多边形举行 this.polygonTiles=[]; this.polygonTileAngles=[]; let tile:cc.Rect; for (let index = 0; index < this.count; index++) { tile=new cc.Rect(); tile.x=index*this.side; tile.y=0; tile.width=this.side; tile.height=this.length; this.polygonTiles.push(tile); this.polygonTileAngles.push(index*-this.angle); } let lastTile:cc.Rect=this.polygonTiles[this.polygonTiles.length-1]; tile=new cc.Rect(); tile.x=-this.side; tile.y=0; tile.width=lastTile.width; tile.height=lastTile.height; this.polygonTiles.unshift(tile); tile=new cc.Rect(); tile.x=lastTile.x+lastTile.width; tile.y=0; tile.width=this.polygonTiles[0].width; tile.height=this.polygonTiles[0].height; this.polygonTiles.push(tile); let leftAngle:number=this.angle; let rightAngle:number=-360; this.polygonTileAngles.unshift(leftAngle); this.polygonTileAngles.push(rightAngle); } /** * 重置 */ Reset():void{ this.SetAngle(0); this.SetCenter(0,this.centerHeight,0); } /** * 测试并返回相交的内容 * @param rect * @param out */ PolygonIntersects(rect:cc.Rect,out:number[]):void{ out.length=0; let tile:cc.Rect; for (let index = 0; index < this.polygonTiles.length; index++) { tile=this.polygonTiles[index]; if(rect.intersects(tile)){ out.push(index); } } } /** * 获取多边形块 * @param index */ GetPolygonTile(index:number):cc.Rect{ return this.polygonTiles[index]; } /** * 获取多边形块角度 * @param index */ GetPolygonTileAngle(index:number):number{ return this.polygonTileAngles[index]; } Update(dt:number):void{ this.polygon.x=this.center.x; this.polygon.y=this.center.y; this.polygon.z=this.center.z; // cc.log("多边形位置:",this.polygon.x,this.polygon.y,this.polygon.z); } /** * 获取物理状态 * @param px * @param py */ GetPhysicsState(x:number,y:number):number{ if(x<0||x>=this.physicsSize.x){ return 0; } if(y<0||y>=this.physicsSize.y){ return; } return this.physicsData[y][x]; } /** * 逻辑坐标转物理坐标 * @param logicX * @param logicY * @param out */ GetPhysicsPos(logicX:number,logicY:number,out:{x:number,y:number}):void{ out.x=this.Pixel2Physics(logicX,this.physicsTileSize.x); out.y=this.Pixel2Physics(logicY,this.physicsTileSize.y); } public Pixel2Physics(value:number,baseValue:number):number{ let fValue:number=value/baseValue; let iValue:number=Math.floor(value/baseValue); if(fValue-iValue>0){ iValue+=1; } iValue-=1; if(iValue<0){ iValue=0; } return iValue; } /** * 设置角度 * @param value */ SetAngle(value:number):void{ this.polygon.angle=value; } /** * 设置中心点 * @param value */ SetCenter(x:number,y:number,z:number){ this.center.x=x; this.center.y=y; this.center.z=z; } private __tempVec3:cc.Vec3=new cc.Vec3(); private __tempVec3_1:cc.Vec3=new cc.Vec3(); private __tempMat4:cc.Mat4=new cc.Mat4(); private __tempQuat:cc.Quat=new cc.Quat(); /** * 旋转中心点 * @param angle * @param point * @param origin */ RotationCenter(angle:number,point:cc.Vec3,origin:cc.Vec3):void{ let red:number=MathUtils.angle2Radian(angle); let srcDir:cc.Vec3=this.__tempVec3; cc.Vec3.subtract(srcDir,point,origin); let q:cc.Quat=this.__tempQuat; cc.Quat.fromAxisAngle(q,new cc.Vec3(0,0,1),red); let m:cc.Mat4=this.__tempMat4; cc.Mat4.fromRTS(m,q,cc.Vec3.ZERO,cc.Vec3.ONE); let newDir:cc.Vec3=this.__tempVec3_1; cc.Vec3.transformMat4(newDir,srcDir,m); origin.add(newDir,this.center); } }