2048网页版是一款开源游戏:Gabriele Cirulli.
在线游戏地址:https://2048game.com/
本人的历史成绩:
于是范总提出了质疑:
下面我给大家公布一下,在2048游戏开挂的方法。
源码分析
源码地址:https://gitcode.net/mirrors/gabrielecirulli/2048
游戏的入口代码是
js/application.js
:
window.requestAnimationFrame(function(){newGameManager(4,KeyboardInputManager,HTMLActuator,LocalStorageManager);});
GameManager的定义在
js/game_manager.js
:
functionGameManager(size, InputManager, Actuator, StorageManager){this.size = size;this.inputManager =newInputManager;this.storageManager =newStorageManager;this.actuator =newActuator;this.startTiles =2;this.inputManager.on("move",this.move.bind(this));this.inputManager.on("restart",this.restart.bind(this));this.inputManager.on("keepPlaying",this.keepPlaying.bind(this));this.setup();}
setup
启动方法:
GameManager.prototype.setup=function(){var previousState =this.storageManager.getGameState();if(previousState){this.grid =newGrid(previousState.grid.size,previousState.grid.cells);this.score = previousState.score;this.over = previousState.over;this.won = previousState.won;this.keepPlaying = previousState.keepPlaying;}else{this.grid =newGrid(this.size);this.score =0;this.over =false;this.won =false;this.keepPlaying =false;this.addStartTiles();}this.actuate();}
主要逻辑:
- storageManager.getGameState()读取了本地存储的gameState的值。
- actuate()可以将当前GameManager对象的属性值刷新显示到HTML元素中。
高分方案
直接修改分数
修改本地存储gameState的值后刷新页面可以自定义当前分数和布局。
不过这样就太没意思了,压根没玩。
交换位置功能开发
考虑设计增加一个交换位置的方法,可以在游戏难以进行时,交换指定两个格子的位置。
首先我们启动本地替代后,修改
js/application.js
的代码,将GameManager导出,即增加
window.manager
的代码:
然后使用同样的方法修改
js/game_manager.js
的代码:
增加了如下代码:
GameManager.prototype.swapTile=function(x1,y1,x2,y2){let tmp=this.grid.cells[x1][y1].value;this.grid.cells[x1][y1].value=this.grid.cells[x2][y2].value;this.grid.cells[x2][y2].value=tmp;this.actuate();};
保存后刷新页面即可生效。
效果:
只需再控制台执行:
manager.swapTile(2,3,3,3)
表示坐标(2,3)位置与(3,3)位置进行交换。
为了方便获取目标格子的坐标,我们可以在游览器中执行如下代码:
$('.tile-container').onclick=function(e){var[_,x,y]=/(\d)-(\d)/.exec(e.toElement.offsetParent.className);[x,y]=[x,y].map(Number);
console.log(`${x-1},${y-1}`);}
这样点击目标就可以打印目标格子的坐标。
注意:将onclick修改为onmouseover即可在鼠标移动上去时打印。
当然也可以将以下代码添加到
application.js
脚本之前,这样不需要刷新页面后手动执行该代码。
js/application.js
最终的完整内容为:
document.querySelector('.tile-container').addEventListener('click',function(e){var[_,x,y]=/(\d)-(\d)/.exec(e.toElement.offsetParent.className);[x,y]=[x,y].map(Number);
console.log(`${x-1},${y-1}`);});
window.requestAnimationFrame(function(){
window.manager=newGameManager(4,KeyboardInputManager,HTMLActuator,LocalStorageManager);});
撤回功能开发
我们考虑增加一个撤回功能,正常玩不小心玩错了就撤回。不过我设计的撤回代码仅能一步,有需要撤回多步的,大家可以继续发挥。
这里我们首先需要能够保存之前的数据,可以在move方法中增加以下两行代码:
var last_data =this.serialize();this.last_data=last_data;
然后增加撤回方法:
GameManager.prototype.recall=function(){var previousState =this.last_data;if(previousState){this.grid =newGrid(previousState.grid.size,previousState.grid.cells);this.score = previousState.score;this.over = previousState.over;this.won = previousState.won;this.keepPlaying = previousState.keepPlaying;this.actuate();}};
重启后,测试在控制台中调用以下代码,成功完成单步撤回功能:
manager.recall()
针对CSDN的2048游戏的处理
对于CSDN的2048游戏,游戏地址是https://edu.csdn.net/1024
该页面使用了webpack打包,会丢失原有的变量名,我们可以通过搜索关键字,或使用dom断点找到对应的代码进行修改。
交换位置功能
可以全局搜索
y.prototype.moveTile
后再增加如下代码:
y.prototype.swapTile=function(x1,y1,x2,y2){let tmp=this.grid.cells[x1][y1].value;this.grid.cells[x1][y1].value=this.grid.cells[x2][y2].value;this.grid.cells[x2][y2].value=tmp;this.actuate();}
然后通过断点调试找到如下代码:
可以通过对y对象的构造方法下断点找到:
找到后将其修改为:
1181:function(t, e, n){"use strict";
n.r(e);var o =n(1171), r =n(1017), c =n(1018), l =n(1020);
document.querySelector('.tile-container').addEventListener('click',function(e){var[_,x,y]=/(\d)-(\d)/.exec(e.toElement.offsetParent.className);[x,y]=[x,y].map(Number);
console.log(`${x-1},${y-1}`);});
window.requestAnimationFrame(function(){
window.manager=newo.default(4,r.default,c.default,l.default)})},
撤回功能
首先增加如下两行代码:
然后在上面增加撤回方法的定义:
y.prototype.recall=function(){var previousState =this.last_data;if(previousState){this.grid =newv.default(previousState.grid.size,previousState.grid.cells);this.score = previousState.score;this.over = previousState.over;this.won = previousState.won;this.keepPlaying = previousState.keepPlaying;this.actuate();}},
保存后刷新页面即可在控制台使用。
版权归原作者 小小明-代码实体 所有, 如有侵权,请联系我们删除。