{"size": 10261, "ext": "js", "max_stars_repo_path": "assets/script/game_2048_js/2048_start.js", "max_stars_repo_name": "antiwise/game_with_cocosCreater", "max_stars_repo_stars_event_min_datetime": "2019-09-18T06:31:16.000Z", "max_stars_repo_stars_event_max_datetime": "2019-09-18T06:31:16.000Z", "max_issues_repo_path": "assets/script/game_2048_js/2048_start.js", "max_issues_repo_name": "antiwise/game_with_cocosCreater", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "assets/script/game_2048_js/2048_start.js", "max_forks_repo_name": "antiwise/game_with_cocosCreater", "max_forks_repo_forks_event_min_datetime": "2019-09-18T06:31:21.000Z", "max_forks_repo_forks_event_max_datetime": "2019-09-18T06:31:21.000Z"}
{"max_stars_count": 1, "max_issues_count": null, "max_forks_count": 1, "avg_line_length": 34.0897009967, "max_line_length": 247, "alphanum_fraction": 0.4366046194}
const Utils = require('../utils.js');

cc.Class({
    extends: cc.Component,
    properties: {
        rectPfb: {
            default: null,
            type: cc.Prefab
        },
        currentScore: {
            default: null,
            type: cc.Node
        },
        infoPanel: {
            default: null,
            type: cc.Node
        },
        infoScore: {
            default: null,
            type: cc.Node
        },
        infoBestScore: {
            default: null,
            type: cc.Node
        },
        gameWinMask: {
            default: null,
            type: cc.Node
        }
    },
    onLoad() {
        let windowSize = cc.view.getVisibleSize();
        this.node.height = this.node.width = windowSize.width - 14;
        let rectBgNode = this.node.getChildByName('gameShadowRect');
        this.ctx = rectBgNode.getComponent(cc.Graphics);
        //格子数组
        this.map = [
            [0, 0, 0, 0],
            [0, 0, 0, 0],
            [0, 0, 0, 0],
            [0, 0, 0, 0]
        ];
        this.box_width = this.node.width * 0.86 * 0.25; //单个方块宽度
        this.margin_width = this.node.width * 0.14 * 0.2; //方块之间的间隔
        //不同数字的背景颜色信息
        this.num_color = {
            '0': "#ccc0b3",
            '2': "#ffeecd",
            '4': "#ffcb6a",
            '8': "#ffa65a",
            '16': "#ff8545",
            '32': "#ff643f",
            '64': "#e4451e",
            '128': "#bd3b18",
            '256': "#ece688",
            '512': "#f8ec24",
            '1024': "#42f391",
            '2048': "#00ffae"
        };
        //space表示当前剩余的空格块数，score表示当前的分数
        this.space = 16;
        this.score = 0;
        this.isGameOver = false;
        this.bestScore = Utils.GD.userGameInfo.tzfeBestScore || 0;
        this.WinTimes = Utils.GD.userGameInfo.tzfeWinNum || 0;
    },
    //循环
    loop(func) {
        for (let i = 0; i < 4; i++)
            for (let j = 0; j < 4; j++) func(i, j);
    },
    //绘制方块背景
    drawBgShadowRect() {
        const self = this;
        let color = new cc.Color(255, 255, 255, 30);
        self.loop(function (i, j) {
            let x = j == 0 ? self.margin_width : j * (self.box_width + self.margin_width) + self.margin_width,
                y = i == 3 ? self.margin_width : (3 - i) * (self.box_width + self.margin_width) + self.margin_width;
            self.ctx.lineWidth = 0;
            self.ctx.rect(x, y, self.box_width, self.box_width);
            self.ctx.fillColor = color;
            self.ctx.fill();
        })
    },
    // 随机生成方块
    produce() {
        // 随机取当前剩余方块以内的数
        const self = this;
        let cot = ~~(Math.random() * self.space);
        let k = 0;
        self.loop(function (i, j) {
            if (self.map[i][j] == 0) {
                if (cot == k) {
                    self.map[i][j] = 2;
                    self.block();
                }
                k += 1;
            }
        });
        self.space -= 1;
    },
    clearNumRects() { //销毁方块
        for (let i = 0; i < this.node.children.length; i++) {
            if (this.node.children[i]._name == '2048RectPfb') this.node.children[i].destroy();
        }
    },
    // 根据map 数组渲染方块
    block() {
        const self = this;
        self.clearNumRects();
        self.loop((i, j) => {
            let num = self.map[i][j],
                color = self.num_color[String(num)];
            if (num != 0) {
                self.drawRects(j == 0 ? self.margin_width : j * (self.box_width + self.margin_width) + self.margin_width, i == 3 ? self.margin_width : (3 - i) * (self.box_width + self.margin_width) + self.margin_width, self.box_width, color, num);
            }
        })
    },
    // 绘制单个矩形
    drawRects(x, y, w, c, n) {
        let rect = cc.instantiate(this.rectPfb);
        rect.width = rect.height = w;
        rect.setPosition(cc.p(x, y));
        let label = rect.getChildByName('2048Number'),
            bg = rect.getChildByName('2048RectBg');
        bg.color = cc.hexToColor(String(c));
        label.color = (n <= 4) ? cc.hexToColor("#ffb638") : cc.Color.WHITE;
        label.getComponent(cc.Label).string = n;
        this.node.addChild(rect);
    },
    // game start 默认生成两个方块
    init() {
        for (let i = 0; i < 2; i++) this.produce();
    },
    move(direction) {
        let isValid = false; //判断是否是有效移动
        if (this.isGameOver) return;

        function convert(x, y) { //根据不同方向调整遍历方式
            let tx = x,
                ty = y,
                tmpTx = tx;
            if (direction[0] == 0) {
                tx = ty;
                ty = tmpTx;
            };
            if (direction[1] > 0) tx = 3 - tx;
            if (direction[0] > 0) ty = 3 - ty;
            return [tx, ty];
        };

        for (let i = 0; i < 4; i++) {
            let tmp = [];
            let isadd = false; //每一行或者每一列只能有一次数字合并
            for (let j = 0; j < 4; j++) {
                let ti = convert(i, j)[0],
                    tj = convert(i, j)[1];
                if (this.map[ti][tj] != 0) {
                    if (!isadd && this.map[ti][tj] == tmp[tmp.length - 1]) {
                        this.score += (tmp[tmp.length - 1] *= 2); //数字合并获得分数加成
                        if (tmp[tmp.length - 1] == 2048) { //如果获得2048则游戏结束
                            this.isGameOver = true;
                            this.showTheGamePanel(true, this.gameWinMask);
                            this.setWinTimes();
                        };
                        isadd = true;
                        this.space += 1;
                        if (!isValid) isValid = true; //发生数字合并认定这次移动为有效移动
                        this.currentScore.getComponent(cc.Label).string = 'score:' + this.score;
                    } else {
                        tmp.push(this.map[ti][tj]);
                    }
                }
            };
            for (let j = 0; j < 4; j++) {
                let ti = convert(i, j)[0],
                    tj = convert(i, j)[1];
                if (this.map[ti][tj] == 0 && tmp[j] > 0)
                    if (!isValid) isValid = true; //数字发生移动，（原来为0的数字变为大于0被认为是有效移动）
                this.map[ti][tj] = isNaN(tmp[j]) ? 0 : tmp[j];
            }
        };
        if (isValid && this.space > 0) { //如果是有效移动则在随机空位新生成一个数字2
            this.produce();
            isValid = false;
        };
        if (this.space == 0 && this.gameOver() && !this.isGameOver) { //判断游戏失败 剩余空格为0 并且没有数字可以合并时游戏结束
            this.isGameOver = true;
            this.infoScore.getComponent(cc.Label).string = 'score:' + this.score;

            this.setDbDataWhenScoreChange(); //保存最高分
            this.infoBestScore.getComponent(cc.Label).string = 'best:' + this.bestScore;
            this.showTheGamePanel(true, this.infoPanel);
            return;
        }
    },
    gameOver() { //判断是否还有可能的合并
        for (let i = 0; i < 4; i++) {
            for (let j = 0; j < 4; j++) {
                let t = ((i == 0) ? null : [i - 1, j]),
                    r = ((j == 3) ? null : [i, j + 1]),
                    b = ((i == 3) ? null : [i + 1, j]),
                    l = ((j == 0) ? null : [i, j - 1]);
                if (t && this.map[i][j] == this.map[t[0]][t[1]]) return false;
                if (r && this.map[i][j] == this.map[r[0]][r[1]]) return false;
                if (b && this.map[i][j] == this.map[b[0]][b[1]]) return false;
                if (l && this.map[i][j] == this.map[l[0]][l[1]]) return false;
            }
        };
        return true;
    },
    setDbDataWhenScoreChange() {
        const self = this;
        if (self.score > self.bestScore) {
            self.bestScore = self.score;
            Utils.GD.updateGameScore({tzfeBestScore: self.bestScore}, () => {
                Utils.GD.setUserGameInfo('tzfeBestScore', self.bestScore);
                console.log('保存成功');
            })
        }
    },
    setWinTimes() {
        const self = this;
        self.WinTimes = self.WinTimes + 1;
        Utils.GD.updateGameScore({tzfeWinNum: self.WinTimes}, () => {
            Utils.GD.setUserGameInfo('tzfeWinNum', self.WinTimes);
            console.log('保存成功');
        })
    },
    showTheGamePanel(bool, cpt) {
        if (bool) {
            cpt.active = bool;
            cpt.opacity = 0;
            cpt.runAction(
                cc.fadeIn(0.2)
            )
        } else {
            cpt.runAction(
                cc.sequence(
                    cc.fadeOut(0.2),
                    cc.callFunc(() => {
                        // 加载列表
                        cpt.active = bool;
                    }, this)
                )
            )
        }
    },
    //玩家触摸事件
    eventHandle() {
        let canvasScr = this.node.parent,
            sx, sy, dx, dy;
        canvasScr.on(cc.Node.EventType.TOUCH_START, (e) => {
            let startPoint = e.getLocation();
            sx = startPoint.x;
            sy = startPoint.y;
            dx = 0;
            dy = 0;
        }, this);

        canvasScr.on(cc.Node.EventType.TOUCH_MOVE, (e) => {
            let startPoint = e.getLocation();
            let ex = startPoint.x;
            let ey = startPoint.y;
            dx = ex - sx;
            dy = ey - sy;
        }, this);

        canvasScr.on(cc.Node.EventType.TOUCH_END, (e) => {
            //根据横纵坐标位移判断滑动方向
            if (dy < -30 && Math.abs(dy / dx) > 2) this.move([0, 1]);
            if (dy > 30 && Math.abs(dy / dx) > 2) this.move([0, -1]);
            if (dx < -30 && Math.abs(dx / dy) > 2) this.move([-1, 0]);
            if (dx > 30 && Math.abs(dx / dy) > 2) this.move([1, 0]);
        }, this);
    },
    back_game_list() {
        cc.director.loadScene('startscene');
    },
    restartGame() {
        this.clearNumRects();
        this.space = 16;
        this.score = 0;
        this.isGameOver = false;
        this.map = [
            [0, 0, 0, 0],
            [0, 0, 0, 0],
            [0, 0, 0, 0],
            [0, 0, 0, 0]
        ];
        this.showTheGamePanel(false, this.infoPanel);
        this.showTheGamePanel(false, this.gameWinMask);
        this.currentScore.getComponent(cc.Label).string = 'score:' + this.score;
        this.init();
    },
    start() { //初始化
        this.drawBgShadowRect();
        this.eventHandle();
        this.init();
    }
})