var Class = require('../utils/Class'); var EventEmitter = require('eventemitter3'); var Gamepad = require('./gamepad/GamepadManager'); var Keyboard = require('./keyboard/KeyboardManager'); var Mouse = require('./mouse/MouseManager'); var Pointer = require('./Pointer'); var Rectangle = require('../geom/rectangle/Rectangle'); var Touch = require('./touch/TouchManager'); var TransformMatrix = require('../gameobjects/components/TransformMatrix'); var TransformXY = require('../math/TransformXY'); var InputManager = new Class({ initialize: function InputManager(game, config){ this.game = game; this.canvas; this.config = config; this.enabled = true ; this.events = new EventEmitter(); this.queue = [] ; this.keyboard = new Keyboard(this); this.mouse = new Mouse(this); this.touch = new Touch(this); this.gamepad = new Gamepad(this); this.activePointer = new Pointer(this, 0); this.scale = { x: 1, y: 1} ; this.globalTopOnly = true ; this.ignoreEvents = false ; this.bounds = new Rectangle(); this._tempPoint = { x: 0, y: 0} ; this._tempHitTest = [] ; this._tempMatrix = new TransformMatrix(); game.events.once('boot', this.boot, this); } , boot: function (){ this.canvas = this.game.canvas; this.updateBounds(); this.keyboard.boot(); this.mouse.boot(); this.touch.boot(); this.gamepad.boot(); this.game.events.on('prestep', this.update, this); this.game.events.once('destroy', this.destroy, this); } , updateBounds: function (){ var bounds = this.bounds; var clientRect = this.canvas.getBoundingClientRect(); bounds.x = clientRect.left + window.pageXOffset - document.documentElement.clientLeft; bounds.y = clientRect.top + window.pageYOffset - document.documentElement.clientTop; bounds.width = clientRect.width; bounds.height = clientRect.height; } , resize: function (){ this.updateBounds(); var gw = this.game.config.width; var gh = this.game.config.height; var bw = this.bounds.width; var bh = this.bounds.height; this.scale.x = gw / bw; this.scale.y = gh / bh; } , update: function (time){ this.keyboard.update(); this.gamepad.update(); this.ignoreEvents = false ; var len = _AN_Read_length('length', this.queue); var pointer = this.activePointer; pointer.reset(); if (!this.enabled || len === 0) { return ; } this.updateBounds(); this.scale.x = this.game.config.width / this.bounds.width; this.scale.y = this.game.config.height / this.bounds.height; var queue = this.queue.splice(0, len); for (var i = 0; i < len; i++ ){ var event = queue[i]; switch (event.type){ case 'mousemove': pointer.move(event, time); break ; case 'mousedown': pointer.down(event, time); break ; case 'mouseup': pointer.up(event, time); break ; case 'touchmove': pointer.touchmove(event, time); break ; case 'touchstart': pointer.touchstart(event, time); break ; case 'touchend': pointer.touchend(event, time); break ; case 'pointerlockchange': this.events.emit('pointerlockchange', event, this.mouse.locked); break ; } } } , hitTest: function (x, y, gameObjects, camera, output){ if (output === undefined) { output = this._tempHitTest; } var tempPoint = this._tempPoint; var cameraW = camera.width; var cameraH = camera.height; output.length = 0; if (!(x >= camera.x && y >= camera.y && x <= camera.x + cameraW && y <= camera.y + cameraH)) { return output; } camera.getWorldPoint(x, y, tempPoint); var culledGameObjects = camera.cull(gameObjects); var point = { x: 0, y: 0} ; var res = this.game.config.resolution; var matrix = this._tempMatrix; for (var i = 0; i < (_AN_Read_length('length', culledGameObjects)); i++ ){ var gameObject = culledGameObjects[i]; if (!gameObject.input || !gameObject.input.enabled || !gameObject.willRender()) { continue ; } var px = tempPoint.x * res + (camera.scrollX * gameObject.scrollFactorX) - camera.scrollX; var py = tempPoint.y * res + (camera.scrollY * gameObject.scrollFactorY) - camera.scrollY; if (gameObject.parentContainer) { gameObject.getWorldTransformMatrix(matrix); TransformXY(px, py, matrix.tx, matrix.ty, matrix.rotation, matrix.scaleX, matrix.scaleY, point); } else { TransformXY(px, py, gameObject.x, gameObject.y, gameObject.rotation, gameObject.scaleX, gameObject.scaleY, point); } if (this.pointWithinHitArea(gameObject, point.x, point.y)) { output.push(gameObject); } } return output; } , pointWithinHitArea: function (gameObject, x, y){ var input = gameObject.input; x += gameObject.displayOriginX; y += gameObject.displayOriginY; if (input.hitAreaCallback(input.hitArea, x, y, gameObject)) { input.localX = x; input.localY = y; return true ; } else { return false ; } } , pointWithinInteractiveObject: function (object, x, y){ if (!object.hitArea) { return false ; } x += object.gameObject.displayOriginX; y += object.gameObject.displayOriginY; object.localX = x; object.localY = y; return object.hitAreaCallback(object.hitArea, x, y, object); } , transformX: function (pageX){ return (pageX - this.bounds.left) * this.scale.x; } , transformY: function (pageY){ return (pageY - this.bounds.top) * this.scale.y; } , getOffsetX: function (){ return this.bounds.left; } , getOffsetY: function (){ return this.bounds.top; } , getScaleX: function (){ return this.game.config.width / this.bounds.width; } , getScaleY: function (){ return this.game.config.height / this.bounds.height; } , destroy: function (){ this.events.removeAllListeners(); this.keyboard.destroy(); this.mouse.destroy(); this.touch.destroy(); this.gamepad.destroy(); this.activePointer.destroy(); this.queue = [] ; this.game = null ; } } ); module.exports = InputManager;