CameraControl.js 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. cc.Class({
  2. extends: cc.Component,
  3. properties: {
  4. target: {
  5. default: null,
  6. type: cc.Node
  7. },
  8. camera: cc.Camera,
  9. anim: cc.Animation,
  10. //Jump Zoom
  11. jumpZoom: false,
  12. centerAtStart: false,
  13. //Smooth Follow
  14. smoothFollow: false,
  15. followX: {
  16. default: 0,
  17. visible () {
  18. return this.smoothFollow;
  19. }
  20. },
  21. followY: {
  22. default: 0,
  23. visible () {
  24. return this.smoothFollow;
  25. }
  26. },
  27. minFollowDist: {
  28. default: 0,
  29. visible () {
  30. return this.smoothFollow;
  31. }
  32. },
  33. followRatio:{
  34. default: 0,
  35. visible () {
  36. return this.smoothFollow;
  37. }
  38. },
  39. //Overview
  40. overview: false,
  41. overviewTargets: {
  42. default: [],
  43. type: [cc.Node],
  44. visible () {
  45. return this.overview;
  46. }
  47. },
  48. overviewMargin: {
  49. default: 0,
  50. visible () {
  51. return this.overview;
  52. }
  53. },
  54. //Speed Zoom
  55. speedZoom: false,
  56. zoomInSpeed: {
  57. default: 0,
  58. visible () {
  59. return this.speedZoom;
  60. }
  61. },
  62. zoomOutSpeed: {
  63. default: 0,
  64. visible () {
  65. return this.speedZoom;
  66. }
  67. },
  68. //Camera Shake
  69. canShake: false,
  70. shakeDuration: {
  71. default: 0,
  72. visible () {
  73. return this.canShake;
  74. }
  75. },
  76. //Pointer Pan
  77. pointerPan: false,
  78. pointerXMult: {
  79. default: 0,
  80. visible () {
  81. return this.pointerPan;
  82. }
  83. },
  84. pointerYMult: {
  85. default: 0,
  86. visible () {
  87. return this.pointerPan;
  88. }
  89. },
  90. //Boundaries in world position
  91. useBoundaries: false,
  92. topBound: {
  93. default: 0,
  94. visible () {
  95. return this.useBoundaries;
  96. }
  97. },
  98. bottomBound: {
  99. default: 0,
  100. visible () {
  101. return this.useBoundaries;
  102. }
  103. },
  104. leftBound: {
  105. default: 0,
  106. visible () {
  107. return this.useBoundaries;
  108. }
  109. },
  110. rightBound: {
  111. default: 0,
  112. visible () {
  113. return this.useBoundaries;
  114. }
  115. }
  116. },
  117. // use this for initialization
  118. onLoad: function () {
  119. // cc.director.getPhysicsManager().debugDrawFlags =
  120. // cc.PhysicsManager.DrawBits.e_aabbBit |
  121. // cc.PhysicsManager.DrawBits.e_jointBit|
  122. // cc.PhysicsManager.DrawBits.e_shapeBit;
  123. // ;
  124. this.startFollow = false;
  125. let canvas = cc.find('Canvas').getComponent(cc.Canvas);
  126. this.visibleSize = cc.view.getVisibleSize();
  127. this.initZoomRatio = this.camera.zoomRatio;
  128. //place camera on target if centerAtStart
  129. if (this.centerAtStart) {
  130. this.node.position = this.target.convertToWorldSpaceAR(cc.Vec2.ZERO);
  131. }
  132. this.previousPos = this.node.position;
  133. if (this.pointerPan) {
  134. // this.jumpZoom = false;
  135. this.overview = false;
  136. this.speedZoom = false;
  137. canvas.node.on('mousemove', this.onMouseMove, this);
  138. canvas.node.on('touchmove', this.onTouchMove, this);
  139. this.pointerPos = null;
  140. }
  141. if (this.overview) {
  142. this.jumpZoom = false;
  143. this.speedZoom = false;
  144. }
  145. if (this.speedZoom) {
  146. this.jumpZoom = false;
  147. }
  148. },
  149. onEnable: function () {
  150. cc.director.getPhysicsManager().attachDebugDrawToCamera(this.camera);
  151. },
  152. onDisable: function () {
  153. cc.director.getPhysicsManager().detachDebugDrawFromCamera(this.camera);
  154. },
  155. // called every frame, uncomment this function to activate update callback
  156. lateUpdate: function (dt) {
  157. let targetPos;
  158. if (this.overview){
  159. targetPos = this.target.parent.convertToWorldSpaceAR(this.getOverviewTargetsMidpoint());
  160. } else {
  161. targetPos = this.target.parent.convertToWorldSpaceAR(this.target.position);
  162. }
  163. if (this.pointerPan && this.pointerPos) {
  164. let xDelta = this.pointerPos.x / (this.visibleSize.width/2) - 1;
  165. let yDelta = this.pointerPos.y / (this.visibleSize.height/2) - 1;
  166. xDelta *= this.pointerXMult;
  167. yDelta *= this.pointerYMult;
  168. targetPos = cc.pAdd(targetPos, cc.p(xDelta, yDelta));
  169. }
  170. //smooth follow
  171. if (this.smoothFollow) {
  172. if (Math.abs(targetPos.x - this.node.x) >= this.followX ||
  173. Math.abs(targetPos.y - this.node.y) >= this.followY) {//when camera and target distance is larger than max distance
  174. this.startFollow = true;
  175. }
  176. if (this.startFollow) {
  177. this.node.position = this.node.position.lerp(targetPos,this.followRatio);
  178. if (cc.pDistance(targetPos, this.node.position) <= this.minFollowDist) {
  179. this.startFollow = false;
  180. }
  181. }
  182. } else {
  183. this.node.position = this.node.parent.convertToNodeSpaceAR(targetPos);
  184. }
  185. //speed zoom
  186. if (this.speedZoom) {
  187. let curSpeed = Math.abs(this.previousPos.x - targetPos.x) / dt;
  188. let ratio = 0;
  189. if (curSpeed > this.zoomOutSpeed) {
  190. ratio = 1 - (curSpeed - this.zoomOutSpeed) / (this.zoomInSpeed - this.zoomOutSpeed);
  191. this.camera.zoomRatio = cc.lerp(this.camera.zoomRatio, ratio, 0.02);
  192. } else {
  193. this.camera.zoomRatio = cc.lerp(this.camera.zoomRatio, this.initZoomRatio, 0.02);
  194. }
  195. }
  196. this.previousPos = targetPos;
  197. //jump zoom
  198. if (this.jumpZoom) {
  199. let ratio = targetPos.y / cc.winSize.height;
  200. this.camera.zoomRatio = 1 + (0.6 - ratio) * 0.35;
  201. }
  202. //boundaries
  203. if (this.useBoundaries) {
  204. let width = (this.visibleSize.width/2) / this.camera.zoomRatio;
  205. let height = (this.visibleSize.height/2) / this.camera.zoomRatio;
  206. let minX = this.node.x - width;
  207. let maxX = this.node.x + width;
  208. let minY = this.node.y - height;
  209. let maxY = this.node.y + height;
  210. if (minX < this.leftBound) {
  211. this.node.x = this.leftBound + width;
  212. }
  213. if (minY < this.bottomBound) {
  214. this.node.y = this.bottomBound + height;
  215. }
  216. if (maxX > this.rightBound) {
  217. this.node.x = this.rightBound - width;
  218. }
  219. if (maxY > this.topBound) {
  220. this.node.y = this.topBound - height;
  221. }
  222. }
  223. },
  224. getOverviewTargetsMidpoint () {
  225. let midPoint = cc.p(0, 0);
  226. let minX = 99999, minY = 99999, maxX = -99999, maxY = -99999;
  227. for (let i = 0; i < this.overviewTargets.length; ++i) {
  228. let target = this.overviewTargets[i];
  229. maxX = target.x > maxX ? target.x : maxX;
  230. minX = target.x < minX ? target.x : minX;
  231. maxY = target.y > maxY ? target.y : maxY;
  232. minY = target.y < minY ? target.y : minY;
  233. }
  234. maxX += this.overviewMargin;
  235. minX -= this.overviewMargin;
  236. maxY += this.overviewMargin;
  237. minY -= this.overviewMargin;
  238. let distX = Math.abs(maxX - minX);
  239. let distY = Math.abs(maxY - minY);
  240. midPoint = cc.p(minX + distX/2, minY + distY/2);
  241. let ratio = Math.max(distX / this.visibleSize.width, distY / this.visibleSize.height);
  242. this.camera.zoomRatio = 1/ratio;
  243. return midPoint;
  244. },
  245. shakeCamera () {
  246. if (!this.canShake) return;
  247. this.anim.play('shake');
  248. this.scheduleOnce(this.stopShake.bind(this), this.shakeDuration);
  249. },
  250. stopShake () {
  251. this.anim.stop();
  252. this.camera.node.position = cc.p(0, 0);
  253. },
  254. onMouseMove (event) {
  255. this.pointerPos = event.getLocation();
  256. },
  257. onTouchMove (event) {
  258. this.pointerPos = event.getLocation();
  259. }
  260. });