`
jobar
  • 浏览: 340924 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

用Sencha Touch写2048游戏

 
阅读更多
1 UI部分
Ext.define('mobile2048.view.maincontainer', {
    extend: 'Ext.Container',

    requires: [
        'Ext.Panel',
        'Ext.field.Text',
        'Ext.Button'
    ],

    config: {
        height: 400,
        itemId: 'maincontainer',
        style: 'background:#bbada0',
        width: 326,
        layout: 'fit',
        items: [
            {
                xtype: 'container',
                layout: 'vbox',
                items: [
                    {
                        xtype: 'panel',
                        height: 80,
                        style: '',
                        layout: 'hbox',
                        items: [
                            {
                                xtype: 'container',
                                border: 2,
                                centered: false,
                                height: 68,
                                itemId: 'g11',
                                margin: 5,
                                padding: 28,
                                style: 'background:rgba(238, 228, 218, 0.35)',
                                width: 71
                            },
                            {
                                xtype: 'container',
                                baseCls: '',
                                border: 2,
                                centered: false,
                                cls: 'backgroud-color:blue',
                                height: 68,
                                itemId: 'g12',
                                margin: 5,
                                padding: 28,
                                style: 'background:rgba(238, 228, 218, 0.35)',
                                width: 71
                            },
                            {
                                xtype: 'container',
                                baseCls: '',
                                border: 2,
                                centered: false,
                                cls: 'backgroud-color:blue',
                                height: 68,
                                itemId: 'g13',
                                margin: 5,
                                padding: 28,
                                style: 'background:rgba(238, 228, 218, 0.35)',
                                width: 71
                            },
                            {
                                xtype: 'container',
                                baseCls: '',
                                border: 2,
                                centered: false,
                                cls: 'backgroud-color:blue',
                                height: 68,
                                itemId: 'g14',
                                margin: 5,
                                padding: 28,
                                style: 'background:rgba(238, 228, 218, 0.35)',
                                width: 71
                            }
                        ]
                    },
                    {
                        xtype: 'panel',
                        height: 80,
                        layout: 'hbox',
                        items: [
                            {
                                xtype: 'container',
                                border: 2,
                                centered: false,
                                height: 68,
                                itemId: 'g21',
                                margin: 5,
                                padding: 28,
                                style: 'background:rgba(238, 228, 218, 0.35)',
                                width: 71
                            },
                            {
                                xtype: 'container',
                                baseCls: '',
                                border: 2,
                                centered: false,
                                cls: 'backgroud-color:blue',
                                height: 68,
                                itemId: 'g22',
                                margin: 5,
                                padding: 28,
                                style: 'background:rgba(238, 228, 218, 0.35)',
                                width: 71
                            },
                            {
                                xtype: 'container',
                                baseCls: '',
                                border: 2,
                                centered: false,
                                cls: 'backgroud-color:blue',
                                height: 68,
                                itemId: 'g23',
                                margin: 5,
                                padding: 28,
                                style: 'background:rgba(238, 228, 218, 0.35)',
                                width: 71
                            },
                            {
                                xtype: 'container',
                                baseCls: '',
                                border: 2,
                                centered: false,
                                cls: 'backgroud-color:blue',
                                height: 68,
                                itemId: 'g24',
                                margin: 5,
                                padding: 28,
                                style: 'background:rgba(238, 228, 218, 0.35)',
                                width: 71
                            }
                        ]
                    },
                    {
                        xtype: 'panel',
                        height: 80,
                        layout: 'hbox',
                        items: [
                            {
                                xtype: 'container',
                                border: 2,
                                centered: false,
                                height: 68,
                                itemId: 'g31',
                                margin: 5,
                                padding: 28,
                                style: 'background:rgba(238, 228, 218, 0.35)',
                                width: 71
                            },
                            {
                                xtype: 'container',
                                baseCls: '',
                                border: 2,
                                centered: false,
                                cls: 'backgroud-color:blue',
                                height: 68,
                                itemId: 'g32',
                                margin: 5,
                                padding: 28,
                                style: 'background:rgba(238, 228, 218, 0.35)',
                                width: 71
                            },
                            {
                                xtype: 'container',
                                baseCls: '',
                                border: 2,
                                centered: false,
                                height: 68,
                                itemId: 'g33',
                                margin: 5,
                                padding: 28,
                                style: 'background:rgba(238, 228, 218, 0.35)',
                                width: 71
                            },
                            {
                                xtype: 'container',
                                baseCls: '',
                                border: 2,
                                centered: false,
                                cls: 'backgroud-color:blue',
                                height: 68,
                                itemId: 'g34',
                                margin: 5,
                                padding: 28,
                                style: 'background:rgba(238, 228, 218, 0.35)',
                                width: 71
                            }
                        ]
                    },
                    {
                        xtype: 'panel',
                        height: 80,
                        layout: 'hbox',
                        items: [
                            {
                                xtype: 'container',
                                border: 2,
                                centered: false,
                                height: 68,
                                itemId: 'g41',
                                margin: 5,
                                padding: 28,
                                style: 'background:rgba(238, 228, 218, 0.35)',
                                width: 71
                            },
                            {
                                xtype: 'container',
                                baseCls: '',
                                border: 2,
                                centered: false,
                                cls: 'backgroud-color:blue',
                                height: 68,
                                itemId: 'g42',
                                margin: 5,
                                padding: 28,
                                style: 'background:rgba(238, 228, 218, 0.35)',
                                width: 71
                            },
                            {
                                xtype: 'container',
                                baseCls: '',
                                border: 2,
                                centered: false,
                                cls: 'backgroud-color:blue',
                                height: 68,
                                itemId: 'g43',
                                margin: 5,
                                padding: 28,
                                style: 'background:rgba(238, 228, 218, 0.35)',
                                width: 71
                            },
                            {
                                xtype: 'container',
                                baseCls: '',
                                border: 2,
                                centered: false,
                                cls: 'backgroud-color:blue',
                                height: 68,
                                itemId: 'g44',
                                margin: 5,
                                padding: 28,
                                style: 'background:rgba(238, 228, 218, 0.35)',
                                width: 71
                            }
                        ]
                    },
                    {
                        xtype: 'textfield',
                        itemId: 'score',
                        label: '分数',
                        value: 100,
                        readOnly: true
                    },
                    {
                        xtype: 'button',
                        itemId: 'reset',
                        width: 121,
                        text: '重新开始'
                    }
                ]
            }
        ]
    }

});


2 控制器
Ext.define('mobile2048.controller.main', {
    extend: 'Ext.app.Controller',

    config: {
        refs: {
            main: '#maincontainer'
        },

        control: {
            "container#maincontainer": {
                initialize: 'onMaincontainerInitialize'
            },
            "button#reset": {
                tap: 'onResetTap'
            }
        }
    },

    onMaincontainerInitialize: function(component, eOpts) {
        var com = component;
        this.initGrid(com);
        com.renderElement.addListener('swipe',this.handleSwipe,this);
        return false;
    },

    onResetTap: function(button, e, eOpts) {
        this.initGrid();
        return false;
    },

    initGrid: function(com) {
        // console.log('initGrid');
        this.resetGame();
        this.generateRandomNum();
        return false;
    },

    handleSwipe: function(e,node,options) {
        if(this.gameOver()){
            Ext.Msg.show({
                title: '游戏结束,请重新开始',
                buttons: Ext.Msg.OK
            });
            return;
        }
        var direc = e.direction;
        switch(direc){
            case 'up':
                this.processUp();
                break;
            case 'down':
                this.processDown();
                break;
            case 'left':
                this.processLeft();
                break;
            case 'right':
                this.processRight();
                break;
        }
        return false;
    },

    processUp: function() {
        console.log('up');
        for(var i=1;i<=4;i++){
            var row = this.fetchRow(i,1);
            this.reArrange(i,row,'UP');
        }
        this.generateRandomNum();
        return false;
    },

    processDown: function() {
        console.log('down');
        for(var i=1;i<=4;i++){
            var row = this.fetchRow(i,1).reverse();
            this.reArrange(i,row,'DOWN');
        }
        this.generateRandomNum();
        return false;
    },

    processLeft: function() {
        console.log('left');
        for(var i=1;i<=4;i++){
            var row = this.fetchRow(i,0);
            this.reArrange(i,row,'LEFT');
        }
        this.generateRandomNum();
        return false;
    },

    processRight: function() {
        console.log('right');
        for(var i=1;i<=4;i++){
            var row = this.fetchRow(i,0).reverse();
            this.reArrange(i,row,'RIGHT');
        }
        this.generateRandomNum();
        return false;
    },

    generateRandomNum: function(num) {
        var main = this.getMain();
        var randomNum = Math.floor((Math.random() * 2) + 2);
        var count = 0;
        var roundNum = Math.min(randomNum, this.getEmptyCellNum());
        while(count<roundNum){
            var col = Math.floor((Math.random() * 4) + 1);
            var row = Math.floor((Math.random() * 4) + 1);
            var cub = main.down('#g'+row+col);

            if(Ext.isEmpty(cub.get('html'))){
                randomNum = Math.floor((Math.random() * 2)) * 2 + 2;
                cub.set('html',randomNum);
                this.totalScore += randomNum;
        //         console.log(row,col,randomNum,count);
                cub.set('style',mobile2048.Color[randomNum]);
                count++;
            }
        }
        this.updateScore();
        return false;
    },

    gameOver: function() {
        var main = this.getMain(),cell_a,a_v,cell_b,b_v, over = true;
        if(this.getEmptyCellNum() !== 0){
            return false;
        }
        for(var i=1;i<=4;i++){
            var k=1;
            for(var j=1;j<=4 && k<=4;j++){
                var k = j+1;
                cell_a = main.down('#g' + i + j);
                cell_b = main.down('#g' + i + k);
                a_v = (cell_a && cell_a.get('html')) ? cell_a.get('html') : null;
                b_v = cell_b && cell_b.get('html') ? cell_b.get('html') : null;
                if(a_v === b_v){
                    over = false;
                    break;
                }
            }
            if(!over) break;
        }
        if(over){
            for(var i=1;i<=4;i++){
                var k=1;
                for(var j=1;j<=4 && k<=4;j++){
                    var k = j+1;
                    cell_a = main.down('#g' + j + i);
                    cell_b = main.down('#g' + k + i);
                    a_v = (cell_a && cell_a.get('html')) ? cell_a.get('html') : null;
                    b_v = cell_b && cell_b.get('html') ? cell_b.get('html') : null;
                    if(a_v === b_v){
                        over = false;
                        break;
                    }
                }
                if(!over) break;
            }
        }
        return over;
    },

    fetchRow: function(rowNum, flag) {
        var row = [], main = this.getMain(),cube;
        for(var i=1;i<5;i++){
            if(flag === 0){
                cube = main.down('#g' + rowNum + i);
            }else{
                cube = main.down('#g' + i + rowNum);
            }
            var val = cube.get('html');
            val = val?val:0;
            row.push(val);
        }
        // console.log('fetched '+row);
        return row;
    },

    updateScore: function() {
        var main = this.getMain();
        main.down('#score').setValue(this.totalScore);
    },

    reArrange: function(rownum,row,direction) {
        var main = this.getMain();
        if(row){
            switch(direction){
                case 'LEFT':
                    row = this.merge(row);
                    break;
                case 'RIGHT':
                    row = this.merge(row).reverse();
                    break;
                case 'UP':
                    row = this.merge(row);
                    break;
                case 'DOWN':
                    row = this.merge(row).reverse();
                    break;
            }
        //     console.log('rearrange ' + row);
            var len = row.length,cell;
            for(var i=1;i<=len;i++){
                if(direction === 'LEFT' || direction === 'RIGHT'){
                    cel = main.down('#g'+rownum+i);
                }else{
                    cel = main.down('#g'+i+rownum);
                }
                var val = row[i-1];
                cel.set('html',val !== 0 ? val : null);
                cel.set('style',val !== 0 ? mobile2048.Color[val] : mobile2048.Color.defaultStyle);
            }
        }
    },

    merge: function(row) {
        for(var i=0;i<row.length;i++){
            if(row[i] === 0)
                continue;
            for(var j = i+1;j<row.length;j++){
                if(row[i] === row[j] && j === i+1){
                    row[i] += row[j];
                    row[j] = 0;
                    i++;
                }
            }
        }
        var count = 0;
        var len = row.length;
        var arr = [];
        for(var i=0; i<len;i++){
            if(row[i] !== 0){
                arr.push(row[i]);
            }
        }
        while(arr.length<len){
            arr.push(0);
        }
        return arr;
    },

    getEmptyCellNum: function() {
        var row,num = 0;
        for(var i=1;i<=4;i++){
            row = this.fetchRow(i);
            for(var j = 0;j<row.length;j++){
                if(row[j] === 0)
                    num++;
            }
        }
        console.log('Empty num of cell:' + num);
        return num;
    },

    resetGame: function() {
        var main = this.getMain();
        this.totalScore = 0;
        for(var i=1;i<5;i++){
            for(j=1;j<5;j++){
                cell = main.down('#g' + i + j);
                cell.set('html',null);
                cell.set('style',mobile2048.Color.defaultStyle);
            }
        }
    },

    getScore: function(row) {
        var score = 0;
        for(var i=0;i<row.length;i++){
            score += row[i];
        }
        return score;
    },

    init: function(application) {

    },

    launch: function() {
        this.totalScore = 0;
    }

});

3 application
// @require @packageOverrides
Ext.Loader.setConfig({

});


Ext.application({
    views: [
        'maincontainer'
    ],
    controllers: [
        'main'
    ],
    name: 'mobile2048',

    launch: function() {
        Ext.define('mobile2048.Color', {
            singleton: true,
            'defaultStyle': 'background:rgba(238, 228, 218, 0.35)',
            '2': 'background:#eee4da',
            '4':'background:#ede0c8',
            '8':'background:#f2b179',
            '16':'background:#f59563',
            '32':'background:#f67c5f',
            '64':'background:#f65e3b',
            '128':'background:#edcf72',
            '256':'background:#edcc61',
            '512': 'background:#edc850',
            '1024': 'background:#edc53f',
            '2048':'background:edc22e'
        });
        Ext.create('mobile2048.view.maincontainer', {fullscreen: true});
    }

});


4 效果:





  • 大小: 7.3 KB
  • 大小: 15.1 KB
分享到:
评论
3 楼 jobar 2014-06-10  
修正merge算法
    merge: function(row) {
        for(var i=0;i<row.length;i++){
            if(row[i] === 0)
                continue;
            for(var j = i+1;j<row.length;j++){
                if(row[j] === 0) continue;
                if(row[i] === row[j]){
                    row[i] += row[j];
                    row[j] = 0;
                    i++;
                }else{
                    break;
                }
            }
        }
        var count = 0;
        var len = row.length;
        var arr = [];
        for(var i=0; i<len;i++){
            if(row[i] !== 0){
                arr.push(row[i]);
            }
        }
        while(arr.length<len){
            arr.push(0);
        }
        return arr;
    }
2 楼 jobar 2014-06-10  
修正初始化函数:
    initGrid: function(com) {
        // console.log('initGrid');
        this.resetGame();
        this.generateRandomNum(true);
        return false;
    },
1 楼 jobar 2014-06-10  
修改随机数生产函数:

    generateRandomNum: function(init) {
        var main = this.getMain();
        var randomNum = Math.floor((Math.random() * 2) + 2);
        var count = 0;
        var roundNum = init ? randomNum : 1;
        while(count<roundNum){
            var col = Math.floor((Math.random() * 4) + 1);
            var row = Math.floor((Math.random() * 4) + 1);
            var cub = main.down('#g'+row+col);

            if(Ext.isEmpty(cub.get('html'))){
                randomNum = Math.floor((Math.random() * 2)) * 2 + 2;
                cub.set('html',randomNum);
                this.totalScore += randomNum;
                cub.set('style',mobile2048.Color[randomNum]);
                count++;
            }else if(this.getEmptyCellNum() === 0){
                count++;
            }
        }
        this.updateScore();
        return false;
    },

相关推荐

Global site tag (gtag.js) - Google Analytics