@smoud/tiny
Version:
Fast and tiny JavaScript library for HTML5 game and playable ads creation.
251 lines (191 loc) • 7.51 kB
JavaScript
import { registerSystem } from './registrar';
import { EventEmitter } from '../utils/EventEmitter';
import { _Math } from '../math/Math';
var listeningToTouchEvents;
var Input = function (game) {
this.game = game;
var view = (this.domElement = game.inputView);
this.bounds = { x: 0, y: 0, width: 0, height: 0 };
this.candidates = [];
this.list = [];
this.lastMove = null;
this.isDown = false;
this.downHandler = this.downHandler.bind(this);
this.moveHandler = this.moveHandler.bind(this);
this.upHandler = this.upHandler.bind(this);
// this.clickHandler.bind(this);
view.addEventListener('touchstart', this.downHandler);
view.addEventListener('touchmove', this.moveHandler);
view.addEventListener('touchend', this.upHandler);
view.addEventListener('touchcancel', this.upHandler);
// view.addEventListener('click', this.clickHandler);
view.addEventListener('mousedown', this.downHandler);
view.addEventListener('mousemove', this.moveHandler);
view.addEventListener('mouseup', this.upHandler);
EventEmitter.mixin(this);
for (var i = 0; i < Input.systems.length; i++) {
Input.systems[i].init.call(this);
}
this.updateBounds();
};
Input.prototype = {
add: function (object, options) {
object.inputEnabled = true;
options = options || {};
options.system = this;
object.input = options;
EventEmitter.mixin(object.input);
this.list.push(object);
},
remove: function (object) {
var index = this.list.indexOf(object);
if (index > -1) {
var removed = this.list[index];
removed.input = null;
removed.inputEnabled = false;
this.list.splice(index, 1);
return removed;
}
},
inputHandler: function (name, event) {
// console.log(name)
var coords = this.getCoords(event);
if (coords !== null) {
if (name != 'move') {
this.candidates.length = 0;
for (var i = 0; i < Input.systems.length; i++) {
Input.systems[i].preHandle.call(this, coords.x, coords.y);
}
var isGood, obj;
for (var t = 0; t < this.list.length; t++) {
obj = this.list[t];
if (!obj.inputEnabled || !obj.parent) continue;
if (obj.input.checkBounds)
isGood = obj.input.checkBounds.call(this, obj, coords.x, coords.y);
else isGood = Input.checkBounds.call(this, obj, coords.x, coords.y);
if (isGood) this.candidates.push(obj);
}
//var i = this.candidates.length
for (var i = this.candidates.length - 1; i >= 0; i--) {
obj = this.candidates[i];
obj.input['last_' + name] = {
x: coords.x,
y: coords.y
};
obj.input.emit(name, {
x: coords.x,
y: coords.y
});
if (name == 'up') {
var point = obj.input['last_down'];
if (point && _Math.distance(point.x, point.y, coords.x, coords.y) < 30)
obj.input.emit('click', {
x: coords.x,
y: coords.y
});
}
if (!obj.input.transparent) {
break;
}
}
// if (i > 0) {
// var obj = this.candidates[i - 1]
// obj.input["last_" + name] = {x: coords.x, y: coords.y}
// obj.input.emit(name, {x: coords.x, y: coords.y})
// if (name == "up") {
// var point = obj.input["last_down"]
// if (point && _Math.distance(point.x, point.y, coords.x, coords.y) < 30)
// obj.input.emit("click", {x: coords.x, y: coords.y})
// }
// }
}
this.emit(name, {
x: coords.x,
y: coords.y
});
}
},
moveHandler: function (event) {
this.lastMove = event;
this.inputHandler('move', event);
},
upHandler: function (event) {
this.isDown = false;
this.inputHandler('up', this.lastMove);
},
downHandler: function (event) {
this.isDown = true;
this.lastMove = event;
this.inputHandler('down', event);
},
clickHandler: function (event) {
this.inputHandler('click', event);
},
getCoords: function (event) {
var coords = null;
if (typeof TouchEvent !== 'undefined' && event instanceof TouchEvent) {
listeningToTouchEvents = true;
if (event.touches.length > 0) {
coords = {
x: event.touches[0].clientX,
y: event.touches[0].clientY
};
} else if (event.clientX && event.clientY) {
coords = {
x: event.clientX,
y: event.clientY
};
} else {
// listeningToTouchEvents = false;
}
} else {
// Mouse event
coords = {
x: event.clientX,
y: event.clientY
};
}
if ((listeningToTouchEvents && event instanceof MouseEvent) || coords === null) return null;
coords = {
x: coords.x - this.bounds.x,
y: coords.y - this.bounds.y
};
return coords;
},
updateBounds: function () {
var bounds = this.bounds;
var clientRect = this.domElement.getBoundingClientRect();
bounds.x = clientRect.left;
bounds.y = clientRect.top;
bounds.width = clientRect.width;
bounds.height = clientRect.height;
},
destroy: function () {
var view = this.domElement;
view.removeEventListener('touchstart', this.downHandler);
view.removeEventListener('touchmove', this.moveHandler);
view.removeEventListener('touchend', this.upHandler);
view.removeEventListener('touchcancel', this.upHandler);
// view.removeEventListener('click', this.clickHandler);
view.removeEventListener('mousedown', this.downHandler);
view.removeEventListener('mousemove', this.moveHandler);
view.removeEventListener('mouseup', this.upHandler);
}
};
Input.checkBounds = function (obj, x, y) {
if (obj.worldVisible) {
if (obj.getBounds().contains(x, y)) {
return true;
}
}
// if (obj.children && obj.children.length > 0)
// {
// for (var t = 0; t < obj.children.length; t++)
// {
// _checkOnActiveObjects(obj.children[t], x, y);
// }
// }
};
Input.systems = [];
registerSystem('input', Input);
export { Input };