OLD | NEW |
---|---|
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 (function() { | 4 (function() { |
5 'use strict'; | 5 'use strict'; |
6 /** | 6 /** |
7 * T-Rex runner. | 7 * T-Rex runner. |
8 * @param {string} outerContainerId Outer containing element id. | 8 * @param {string} outerContainerId Outer containing element id. |
9 * @param {Object} opt_config | 9 * @param {Object} opt_config |
10 * @constructor | 10 * @constructor |
11 * @export | 11 * @export |
12 */ | 12 */ |
13 function Runner(outerContainerId, opt_config) { | 13 function Runner(outerContainerId, opt_config) { |
14 // Singleton | 14 // Singleton |
15 if (Runner.instance_) { | 15 if (Runner.instance_) { |
16 return Runner.instance_; | 16 return Runner.instance_; |
17 } | 17 } |
18 Runner.instance_ = this; | 18 Runner.instance_ = this; |
19 | 19 |
20 this.outerContainerEl = document.querySelector(outerContainerId); | 20 this.outerContainerEl = document.querySelector(outerContainerId); |
21 this.containerEl = null; | 21 this.containerEl = null; |
22 this.snackbarEl = null; | 22 this.snackbarEl = null; |
23 | 23 |
24 this.config = opt_config || Runner.config; | 24 this.config = opt_config || Runner.config; |
25 | 25 |
26 this.dimensions = Runner.defaultDimensions; | 26 this.dimensions = Runner.defaultDimensions; |
mmenke
2017/07/05 18:51:29
I guess these are now logical dimensions, as oppos
edwardjung
2017/07/06 19:33:20
Done.
| |
27 | 27 |
28 this.canvas = null; | 28 this.canvas = null; |
29 this.canvasCtx = null; | 29 this.canvasCtx = null; |
30 | 30 |
31 this.tRex = null; | 31 this.tRex = null; |
32 | 32 |
33 this.distanceMeter = null; | 33 this.distanceMeter = null; |
34 this.distanceRan = 0; | 34 this.distanceRan = 0; |
35 | 35 |
36 this.highestScore = 0; | 36 this.highestScore = 0; |
(...skipping 52 matching lines...) Loading... | |
89 | 89 |
90 /** @const */ | 90 /** @const */ |
91 var IS_IOS = /iPad|iPhone|iPod/.test(window.navigator.platform); | 91 var IS_IOS = /iPad|iPhone|iPod/.test(window.navigator.platform); |
92 | 92 |
93 /** @const */ | 93 /** @const */ |
94 var IS_MOBILE = /Android/.test(window.navigator.userAgent) || IS_IOS; | 94 var IS_MOBILE = /Android/.test(window.navigator.userAgent) || IS_IOS; |
95 | 95 |
96 /** @const */ | 96 /** @const */ |
97 var IS_TOUCH_ENABLED = 'ontouchstart' in window; | 97 var IS_TOUCH_ENABLED = 'ontouchstart' in window; |
98 | 98 |
99 /** @const */ | |
100 var ARCADE_MODE_URL = 'chrome://dino/'; | |
101 | |
99 /** | 102 /** |
100 * Default game configuration. | 103 * Default game configuration. |
101 * @enum {number} | 104 * @enum {number} |
102 */ | 105 */ |
103 Runner.config = { | 106 Runner.config = { |
104 ACCELERATION: 0.001, | 107 ACCELERATION: 0.001, |
105 BG_CLOUD_SPEED: 0.2, | 108 BG_CLOUD_SPEED: 0.2, |
106 BOTTOM_PAD: 10, | 109 BOTTOM_PAD: 10, |
107 CLEAR_TIME: 3000, | 110 CLEAR_TIME: 3000, |
108 CLOUD_FREQUENCY: 0.5, | 111 CLOUD_FREQUENCY: 0.5, |
109 GAMEOVER_CLEAR_TIME: 750, | 112 GAMEOVER_CLEAR_TIME: 750, |
110 GAP_COEFFICIENT: 0.6, | 113 GAP_COEFFICIENT: 0.6, |
111 GRAVITY: 0.6, | 114 GRAVITY: 0.6, |
112 INITIAL_JUMP_VELOCITY: 12, | 115 INITIAL_JUMP_VELOCITY: 12, |
113 INVERT_FADE_DURATION: 12000, | 116 INVERT_FADE_DURATION: 12000, |
114 INVERT_DISTANCE: 700, | 117 INVERT_DISTANCE: 700, |
115 MAX_BLINK_COUNT: 3, | 118 MAX_BLINK_COUNT: 3, |
116 MAX_CLOUDS: 6, | 119 MAX_CLOUDS: 6, |
117 MAX_OBSTACLE_LENGTH: 3, | 120 MAX_OBSTACLE_LENGTH: 3, |
118 MAX_OBSTACLE_DUPLICATION: 2, | 121 MAX_OBSTACLE_DUPLICATION: 2, |
119 MAX_SPEED: 13, | 122 MAX_SPEED: 13, |
120 MIN_JUMP_HEIGHT: 35, | 123 MIN_JUMP_HEIGHT: 35, |
121 MOBILE_SPEED_COEFFICIENT: 1.2, | 124 MOBILE_SPEED_COEFFICIENT: 1.2, |
122 RESOURCE_TEMPLATE_ID: 'audio-resources', | 125 RESOURCE_TEMPLATE_ID: 'audio-resources', |
123 SPEED: 6, | 126 SPEED: 6, |
124 SPEED_DROP_COEFFICIENT: 3 | 127 SPEED_DROP_COEFFICIENT: 3, |
128 TOP_MARGIN: 35, | |
129 TOP_POSITION_WEIGHT: 10 | |
mmenke
2017/07/05 18:51:29
Should document these, and name them so it's clear
edwardjung
2017/07/06 19:33:19
Done.
| |
125 }; | 130 }; |
126 | 131 |
127 | 132 |
128 /** | 133 /** |
129 * Default dimensions. | 134 * Default dimensions. |
130 * @enum {string} | 135 * @enum {string} |
131 */ | 136 */ |
132 Runner.defaultDimensions = { | 137 Runner.defaultDimensions = { |
133 WIDTH: DEFAULT_WIDTH, | 138 WIDTH: DEFAULT_WIDTH, |
134 HEIGHT: 150 | 139 HEIGHT: 150 |
135 }; | 140 }; |
136 | 141 |
137 | 142 |
138 /** | 143 /** |
139 * CSS class names. | 144 * CSS class names. |
140 * @enum {string} | 145 * @enum {string} |
141 */ | 146 */ |
142 Runner.classes = { | 147 Runner.classes = { |
148 ARCADE_MODE: 'arcade-mode', | |
143 CANVAS: 'runner-canvas', | 149 CANVAS: 'runner-canvas', |
144 CONTAINER: 'runner-container', | 150 CONTAINER: 'runner-container', |
145 CRASHED: 'crashed', | 151 CRASHED: 'crashed', |
146 ICON: 'icon-offline', | 152 ICON: 'icon-offline', |
147 INVERTED: 'inverted', | 153 INVERTED: 'inverted', |
148 SNACKBAR: 'snackbar', | 154 SNACKBAR: 'snackbar', |
149 SNACKBAR_SHOW: 'snackbar-show', | 155 SNACKBAR_SHOW: 'snackbar-show', |
150 TOUCH_CONTROLLER: 'controller' | 156 TOUCH_CONTROLLER: 'controller' |
151 }; | 157 }; |
152 | 158 |
(...skipping 65 matching lines...) Loading... | |
218 MOUSEUP: 'mouseup', | 224 MOUSEUP: 'mouseup', |
219 RESIZE: 'resize', | 225 RESIZE: 'resize', |
220 TOUCHEND: 'touchend', | 226 TOUCHEND: 'touchend', |
221 TOUCHSTART: 'touchstart', | 227 TOUCHSTART: 'touchstart', |
222 VISIBILITY: 'visibilitychange', | 228 VISIBILITY: 'visibilitychange', |
223 BLUR: 'blur', | 229 BLUR: 'blur', |
224 FOCUS: 'focus', | 230 FOCUS: 'focus', |
225 LOAD: 'load' | 231 LOAD: 'load' |
226 }; | 232 }; |
227 | 233 |
228 | |
229 Runner.prototype = { | 234 Runner.prototype = { |
230 /** | 235 /** |
231 * Whether the easter egg has been disabled. CrOS enterprise enrolled devices. | 236 * Whether the easter egg has been disabled. CrOS enterprise enrolled devices. |
232 * @return {boolean} | 237 * @return {boolean} |
233 */ | 238 */ |
234 isDisabled: function() { | 239 isDisabled: function() { |
235 return loadTimeData && loadTimeData.valueExists('disabledEasterEgg'); | 240 return loadTimeData && loadTimeData.valueExists('disabledEasterEgg'); |
236 }, | 241 }, |
237 | 242 |
238 /** | 243 /** |
(...skipping 172 matching lines...) Loading... | |
411 */ | 416 */ |
412 adjustDimensions: function() { | 417 adjustDimensions: function() { |
413 clearInterval(this.resizeTimerId_); | 418 clearInterval(this.resizeTimerId_); |
414 this.resizeTimerId_ = null; | 419 this.resizeTimerId_ = null; |
415 | 420 |
416 var boxStyles = window.getComputedStyle(this.outerContainerEl); | 421 var boxStyles = window.getComputedStyle(this.outerContainerEl); |
417 var padding = Number(boxStyles.paddingLeft.substr(0, | 422 var padding = Number(boxStyles.paddingLeft.substr(0, |
418 boxStyles.paddingLeft.length - 2)); | 423 boxStyles.paddingLeft.length - 2)); |
419 | 424 |
420 this.dimensions.WIDTH = this.outerContainerEl.offsetWidth - padding * 2; | 425 this.dimensions.WIDTH = this.outerContainerEl.offsetWidth - padding * 2; |
426 if (this.isArcadeMode()) { | |
427 this.dimensions.WIDTH = Math.min(DEFAULT_WIDTH, this.dimensions.WIDTH); | |
428 if (this.activated) { | |
429 this.setContainerScale(); | |
430 } | |
431 } | |
421 | 432 |
422 // Redraw the elements back onto the canvas. | 433 // Redraw the elements back onto the canvas. |
423 if (this.canvas) { | 434 if (this.canvas) { |
424 this.canvas.width = this.dimensions.WIDTH; | 435 this.canvas.width = this.dimensions.WIDTH; |
425 this.canvas.height = this.dimensions.HEIGHT; | 436 this.canvas.height = this.dimensions.HEIGHT; |
426 | 437 |
427 Runner.updateCanvasScaling(this.canvas); | 438 Runner.updateCanvasScaling(this.canvas); |
428 | 439 |
429 this.distanceMeter.calcXPos(this.dimensions.WIDTH); | 440 this.distanceMeter.calcXPos(this.dimensions.WIDTH); |
430 this.clearCanvas(); | 441 this.clearCanvas(); |
(...skipping 48 matching lines...) Loading... | |
479 } else if (this.crashed) { | 490 } else if (this.crashed) { |
480 this.restart(); | 491 this.restart(); |
481 } | 492 } |
482 }, | 493 }, |
483 | 494 |
484 | 495 |
485 /** | 496 /** |
486 * Update the game status to started. | 497 * Update the game status to started. |
487 */ | 498 */ |
488 startGame: function() { | 499 startGame: function() { |
500 this.setArcadeMode(); | |
489 this.runningTime = 0; | 501 this.runningTime = 0; |
490 this.playingIntro = false; | 502 this.playingIntro = false; |
491 this.tRex.playingIntro = false; | 503 this.tRex.playingIntro = false; |
492 this.containerEl.style.webkitAnimation = ''; | 504 this.containerEl.style.webkitAnimation = ''; |
493 this.playCount++; | 505 this.playCount++; |
494 | 506 |
495 // Handle tabbing off the page. Pause the current game. | 507 // Handle tabbing off the page. Pause the current game. |
496 document.addEventListener(Runner.events.VISIBILITY, | 508 document.addEventListener(Runner.events.VISIBILITY, |
497 this.onVisibilityChange.bind(this)); | 509 this.onVisibilityChange.bind(this)); |
498 | 510 |
(...skipping 320 matching lines...) Loading... | |
819 this.distanceMeter.reset(this.highestScore); | 831 this.distanceMeter.reset(this.highestScore); |
820 this.horizon.reset(); | 832 this.horizon.reset(); |
821 this.tRex.reset(); | 833 this.tRex.reset(); |
822 this.playSound(this.soundFx.BUTTON_PRESS); | 834 this.playSound(this.soundFx.BUTTON_PRESS); |
823 this.invert(true); | 835 this.invert(true); |
824 this.update(); | 836 this.update(); |
825 } | 837 } |
826 }, | 838 }, |
827 | 839 |
828 /** | 840 /** |
841 * Whether the game should go into arcade mode. | |
842 * @return {boolean} | |
843 */ | |
844 isArcadeMode: function() { | |
845 return document.title == ARCADE_MODE_URL; | |
846 }, | |
847 | |
848 /** | |
849 * Hides offline messaging for a fullscreen game only experience. | |
850 */ | |
851 setArcadeMode: function() { | |
852 if (this.isArcadeMode()) { | |
mmenke
2017/07/05 18:51:29
I'd suggest moving this to the callsite, to make i
edwardjung
2017/07/06 19:33:20
Done.
| |
853 document.body.classList.add(Runner.classes.ARCADE_MODE); | |
854 this.setContainerScale(); | |
855 } | |
856 }, | |
857 | |
858 /** | |
859 * Sets the scaling for arcade mode. | |
860 */ | |
861 setContainerScale: function() { | |
mmenke
2017/07/05 18:51:29
setContainerScaleForArcadeMode?
edwardjung
2017/07/06 19:33:19
Changed to: setArcadeModeContainerScale
| |
862 var windowHeight = window.innerHeight; | |
863 var scaleHeight = windowHeight / this.dimensions.HEIGHT; | |
864 var scaleWidth = window.innerWidth / this.dimensions.WIDTH; | |
865 var scale = Math.max(1, Math.min(scaleHeight, scaleWidth)); | |
mmenke
2017/07/05 18:51:29
So does this mean you can see farther if you make
edwardjung
2017/07/06 19:33:19
No, this just scales up the game container in the
| |
866 var position = Math.max(-Runner.config.TOP_MARGIN, (windowHeight - | |
867 (this.dimensions.HEIGHT * scale)) / Runner.config.TOP_POSITION_WEIGHT); | |
mmenke
2017/07/05 18:51:29
So I guess this is figuring out how much extra hei
edwardjung
2017/07/06 19:33:20
Did you mean"
Math.max(-Runner.config.TOP_MARGI
mmenke
2017/07/07 16:28:10
No, I did not - dividing by percents generally mea
edwardjung
2017/07/10 15:17:11
Aaah, got it. Switched to to 0.1.
| |
868 this.containerEl.style.transform = 'scale(' + scale + ') translateY(' + | |
869 position + 'px)'; | |
870 }, | |
871 | |
872 /** | |
829 * Pause the game if the tab is not in focus. | 873 * Pause the game if the tab is not in focus. |
830 */ | 874 */ |
831 onVisibilityChange: function(e) { | 875 onVisibilityChange: function(e) { |
832 if (document.hidden || document.webkitHidden || e.type == 'blur' || | 876 if (document.hidden || document.webkitHidden || e.type == 'blur' || |
833 document.visibilityState != 'visible') { | 877 document.visibilityState != 'visible') { |
834 this.stop(); | 878 this.stop(); |
835 } else if (!this.crashed) { | 879 } else if (!this.crashed) { |
836 this.tRex.reset(); | 880 this.tRex.reset(); |
837 this.play(); | 881 this.play(); |
838 } | 882 } |
(...skipping 1850 matching lines...) Loading... | |
2689 | 2733 |
2690 /** | 2734 /** |
2691 * Add a new cloud to the horizon. | 2735 * Add a new cloud to the horizon. |
2692 */ | 2736 */ |
2693 addCloud: function() { | 2737 addCloud: function() { |
2694 this.clouds.push(new Cloud(this.canvas, this.spritePos.CLOUD, | 2738 this.clouds.push(new Cloud(this.canvas, this.spritePos.CLOUD, |
2695 this.dimensions.WIDTH)); | 2739 this.dimensions.WIDTH)); |
2696 } | 2740 } |
2697 }; | 2741 }; |
2698 })(); | 2742 })(); |
OLD | NEW |