define([ 'js/system/client', 'js/misc/physics', 'js/system/events' ], function ( client, physics, events ) { return { type: 'touchMover', lastNode: null, nodes: [], hoverTile: null, minSqrDistance: 1650, init: function () { ['onTouchStart', 'onTouchMove', 'onTouchEnd', 'onTouchCancel'].forEach(e => { this.hookEvent(e, this[e].bind(this)); }); this.obj.on('onShake', this.onShake.bind(this)); }, onTouchStart: function (e) { this.lastNode = e; let tileX = ~~(e.worldX / scale); let tileY = ~~(e.worldY / scale); this.hoverTile = { x: tileX, y: tileY }; events.emit('onChangeHoverTile', tileX, tileY); }, onTouchMove: function (e) { const lastNode = this.lastNode; let sqrDistance = Math.pow(lastNode.x - e.x, 2) + Math.pow(lastNode.y - e.y, 2); if (sqrDistance < this.minSqrDistance) return; let dx = e.x - lastNode.x; let dy = e.y - lastNode.y; if (e.touches > 1) { dx = ~~(dx / Math.abs(dx)); dy = ~~(dy / Math.abs(dy)); } else if (Math.abs(dx) > Math.abs(dy)) { dx = ~~(dx / Math.abs(dx)); dy = 0; } else { dx = 0; dy = ~~(dy / Math.abs(dy)); } this.lastNode = e; let newX = this.obj.pather.pathPos.x + dx; let newY = this.obj.pather.pathPos.y + dy; if (physics.isTileBlocking(~~newX, ~~newY)) { this.bump(dx, dy); return; } this.obj.pather.add(newX, newY); }, onTouchEnd: function (e) { this.lastNode = null; }, onTouchCancel: function () { this.lastNode = null; }, onShake: function () { if (!this.obj.pather.path.length) return; client.request({ cpn: 'player', method: 'queueAction', data: { action: 'clearQueue', priority: true } }); window.navigator.vibrate(150); }, bump: function (dx, dy) { if (this.obj.pather.path.length > 0) return; this.obj.addComponent('bumpAnimation', { deltaX: dx, deltaY: dy }); }, destroy: function () { this.unhookEvents(); } }; });