本站使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或从新修改使用,但须要注明来源。 署名 4.0 国际 (CC BY 4.0)javascript
本文做者: 苏洋html
建立时间: 2018年09月13日 统计字数: 4298字 阅读时间: 9分钟阅读 本文连接: soulteary.com/2018/09/13/…前端
今天看论坛发现有人发帖说 Chrome周年庆祝
在“小恐龙”游戏中埋入了新的菜单,能够触碰的 蛋糕 以及触碰以后得到的 生日帽。java
看到如今“小恐龙”这个彩蛋的改进,往事历历在目。可是很快,帖子中有人晒高分引发了个人注意:这个游戏虽然说简单,可是在分数达到必定程度后,加速度会让玩家很难继续游戏。git
记得很早以前在机场玩过这个游戏,记忆中获取三千以上的分数仍是挺困难的,更别提八千分,因此我这里推测这个玩家应该是有一些“特别的技巧”。github
在游戏中取得使人叹为观止的高分,通常来讲无非三种手段:chrome
第一种方式咱们暂且略过,后面若是实在闲,再进行尝试,咱们直接开始后面两种方案的尝试。编程
君子性非异也,擅假于物也。浏览器
网上有个老外曾经编写过一个根据判断X轴方向小恐龙和前面物品距离进行自动跳跃的程序,在稍加改造后,将下面的代码贴到控制台中,便可完成小恐龙自动奔跑的神操做。bash
这里添加了代码避免小恐龙跳过蛋糕、避而不吃,以及调整了对障碍物须要跳跃的高度判断,防止小恐龙看到低飞的鸟儿迎面而上,固然,还有可以在代码执行后,自动开始游戏。
function TrexRunnerBot() {
const makeKeyArgs = (keyCode) => {
const preventDefault = () => void 0;
return {keyCode, preventDefault};
};
const upKeyArgs = makeKeyArgs(38);
const downKeyArgs = makeKeyArgs(40);
const startArgs = makeKeyArgs(32);
if (!Runner().playing) {
Runner().onKeyDown(startArgs);
setTimeout(() => {
Runner().onKeyUp(startArgs);
}, 500);
}
function conquerTheGame() {
if (!Runner || !Runner().horizon.obstacles[0]) return;
const obstacle = Runner().horizon.obstacles[0];
if (obstacle.typeConfig && obstacle.typeConfig.type === 'SNACK') return;
if (needsToTackle(obstacle) && closeEnoughToTackle(obstacle)) tackle(obstacle);
}
function needsToTackle(obstacle) {
return obstacle.yPos !== 50;
}
function closeEnoughToTackle(obstacle) {
return obstacle.xPos <= Runner().currentSpeed * 18;
}
function tackle(obstacle) {
if (isDuckable(obstacle)) {
duck();
} else {
jumpOver(obstacle);
}
}
function isDuckable(obstacle) {
return obstacle.yPos === 50;
}
function duck() {
Runner().onKeyDown(downKeyArgs);
setTimeout(() => {
Runner().onKeyUp(downKeyArgs);
}, 500);
}
function jumpOver(obstacle) {
if (isNextObstacleCloseTo(obstacle))
jumpFast();
else
Runner().onKeyDown(upKeyArgs);
}
function isNextObstacleCloseTo(currentObstacle) {
const nextObstacle = Runner().horizon.obstacles[1];
return nextObstacle && nextObstacle.xPos - currentObstacle.xPos <= Runner().currentSpeed * 42;
}
function jumpFast() {
Runner().onKeyDown(upKeyArgs);
Runner().onKeyUp(upKeyArgs);
}
return {conquerTheGame: conquerTheGame};
}
let bot = TrexRunnerBot();
let botInterval = setInterval(bot.conquerTheGame, 2);
复制代码
固然,为了你可以在移动端的复制便捷,我这里提供了压缩版的代码。
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);
复制代码
若是你想在桌面端浏览器游玩小恐龙游戏,除了断网的操做外,还能够直接访问 chrome://dino/
这个地址。
若是你想在手机上体验小恐龙自动奔跑,请参考下面的操做:
javascript:
,而后确认。你的小恐龙就自个去浪了,不过这里你获取分数的速度依然和正常游玩的玩家是同样的,小恐龙走一步记一分。
那么,接下来咱们换个套路。
与其说改写,不如说“劫持”。ES5 有一个很古老的 API, Object.defineProperty()
,借助这个 API ,咱们可以轻易的修改现有对象上的属性,配合从新定义对象具体内容的 getter
、setter
描述符,能够作到对于属性的劫持操做,是否是很眼熟?没错,这个方案也是老生常谈的 MVVM 框架的双向数据绑定的实现方案之一。
let hackScore = 0;
Object.defineProperty(Runner.instance_, 'distanceRan', {
get: () => hackScore,
set: (value) => hackScore = value + Math.floor(Math.random() * 1000),
configurable: true,
enumerable: true,
});
复制代码
一样提供了压缩版本。
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});
复制代码
将上面代码执行以后,再次运行程序,你会发现你获取分数的速度提高了一千倍。
若是你将第一个方案和这个方案的代码结合,会得到一个可以自动奔跑得到高分的“智能小恐龙”。
不过由于咱们的“外挂”是基于计时器进行距离计算并模拟用户操做的,当你得到很高很高的分数以后,障碍物推动速度过快,一旦你进行窗口的来回切换,游戏进行暂停和游玩的状态切换,很大几率上“外挂”操做会延时,致使 GAME OVER
。
如何能避免这个事情呢,咱们来说讲第三个套路。
若是说第一个方案起码还有付出时间成本,模拟玩家操做一步一步循序渐进的获取分数;第二个方案偷天换日,一步当一千步使;那么接下来的方案就显得十分无耻了。
Runner.instance_.gameOver=function(){};
复制代码
下面代码在执行以后,会清空游戏的中断逻辑,配合第二个方案的快速得到分数的代码,你能够获得一只拥有穿越障碍物能力的小恐龙:勇往无前,永不停歇,分数不停的增加,直到报错。
相关代码我推到了 GitHub 上,有兴趣的同窗也能够访问,以了解更多内容。
先写到这里,去看苹果发布会了。
--EOF
我如今有一个小小的折腾群,里面汇集了一些喜欢折腾的小伙伴。
在不发广告的状况下,咱们在里面会一块儿聊聊软件、HomeLab、编程上的一些问题,也会在群里不按期的分享一些技术沙龙的资料。
喜欢折腾的小伙伴欢迎扫码添加好友。(请注明来源和目的,不然不会经过审核) 关于折腾群入群的那些事