找回密码
 立即注册

扫一扫,访问微社区

查看: 11469|回复: 7

小程序demo:2048游戏;基于web版2048游戏开发

  [复制链接]
发表于 2017-2-13 20:09:56 | 显示全部楼层 |阅读模式
似乎比以前的2048类游戏都复杂一些,我是没看懂;




[size=0.83em]
11.png (11.32 KB, 下载次数: 16)
[color=rgb(153, 153, 153) !important]2016-12-17 15:00 上传








[mw_shl_code=applescript,true]var Grid = require('./grid.js');
var Tile = require('./tile.js');

function GameManager(size) {
    this.size = size;
    this.startTiles = 2;
}

GameManager.prototype = {
    setup: function() {

        this.grid = new Grid(this.size);
        this.score = 0;
        this.over = false;
        this.won = false;
        this.addStartTiles();
        return this.grid.cells;
    },

    // 初始化数据
    addStartTiles: function() {
        for (var x = 0; x < this.startTiles; x++) {
            this.addRandomTiles();
        }
    },

    // 在一个随机单元格中随机填充2或4
    addRandomTiles: function() {

        if (this.grid.cellsAvailable()) {
            var value = Math.random() < 0.9 ? 2 : 4;
            var cell = this.grid.randomAvailableCell();
            var tile = new Tile(cell, value);
            this.grid.insertTile(tile); // 插入一个单元格
        }

    },

    actuate: function() {

        return {
            grids: this.grid.cells,
            over: this.over,
            won: this.won,
            score: this.score
        }
    },

    // 偏移向量
    getVector: function(direction) {
         
        var map = {
            0: { // 上
                x: -1,
                y: 0
            },
            1: { // 右
                x: 0,
                y: 1
            },
            2: { // 下
                x: 1,
                y: 0
            },
            3: { // 左
                x: 0,
                y: -1
            }
        };
        return map[direction];
    },

    buildTraversals: function(vector) {
        var traversals = {
            x: [],
            y: []
        };

        for (var pos = 0; pos < this.size; pos++) {
            traversals.x.push(pos);
            traversals.y.push(pos);
        }

        // 为什么要加这个,看findFarthestTail
        if (vector.x === 1) {
            // 向右时
            traversals.x = traversals.x.reverse();
        }

        if (vector.y === 1) {
            // 向下
            traversals.y = traversals.y.reverse();
        }

        return traversals;
    },

    // 把当前单元格挪至下一个可放置的区域
    moveTile: function(tile, cell) {
        this.grid.cells[tile.x][tile.y] = null;
        this.grid.cells[cell.x][cell.y] = tile;
        tile.updatePosition(cell);
    },

    // 特定方向移动单元格
    move: function(direction) {
        // 0: up, 1: right, 2: down, 3: left
        var self = this;
        var vector = this.getVector(direction);
        var traversals = this.buildTraversals(vector);

        var cell;
        var tile;
        var moved = false;
        self.prepareTiles();

        traversals.x.forEach(function(x) {
            traversals.y.forEach(function(y) {
                // console.log('x:', x, 'y:', y);
                cell = {
                    x: x,
                    y: y
                };
                tile = self.grid.cellContent(cell);

                if (tile) { // 单元格有内容
                    var positions = self.findFarthestTail(cell, vector);
                    var next = self.grid.cellContent(positions.next);

                    if (next && next.value === tile.value && !next.mergedFrom) {
                        // 当前格子和其移动方向格子内容相同,需要合并
                        var merged = new Tile(positions.next, tile.value * 2); // 合并后的格子信息

                        merged.mergedFrom = [tile, next];

                        self.grid.insertTile(merged); // 把合并的盒子插入到当前格子数据中
                        self.grid.removeTile(tile); // 删除当前格子内容

                        tile.updatePosition(positions.next);

                        self.score += merged.value;
                        if (merged.value === 2048) self.won = true;
                    } else {
                        self.moveTile(tile, positions.farthest);
                    }

                    // 是否从当前位置移到当前位置
                    if (!self.positionsEqual(cell, tile)) {
                        moved = true;
                    }
                }
            });
        });

        if (moved) {
            this.addRandomTiles();

            if (!this.movesAvailable()) {
                this.over = true;
            }

            return this.actuate();
        }

        // return this.grid.cells

    },

    prepareTiles: function() {

        var tile;
        for (var x = 0; x < this.size; x++) {
            for (var y = 0; y < this.size; y++) {
                tile = this.grid.cells[x][y];
                if (tile) {
                    tile.mergedFrom = null;
                    tile.savePosition();
                }
            }
        }
    },

    positionsEqual: function(first, second) {
        return first.x === second.x && first.y === second.y;
    },

    movesAvailable: function() {
        return this.grid.cellsAvailable() || this.tileMatchesAvailable();
    },

    tileMatchesAvailable: function() {
        var self = this;

        var tile;

        for (var x = 0; x < this.size; x++) {
            for (var y = 0; y < this.size; y++) {
                tile = this.grid.cellContent({ x: x, y: y });

                if (tile) {
                    for (var direction = 0; direction < 4; direction++) {
                        var vector = self.getVector(direction);
                        var cell = { x: x + vector.x, y: y + vector.y };

                        var other = self.grid.cellContent(cell);

                        if (other && other.value === tile.value) {
                            return true;
                        }
                    }
                }
            }
        }

        return false;
    },

    // 找到当前偏移方向存在最远的空单元格
    // 如:向右偏移,那么返回当前行最靠右的空单元格及其右侧距离其最远的一个格子,向下一样
    findFarthestTail: function(cell, vector) {
        var previous;

        // 当前单元格在范围内且存在可用单元格
        do {
            previous = cell;
            cell = {
                x: previous.x + vector.x,
                y: previous.y + vector.y
            };
        }
        while (this.grid.withinBounds(cell) && this.grid.emptyCell(cell));

        return {
            farthest: previous,
            next: cell
        }
    },

    // 重新开始
    restart: function() {
        return this.setup();
    }
}

module.exports = GameManager;[/mw_shl_code]




游客,如果您要查看本帖隐藏内容请回复

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×

0

主题

17

回帖

37

金钱

新人求带

积分
0
发表于 2017-11-6 13:19:58 | 显示全部楼层
不错,打个call

0

主题

10

回帖

38

金钱

新人求带

积分
0
发表于 2018-4-9 18:37:19 | 显示全部楼层
看一看 感谢

0

主题

3

回帖

14

金钱

新人求带

积分
0
发表于 2018-5-19 14:01:50 | 显示全部楼层
6666666666666666666666666666

0

主题

16

回帖

28

金钱

新人求带

积分
0
发表于 2018-6-2 22:48:37 | 显示全部楼层

看一看 感谢

0

主题

7

回帖

40

金钱

新人求带

积分
0
发表于 2018-6-9 13:03:23 | 显示全部楼层
回复

使用道具 举报

0

主题

22

回帖

70

金钱

新人求带

积分
0
发表于 2018-6-20 14:04:27 | 显示全部楼层
666666666666666666666666666666

0

主题

353

回帖

830

金钱

新人求带

积分
0
发表于 2020-4-7 11:28:45 | 显示全部楼层
我有流量,寻求个人游戏开发者合作,有意者联系微信号jim20180688
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|微信小程序开发|教程|文档|资源汇总_即速论坛 ( 粤ICP备14097199号-1  

GMT+8, 2024-12-24 02:33 , Processed in 0.121437 second(s), 31 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表