大家好,欢迎来到IT知识分享网。
2048网页版是一款开源游戏:Gabriele Cirulli.
在线游戏地址:https://2048game.com/
本人的历史成绩:
于是范总提出了质疑:
下面我给大家公布一下,在2048游戏开挂的方法。
源码分析
源码地址:https://gitcode.net/mirrors/gabrielecirulli/2048
游戏的入口代码是js/application.js
:
window.requestAnimationFrame(function() {
new GameManager(4,KeyboardInputManager,HTMLActuator,LocalStorageManager); });
GameManager的定义在js/game_manager.js
:
function GameManager(size, InputManager, Actuator, StorageManager) {
this.size = size; this.inputManager = new InputManager; this.storageManager = new StorageManager; this.actuator = new Actuator; 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 = new Grid(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 = new Grid(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=new GameManager(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 = new Grid(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=new o.default(4,r.default,c.default,l.default) }) },
撤回功能
首先增加如下两行代码:
然后在上面增加撤回方法的定义:
y.prototype.recall = function() {
var previousState = this.last_data; if (previousState) {
this.grid = new v.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(); } },
保存后刷新页面即可在控制台使用。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/136271.html