本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。 署名 4.0 国际 (CC BY 4.0)

本文作者: 苏洋

创建时间: 2018年09月13日 统计字数: 2506字 阅读时间: 6分钟阅读 本文链接: https://soulteary.com/2018/09/13/use-the-front-end-approach-to-challenge-chrome-dinosaur-high-scores.html


使用前端方式挑战 Chrome 小恐龙游戏高分

今天看论坛发现有人发帖说 Chrome周年庆祝 在“小恐龙”游戏中埋入了新的菜单,可以触碰的 蛋糕 以及触碰之后获得的 生日帽

看到现在“小恐龙”这个彩蛋的改进,往事历历在目。但是很快,帖子中有人晒高分引起了我的注意:这个游戏虽说简单,但是在分数达到一定程度后,加速度会让玩家很难继续游戏。

记得很早之前在机场玩过这个游戏,记忆中获取三千以上的分数还是挺困难的,更别提八千分,所以我这里推测这个玩家应该是有一些“特别的技巧”。

在游戏中取得令人叹为观止的高分,一般来说无非三种手段:

  1. 练习:勤学苦练,熟能生巧,加上极致的耐心。
  2. 工具:使用一些辅助设施来模拟人的操作。
  3. 外挂:针对难度或者得分倍数进行改造或者直接对结果进行修改、甚至破坏游戏规则。

第一种方式我们暂且略过,后面如果实在闲,再进行尝试,我们直接开始后面两种方案的尝试。

编写辅助工具

君子性非异也,擅假于物也。

网上有个老外曾经编写过一个根据判断X轴方向小恐龙和前面物品距离进行自动跳跃的程序,在稍加改造后,将下面的代码贴到控制台中,即可完成小恐龙自动奔跑的神操作。

这里添加了代码避免小恐龙跳过蛋糕、避而不吃,以及调整了对障碍物需要跳跃的高度判断,防止小恐龙看到低飞的鸟儿迎面而上,当然,还有能够在代码执行后,自动开始游戏。

  1. function TrexRunnerBot() {
  2. const makeKeyArgs = (keyCode) => {
  3. const preventDefault = () => void 0;
  4. return {keyCode, preventDefault};
  5. };
  6. const upKeyArgs = makeKeyArgs(38);
  7. const downKeyArgs = makeKeyArgs(40);
  8. const startArgs = makeKeyArgs(32);
  9. if (!Runner().playing) {
  10. Runner().onKeyDown(startArgs);
  11. setTimeout(() => {
  12. Runner().onKeyUp(startArgs);
  13. }, 500);
  14. }
  15. function conquerTheGame() {
  16. if (!Runner || !Runner().horizon.obstacles[0]) return;
  17. const obstacle = Runner().horizon.obstacles[0];
  18. if (obstacle.typeConfig && obstacle.typeConfig.type === 'SNACK') return;
  19. if (needsToTackle(obstacle) && closeEnoughToTackle(obstacle)) tackle(obstacle);
  20. }
  21. function needsToTackle(obstacle) {
  22. return obstacle.yPos !== 50;
  23. }
  24. function closeEnoughToTackle(obstacle) {
  25. return obstacle.xPos <= Runner().currentSpeed * 18;
  26. }
  27. function tackle(obstacle) {
  28. if (isDuckable(obstacle)) {
  29. duck();
  30. } else {
  31. jumpOver(obstacle);
  32. }
  33. }
  34. function isDuckable(obstacle) {
  35. return obstacle.yPos === 50;
  36. }
  37. function duck() {
  38. Runner().onKeyDown(downKeyArgs);
  39. setTimeout(() => {
  40. Runner().onKeyUp(downKeyArgs);
  41. }, 500);
  42. }
  43. function jumpOver(obstacle) {
  44. if (isNextObstacleCloseTo(obstacle))
  45. jumpFast();
  46. else
  47. Runner().onKeyDown(upKeyArgs);
  48. }
  49. function isNextObstacleCloseTo(currentObstacle) {
  50. const nextObstacle = Runner().horizon.obstacles[1];
  51. return nextObstacle && nextObstacle.xPos - currentObstacle.xPos <= Runner().currentSpeed * 42;
  52. }
  53. function jumpFast() {
  54. Runner().onKeyDown(upKeyArgs);
  55. Runner().onKeyUp(upKeyArgs);
  56. }
  57. return {conquerTheGame: conquerTheGame};
  58. }
  59. let bot = TrexRunnerBot();
  60. let botInterval = setInterval(bot.conquerTheGame, 2);

当然,为了你能够在移动端的复制便捷,我这里提供了压缩版的代码。

  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);

如果你想在桌面端浏览器游玩小恐龙游戏,除了断网的操作外,还可以直接访问 chrome://dino/ 这个地址。

如果你想在手机上体验小恐龙自动奔跑,请参考下面的操作:

  1. 飞行模式后打开 Chrome ,然后访问任意页面,呼出小恐龙界面。
  2. 将上面的代码粘贴到地址栏。
  3. 在地址栏前手动加上 javascript: ,然后确认。

你的小恐龙就自个去浪了,不过这里你获取分数的速度依然和正常游玩的玩家是一样的,小恐龙走一步记一分。

那么,接下来我们换个套路。

改写计分逻辑

与其说改写,不如说“劫持”。ES5 有一个很古老的 API, Object.defineProperty(),借助这个 API ,我们能够轻易的修改现有对象上的属性,配合重新定义对象具体内容的 getter、 setter 描述符,可以做到对于属性的劫持操作,是不是很眼熟?没错,这个方案也是老生常谈的 MVVM 框架的双向数据绑定的实现方案之一。

  1. let hackScore = 0;
  2. Object.defineProperty(Runner.instance_, 'distanceRan', {
  3. get: () => hackScore,
  4. set: (value) => hackScore = value + Math.floor(Math.random() * 1000),
  5. configurable: true,
  6. enumerable: true,
  7. });

同样提供了压缩版本。

  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});

将上面代码执行之后,再次运行程序,你会发现你获取分数的速度提升了一千倍。

如果你将第一个方案和这个方案的代码结合,会获得一个能够自动奔跑获得高分的“智能小恐龙”。

不过因为我们的“外挂”是基于计时器进行距离计算并模拟用户操作的,当你获得很高很高的分数之后,障碍物推进速度过快,一旦你进行窗口的来回切换,游戏进行暂停和游玩的状态切换,很大概率上“外挂”操作会延时,导致 GAME OVER

如何能避免这个事情呢,我们来讲讲第三个套路。

破坏规则大法

如果说第一个方案起码还有付出时间成本,模拟玩家操作一步一步按部就班的获取分数;第二个方案偷天换日,一步当一千步使;那么接下来的方案就显得十分无耻了。

  1. Runner.instance_.gameOver=function(){};

下面代码在执行之后,会清空游戏的中断逻辑,配合第二个方案的快速获得分数的代码,你可以得到一只拥有穿越障碍物能力的小恐龙:勇往无前,永不停歇,分数不停的增长,直到报错。

其他

相关代码我推到了 GitHub 上,有兴趣的同学也可以访问,以了解更多内容。

先写到这里,去看苹果发布会了。

--EOF

使用前端方式挑战 Chrome 小恐龙游戏高分相关推荐

  1. 【MM32F5270开发板试用】移植Google Chrome小恐龙游戏到MM32F5270

    本篇文章来自极术社区与灵动组织的MM32F5270开发板评测活动,更多开发板试用活动请关注极术社区网站.作者:曾是一颗薏米 一.项目背景 在几年前,Google 给 Chrome 浏览器加了一个有趣的 ...

  2. Chrome 的小恐龙游戏,被我破解了...

    一个阳光明媚的周末,透光的窗帘把我从睡梦中叫醒,大脑说今天是周六,可以慵懒个一上午,于是开心地打开我的 Mac 准备看两集Rick and Morty再起床洗漱. 我迫不及待打开了对应的网站,发现浏览 ...

  3. Chrome 的小恐龙游戏,被破解了...

    一个阳光明媚的周末,透光的窗帘把我从睡梦中叫醒,大脑说今天是周六,可以慵懒个一上午,于是开心地打开我的 Mac 准备看两集 Rick and Morty 再起床洗漱. 我迫不及待打开了对应的网站,发现 ...

  4. [c++简单小游戏]东搞西搞第二弹——谷歌chrome小恐龙升级版(啊哈)

    上效果图~~~ 灵感来源:谷歌chrome的小恐龙游戏(就是每次断网都会弹出来的那个) 那个#是墙... <是飞弹,移动速度为墙的两倍... 飞弹的走位很像小恐龙里的鸟,但它并不算一个墙...而 ...

  5. 在OLED12864竟然也能玩Chrome 小恐龙跳一跳的游戏?附所有软硬件资料【全开源】

    摘要 最近在课堂上发现学生经常玩游戏,要么在手机上玩王者荣耀,要么在Chrome 浏览器玩跳一跳小游戏,既然他们喜欢玩游戏,那就惩罚他们设计一款游戏机吧. OLED12864上面玩游戏,Chrome ...

  6. 小恐龙游戏python_补一波之前说好的用DQN自动玩Chrome浏览器的小恐龙游戏呗~

    原文链接补一波之前说好的用DQN自动玩Chrome浏览器的小恐龙游戏呗~​mp.weixin.qq.com 效果展示 在cmd窗口运行如下命令即可: 模型训练: python TRexRush.py ...

  7. 小恐龙游戏制作挑战:第8天-确定图片如何制作

    第8天 小恐龙游戏程序进度 图像部分 代码部分 当日记录 定位日期 小恐龙游戏程序进度 图像部分 虽然我现在的绘画功底不好,但我可以先描线,先找找绘画空间分配的手感.小恐龙的图像也不用非在网上找,我可 ...

  8. python实现图片找不同游戏_用Python实现谷歌的小恐龙游戏

    (给Python开发者加星标,提升Python技能) 来源: Charles的皮卡丘-白露未晞me理 谷歌流量器中有个很有名的彩蛋:当你网络出现问题时,就会出现一个"小恐龙游戏". ...

  9. Java 独门绝技 用Java玩谷歌小恐龙游戏 (有源码)

    目录 1.Swing成品演示 2.简介 3.Java的Robot类 4.实战开发例子 1.Swing成品演示 2.简介 Java有一个很厉害的类Robot类,这个类可以模仿人的手去操作电脑,鼠标移动, ...

  10. java小恐龙游戏_用Python实现谷歌的小恐龙游戏

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理. 谷歌流量器中有个很有名的彩蛋:当你网络出现问题时,就会出现一个"小恐龙游戏&quo ...

最新文章

  1. GVINS:基于GNSS视觉惯性紧耦合的平滑状态估计方法
  2. Linux常用命令汇总(持续更新中)
  3. python socket tcp客户端_python网络编程socketserver模块(实现TCP客户端/服务器)
  4. 华盛顿大学《生成模型》2020秋季课程完结,课件、讲义全部放出
  5. codeup 二叉树(dfs超时版)
  6. python基础学习[python编程从入门到实践读书笔记(连载三)]:django学习笔记web项目
  7. Linux nano编辑txt文件,Linux 文本编辑器 nano 的简单使用
  8. argumentoutofrangeexception:长度不能小于0_数组长度属性背后的魔力有哪些?
  9. 可迭代对象与迭代器 0318 草稿
  10. Less入门与安装(转)
  11. 2018.7.28 二叉树的遍历规则(前序遍历、后序遍历、中序遍历)
  12. 七大排序的 java 实现和理解
  13. 泛化误差,交叉验证和特征选择
  14. mysql误删数据快速恢复
  15. FatFs(通用FAT文件系统模块)下载与介绍
  16. Centos7 安装teamviewer
  17. 不要为优势忘乎所以——职场人士寓言(6)
  18. 番茄ToDo帮助文档
  19. 世界上最美的公式——欧拉公式
  20. js经典代码200句

热门文章

  1. 配置项目构建完成后文件移动---- Jenkins自动化部署学习笔记(三)
  2. 学中式烹调10天笔记(备用)
  3. C# 正则表达式数字匹配
  4. idea 如何修改主题
  5. 通过对arcsinx的泰勒展开式求圆周率值
  6. Chrome清理网页缓存
  7. C++基础之detele和detele[]
  8. 实验3ospf路由聚合
  9. 如何给Layout文件夹分类
  10. phpstudy重置密码登录报错#1045