2048网页版游戏高分插件代码分享

2048网页版是一款开源游戏:Gabriele Cirulli.

在线游戏地址:https://2048game.com/

本人的历史成绩:

image-20221025183914736

于是范总提出了质疑:

image-20221025184008734

下面我给大家公布一下,在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的值后刷新页面可以自定义当前分数和布局。

image-20221025144517681

不过这样就太没意思了,压根没玩。

交换位置功能开发

考虑设计增加一个交换位置的方法,可以在游戏难以进行时,交换指定两个格子的位置。

首先我们启动本地替代后,修改js/application.js的代码,将GameManager导出,即增加window.manager的代码:

image-20221025145746955

然后使用同样的方法修改js/game_manager.js的代码:

image-20221025150052811

增加了如下代码:

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

保存后刷新页面即可生效。

效果:

image-20221025150340951

只需再控制台执行:

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;

image-20221025175745050

然后增加撤回方法:

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

image-20221025180632226

然后通过断点调试找到如下代码:

image-20221025180925579

可以通过对y对象的构造方法下断点找到:

image-20221025181107913

找到后将其修改为:

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

撤回功能

首先增加如下两行代码:

image-20221025183024659

然后在上面增加撤回方法的定义:

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

保存后刷新页面即可在控制台使用。

猜你喜欢

转载自blog.csdn.net/as604049322/article/details/127519176