├── LICENSE ├── README.md ├── src ├── trex-runner-bot.js ├── trex-runner-bot.min.js ├── trex-runner-break-rule.js ├── trex-runner-break-rule.min.js ├── trex-runner-score-hacking.js └── trex-runner-score-hacking.min.js └── standalone ├── index.html ├── package.json └── t-rex.js /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Uku Pattak 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Chrome Offline page "T-Rex Runner" game bot 2 | 3 | ![TRex](http://i.imgur.com/9oO7aQ9.gif) 4 | 5 | **Are you tired of failing like this?** Try using this bot to show off to Your friends what "mad skills" you have in T-Rex Runner game. 6 | 7 | ## Try it out 8 | 9 | 1. Copy the minified source code, 10 | 2. disconnect from the Internet, 11 | 3. paste the code to the Chrome Dev tools Console and 12 | 4. let the T-Rex run! 13 | 14 | ```javascript 15 | function TrexRunnerBot(){function n(){if(Runner&&Runner().horizon.obstacles[0]){var n=Runner().horizon.obstacles[0];e(n)&&o(n)&&r(n)}}function e(n){return 50!==n.yPos}function o(n){return n.xPos<=18*Runner().currentSpeed}function r(n){u(n)?t():c(n)}function u(n){return 75===n.yPos}function t(){Runner().onKeyDown(R),setTimeout(function(){Runner().onKeyUp(R)},500)}function c(n){i(n)?f():Runner().onKeyDown(s)}function i(n){var e=Runner().horizon.obstacles[1];return e&&e.xPos-n.xPos<=42*Runner().currentSpeed}function f(){Runner().onKeyDown(s),Runner().onKeyUp(s)}var s={keyCode:38},R={keyCode:40,preventDefault:function(){}};return{conquerTheGame:n}}var bot=TrexRunnerBot(),botInterval=setInterval(bot.conquerTheGame,2); 16 | ``` 17 | 18 | ## License 19 | 20 | [MIT](//github.com/ukupat/trex-runner-bot/blob/master/LICENSE) 21 | -------------------------------------------------------------------------------- /src/trex-runner-bot.js: -------------------------------------------------------------------------------- 1 | function TrexRunnerBot() { 2 | 3 | const makeKeyArgs = (keyCode) => { 4 | const preventDefault = () => void 0; 5 | return {keyCode, preventDefault}; 6 | }; 7 | 8 | const upKeyArgs = makeKeyArgs(38); 9 | const downKeyArgs = makeKeyArgs(40); 10 | const startArgs = makeKeyArgs(32); 11 | 12 | if (!Runner().playing) { 13 | Runner().onKeyDown(startArgs); 14 | setTimeout(() => { 15 | Runner().onKeyUp(startArgs); 16 | }, 500); 17 | } 18 | 19 | function conquerTheGame() { 20 | if (!Runner || !Runner().horizon.obstacles[0]) return; 21 | 22 | const obstacle = Runner().horizon.obstacles[0]; 23 | 24 | if (obstacle.typeConfig && obstacle.typeConfig.type === 'SNACK') return; 25 | 26 | if (needsToTackle(obstacle) && closeEnoughToTackle(obstacle)) tackle(obstacle); 27 | } 28 | 29 | function needsToTackle(obstacle) { 30 | return obstacle.yPos !== 50; 31 | } 32 | 33 | function closeEnoughToTackle(obstacle) { 34 | return obstacle.xPos <= Runner().currentSpeed * 18; 35 | } 36 | 37 | function tackle(obstacle) { 38 | if (isDuckable(obstacle)) { 39 | duck(); 40 | } else { 41 | jumpOver(obstacle); 42 | } 43 | } 44 | 45 | function isDuckable(obstacle) { 46 | return obstacle.yPos === 50; 47 | } 48 | 49 | function duck() { 50 | Runner().onKeyDown(downKeyArgs); 51 | 52 | setTimeout(() => { 53 | Runner().onKeyUp(downKeyArgs); 54 | }, 500); 55 | } 56 | 57 | function jumpOver(obstacle) { 58 | if (isNextObstacleCloseTo(obstacle)) 59 | jumpFast(); 60 | else 61 | Runner().onKeyDown(upKeyArgs); 62 | } 63 | 64 | function isNextObstacleCloseTo(currentObstacle) { 65 | const nextObstacle = Runner().horizon.obstacles[1]; 66 | 67 | return nextObstacle && nextObstacle.xPos - currentObstacle.xPos <= Runner().currentSpeed * 42; 68 | } 69 | 70 | function jumpFast() { 71 | Runner().onKeyDown(upKeyArgs); 72 | Runner().onKeyUp(upKeyArgs); 73 | } 74 | 75 | return {conquerTheGame: conquerTheGame}; 76 | } 77 | 78 | let bot = TrexRunnerBot(); 79 | let botInterval = setInterval(bot.conquerTheGame, 2); 80 | -------------------------------------------------------------------------------- /src/trex-runner-bot.min.js: -------------------------------------------------------------------------------- 1 | function TrexRunnerBot(){function f(){Runner().onKeyDown(d);setTimeout(function(){Runner().onKeyUp(d)},500)}var b=function(a){return{keyCode:a,preventDefault:function(){}}},c=b(38),d=b(40),e=b(32);Runner().playing||(Runner().onKeyDown(e),setTimeout(function(){Runner().onKeyUp(e)},500));return{conquerTheGame:function(){if(Runner&&Runner().horizon.obstacles[0]){var a=Runner().horizon.obstacles[0];if((!a.typeConfig||"SNACK"!==a.typeConfig.type)&&50!==a.yPos&&a.xPos<=18*Runner().currentSpeed)if(50=== a.yPos)f();else{var b=Runner().horizon.obstacles[1];if(b&&b.xPos-a.xPos<=42*Runner().currentSpeed)Runner().onKeyDown(c),Runner().onKeyUp(c);else Runner().onKeyDown(c)}}}}}var bot=TrexRunnerBot(),botInterval=setInterval(bot.conquerTheGame,2); -------------------------------------------------------------------------------- /src/trex-runner-break-rule.js: -------------------------------------------------------------------------------- 1 | Runner.instance_.gameOver = () => {}; 2 | -------------------------------------------------------------------------------- /src/trex-runner-break-rule.min.js: -------------------------------------------------------------------------------- 1 | Runner.instance_.gameOver=function(){}; -------------------------------------------------------------------------------- /src/trex-runner-score-hacking.js: -------------------------------------------------------------------------------- 1 | let hackScore = 0; 2 | 3 | Object.defineProperty(Runner.instance_, 'distanceRan', { 4 | get: () => hackScore, 5 | set: (value) => hackScore = value + Math.floor(Math.random() * 1000), 6 | configurable: true, 7 | enumerable: true, 8 | }); -------------------------------------------------------------------------------- /src/trex-runner-score-hacking.min.js: -------------------------------------------------------------------------------- 1 | var hackScore=0;Object.defineProperty(Runner.instance_,"distanceRan",{get:function(){return hackScore},set:function(a){return hackScore=a+Math.floor(1E3*Math.random())},configurable:!0,enumerable:!0}); 2 | -------------------------------------------------------------------------------- /standalone/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | T-REX 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /standalone/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "t-rex-standalone", 3 | "version": "1.2.1", 4 | "description": "", 5 | "main": "t-rex.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC" 11 | } 12 | -------------------------------------------------------------------------------- /standalone/t-rex.js: -------------------------------------------------------------------------------- 1 | !function(A,i){"object"==typeof exports&&"object"==typeof module?module.exports=i():"function"==typeof define&&define.amd?define([],i):"object"==typeof exports?exports.TREX=i():A.TREX=i()}(this,function(){return function(A){function i(s){if(t[s])return t[s].exports;var e=t[s]={exports:{},id:s,loaded:!1};return A[s].call(e.exports,e,e.exports,i),e.loaded=!0,e.exports}var t={};return i.m=A,i.c=t,i.p="",i(0)}([function(A,i,t){function s(A,i){var t="string"==typeof A?document.querySelector(A):A;return t.classList.add("interstitial-wrapper"),new e(t,i)}document.body.insertAdjacentHTML("beforeend",t(3)),t(5);var e=t(6),n=document.getElementById("t-rex"),o=null,h=null;n&&(o=n.getAttribute("container"),o?(h=document.querySelector(o),h&&setTimeout(function(){s(o)},0)):(s("body"),h=document.querySelector(".trex-container"),h.style="position: absolute;z-index: 999;top: 0;")),A.exports=s},function(A,i,t){i=A.exports=t(2)(),i.push([A.id,".interstitial-wrapper{box-sizing:border-box;margin:0 auto;max-width:600px}.trex-container{width:44px}.trex-canvas,.trex-container{height:150px;max-width:600px;overflow:hidden}.trex-canvas{opacity:1;position:relative;z-index:2}.inverted{transition:background-color 1.5s cubic-bezier(.65,.05,.36,1);will-change:-webkit-filter,background-color;-webkit-filter:invert(100%);background-color:#000}.controller{background:hsla(0,0%,97%,.1);height:100vh;left:0;position:absolute;top:0;width:100vw;z-index:1}#offline-resources{display:none}",""])},function(A,i){A.exports=function(){var A=[];return A.toString=function(){for(var A=[],i=0;i=0&&m.splice(i,1)}function h(A){var i=document.createElement("style");return i.type="text/css",n(A,i),i}function a(A){var i=document.createElement("link");return i.rel="stylesheet",n(A,i),i}function r(A,i){var t,s,e;if(i.singleton){var n=C++;t=l||(l=h(i)),s=c.bind(null,t,n,!1),e=c.bind(null,t,n,!0)}else A.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(t=a(i),s=d.bind(null,t),e=function(){o(t),t.href&&URL.revokeObjectURL(t.href)}):(t=h(i),s=g.bind(null,t),e=function(){o(t)});return s(A),function(i){if(i){if(i.css===A.css&&i.media===A.media&&i.sourceMap===A.sourceMap)return;s(A=i)}else e()}}function c(A,i,t,s){var e=t?"":s.css;if(A.styleSheet)A.styleSheet.cssText=f(i,e);else{var n=document.createTextNode(e),o=A.childNodes;o[i]&&A.removeChild(o[i]),o.length?A.insertBefore(n,o[i]):A.appendChild(n)}}function g(A,i){var t=i.css,s=i.media;if(s&&A.setAttribute("media",s),A.styleSheet)A.styleSheet.cssText=t;else{for(;A.firstChild;)A.removeChild(A.firstChild);A.appendChild(document.createTextNode(t))}}function d(A,i){var t=i.css,s=i.sourceMap;s&&(t+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(s))))+" */");var e=new Blob([t],{type:"text/css"}),n=A.href;A.href=URL.createObjectURL(e),n&&URL.revokeObjectURL(n)}var u={},I=function(A){var i;return function(){return"undefined"==typeof i&&(i=A.apply(this,arguments)),i}},p=I(function(){return/msie [6-9]\b/.test(self.navigator.userAgent.toLowerCase())}),E=I(function(){return document.head||document.getElementsByTagName("head")[0]}),l=null,C=0,m=[];A.exports=function(A,i){i=i||{},"undefined"==typeof i.singleton&&(i.singleton=p()), 2 | "undefined"==typeof i.insertAt&&(i.insertAt="bottom");var t=e(A);return s(t,i),function(A){for(var n=[],o=0;o0)return t.actions.DAZE;if("PTERODACTYL"===A.typeConfig.type)switch(h){case 100:return t.actions.JUMP;case 75:return t.actions.DUCK;case 45:return t.actions.DAZE;default:return t.actions.DAZE}else{if("CACTUS_SMALL"===A.typeConfig.type)return e>o?t.actions.JUMP:t.actions.SUPER_JUMP;if("CACTUS_LARGE"===A.typeConfig.type)return e>o?t.actions.JUMP:t.actions.SUPER_JUMP}}function a(A,i,t,s){this.x=A,this.y=i,this.width=t,this.height=s}function r(A,i,t,e,n,o,h){this.canvasCtx=A,this.spritePos=t,this.typeConfig=i,this.gapCoefficient=n,this.size=s(1,r.MAX_OBSTACLE_LENGTH),this.dimensions=e,this.remove=!1,this.xPos=e.WIDTH+(h||0),this.yPos=0,this.width=0,this.collisionBoxes=[],this.gap=0,this.speedOffset=0,this.currentFrame=0,this.timer=0,this.init(o)}function c(A,i){this.canvas=A,this.canvasCtx=A.getContext("2d"),this.spritePos=i,this.xPos=0,this.yPos=0,this.groundYPos=0,this.currentFrame=0,this.currentAnimFrames=[],this.blinkDelay=0,this.animStartTime=0,this.timer=0,this.msPerFrame=1e3/E,this.config=c.config,this.status=c.status.WAITING,this.jumping=!1,this.ducking=!1,this.jumpVelocity=0,this.reachedMinHeight=!1,this.speedDrop=!1,this.jumpCount=0,this.jumpspotX=0,this.init()}function g(A,i,t){this.canvas=A,this.canvasCtx=this.canvas.getContext("2d"),this.spritePos=i,this.containerWidth=t,this.xPos=t,this.yPos=0,this.remove=!1,this.cloudGap=s(g.config.MIN_CLOUD_GAP,g.config.MAX_CLOUD_GAP),this.init()}function d(A,i,t){this.spritePos=i,this.canvas=A,this.canvasCtx=A.getContext("2d"),this.xPos=t-50,this.yPos=30,this.currentPhase=0,this.opacity=0,this.containerWidth=t,this.stars=[],this.drawStars=!1,this.placeStars()}function u(A,i){this.spritePos=i,this.canvas=A,this.canvasCtx=A.getContext("2d"),this.sourceDimensions={},this.dimensions=u.dimensions,this.sourceXPos=[this.spritePos.x,this.spritePos.x+this.dimensions.WIDTH],this.xPos=[],this.yPos=0,this.bumpThreshold=.5,this.setSourceDimensions(),this.draw()}function I(A,i,t,s){this.canvas=A,this.canvasCtx=this.canvas.getContext("2d"),this.config=I.config,this.dimensions=t,this.gapCoefficient=s,this.obstacles=[],this.obstacleHistory=[],this.horizonOffsets=[0,0],this.cloudFrequency=this.config.CLOUD_FREQUENCY,this.spritePos=i,this.nightMode=null,this.clouds=[],this.cloudSpeed=this.config.BG_CLOUD_SPEED,this.horizonLine=null,this.init()}A.exports=t;var p=600,E=60,l=window.devicePixelRatio>1,C=window.navigator.userAgent.indexOf("CriOS")>-1||"UIWebViewForStaticFileContent"==window.navigator.userAgent,m=window.navigator.userAgent.indexOf("Mobi")>-1||C;t.config={ACCELERATION:.001,BG_CLOUD_SPEED:.2,BOTTOM_PAD:10,CLEAR_TIME:100,CLOUD_FREQUENCY:.5,GAMEOVER_CLEAR_TIME:750,GAP_COEFFICIENT:.6,GRAVITY:.6,INITIAL_JUMP_VELOCITY:12,INVERT_FADE_DURATION:12e3,INVERT_DISTANCE:30,MAX_CLOUDS:6,MAX_OBSTACLE_LENGTH:3,MAX_OBSTACLE_DUPLICATION:2,MAX_SPEED:13,MIN_JUMP_HEIGHT:35,MOBILE_SPEED_COEFFICIENT:1.2,RESOURCE_TEMPLATE_ID:"audio-resources",SPEED:10,SPEED_DROP_COEFFICIENT:3},t.defaultDimensions={WIDTH:p,HEIGHT:150},t.classes={CANVAS:"trex-canvas",CONTAINER:"trex-container",CRASHED:"crashed",ICON:"icon-offline",INVERTED:"inverted"},t.spriteDefinition={LDPI:{CACTUS_LARGE:{x:332,y:2},CACTUS_SMALL:{x:228,y:2},CLOUD:{x:86,y:2},HORIZON:{x:2,y:54},MOON:{x:484,y:2},PTERODACTYL:{x:134,y:2},TEXT_SPRITE:{x:655,y:2},TREX:{x:848,y:2},STAR:{x:645,y:2}},HDPI:{CACTUS_LARGE:{x:652,y:2},CACTUS_SMALL:{x:446,y:2},CLOUD:{x:166,y:2},HORIZON:{x:2,y:104},MOON:{x:954,y:2},PTERODACTYL:{x:260,y:2},TEXT_SPRITE:{x:1294,y:2},TREX:{x:1678,y:2},STAR:{x:1276,y:2}}},t.sounds={BUTTON_PRESS:"offline-sound-press",SCORE:"offline-sound-reached"},t.keycodes={JUMP:{38:1,32:1},DUCK:{40:1}},t.events={ANIM_END:"webkitAnimationEnd",CLICK:"click",KEYDOWN:"keydown",KEYUP:"keyup",MOUSEDOWN:"mousedown",MOUSEUP:"mouseup",RESIZE:"resize",TOUCHEND:"touchend",TOUCHSTART:"touchstart",VISIBILITY:"visibilitychange",BLUR:"blur",FOCUS:"focus",LOAD:"load"},t.actions={DUCK:"duck",DAZE:"daze",SUPER_JUMP:"superjump",JUMP:"jump",BOOM:"boom"},t.prototype={updateConfigSetting:function(A,i){if(A in this.config&&void 0!=i)switch(this.config[A]=i,A){case"GRAVITY":case"MIN_JUMP_HEIGHT":case"SPEED_DROP_COEFFICIENT":this.tRex.config[A]=i;break;case"INITIAL_JUMP_VELOCITY":this.tRex.setJumpVelocity(i);break;case"SPEED":this.setSpeed(i)}},loadImages:function(){l?(t.imageSprite=document.getElementById("offline-resources-2x"),this.spriteDef=t.spriteDefinition.HDPI):(t.imageSprite=document.getElementById("offline-resources-1x"),this.spriteDef=t.spriteDefinition.LDPI),this.init()},loadSounds:function(){if(!C&&window.AudioContext){this.audioContext=new AudioContext;var A=document.getElementById(this.config.RESOURCE_TEMPLATE_ID).content;for(var i in t.sounds){var s=A.getElementById(t.sounds[i]).src;s=s.substr(s.indexOf(",")+1);var e=n(s);this.audioContext.decodeAudioData(e,function(A,i){this.soundFx[A]=i}.bind(this,i))}}},setSpeed:function(A){var i=A||this.currentSpeed;if(this.dimensions.WIDTHi?i:t}else A&&(this.currentSpeed=A)},init:function(){this.adjustDimensions(),this.setSpeed(),this.containerEl=document.createElement("div"),this.containerEl.className=t.classes.CONTAINER,this.canvas=e(this.containerEl,this.dimensions.WIDTH,this.dimensions.HEIGHT,t.classes.PLAYER),this.canvasCtx=this.canvas.getContext("2d"),this.canvasCtx.fillStyle="#f7f7f7",this.canvasCtx.fill(),t.updateCanvasScaling(this.canvas),this.horizon=new I(this.canvas,this.spriteDef,this.dimensions,this.config.GAP_COEFFICIENT),this.tRex=new c(this.canvas,this.spriteDef.TREX),this.outerContainerEl.appendChild(this.containerEl),this.outerContainerEl.style.background="transparent",this.update(),window.addEventListener(t.events.RESIZE,this.debounceResize.bind(this))},debounceResize:function(){this.resizeTimerId_||(this.resizeTimerId_=setInterval(this.adjustDimensions.bind(this),250))},adjustDimensions:function(){clearInterval(this.resizeTimerId_),this.resizeTimerId_=null;var A=window.getComputedStyle(this.outerContainerEl),i=Number(A.paddingLeft.substr(0,A.paddingLeft.length-2));this.dimensions.WIDTH=this.outerContainerEl.offsetWidth-2*i,this.canvas&&(this.canvas.width=this.dimensions.WIDTH,this.canvas.height=this.dimensions.HEIGHT,t.updateCanvasScaling(this.canvas),this.clearCanvas(),this.horizon.update(0,0,!0),this.tRex.update(0),this.activated||this.paused?(this.containerEl.style.width=this.dimensions.WIDTH+"px",this.containerEl.style.height=this.dimensions.HEIGHT+"px",this.stop()):this.tRex.draw(0,0))},playIntro:function(){if(!this.started){this.playingIntro=!0,this.tRex.playingIntro=!0;var A="@-webkit-keyframes intro { from { width:"+c.config.WIDTH+"px }to { width: "+this.dimensions.WIDTH+"px }}";document.styleSheets[0].insertRule(A,0),this.containerEl.addEventListener(t.events.ANIM_END,this.startGame.bind(this)),this.containerEl.style.webkitAnimation="intro .4s ease-out 1 both",this.containerEl.style.width=this.dimensions.WIDTH+"px",this.activated=!0,this.started=!0}},startGame:function(){this.runningTime=0,this.playingIntro=!1,this.tRex.playingIntro=!1,this.containerEl.style.webkitAnimation="",this.playCount++,document.addEventListener(t.events.VISIBILITY,this.onVisibilityChange.bind(this)),window.addEventListener(t.events.BLUR,this.onVisibilityChange.bind(this)),window.addEventListener(t.events.FOCUS,this.onVisibilityChange.bind(this))},clearCanvas:function(){this.canvasCtx.clearRect(0,0,this.dimensions.WIDTH,this.dimensions.HEIGHT)},update:function(){this.drawPending=!1;var A=o(),i=A-(this.time||A);if(this.time=A,this.activated){this.clearCanvas(),this.tRex.jumping&&this.tRex.updateJump(i),this.runningTime+=i;var s=this.runningTime>this.config.CLEAR_TIME;if(1!=this.tRex.jumpCount||this.playingIntro||this.playIntro(),this.playingIntro?this.horizon.update(0,this.currentSpeed,s):(i=this.started?i:0,this.horizon.update(i,this.currentSpeed,s,this.inverted)),s){var e=h(this.horizon.obstacles[0],this.tRex);switch(e){case t.actions.JUMP:this.doJump();break;case t.actions.SUPER_JUMP:this.doJump(!0);break;case t.actions.DUCK:this.doDuck();break;case t.actions.DAZE:this.distanceRan+=this.currentSpeed*i/this.msPerFrame,this.currentSpeedthis.config.INVERT_FADE_DURATION)this.invertTimer=0,this.invertTrigger=!1,this.invert();else if(this.invertTimer)this.invertTimer+=i;else{var n=.025,a=Math.round(Math.ceil(this.distanceRan)*n);a>0&&(this.invertTrigger=!(a%this.config.INVERT_DISTANCE),this.invertTrigger&&0===this.invertTimer&&(this.invertTimer+=i,this.invert()))}}this.tRex.update(i),this.raq()},genNum:function(A,i){return Math.floor(Math.floor(Math.random()*i)+A)},doJump:function(A){this.activated||(this.loadSounds(),this.activated=!0),this.tRex.jumping||this.tRex.ducking||(this.playSound(this.soundFx.BUTTON_PRESS),this.tRex.startJump(this.currentSpeed));var i=A?this.genNum(430,550):this.genNum(6,20),t=this;setTimeout(function(){t.isRunning()?t.tRex.endJump():t.paused&&(t.tRex.reset(),t.play())},i)},doDuck:function(){this.tRex.jumping?this.tRex.setSpeedDrop():this.tRex.jumping||this.tRex.ducking||this.tRex.setDuck(!0);var A=this;setTimeout(function(){A.tRex.speedDrop=!1,A.tRex.setDuck(!1)},200)},raq:function(){this.drawPending||(this.drawPending=!0,this.raqId=requestAnimationFrame(this.update.bind(this)))},isRunning:function(){return!!this.raqId},stop:function(){this.activated=!1,this.paused=!0,cancelAnimationFrame(this.raqId),this.raqId=0},play:function(){this.activated=!0,this.paused=!1,this.tRex.update(0,c.status.RUNNING),this.time=o(),this.update()},onVisibilityChange:function(A){document.hidden||document.webkitHidden||"blur"==A.type||"visible"!=document.visibilityState?this.stop():(this.tRex.reset(),this.play())},playSound:function(A){if(A){var i=this.audioContext.createBufferSource();i.buffer=A,i.connect(this.audioContext.destination),i.start(0)}},invert:function(A){A?(document.body.classList.toggle(t.classes.INVERTED,!1),this.invertTimer=0,this.inverted=!1):this.inverted=document.body.classList.toggle(t.classes.INVERTED,this.invertTrigger)}},t.updateCanvasScaling=function(A,i,t){var s=A.getContext("2d"),e=Math.floor(window.devicePixelRatio)||1,n=Math.floor(s.webkitBackingStorePixelRatio)||1,o=e/n;if(e!==n){var h=i||A.width,a=t||A.height;return A.width=h*o,A.height=a*o,A.style.width=h+"px",A.style.height=a+"px",s.scale(o,o),!0}return 1==e&&(A.style.width=A.width+"px",A.style.height=A.height+"px"),!1},r.MAX_GAP_COEFFICIENT=1.5,r.MAX_OBSTACLE_LENGTH=3,r.prototype={init:function(A){if(this.cloneCollisionBoxes(),this.size>1&&this.typeConfig.multipleSpeed>A&&(this.size=1),this.width=this.typeConfig.width*this.size,Array.isArray(this.typeConfig.yPos)){var i=m?this.typeConfig.yPosMobile:this.typeConfig.yPos;this.yPos=i[s(0,i.length-1)]}else this.yPos=this.typeConfig.yPos;this.draw(),this.size>1&&(this.collisionBoxes[1].width=this.width-this.collisionBoxes[0].width-this.collisionBoxes[2].width,this.collisionBoxes[2].x=this.width-this.collisionBoxes[2].width),this.typeConfig.speedOffset&&(this.speedOffset=Math.random()>.5?this.typeConfig.speedOffset:-this.typeConfig.speedOffset),this.gap=this.getGap(this.gapCoefficient,A)},draw:function(){var A=this.typeConfig.width,i=this.typeConfig.height;l&&(A*=2,i*=2);var s=A*this.size*(.5*(this.size-1))+this.spritePos.x;this.currentFrame>0&&(s+=A*this.currentFrame),this.canvasCtx.drawImage(t.imageSprite,s,this.spritePos.y,A*this.size,i,this.xPos,this.yPos,this.typeConfig.width*this.size,this.typeConfig.height)},update:function(A,i){this.remove||(this.typeConfig.speedOffset&&(i+=this.speedOffset),this.xPos-=Math.floor(i*E/1e3*A),this.typeConfig.numFrames&&(this.timer+=A,this.timer>=this.typeConfig.frameRate&&(this.currentFrame=this.currentFrame==this.typeConfig.numFrames-1?0:this.currentFrame+1,this.timer=0)),this.draw(),this.isVisible()||(this.remove=!0))},getGap:function(A,i){var t=Math.round(this.width*i+this.typeConfig.minGap*A),e=Math.round(t*r.MAX_GAP_COEFFICIENT);return s(t,e)},isVisible:function(){return this.xPos+this.width>0},cloneCollisionBoxes:function(){for(var A=this.typeConfig.collisionBoxes,i=A.length-1;i>=0;i--)this.collisionBoxes[i]=new a(A[i].x,A[i].y,A[i].width,A[i].height)}},r.types=[{type:"CACTUS_SMALL",width:17,height:35,yPos:105,multipleSpeed:4,minGap:120,minSpeed:0,collisionBoxes:[new a(0,7,5,27),new a(4,0,6,34),new a(10,4,7,14)]},{type:"CACTUS_LARGE",width:25,height:50,yPos:90,multipleSpeed:7,minGap:120,minSpeed:0,collisionBoxes:[new a(0,12,7,38),new a(8,0,7,49),new a(13,10,10,38)]},{type:"PTERODACTYL",width:46,height:40,yPos:[100,75,50],yPosMobile:[100,50],multipleSpeed:999,minSpeed:8.5,minGap:150,collisionBoxes:[new a(15,15,16,5),new a(18,21,24,6),new a(2,14,4,3),new a(6,10,4,7),new a(10,8,6,9)],numFrames:2,frameRate:1e3/6,speedOffset:.8}],c.config={DROP_VELOCITY:-5,GRAVITY:.6,HEIGHT:47,HEIGHT_DUCK:25,INIITAL_JUMP_VELOCITY:-10,INTRO_DURATION:1500,MAX_JUMP_HEIGHT:30,MIN_JUMP_HEIGHT:30,SPEED_DROP_COEFFICIENT:3,SPRITE_WIDTH:262,START_X_POS:50,WIDTH:44,WIDTH_DUCK:59},c.collisionBoxes={DUCKING:[new a(1,18,55,25)],RUNNING:[new a(22,0,17,16),new a(1,18,30,9),new a(10,35,14,8),new a(1,24,29,5),new a(5,30,21,4),new a(9,34,15,4)]},c.status={CRASHED:"CRASHED",DUCKING:"DUCKING",JUMPING:"JUMPING",RUNNING:"RUNNING",WAITING:"WAITING"},c.BLINK_TIMING=7e3,c.animFrames={WAITING:{frames:[44,0],msPerFrame:1e3/3},RUNNING:{frames:[88,132],msPerFrame:1e3/12},CRASHED:{frames:[220],msPerFrame:1e3/60},JUMPING:{frames:[0],msPerFrame:1e3/60},DUCKING:{frames:[262,321],msPerFrame:125}},c.prototype={init:function(){this.blinkDelay=this.setBlinkDelay(),this.groundYPos=t.defaultDimensions.HEIGHT-this.config.HEIGHT-t.config.BOTTOM_PAD,this.yPos=this.groundYPos,this.minJumpHeight=this.groundYPos-this.config.MIN_JUMP_HEIGHT,this.draw(0,0),this.update(0,c.status.WAITING)},setJumpVelocity:function(A){this.config.INIITAL_JUMP_VELOCITY=-A,this.config.DROP_VELOCITY=-A/2},update:function(A,i){this.timer+=A,i&&(this.status=i,this.currentFrame=0,this.msPerFrame=c.animFrames[i].msPerFrame,this.currentAnimFrames=c.animFrames[i].frames,i==c.status.WAITING&&(this.animStartTime=o(),this.setBlinkDelay())),this.playingIntro&&this.xPos=this.msPerFrame&&(this.currentFrame=this.currentFrame==this.currentAnimFrames.length-1?0:this.currentFrame+1,this.timer=0),this.speedDrop&&this.yPos==this.groundYPos&&(this.speedDrop=!1,this.setDuck(!0))},draw:function(A,i){var s=A,e=i,n=this.ducking&&this.status!=c.status.CRASHED?this.config.WIDTH_DUCK:this.config.WIDTH,o=this.config.HEIGHT;l&&(s*=2,e*=2,n*=2,o*=2),s+=this.spritePos.x,e+=this.spritePos.y,this.ducking&&this.status!=c.status.CRASHED?this.canvasCtx.drawImage(t.imageSprite,s,e,n,o,this.xPos,this.yPos,this.config.WIDTH_DUCK,this.config.HEIGHT):(this.ducking&&this.status==c.status.CRASHED&&this.xPos++,this.canvasCtx.drawImage(t.imageSprite,s,e,n,o,this.xPos,this.yPos,this.config.WIDTH,this.config.HEIGHT))},setBlinkDelay:function(){this.blinkDelay=Math.ceil(Math.random()*c.BLINK_TIMING)},blink:function(A){var i=A-this.animStartTime;i>=this.blinkDelay&&(this.draw(this.currentAnimFrames[this.currentFrame],0),1==this.currentFrame&&(this.setBlinkDelay(),this.animStartTime=A))},startJump:function(A){this.jumping||(this.update(0,c.status.JUMPING),this.jumpVelocity=this.config.INIITAL_JUMP_VELOCITY-A/10,this.jumping=!0,this.reachedMinHeight=!1,this.speedDrop=!1)},endJump:function(){this.reachedMinHeight&&this.jumpVelocitythis.groundYPos&&(this.reset(),this.jumpCount++),this.update(A)},setSpeedDrop:function(){this.speedDrop=!0,this.jumpVelocity=1},setDuck:function(A){A&&this.status!=c.status.DUCKING?(this.update(0,c.status.DUCKING),this.ducking=!0):this.status==c.status.DUCKING&&(this.update(0,c.status.RUNNING),this.ducking=!1)},reset:function(){this.yPos=this.groundYPos,this.jumpVelocity=0,this.jumping=!1,this.ducking=!1,this.update(0,c.status.RUNNING),this.midair=!1,this.speedDrop=!1,this.jumpCount=0}},g.config={HEIGHT:14,MAX_CLOUD_GAP:400,MAX_SKY_LEVEL:30,MIN_CLOUD_GAP:100,MIN_SKY_LEVEL:71,WIDTH:46},g.prototype={init:function(){this.yPos=s(g.config.MAX_SKY_LEVEL,g.config.MIN_SKY_LEVEL),this.draw()},draw:function(){this.canvasCtx.save();var A=g.config.WIDTH,i=g.config.HEIGHT;l&&(A*=2,i*=2),this.canvasCtx.drawImage(t.imageSprite,this.spritePos.x,this.spritePos.y,A,i,this.xPos,this.yPos,g.config.WIDTH,g.config.HEIGHT),this.canvasCtx.restore()},update:function(A){this.remove||(this.xPos-=Math.ceil(A),this.draw(),this.isVisible()||(this.remove=!0))},isVisible:function(){return this.xPos+g.config.WIDTH>0}},d.config={FADE_SPEED:.035,HEIGHT:40,MOON_SPEED:.25,NUM_STARS:2,STAR_SIZE:9,STAR_SPEED:.3,STAR_MAX_Y:70,WIDTH:20},d.phases=[140,120,100,60,40,20,0],d.prototype={update:function(A,i){if(A&&0==this.opacity&&(this.currentPhase++,this.currentPhase>=d.phases.length&&(this.currentPhase=0)),A&&(this.opacity<1||0==this.opacity)?this.opacity+=d.config.FADE_SPEED:this.opacity>0&&(this.opacity-=d.config.FADE_SPEED),this.opacity>0){if(this.xPos=this.updateXPos(this.xPos,d.config.MOON_SPEED),this.drawStars)for(var t=0;tthis.bumpThreshold?this.dimensions.WIDTH:0},draw:function(){this.canvasCtx.drawImage(t.imageSprite,this.sourceXPos[0],this.spritePos.y,this.sourceDimensions.WIDTH,this.sourceDimensions.HEIGHT,this.xPos[0],this.yPos,this.dimensions.WIDTH,this.dimensions.HEIGHT),this.canvasCtx.drawImage(t.imageSprite,this.sourceXPos[1],this.spritePos.y,this.sourceDimensions.WIDTH,this.sourceDimensions.HEIGHT,this.xPos[1],this.yPos,this.dimensions.WIDTH,this.dimensions.HEIGHT)},updateXPos:function(A,i){var t=A,s=0==A?1:0;this.xPos[t]-=i,this.xPos[s]=this.xPos[t]+this.dimensions.WIDTH,this.xPos[t]<=-this.dimensions.WIDTH&&(this.xPos[t]+=2*this.dimensions.WIDTH,this.xPos[s]=this.xPos[t]-this.dimensions.WIDTH,this.sourceXPos[t]=this.getRandomType()+this.spritePos.x)},update:function(A,i){var t=Math.floor(.06*i*A);this.xPos[0]<=0?this.updateXPos(0,t):this.updateXPos(1,t),this.draw()},reset:function(){this.xPos[0]=0,this.xPos[1]=u.dimensions.WIDTH}},I.config={BG_CLOUD_SPEED:.2,BUMPY_THRESHOLD:.3,CLOUD_FREQUENCY:.5,HORIZON_HEIGHT:16,MAX_CLOUDS:6},I.prototype={init:function(){this.addCloud(),this.horizonLine=new u(this.canvas,this.spritePos.HORIZON),this.nightMode=new d(this.canvas,this.spritePos.MOON,this.dimensions.WIDTH)},update:function(A,i,t,s){this.runningTime+=A,this.horizonLine.update(A,i),this.nightMode.update(s),this.updateClouds(A,i),t&&this.updateObstacles(A,i)},updateClouds:function(A,i){var t=this.cloudSpeed/1e3*A*i,s=this.clouds.length;if(s){for(var e=s-1;e>=0;e--)this.clouds[e].update(t);var n=this.clouds[s-1];sn.cloudGap&&this.cloudFrequency>Math.random()&&this.addCloud(),this.clouds=this.clouds.filter(function(A){return!A.remove})}else this.addCloud()},updateObstacles:function(A,i){for(var t=this.obstacles.slice(0),s=0;s0){var n=this.obstacles[this.obstacles.length-1];n&&!n.followingObstacleCreated&&n.isVisible()&&n.xPos+n.width+n.gap1&&this.obstacleHistory.splice(t.config.MAX_OBSTACLE_DUPLICATION)}},duplicateObstacleCheck:function(A){for(var i=0,s=0;s=t.config.MAX_OBSTACLE_DUPLICATION},reset:function(){this.obstacles=[],this.horizonLine.reset(),this.nightMode.reset()},resize:function(A,i){this.canvas.width=A,this.canvas.height=i},addCloud:function(){this.clouds.push(new g(this.canvas,this.spritePos.CLOUD,this.dimensions.WIDTH))}}}])}); --------------------------------------------------------------------------------