VirtualJoystick.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. /**
  2. * A Virtual Joystick
  3. * @class Phaser.Plugin.VirtualJoystick
  4. */
  5. Phaser.Plugin.VirtualJoystick = function (game, parent) {
  6. Phaser.Plugin.call(this, game, parent);
  7. this.x = 0;
  8. this.y = 0;
  9. this.limit = 10;
  10. this.baseCircle;
  11. this.baseBMD;
  12. this.nubBMD;
  13. this.base;
  14. this.nub;
  15. this.buttonA;
  16. this.buttonB;
  17. this.buttonC;
  18. this.baseCenter;
  19. this.nubCenter;
  20. this.isDragging = false;
  21. this.angle = 0;
  22. this.distance = 0;
  23. this.force = 0;
  24. this.deltaX = 0;
  25. this.deltaY = 0;
  26. this.speed = 0;
  27. this.pointer = null;
  28. this.callbackID = -1;
  29. };
  30. Phaser.Plugin.VirtualJoystick.prototype = Object.create(Phaser.Plugin.prototype);
  31. Phaser.Plugin.VirtualJoystick.prototype.constructor = Phaser.Plugin.VirtualJoystick;
  32. Phaser.Plugin.VirtualJoystick.prototype.init = function (x, y, baseDiameter, stickDiameter, limit, baseColor, stickColor) {
  33. if (typeof x === 'undefined') { x=this.game.stage.width/6; }
  34. if (typeof y === 'undefined') { y=this.game.stage.height-this.game.stage.height/5; }
  35. if (typeof baseDiameter === 'undefined') { baseDiameter = 140; }
  36. if (typeof stickDiameter === 'undefined') { stickDiameter = 100; }
  37. if (typeof limit === 'undefined') { limit = Math.floor(baseDiameter / 2); }
  38. if (typeof baseColor === 'undefined') { baseColor = 'rgba(255, 0, 0, 0.5)'; }
  39. if (typeof stickColor === 'undefined') { stickColor = 'rgba(0, 255, 0, 0.7)'; }
  40. this.x = x;
  41. this.y = y;
  42. this.isDragging = false;
  43. this.limit = limit;
  44. this.limitPoint = new Phaser.Point(x, y);
  45. this.location = new Phaser.Point(x, y);
  46. var radius = Math.floor(baseDiameter / 2);
  47. var nr = Math.floor(stickDiameter / 2);
  48. this.baseCircle = new Phaser.Circle(x, y, baseDiameter);
  49. this.baseBMD = this.game.make.bitmapData(baseDiameter, baseDiameter);
  50. this.nubBMD = this.game.make.bitmapData(stickDiameter, stickDiameter);
  51. this.baseBMD.circle(radius, radius, radius, baseColor);
  52. this.nubBMD.circle(nr, nr, nr, stickColor);
  53. // Base
  54. this.base = this.game.make.sprite(x, y, this.baseBMD);
  55. this.base.anchor.set(0.5);
  56. // Nub (stick)
  57. this.nub = this.game.make.sprite(x, y, this.nubBMD);
  58. this.nub.anchor.set(0.5);
  59. this.nub.inputEnabled = true;
  60. this.nub.events.onInputDown.add(this.startDrag, this);
  61. this.nub.events.onInputUp.add(this.stopDrag, this);
  62. };
  63. Phaser.Plugin.VirtualJoystick.prototype.start = function () {
  64. this.game.stage.addChild(this.base);
  65. this.game.stage.addChild(this.nub);
  66. if (this.callbackID > -1)
  67. {
  68. this.game.input.deleteMoveCallback(this.callbackID);
  69. }
  70. this.callbackID = this.game.input.addMoveCallback(this.move, this);
  71. this.isDragging = false;
  72. this.distance = 0;
  73. this.speed = 0;
  74. this.force = 0;
  75. this.deltaX = 0;
  76. this.deltaY = 0;
  77. this.nub.x = this.base.x;
  78. this.nub.y = this.base.y;
  79. this.base.visible = true;
  80. this.nub.visible = true;
  81. this.limitPoint.set(this.base.x, this.base.y);
  82. this.location.set(this.base.x, this.base.y);
  83. };
  84. Phaser.Plugin.VirtualJoystick.prototype.stop = function () {
  85. // if (this.nub.parent === null || this.base.parent === null)
  86. // {
  87. // return;
  88. // }
  89. this.base.visible = false;
  90. this.nub.visible = false;
  91. this.nub.x = this.base.x;
  92. this.nub.y = this.base.y;
  93. this.nub.input.enabled = false;
  94. this.game.stage.removeChild(this.base);
  95. this.game.stage.removeChild(this.nub);
  96. if(this.buttonA){
  97. this.game.stage.removeChild(this.buttonA);
  98. }
  99. if(this.buttonB){
  100. this.game.stage.removeChild(this.buttonB);
  101. }
  102. if(this.buttonC){
  103. this.game.stage.removeChild(this.buttonC);
  104. }
  105. this.game.input.deleteMoveCallback(this.callbackID);
  106. };
  107. //Phaser.Plugin.VirtualJoystick.prototype.resize = function (x, y, baseDiameter, stickDiameter, limit, baseColor, stickColor) {
  108. // this.stop();
  109. //
  110. // this.init(arguments)
  111. //
  112. // this.start();
  113. //};
  114. Phaser.Plugin.VirtualJoystick.prototype.startDrag = function (nub, pointer) {
  115. this.isDragging = true;
  116. this.pointer = pointer;
  117. this.location.set(pointer.x, pointer.y);
  118. this.distance = Phaser.Point.distance(this.base, this.location, true);
  119. this.angle = this.game.math.wrapAngle(this.location.angle(this.base, true) + 180);
  120. this.force = this.game.math.percent(this.distance, this.limit);
  121. this.deltaX = Math.cos(this.game.math.degToRad(this.angle));
  122. this.deltaY = Math.sin(this.game.math.degToRad(this.angle));
  123. };
  124. Phaser.Plugin.VirtualJoystick.prototype.stopDrag = function (nub, pointer) {
  125. console.log('stopDrag');
  126. this.isDragging = false;
  127. this.distance = 0;
  128. this.angle = 0;
  129. this.force = 0;
  130. this.nub.x = this.base.x;
  131. this.nub.y = this.base.y;
  132. this.deltaX = 0;
  133. this.deltaY = 0;
  134. this.limitPoint.set(this.base.x, this.base.y);
  135. };
  136. Phaser.Plugin.VirtualJoystick.prototype.move = function (pointer, x, y) {
  137. if (!this.isDragging)
  138. {
  139. return;
  140. }
  141. var _location = new Phaser.Point(x,y);
  142. var _distance = Phaser.Point.distance(this.limitPoint,_location, true);
  143. if (_distance > this.limit)
  144. {
  145. //超出了返回的点击事件,不处理 多点触摸的时候很有用
  146. //console.log("超出了返回的点击事件,不处理");
  147. return;
  148. }
  149. this.location.set(x, y);
  150. this.distance = Phaser.Point.distance(this.base, this.location, true);
  151. this.angle = this.game.math.wrapAngle(this.location.angle(this.base, true) + 180);
  152. this.force = this.game.math.percent(this.distance, this.limit);
  153. if (this.distance < this.limit)
  154. {
  155. this.limitPoint.copyFrom(this.location);
  156. }
  157. else
  158. {
  159. this.baseCircle.circumferencePoint(this.angle, true, this.limitPoint);
  160. }
  161. this.nub.position.set(this.limitPoint.x, this.limitPoint.y);
  162. this.deltaX = Math.cos(this.game.math.degToRad(this.angle));
  163. this.deltaY = Math.sin(this.game.math.degToRad(this.angle));
  164. };
  165. /**
  166. * Given the speed calculate the velocity and return it as a Point object, or set it to the given point object.
  167. * One way to use this is: velocityFromAngle(angle, 200, sprite.velocity) which will set the values directly to the sprites velocity and not create a new Point object.
  168. *
  169. * @method Phaser.Plugin.VirtualJoystick#setVelocity
  170. * @param {Phaser.Sprite} sprite - The Sprite to set the velocity on. The Sprite must have a physics body already set. The value will be set into Sprite.body.velocity.
  171. * @param {number} [minSpeed=0] - The minimum speed the Sprite will move if the joystick is at its default (non-moved) position.
  172. * @param {number} [maxSpeed=100] - The maximum speed the Sprite will move if the joystick is at its full extent.
  173. * @return {Phaser.Sprite} The Sprite object.
  174. */
  175. Phaser.Plugin.VirtualJoystick.prototype.setVelocity = function (sprite, minSpeed, maxSpeed) {
  176. if (typeof minSpeed === 'undefined') { minSpeed = 0; }
  177. if (typeof maxSpeed === 'undefined') { maxSpeed = 200; }
  178. if (this.force === 0 && minSpeed === 0)
  179. {
  180. sprite.body.velocity.set(0, 0);
  181. }
  182. else
  183. {
  184. var speed = (maxSpeed - minSpeed) * this.force;
  185. sprite.body.velocity.set(this.deltaX * speed, this.deltaY * speed);
  186. }
  187. return sprite;
  188. };
  189. Phaser.Plugin.VirtualJoystick.prototype.update = function () {
  190. if (this.isDragging && (!this.pointer.isDown || !this.pointer.withinGame))
  191. {
  192. this.stopDrag();
  193. }
  194. };
  195. Phaser.Plugin.VirtualJoystick.prototype.addButton = function (x,y,key,callback, callbackContext, upFrame, downFrame) {
  196. var button = this.game.add.button(x, y,
  197. key, callback, callbackContext, upFrame,upFrame, downFrame,upFrame);
  198. button.anchor.setTo(0.5, 0.5);
  199. //button.scale.setTo(0.8, 0.8);
  200. //button.fixedToCamera = true; //our buttons should stay on the same place 跟下面这种方式可以2选一
  201. this.game.stage.addChild(button);
  202. //this.buttons.push(button);
  203. return button;
  204. };
  205. Phaser.Plugin.VirtualJoystick.prototype.addButtonByKey = function (key,callback,callbackContext) {
  206. if(key=="buttonA"){
  207. if (this.buttonA){
  208. return this.buttonA;
  209. }
  210. var x=this.game.stage.width-this.game.stage.width/3;
  211. var y=this.game.stage.height-this.game.stage.height/5;
  212. var upFrame='button1-up';
  213. var downFrame='button1-down';
  214. this.buttonA = this.game.add.button(x, y,
  215. "generic", callback, callbackContext, upFrame,upFrame, downFrame,upFrame);
  216. this.buttonA.onInputDown.add(callback, callbackContext);
  217. this.buttonA.anchor.setTo(0.5, 0.5);
  218. this.game.stage.addChild(this.buttonA);
  219. return this.buttonA;
  220. }else if(key=="buttonB"){
  221. if (this.buttonB){
  222. return this.buttonB;
  223. }
  224. var x=this.game.stage.width-this.game.stage.width/4;
  225. var y=this.game.stage.height-this.game.stage.height/3;
  226. var upFrame='button2-up';
  227. var downFrame='button2-down';
  228. this.buttonB = this.game.add.button(x, y,
  229. "generic", callback, callbackContext, upFrame,upFrame, downFrame,upFrame);
  230. this.buttonB.anchor.setTo(0.5, 0.5);
  231. this.game.stage.addChild(this.buttonB);
  232. return this.buttonB;
  233. }else if(key=="buttonC"){
  234. if (this.buttonC){
  235. return this.buttonC;
  236. }
  237. var x=this.game.stage.width-this.game.stage.width/6;
  238. var y=this.game.stage.height-this.game.stage.height/5;
  239. var upFrame='button3-up';
  240. var downFrame='button3-down';
  241. this.buttonC = this.game.add.button(x, y,
  242. "generic", callback, callbackContext, upFrame,upFrame, downFrame,upFrame);
  243. this.buttonC.anchor.setTo(0.5, 0.5);
  244. this.game.stage.addChild(this.buttonC);
  245. return this.buttonC;
  246. }
  247. };