Have you played the chrome dinosaur game ? If not paste chrome://dino/ in Chrome address bar, press spacebar and enjoy the game.
Want to surprise someone by giving some Artificial Intelligence to the outdated dinosaur 😉 ?
This was a time when I was facing a lot of Internet issues at my home and struck with a simple idea,
To write a script which will monitor a pixel in front of the dinosaur,
We will keep checking this pixel and when it changes its color we programmatically fire an up key event to make it jump because we found something in front of the Dino.
Simple right ?
We will have 2 functions:
SimulateJump() : Fires the key event for up button so that the Dino will jump. Magic() : Continuously check the pixel in front of Dino, if it has changed to black call SimulateJump.
The first function seems trivial, let’s jump into the Magic function which is more interesting 🙂
We need to get the canvas element to be able to look what is in it, we can find by writing a selector for it,
find elements by right click and selecting inspect element option in chrome:
var rCanvas = document.getElementsByClassName("runner-canvas")[0]; var runnerCanvasContext = rCanvas.getContext('2d');
Now the idea is to monitor a pixel in front of the Dino,
I started with monitoring a single pixel but that did not work very well,
So I came down to monitoring a patch of rectangular area say dangerArea, any pixel which may be black in this area, the Dino should consider a threat and jump:
var dangerArea = runnerCanvasContext.getImageData(rCanvas.width/8, rCanvas.height - rCanvas.height/2.5, rCanvas.width/7, rCanvas.height/5).data;
The area range above has been derived from lot of trials, artificial intelligence requires learning 🙂
You can try different values, which will make the Dino jump a little early or a little later.
Now check each and every pixel in the dangerArea.
var jumpFlag = false; for (var i = 0, n = dangerArea.length; i < n; i += 4) { if( dangerArea[i]>0 || dangerArea[i+1]>0 || dangerArea[i+2]>0 ){ jumpFlag = true; break; } }
Pixel data is stored in rgbα format, hence we are incrementing the loop by value of 4 and checking only the rgb values of interest to us.
It seems the background is light-gray, but in fact it is transparent, grey color is of the parent HTML element.
Hence if there is no obstruction the pixel value is 0, which means if we come inside the if block we have detected an obstruction.
Now based on our obstruction detection we either call
if(jumpFlag){ simulateJump();
and then call the magic function again after some time
return setTimeout(function(){magic();},100); }
otherwise just call magic function again to keep checking for obstructions
else { setTimeout(function(){magic();},50); }
Again above delays of 100ms and 50ms have been found to be good values based on lot of trial runs, you could try other values and see how it works out.
SimulateJump function will create up arrow key event and fire it so that the Dino would jump.
I faced some issues when implementing this function, spacebar event was not allowed due to security reasons and click event on the canvas did not work, eventually got it to work with a tweaked up-key event.
(open the inspector by pressing F12 key)
function magic(){ var rCanvas = document.getElementsByClassName("runner-canvas")[0]; var runnerCanvasContext = rCanvas.getContext('2d'); var imgd = runnerCanvasContext.getImageData(rCanvas.width/8, rCanvas.height - rCanvas.height/2.5, rCanvas.width/7, rCanvas.height/5); var jumpFlag = false; var pix = imgd.data; for (var i = 0, n = pix.length; i < n; i += 4) { if(pix[i]>0||pix[i+1]>0||pix[i+2]>0){ jumpFlag = true; break; } } if(jumpFlag){ simulateJump(); return setTimeout(function(){magic();},100); } else { setTimeout(function(){magic();},50); } }; function simulateJump() { var keyEvent = document.createEvent('KeyboardEvent'); Object.defineProperty(keyEvent, 'keyCode', { get : function() { return this.keyCodeVal; } }); keyEvent.initKeyboardEvent('keydown', true, false, null, 0, false, 0, false, 38, 0); keyEvent.keyCodeVal = 38; document.dispatchEvent(keyEvent); } magic();
Now hit enter so that the code gets added to the browser, close the inspector window.
Psst,
While playing around with all this, I found some of the javascript functions the game uses.
add the following line to the end of above code and you have god-mode on 😉
Runner.prototype.gameOver = simulateJump;