Skip to content

Commit 570e8ac

Browse files
committed
Joystick updates.
1 parent 281e84e commit 570e8ac

4 files changed

Lines changed: 114 additions & 49 deletions

File tree

plugins/VirtualJoystick.js

Lines changed: 72 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -21,33 +21,38 @@ Phaser.Plugin.VirtualJoystick = function (game, parent) {
2121
this.nubCenter;
2222

2323
this.isDragging = false;
24+
25+
this.angle = 0;
2426
this.distance = 0;
27+
this.force = 0;
28+
this.deltaX = 0;
29+
this.deltaY = 0;
30+
this.speed = 0;
2531

2632
};
2733

2834
// Extends the Phaser.Plugin template, setting up values we need
2935
Phaser.Plugin.VirtualJoystick.prototype = Object.create(Phaser.Plugin.prototype);
3036
Phaser.Plugin.VirtualJoystick.prototype.constructor = Phaser.Plugin.VirtualJoystick;
3137

32-
Phaser.Plugin.VirtualJoystick.prototype.init = function (x, y, diameter) {
38+
Phaser.Plugin.VirtualJoystick.prototype.init = function (x, y, diameter, limit) {
3339

3440
if (typeof diameter === 'undefined') { diameter = 80; }
41+
if (typeof limit === 'undefined') { limit = Math.floor(diameter / 2); }
3542

3643
this.x = x;
3744
this.y = y;
3845

3946
var radius = Math.floor(diameter / 2);
40-
41-
this.testCircle = new Phaser.Circle(200, 200, diameter);
42-
this.testPoint = new Phaser.Point();
47+
var nr = radius - 4;
4348

4449
this.baseCircle = new Phaser.Circle(x, y, diameter);
4550

4651
this.baseBMD = this.game.make.bitmapData(diameter, diameter);
47-
this.nubBMD = this.game.make.bitmapData(diameter - 4, diameter - 4);
52+
this.nubBMD = this.game.make.bitmapData(nr * 2, nr * 2);
4853

4954
this.baseBMD.circle(radius, radius, radius, 'rgb(255, 0, 0)');
50-
this.nubBMD.circle(radius, radius, (radius) - 4, 'rgb(0, 255, 0)');
55+
this.nubBMD.circle(nr, nr, nr, 'rgb(0, 255, 0)');
5156

5257
// Base
5358
this.base = this.game.add.sprite(x, y, this.baseBMD);
@@ -62,36 +67,44 @@ Phaser.Plugin.VirtualJoystick.prototype.init = function (x, y, diameter) {
6267
this.nub.events.onInputDown.add(this.startDrag, this);
6368
this.nub.events.onInputUp.add(this.stopDrag, this);
6469

70+
// Need to find a way to not hog this callback
6571
this.game.input.setMoveCallback(this.move, this);
6672

6773
this.isDragging = false;
74+
6875
this.distance = 0;
69-
this.limit = radius;
76+
this.speed = 0;
77+
this.force = 0;
78+
this.limit = limit;
7079
this.limitPoint = new Phaser.Point();
7180

72-
this.m = new Phaser.Point();
73-
74-
75-
this.prev = new Phaser.Point(x, y);
81+
this.location = new Phaser.Point();
7682

7783
}
7884

79-
Phaser.Plugin.VirtualJoystick.prototype.startDrag = function () {
85+
Phaser.Plugin.VirtualJoystick.prototype.startDrag = function (nub, pointer) {
8086

8187
this.isDragging = true;
82-
this.distance = 0;
83-
this.angle = 0;
88+
89+
this.location.set(pointer.x, pointer.y);
90+
this.distance = Phaser.Point.distance(this.base, this.location, true);
91+
this.angle = this.game.math.wrapAngle(this.location.angle(this.base, true) + 180);
92+
this.force = this.game.math.percent(this.distance, this.limit);
8493

8594
};
8695

87-
Phaser.Plugin.VirtualJoystick.prototype.stopDrag = function () {
96+
Phaser.Plugin.VirtualJoystick.prototype.stopDrag = function (nub, pointer) {
8897

8998
this.isDragging = false;
99+
90100
this.distance = 0;
91101
this.angle = 0;
102+
this.force = 0;
103+
92104
this.nub.x = this.base.x;
93105
this.nub.y = this.base.y;
94-
this.prev.set(this.base.x, this.base.y);
106+
107+
this.limitPoint.set(this.base.x, this.base.y);
95108

96109
};
97110

@@ -102,38 +115,54 @@ Phaser.Plugin.VirtualJoystick.prototype.move = function (pointer, x, y) {
102115
return;
103116
}
104117

105-
this.m.set(x, y);
106-
107-
this.distance = Phaser.Point.distance(this.base, this.m, true);
118+
this.location.set(x, y);
108119

109-
this.angle = Phaser.Point.angle(this.base, this.m) * 180 / Math.PI;
110-
this.angle = this.game.math.wrapAngle(this.angle + 180, false);
120+
this.distance = Phaser.Point.distance(this.base, this.location, true);
111121

112-
Phaser.Circle.circumferencePoint(this.testCircle, this.angle, true, this.testPoint);
113-
Phaser.Circle.circumferencePoint(this.baseCircle, this.angle, true, this.limitPoint);
122+
this.angle = this.game.math.wrapAngle(this.location.angle(this.base, true) + 180);
114123

115-
// If the pointer is outside the baseCircle then we don't need to set the sprite like this
124+
this.force = this.game.math.percent(this.distance, this.limit);
116125

117-
if (this.baseCircle.contains(x, y))
126+
if (this.distance < this.limit)
118127
{
119-
this.nub.x = x;
120-
this.nub.y = y;
128+
this.limitPoint.copyFrom(this.location);
121129
}
122130
else
123131
{
124-
// this.nub.position.set(this.limitPoint.x, this.limitPoint.y);
125-
this.nub.x = this.limitPoint.x;
126-
this.nub.y = this.limitPoint.y;
132+
this.baseCircle.circumferencePoint(this.angle, true, this.limitPoint);
127133
}
128134

129-
// if (this.distance < this.limit)
130-
// {
131-
// }
132-
// else
133-
// {
134-
// this.nub.x = this.limitPoint.x;
135-
// this.nub.y = this.limitPoint.y;
136-
// }
135+
this.nub.position.set(this.limitPoint.x, this.limitPoint.y);
136+
137+
};
138+
139+
/**
140+
* Given the speed calculate the velocity and return it as a Point object, or set it to the given point object.
141+
* 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.
142+
*
143+
* @method Phaser.Plugin.VirtualJoystick#setVelocity
144+
* @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.
145+
* @param {number} [minSpeed=0] - The minimum speed the Sprite will move if the joystick is at its default (non-moved) position.
146+
* @param {number} [maxSpeed=100] - The maximum speed the Sprite will move if the joystick is at its full extent.
147+
* @return {Phaser.Sprite} The Sprite object.
148+
*/
149+
Phaser.Plugin.VirtualJoystick.prototype.setVelocity = function (sprite, minSpeed, maxSpeed) {
150+
151+
if (typeof minSpeed === 'undefined') { minSpeed = 0; }
152+
if (typeof maxSpeed === 'undefined') { maxSpeed = 200; }
153+
154+
if (this.force === 0 && minSpeed === 0)
155+
{
156+
sprite.body.velocity.set(0, 0);
157+
}
158+
else
159+
{
160+
var speed = (maxSpeed - minSpeed) * this.force;
161+
162+
sprite.body.velocity.set((Math.cos(this.game.math.degToRad(this.angle)) * speed), (Math.sin(this.game.math.degToRad(this.angle)) * speed));
163+
}
164+
165+
return sprite;
137166

138167
};
139168

@@ -143,15 +172,15 @@ Phaser.Plugin.VirtualJoystick.prototype.update = function () {
143172

144173
Phaser.Plugin.VirtualJoystick.prototype.render = function () {
145174

146-
this.game.debug.text(this.distance, 32, 32);
147-
this.game.debug.text(this.angle, 132, 32);
175+
this.game.debug.text('force: ' + this.force, 32, 32);
176+
// this.game.debug.text(this.distance, 32, 32);
177+
// this.game.debug.text(this.angle, 132, 32);
148178

149-
this.game.debug.text('x: ' + this.m.x + ' y: ' + this.m.y, 32, 64);
179+
// this.game.debug.text('x: ' + this.location.x + ' y: ' + this.location.y, 32, 64);
150180
// this.game.debug.text('x: ' + this.limitPoint.x + ' y: ' + this.limitPoint.y, 32, 64);
151181
// this.game.debug.text('x: ' + this.prev.x + ' y: ' + this.prev.y, 32, 64);
152182
// this.game.debug.text(Phaser.Point.distance(this.base, this.prev, true), 32, 96);
153183

154-
this.game.debug.geom(this.testCircle);
155-
this.game.debug.geom(this.testPoint, 'rgb(255,0,0)');
184+
this.game.debug.geom(this.limitPoint, 'rgb(255,255,0)');
156185

157186
};

src/gameobjects/BitmapData.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -858,9 +858,9 @@ Phaser.BitmapData.prototype = {
858858
* Draws a filled Circle to the BitmapData at the given x, y coordinates and radius in size.
859859
*
860860
* @method Phaser.BitmapData#circle
861-
* @param {number} x - The x coordinate to draw the Circle at.
862-
* @param {number} y - The y coordinate to draw the Circle at.
863-
* @param {number} radius - The radius of the Circle.
861+
* @param {number} x - The x coordinate to draw the Circle at. This is the center of the circle.
862+
* @param {number} y - The y coordinate to draw the Circle at. This is the center of the circle.
863+
* @param {number} radius - The radius of the Circle in pixels. The radius is half the diameter.
864864
* @param {string} [fillStyle] - If set the context fillStyle will be set to this value before the circle is drawn.
865865
*/
866866
circle: function (x, y, radius, fillStyle) {

src/geom/Point.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -283,13 +283,21 @@ Phaser.Point.prototype = {
283283
*
284284
* @method Phaser.Point#angle
285285
* @param {Phaser.Point|any} a - The object to get the angle from this Point to.
286+
* @param {boolean} [asDegrees=false] - Is the given angle in radians (false) or degrees (true)?
286287
* @return {number} The angle between the two objects.
287288
*/
288-
angle: function (a) {
289+
angle: function (a, asDegrees) {
289290

290-
return Math.atan2(a.y - this.y, a.x - this.x);
291+
if (typeof asDegrees === 'undefined') { asDegrees = false; }
291292

292-
// return Math.atan2(this.x * a.y - this.y * a.x, this.x * a.x + this.y * a.y);
293+
if (asDegrees)
294+
{
295+
return Phaser.Math.radToDeg(Math.atan2(a.y - this.y, a.x - this.x));
296+
}
297+
else
298+
{
299+
return Math.atan2(a.y - this.y, a.x - this.x);
300+
}
293301

294302
},
295303

src/math/Math.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,6 +1300,34 @@ Phaser.Math = {
13001300

13011301
},
13021302

1303+
/**
1304+
* Work out what percentage value a is of value b using the given base.
1305+
*
1306+
* @method Phaser.Math#percent
1307+
* @param {number} a - The value to work out the percentage for.
1308+
* @param {number} b - The value you wish to get the percentage of.
1309+
* @param {number} [base=0] - The base value.
1310+
* @return {number} The percentage a is of b, between 0 and 1.
1311+
*/
1312+
percent: function (a, b, base) {
1313+
1314+
if (typeof base === 'undefined') { base = 0; }
1315+
1316+
if (a > b || base > b)
1317+
{
1318+
return 1;
1319+
}
1320+
else if (a < base || base > a)
1321+
{
1322+
return 0;
1323+
}
1324+
else
1325+
{
1326+
return (a - base) / b;
1327+
}
1328+
1329+
},
1330+
13031331
/**
13041332
* Convert degrees to radians.
13051333
*

0 commit comments

Comments
 (0)