PageSourceSearch

http://a-varun.github.io/2048_2pl/2048_files/keyboard_input_manager.js

js a-varun.github.io collected 2026-10-03 08:31:58 UTC 4,321 bytes, 153 lines download raw bytes

1function KeyboardInputManager() {
2  this.events = {};
3
4  if (window.navigator.msPointerEnabled) {
5    //Internet Explorer 10 style
6    this.eventTouchstart    = "MSPointerDown";
7    this.eventTouchmove     = "MSPointerMove";
8    this.eventTouchend      = "MSPointerUp";
9  } else {
10    this.eventTouchstart    = "touchstart";
11    this.eventTouchmove     = "touchmove";
12    this.eventTouchend      = "touchend";
13  }
14
15  this.listen();
16}
17
18KeyboardInputManager.prototype.on = function (event, callback) {
19  if (!this.events[event]) {
20    this.events[event] = [];
21  }
22  this.events[event].push(callback);
23};
24
25KeyboardInputManager.prototype.emit = function (event, data) {
26  var callbacks = this.events[event];
27  if (callbacks) {
28    callbacks.forEach(function (callback) {
29      callback(data);
30    });
31  }
32};
33
34KeyboardInputManager.prototype.listen = function () {
35  var self = this;
36
37  var map = {
38    38: 0, // Up
39    39: 1, // Right
40    40: 2, // Down
41    37: 3, // Left
42    75: 0, // Vim up
43    76: 1, // Vim right
44    74: 2, // Vim down
45    72: 3, // Vim left
46    87: 0, // W
47    68: 1, // D
48    83: 2, // S
49    65: 3  // A
50  };
51
52  // Respond to direction keys
53  document.addEventListener("keydown", function (event) {
54    var modifiers = event.altKey || event.ctrlKey || event.metaKey ||
55                    event.shiftKey;
56    var mapped    = map[event.which];
57
58    // Ignore the event if it's happening in a text field
59    if (self.targetIsInput(event)) return;
60
61    if (!modifiers) {
62      if (mapped !== undefined) {
63        event.preventDefault();
64        self.emit("move", mapped);
65      }
66    }
67
68    // R key restarts the game
69    if (!modifiers && event.which === 82) {
70      self.restart.call(self, event);
71    }
72  });
73
74  // Respond to button presses
75  this.bindButtonPress(".retry-button", this.restart);
76  this.bindButtonPress(".restart-button", this.restart);
77  this.bindButtonPress(".keep-playing-button", this.keepPlaying);
78
79  // Respond to swipe events
80  var touchStartClientX, touchStartClientY;
81  var gameContainer = document.getElementsByClassName("game-container")[0];
82
83  gameContainer.addEventListener(this.eventTouchstart, function (event) {
84    if ((!window.navigator.msPointerEnabled && event.touches.length > 1) ||
85        event.targetTouches > 1 ||
86        self.targetIsInput(event)) {
87      return; // Ignore if touching with more than 1 finger or touching input
88    }
89
90    if (window.navigator.msPointerEnabled) {
91      touchStartClientX = event.pageX;
92      touchStartClientY = event.pageY;
93    } else {
94      touchStartClientX = event.touches[0].clientX;
95      touchStartClientY = event.touches[0].clientY;
96    }
97
98    event.preventDefault();
99  });
100
101  gameContainer.addEventListener(this.eventTouchmove, function (event) {
102    event.preventDefault();
103  });
104
105  gameContainer.addEventListener(this.eventTouchend, function (event) {
106    if ((!window.navigator.msPointerEnabled && event.touches.length > 0) ||
107        event.targetTouches > 0 ||
108        self.targetIsInput(event)) {
109      return; // Ignore if still touching with one or more fingers or input
110    }
111
112    var touchEndClientX, touchEndClientY;
113
114    if (window.navigator.msPointerEnabled) {
115      touchEndClientX = event.pageX;
116      touchEndClientY = event.pageY;
117    } else {
118      touchEndClientX = event.changedTouches[0].clientX;
119      touchEndClientY = event.changedTouches[0].clientY;
120    }
121
122    var dx = touchEndClientX - touchStartClientX;
123    var absDx = Math.abs(dx);
124
125    var dy = touchEndClientY - touchStartClientY;
126    var absDy = Math.abs(dy);
127
128    if (Math.max(absDx, absDy) > 10) {
129      // (right : left) : (down : up)
130      self.emit("move", absDx > absDy ? (dx > 0 ? 1 : 3) : (dy > 0 ? 2 : 0));
131    }
132  });
133};
134
135KeyboardInputManager.prototype.restart = function (event) {
136  event.preventDefault();
137  this.emit("restart");
138};
139
140KeyboardInputManager.prototype.keepPlaying = function (event) {
141  event.preventDefault();
142  this.emit("keepPlaying");
143};
144
145KeyboardInputManager.prototype.bindButtonPress = function (selector, fn) {
146  var button = document.querySelector(selector);
147  button.addEventListener("click", fn.bind(this));
148  button.addEventListener(this.eventTouchend, fn.bind(this));
149};
150
151KeyboardInputManager.prototype.targetIsInput = function (event) {
152  return event.target.tagName.toLowerCase() === "input";
153};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.