mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Made draggableruntimeautomatism.js working with multitouch and added tests for it
This commit is contained in:
@@ -15,6 +15,9 @@ gdjs.DraggableRuntimeAutomatism = function(runtimeScene, automatismData, owner)
|
||||
gdjs.RuntimeAutomatism.call(this, runtimeScene, automatismData, owner);
|
||||
|
||||
this._dragged = false;
|
||||
this._touchId = null;
|
||||
this._mouse = false;
|
||||
|
||||
this._xOffset = 0;
|
||||
this._yOffset = 0;
|
||||
};
|
||||
@@ -23,46 +26,111 @@ gdjs.DraggableRuntimeAutomatism.prototype = Object.create( gdjs.RuntimeAutomatis
|
||||
gdjs.DraggableRuntimeAutomatism.thisIsARuntimeAutomatismConstructor = "DraggableAutomatism::Draggable";
|
||||
|
||||
gdjs.DraggableRuntimeAutomatism.prototype.onDeActivate = function() {
|
||||
if ( this._dragged ) gdjs.DraggableRuntimeAutomatism.draggingSomething = false;
|
||||
this._dragged = false;
|
||||
this._endDrag();
|
||||
};
|
||||
|
||||
gdjs.DraggableRuntimeAutomatism.prototype.doStepPreEvents = function(runtimeScene) {
|
||||
var mousePos = null;
|
||||
gdjs.DraggableRuntimeAutomatism.prototype._endDrag = function() {
|
||||
if ( this._dragged && this._mouse ) gdjs.DraggableRuntimeAutomatism.mouseDraggingSomething = false;
|
||||
if ( this._dragged && this._touchId !== null ) gdjs.DraggableRuntimeAutomatism.touchDraggingSomething[this._touchId] = false;
|
||||
|
||||
//Begin drag ?
|
||||
if ( !this._dragged && runtimeScene.getGame().getInputManager().isMouseButtonPressed(0) &&
|
||||
this._dragged = false;
|
||||
this._mouse = false;
|
||||
this._touchId = null;
|
||||
}
|
||||
|
||||
gdjs.DraggableRuntimeAutomatism.prototype._tryBeginDrag = function(runtimeScene) {
|
||||
if (this._dragged) return false;
|
||||
|
||||
var inputManager = runtimeScene.getGame().getInputManager();
|
||||
|
||||
//Try mouse
|
||||
if (inputManager.isMouseButtonPressed(0) &&
|
||||
!gdjs.DraggableRuntimeAutomatism.leftPressedLastFrame &&
|
||||
!gdjs.DraggableRuntimeAutomatism.draggingSomething ) {
|
||||
!gdjs.DraggableRuntimeAutomatism.mouseDraggingSomething) {
|
||||
|
||||
mousePos = runtimeScene.getLayer(this.owner.getLayer()).convertCoords(
|
||||
runtimeScene.getGame().getInputManager().getMouseX(),
|
||||
runtimeScene.getGame().getInputManager().getMouseY());
|
||||
inputManager.getMouseX(),
|
||||
inputManager.getMouseY());
|
||||
|
||||
if (this.owner.insideObject(mousePos[0], mousePos[1])) {
|
||||
this._dragged = true;
|
||||
gdjs.DraggableRuntimeAutomatism.draggingSomething = true;
|
||||
this._mouse = true;
|
||||
this._xOffset = mousePos[0] - this.owner.getX();
|
||||
this._yOffset = mousePos[1] - this.owner.getY();
|
||||
gdjs.DraggableRuntimeAutomatism.mouseDraggingSomething = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
} else { //Try touches
|
||||
var touchIds = inputManager.getStartedTouchIdentifiers();
|
||||
for(var i = 0;i<touchIds.length;++i) {
|
||||
if (gdjs.DraggableRuntimeAutomatism.touchDraggingSomething[touchIds[i]])
|
||||
continue;
|
||||
|
||||
touchPos = runtimeScene.getLayer(this.owner.getLayer()).convertCoords(
|
||||
inputManager.getTouchX(touchIds[i]),
|
||||
inputManager.getTouchY(touchIds[i]));
|
||||
|
||||
if (this.owner.insideObject(touchPos[0], touchPos[1])) {
|
||||
this._dragged = true;
|
||||
this._touchId = touchIds[i];
|
||||
this._xOffset = touchPos[0] - this.owner.getX();
|
||||
this._yOffset = touchPos[1] - this.owner.getY();
|
||||
gdjs.DraggableRuntimeAutomatism.touchDraggingSomething[touchIds[i]] = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
//End dragging ?
|
||||
else if ( !runtimeScene.getGame().getInputManager().isMouseButtonPressed(0) ) {
|
||||
this._dragged = false;
|
||||
gdjs.DraggableRuntimeAutomatism.draggingSomething = false;
|
||||
}
|
||||
|
||||
//Being dragging ?
|
||||
if ( this._dragged ) {
|
||||
if ( mousePos === null ) {
|
||||
mousePos = runtimeScene.getLayer(this.owner.getLayer()).convertCoords(
|
||||
runtimeScene.getGame().getInputManager().getMouseX(),
|
||||
runtimeScene.getGame().getInputManager().getMouseY());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
gdjs.DraggableRuntimeAutomatism.prototype._shouldEndDrag = function(runtimeScene) {
|
||||
if (!this._dragged) return false;
|
||||
var inputManager = runtimeScene.getGame().getInputManager();
|
||||
|
||||
if (this._mouse)
|
||||
return !inputManager.isMouseButtonPressed(0);
|
||||
else if (this._touchId !== null) {
|
||||
return inputManager.getAllTouchIdentifiers().indexOf(this._touchId) === -1;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
gdjs.DraggableRuntimeAutomatism.prototype._updateObjectPosition = function(runtimeScene) {
|
||||
if (!this._dragged) return false;
|
||||
var inputManager = runtimeScene.getGame().getInputManager();
|
||||
|
||||
if (this._mouse) {
|
||||
mousePos = runtimeScene.getLayer(this.owner.getLayer()).convertCoords(
|
||||
inputManager.getMouseX(),
|
||||
inputManager.getMouseY());
|
||||
|
||||
this.owner.setX(mousePos[0] - this._xOffset);
|
||||
this.owner.setY(mousePos[1] - this._yOffset);
|
||||
}
|
||||
else if (this._touchId !== null) {
|
||||
touchPos = runtimeScene.getLayer(this.owner.getLayer()).convertCoords(
|
||||
inputManager.getTouchX(this._touchId),
|
||||
inputManager.getTouchY(this._touchId));
|
||||
|
||||
this.owner.setX(touchPos[0] - this._xOffset);
|
||||
this.owner.setY(touchPos[1] - this._yOffset);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
gdjs.DraggableRuntimeAutomatism.prototype.doStepPreEvents = function(runtimeScene) {
|
||||
this._tryBeginDrag(runtimeScene);
|
||||
|
||||
if (this._shouldEndDrag(runtimeScene)) {
|
||||
this._endDrag();
|
||||
}
|
||||
|
||||
this._updateObjectPosition(runtimeScene);
|
||||
};
|
||||
|
||||
gdjs.DraggableRuntimeAutomatism.prototype.doStepPostEvents = function(runtimeScene) {
|
||||
@@ -75,7 +143,10 @@ gdjs.DraggableRuntimeAutomatism.prototype.isDragged = function(runtimeScene) {
|
||||
};
|
||||
|
||||
//Static property used to avoid start dragging an object while another is dragged.
|
||||
gdjs.DraggableRuntimeAutomatism.draggingSomething = false;
|
||||
gdjs.DraggableRuntimeAutomatism.mouseDraggingSomething = false;
|
||||
|
||||
//Static property used to avoid start dragging an object while another is dragged by the same touch.
|
||||
gdjs.DraggableRuntimeAutomatism.touchDraggingSomething = [];
|
||||
|
||||
//Static property used to only start dragging when clicking.
|
||||
gdjs.DraggableRuntimeAutomatism.leftPressedLastFrame = false;
|
||||
|
@@ -0,0 +1,117 @@
|
||||
|
||||
describe('gdjs.DraggableRuntimeAutomatism', function() {
|
||||
var runtimeGame = new gdjs.RuntimeGame({variables: [], properties: {windowWidth: 800, windowHeight: 600}});
|
||||
var runtimeScene = new gdjs.RuntimeScene(runtimeGame, null);
|
||||
runtimeScene.loadFromScene({
|
||||
layers:[{name:"", visibility: true}],
|
||||
variables: [],
|
||||
automatismsSharedData: [],
|
||||
objects: [],
|
||||
instances: []
|
||||
});
|
||||
|
||||
var object = new gdjs.RuntimeObject(runtimeScene, {name: "obj1", type: "", automatisms: [{type: "DraggableAutomatism::Draggable"}]});
|
||||
var object2 = new gdjs.RuntimeObject(runtimeScene, {name: "obj1", type: "", automatisms: [{type: "DraggableAutomatism::Draggable"}]});
|
||||
runtimeScene.addObject(object);
|
||||
runtimeScene.addObject(object2);
|
||||
|
||||
it('should handle mouse', function() {
|
||||
object.setPosition(450, 500);
|
||||
|
||||
//Drag'n'drop
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeGame.getInputManager().onMouseMove(450, 500);
|
||||
runtimeGame.getInputManager().onMouseButtonPressed(0);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeGame.getInputManager().onMouseMove(750, 600);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeGame.getInputManager().onMouseButtonReleased(0);
|
||||
runtimeScene.renderAndStep();
|
||||
|
||||
expect(object.getX()).to.be(750);
|
||||
expect(object.getY()).to.be(600);
|
||||
|
||||
//Mouse move with dragging
|
||||
runtimeGame.getInputManager().onMouseMove(600, 600);
|
||||
runtimeScene.renderAndStep();
|
||||
|
||||
expect(object.getX()).to.be(750);
|
||||
expect(object.getY()).to.be(600);
|
||||
|
||||
//Start dragging again
|
||||
runtimeGame.getInputManager().onMouseMove(750, 600);
|
||||
runtimeGame.getInputManager().onMouseButtonPressed(0);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeGame.getInputManager().onMouseMove(850, 700);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeGame.getInputManager().onMouseButtonReleased(0);
|
||||
runtimeScene.renderAndStep();
|
||||
|
||||
expect(object.getX()).to.be(850);
|
||||
expect(object.getY()).to.be(700);
|
||||
|
||||
});
|
||||
it('should handle touches', function() {
|
||||
object.setPosition(450, 500);
|
||||
|
||||
//Drag'n'drop
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeGame.getInputManager().onTouchStart(1, 10, 20);
|
||||
runtimeGame.getInputManager().onTouchStart(0, 450, 500);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
runtimeGame.getInputManager().onTouchMove(0, 750, 600);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
runtimeGame.getInputManager().onTouchEnd(0);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
|
||||
expect(object.getX()).to.be(750);
|
||||
expect(object.getY()).to.be(600);
|
||||
|
||||
//Move another unrelated touch
|
||||
runtimeGame.getInputManager().onTouchMove(1, 750, 600);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeGame.getInputManager().onTouchMove(1, 850, 700);
|
||||
runtimeScene.renderAndStep();
|
||||
|
||||
expect(object.getX()).to.be(750);
|
||||
expect(object.getY()).to.be(600);
|
||||
|
||||
//Start drag'n'drop with another touch
|
||||
runtimeGame.getInputManager().onTouchEnd(1);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeGame.getInputManager().onTouchStart(1, 750, 600);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeGame.getInputManager().onTouchMove(1, 850, 700);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeGame.getInputManager().onTouchEnd(1);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
|
||||
expect(object.getX()).to.be(850);
|
||||
expect(object.getY()).to.be(700);
|
||||
});
|
||||
it('should handle multitouch', function() {
|
||||
object.setPosition(450, 500);
|
||||
object2.setPosition(650, 600);
|
||||
|
||||
//Drag'n'drop
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeGame.getInputManager().onTouchStart(2, 450, 500);
|
||||
runtimeGame.getInputManager().onTouchStart(1, 650, 600);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
runtimeGame.getInputManager().onTouchMove(2, 750, 700);
|
||||
runtimeGame.getInputManager().onTouchMove(1, 100, 200);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
runtimeGame.getInputManager().onTouchEnd(2);
|
||||
|
||||
expect(object.getX()).to.be(750);
|
||||
expect(object.getY()).to.be(700);
|
||||
expect(object2.getX()).to.be(100);
|
||||
expect(object2.getY()).to.be(200);
|
||||
});
|
||||
});
|
@@ -191,7 +191,12 @@ gdjs.InputManager.prototype.getTouchY = function(identifier) {
|
||||
* @method getAllTouchIdentifiers
|
||||
*/
|
||||
gdjs.InputManager.prototype.getAllTouchIdentifiers = function() {
|
||||
return this._touches.keys();
|
||||
var touchIds = this._touches.keys();
|
||||
for(var i = 0;i<touchIds.length;++i) {
|
||||
touchIds[i] = parseInt(touchIds[i], 10);
|
||||
}
|
||||
|
||||
return touchIds;
|
||||
};
|
||||
|
||||
gdjs.InputManager.prototype.onTouchStart = function(identifier, x, y) {
|
||||
@@ -212,6 +217,10 @@ gdjs.InputManager.prototype.onTouchEnd = function(identifier, x, y) {
|
||||
this._touches.remove(identifier);
|
||||
};
|
||||
|
||||
gdjs.InputManager.prototype.getStartedTouchIdentifiers = function() {
|
||||
return this._startedTouches;
|
||||
}
|
||||
|
||||
gdjs.InputManager.prototype.popStartedTouch = function() {
|
||||
return this._startedTouches.shift();
|
||||
}
|
||||
|
@@ -127,7 +127,11 @@ gdjs.RuntimeScene.prototype.loadFromScene = function(sceneData) {
|
||||
|
||||
//Set up the function to be executed at each tick
|
||||
var module = gdjs[sceneData.mangledName+"Code"];
|
||||
if ( module && module.func ) this._eventsFunction = module.func;
|
||||
if ( module && module.func )
|
||||
this._eventsFunction = module.func;
|
||||
else
|
||||
this._eventsFunction = (function() {});
|
||||
|
||||
this._eventsContext = new gdjs.EventsContext();
|
||||
|
||||
//Call global callback
|
||||
@@ -211,7 +215,9 @@ gdjs.RuntimeScene.prototype.renderAndStep = function() {
|
||||
* Render the PIXI stage associated to the runtimeScene.
|
||||
* @method render
|
||||
*/
|
||||
gdjs.RuntimeScene.prototype.render = function(){
|
||||
gdjs.RuntimeScene.prototype.render = function() {
|
||||
if (!this._pixiRenderer) return;
|
||||
|
||||
// render the PIXI stage
|
||||
this._pixiRenderer.render(this._pixiStage);
|
||||
};
|
||||
|
@@ -4,6 +4,8 @@ module.exports = function(config) {
|
||||
|
||||
files: [
|
||||
'node_modules/expect.js/index.js',
|
||||
|
||||
//GDJS game engine files: (Order is important)
|
||||
'../Runtime/libs/pixi.js',
|
||||
'../Runtime/libs/jshashtable.js',
|
||||
'../Runtime/gd.js',
|
||||
@@ -34,7 +36,13 @@ module.exports = function(config) {
|
||||
'../Runtime/storagetools.js',
|
||||
'../Runtime/stringtools.js',
|
||||
'../Runtime/windowtools.js',
|
||||
|
||||
//Extensions:
|
||||
'../../Extensions/DraggableAutomatism/draggableruntimeautomatism.js',
|
||||
|
||||
//All tests files:
|
||||
'../../Extensions/**/tests/**.spec.js',
|
||||
'tests/**/*.js'
|
||||
]
|
||||
});
|
||||
};
|
||||
};
|
||||
|
@@ -95,6 +95,7 @@ describe('gdjs.InputManager', function() {
|
||||
it('should handle touch events', function(){
|
||||
inputManager.onTouchStart(46, 510, 610);
|
||||
inputManager.onTouchStart(10, 510, 610);
|
||||
expect(inputManager.getStartedTouchIdentifiers()).to.have.length(2);
|
||||
expect(inputManager.getTouchX(46)).to.be(510);
|
||||
expect(inputManager.getTouchY(46)).to.be(610);
|
||||
|
||||
@@ -104,6 +105,7 @@ describe('gdjs.InputManager', function() {
|
||||
|
||||
inputManager.onFrameEnded();
|
||||
inputManager.onTouchEnd(10);
|
||||
expect(inputManager.getStartedTouchIdentifiers()).to.have.length(0);
|
||||
expect(inputManager.popStartedTouch()).to.be(undefined);
|
||||
expect(inputManager.popEndedTouch()).to.be(10);
|
||||
});
|
||||
|
Reference in New Issue
Block a user