InCirclePolygon.ts 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. import ConfigManager from "../../../engines/configs/ConfigManager";
  2. import MathUtils from "../../../engines/utils/MathUtils";
  3. import GameController from "./GameController";
  4. /**
  5. * 圆内多边形
  6. */
  7. export default class InCirclePolygon
  8. {
  9. /**
  10. * 中心点
  11. */
  12. center:cc.Vec3;
  13. /**
  14. * 中心点的高度
  15. */
  16. centerHeight:number;
  17. /**
  18. * 外角
  19. */
  20. outAngle:number;
  21. /**
  22. * 内角角度
  23. */
  24. private angle:number;
  25. /**
  26. * 内角数量
  27. */
  28. private count:number;
  29. /**
  30. * 边长
  31. */
  32. private side:number;
  33. private helfSide:number;
  34. /**
  35. * 长度
  36. */
  37. private length:number;
  38. /**
  39. * X轴的数据范围
  40. */
  41. minX:number;
  42. maxX:number;
  43. /**
  44. * 物理数据
  45. */
  46. private physicsData:number[][];
  47. private physicsTileSize:cc.Vec2;
  48. private physicsSize:cc.Vec2;
  49. /**
  50. * 多边形数据
  51. */
  52. private polygon:cc.Node;
  53. private polygonTiles:cc.Rect[];
  54. polygonTileAngles:number[];
  55. /**
  56. * 圆内多边形
  57. * @param side 边长
  58. * @param count 内角数量
  59. * @param length 长度
  60. * @param circumradius 外接圆半径
  61. * @param physicsData 物理数据
  62. */
  63. constructor(polygon:cc.Node){
  64. this.polygon=polygon;
  65. this.side=GameController.single.levelConfig.side;
  66. this.helfSide=this.side*0.5;
  67. this.count=GameController.single.levelConfig.count;
  68. this.angle=360/this.count;
  69. this.length=GameController.single.levelConfig.length;
  70. //物理数据
  71. let jsonAsset:cc.JsonAsset=ConfigManager.single.GetConfig(GameController.single.levelConfig.physicsConfig);
  72. let config:any=jsonAsset.json;
  73. //展开
  74. this.minX=0
  75. this.maxX=this.count*this.side;
  76. this.InitPolygonTiles();
  77. //计算中心点高度
  78. this.center=new cc.Vec3();
  79. this.centerHeight=MathUtils.InCirclePolygonCentre(this.side,this.angle);
  80. this.physicsData=config.data;
  81. //物理块大小
  82. this.physicsTileSize=new cc.Vec2();
  83. this.physicsTileSize.x=this.centerHeight*Math.tanh(MathUtils.angle2Radian(config.angleInterval*0.5))*2;
  84. this.physicsTileSize.y=config.tileHeight;
  85. //物理块索引空间大小
  86. this.physicsSize=new cc.Vec2();
  87. this.physicsSize.x=this.physicsData[0].length;
  88. this.physicsSize.y=this.physicsData.length;
  89. this.outAngle=180-(90-this.angle*0.5)*2;
  90. }
  91. private InitPolygonTiles():void{
  92. //多边形举行
  93. this.polygonTiles=[];
  94. this.polygonTileAngles=[];
  95. let tile:cc.Rect;
  96. for (let index = 0; index < this.count; index++) {
  97. tile=new cc.Rect();
  98. tile.x=index*this.side;
  99. tile.y=0;
  100. tile.width=this.side;
  101. tile.height=this.length;
  102. this.polygonTiles.push(tile);
  103. this.polygonTileAngles.push(index*-this.angle);
  104. }
  105. let lastTile:cc.Rect=this.polygonTiles[this.polygonTiles.length-1];
  106. tile=new cc.Rect();
  107. tile.x=-this.side;
  108. tile.y=0;
  109. tile.width=lastTile.width;
  110. tile.height=lastTile.height;
  111. this.polygonTiles.unshift(tile);
  112. tile=new cc.Rect();
  113. tile.x=lastTile.x+lastTile.width;
  114. tile.y=0;
  115. tile.width=this.polygonTiles[0].width;
  116. tile.height=this.polygonTiles[0].height;
  117. this.polygonTiles.push(tile);
  118. let leftAngle:number=this.angle;
  119. let rightAngle:number=-360;
  120. this.polygonTileAngles.unshift(leftAngle);
  121. this.polygonTileAngles.push(rightAngle);
  122. }
  123. /**
  124. * 重置
  125. */
  126. Reset():void{
  127. this.SetAngle(0);
  128. this.SetCenter(0,this.centerHeight,0);
  129. }
  130. /**
  131. * 测试并返回相交的内容
  132. * @param rect
  133. * @param out
  134. */
  135. PolygonIntersects(rect:cc.Rect,out:number[]):void{
  136. out.length=0;
  137. let tile:cc.Rect;
  138. for (let index = 0; index < this.polygonTiles.length; index++) {
  139. tile=this.polygonTiles[index];
  140. if(rect.intersects(tile)){
  141. out.push(index);
  142. }
  143. }
  144. }
  145. /**
  146. * 获取多边形块
  147. * @param index
  148. */
  149. GetPolygonTile(index:number):cc.Rect{
  150. return this.polygonTiles[index];
  151. }
  152. /**
  153. * 获取多边形块角度
  154. * @param index
  155. */
  156. GetPolygonTileAngle(index:number):number{
  157. return this.polygonTileAngles[index];
  158. }
  159. Update(dt:number):void{
  160. this.polygon.x=this.center.x;
  161. this.polygon.y=this.center.y;
  162. this.polygon.z=this.center.z;
  163. // cc.log("多边形位置:",this.polygon.x,this.polygon.y,this.polygon.z);
  164. }
  165. /**
  166. * 获取物理状态
  167. * @param px
  168. * @param py
  169. */
  170. GetPhysicsState(x:number,y:number):number{
  171. if(x<0||x>=this.physicsSize.x){
  172. return 0;
  173. }
  174. if(y<0||y>=this.physicsSize.y){
  175. return;
  176. }
  177. return this.physicsData[y][x];
  178. }
  179. /**
  180. * 逻辑坐标转物理坐标
  181. * @param logicX
  182. * @param logicY
  183. * @param out
  184. */
  185. GetPhysicsPos(logicX:number,logicY:number,out:{x:number,y:number}):void{
  186. out.x=this.Pixel2Physics(logicX,this.physicsTileSize.x);
  187. out.y=this.Pixel2Physics(logicY,this.physicsTileSize.y);
  188. }
  189. public Pixel2Physics(value:number,baseValue:number):number{
  190. let fValue:number=value/baseValue;
  191. let iValue:number=Math.floor(value/baseValue);
  192. if(fValue-iValue>0){
  193. iValue+=1;
  194. }
  195. iValue-=1;
  196. if(iValue<0){
  197. iValue=0;
  198. }
  199. return iValue;
  200. }
  201. /**
  202. * 设置角度
  203. * @param value
  204. */
  205. SetAngle(value:number):void{
  206. this.polygon.angle=value;
  207. }
  208. /**
  209. * 设置中心点
  210. * @param value
  211. */
  212. SetCenter(x:number,y:number,z:number){
  213. this.center.x=x;
  214. this.center.y=y;
  215. this.center.z=z;
  216. }
  217. private __tempVec3:cc.Vec3=new cc.Vec3();
  218. private __tempVec3_1:cc.Vec3=new cc.Vec3();
  219. private __tempMat4:cc.Mat4=new cc.Mat4();
  220. private __tempQuat:cc.Quat=new cc.Quat();
  221. /**
  222. * 旋转中心点
  223. * @param angle
  224. * @param point
  225. * @param origin
  226. */
  227. RotationCenter(angle:number,point:cc.Vec3,origin:cc.Vec3):void{
  228. let red:number=MathUtils.angle2Radian(angle);
  229. let srcDir:cc.Vec3=this.__tempVec3;
  230. cc.Vec3.subtract(srcDir,point,origin);
  231. let q:cc.Quat=this.__tempQuat;
  232. cc.Quat.fromAxisAngle(q,new cc.Vec3(0,0,1),red);
  233. let m:cc.Mat4=this.__tempMat4;
  234. cc.Mat4.fromRTS(m,q,cc.Vec3.ZERO,cc.Vec3.ONE);
  235. let newDir:cc.Vec3=this.__tempVec3_1;
  236. cc.Vec3.transformMat4(newDir,srcDir,m);
  237. origin.add(newDir,this.center);
  238. }
  239. }