网页斗地主游戏

体系结构图

网页斗地主游戏_第1张图片
体系结构-nsp_k1.png

逻辑流程图

网页斗地主游戏_第2张图片
逻辑流程图.png

逻辑流程图详细

网页斗地主游戏_第3张图片
逻辑流程图详细.png

通讯图

网页斗地主游戏_第4张图片
通讯图.png

图片参考作者kamidox的文章使用 Sublime + PlantUML 高效地画图用代码生成图片

数据结构

var pkObj= {
    data: {
        type: 0,  //牌的类型
        from: 'Alice', //出牌方
        to: '',  //对手
        pokers: [],//出牌数组
        status: INIT,//状态
        counts: 27,//出牌数量
        success: 0
    },
    init: function() {
        ...
    }
}

牌型

网页斗地主游戏_第5张图片
poker.png

通过控制位置移动的方式得到每一张牌

.poker {
    width: 90px;
    height: 120px;
    margin-right: -50px;
    background-image: url("../images/poker.png");
}

按照3,4,5,6,7,8,9,10,J,Q,K,1,2,小王,大王的顺序显示在页面上

for(var j=0;j");
    singlePoker.addClass(pokerj);
    singlePoker.attr("data-value",index);
    singlePoker.css({
        "background-position": left + " " + top
    });
    $(".poker_me").append(singlePoker);
}
网页斗地主游戏_第6张图片
状态机指定出牌类型.png

生成出牌规则

  • 用状态机生成牌的类型
function typeState(type, n, m){
    switch(type){
        case ONE:
            if(n == m) {
                type = TWO;
            }else if(n+1 == m && m == 17){
               type = KING;
            } else if(n+1==m){
                type = STRAIGHT;
            } else {
                type = ERROR;
            }
            break;
        case TWO:
            if(n==m){
                type=THREE;
            }else if(n+1 == m){
                type=TWO_2;
            } else {
                type= ERROR;
            }
            break;
        case TWO_2:
            if(n==m){
                type = TWO;
            }else {
                type=ERROR;
            }
            break;
        case THREE:
            if(n==m){
                type = FOUR;
            }else if(n+1 == m){
                type = THREE_2;
            }else {
                type = ERROR;
            }
            break;
        case THREE_2:
            if(n==m){
                type = THREE_3;
            }else {
                type= ERROR;
            }
            break;
        case THREE_3:
            if(n==m){
                type = THREE;
            }else {
                type = ERROR;
            }
            break;
        case STRAIGHT:
            if(n+1 == m){
                type = STRAIGHT;
            }else {
                type = ERROR;
            }
            break;
        default:
            break;
    }
    return type;
}
  • 得到牌的类型
function getPokerType(pokerList){
    var type = ONE;
    var n,m;
    if(pokerList.length==1){//单张牌
        n = pokerList[0];
    }else {
        for(var i=1;i
  • 比较牌的大小
function comparePoker(sendPoker, receivePoker){
    var check = false;
    var dataSend = getPokerType(sendPoker);//得到发送牌的类型
    var dataReceive = getPokerType(receivePoker);//得到对方牌的类型
    console.log("发送的牌: ");
    console.log(dataSend);
    console.log("对方的牌: ");
    console.log(dataReceive);
    if(dataSend.type == dataReceive.type && (dataSend.length == dataReceive.length)
        &&(sendPoker[0]>receivePoker[0])){
        check = true;
    }
    //炸弹
    else if(dataSend.type == FOUR && dataReceive.type != FOUR){
        check = true;
    }// 王炸
    else if(dataSend.type == KING){
        check = true;
    }
    return check;
}

系统模块

  • 登陆界面
var htmlInit = "
";
网页斗地主游戏_第7张图片
init.png
  • 等待界面
var htmlWaiting = "

等待另一个人加入...

";
wait.png
  • 打牌界面
var htmlDiscard = "
";
网页斗地主游戏_第8张图片
send poker.png

消息模型

  • 服务器端
io.on('connection', function(socket){
   var user;
   //用户上线
   socket.on('startGame', function(obj){
      user = obj.data.from;
      console.log(user+"joined....");
      socket.join(obj.data.from);//加入房间
      if(onlineList.indexOf(user) == -1){
         onlineList.push(user);//添加到在线用户数组
      }
      count++;
      if(count == 1){
         meObj = obj;
         meObj.data.status = config.site.WAITING;//状态机置为waiting状态
         io.to(meObj.data.from).emit("waiting");
      }else if(count == 2){
          frdObj=obj;
          meObj.data.to = frdObj.data.from;
          frdObj.data.to = meObj.data.from;
          meObj.data.status = config.site.DISCARD;
          frdObj.data.status = config.site.DISCARD;
         //洗牌
         var pokers = shuffle();
         var pokerCounts=26;
         var poker_me = new Array(pokerCounts);//我的牌
         var poker_frd = new Array(pokerCounts);//朋友的牌
         for(var k=0, m=0;k<54;k++){
            if(k<=pokerCounts){
                poker_me[k]=pokers[k];
            }else{
                poker_frd[m]=pokers[k];
                m++;
            }
         }
         //排序
         sort(poker_me);
         sort(poker_frd);
         //对象
         meObj.data.pokers = poker_me;
         frdObj.data.pokers = poker_frd;
         //预先发牌
         io.to(meObj.data.from).emit("discard", meObj, frdObj.data.counts);
         io.to(frdObj.data.from).emit("discard", frdObj, meObj.data.counts);
      }else if(count > 2){//第三方加入,显示拥挤
         var index = onlineList.indexOf(user);//查找用户所在的位置
         if(index !== -1){
            onlineList.splice(index,1);//删除用户
         }
         count = 2;
         socket.emit("crowded");
      }
   });
    //发牌
    socket.on('send poker', function(obj, count, sendPoker){
      if(obj.data.counts == 0){
          obj.data.status = config.site.GAMEOVER;
          obj.data.success = 1;//成功
          io.to(obj.data.from).emit("game over", "你成功了");
          io.to(obj.data.to).emit("game over", "你失败了");
      }else{
          //收到牌
          io.to(obj.data.to).emit("receive poker", count, sendPoker);
      }
    });
    //放弃
    socket.on('send abandon', function(obj){
      obj.data.status = config.site.WAITING;
      io.to(obj.data.to).emit("receive abandon");
      var index = onlineList.indexOf(obj.data.from);
      if(index !== -1){
         onlineList.splice(index,1);//删除用户
         socket.leave(obj.data.from);//离开房间
      }
      console.log(obj.data.from + 'Offline....');
    });
   //连接错误
   socket.on('disconnect', function(){
     var index = onlineList.indexOf(user);//查找用户所在的位置
     if(index !== -1){
       onlineList.splice(index,1);//删除用户
       socket.leave(user);//离开房间
     }
     console.log(user + 'Offline....');
   });
   //用户离开
   socket.on('leave', function(){
     socket.emit('disconnect');
   });
});
  • 客户端client
//初始化
socket.on('init', function(obj){
    doInit();
});
//等待
socket.on('waiting', function(obj){
    doWaiting();
});
//发牌
socket.on("discard", function(objMe, countsFrd){
    doDiscard();
    showPoker(objMe);//显示我的牌
    showPokerFrd(countsFrd);//显示对方的牌
    sendPoker(objMe); //发送牌
});
//收到牌
socket.on('receive poker', function(countFrd,sendPoker){
    recePoker(countFrd, sendPoker);
});
//游戏结束
socket.on('game over', function(message){
    alert(message);
});
//一方放弃
socket.on('receive abandon', function(){
    alert("对方放弃了....");
});
//第三方进入,显示拥挤
socket.on('crowded', function(){
    alert("人满了...");
});

出牌函数

  • 洗牌函数(返回洗牌数组)
function shuffle() {
    var temp, count = 54;
    var pokers = new Array(count);//牌
    for (var i = 0; i < count; i++) {
        pokers[i] = i;
    }
    //打乱牌
    for (var j = 0; j < count; j++) {
        var rd = parseInt(Math.random() * count);
        temp = pokers[j];
        pokers[j] = pokers[rd];
        pokers[rd] = temp;
    }
    return pokers;
}
  • 给牌排序(输入:牌的数组)
function sort(pokers){
   var i=27,temp;
   while (i > 0) {
       for (var j = 0; j < i-1; j++) {
         if ((pokers[j]+11)%13 > (pokers[j + 1]+11)%13) {
                temp = pokers[j];
                pokers[j] = pokers[j + 1];
                pokers[j + 1] = temp;
          }
         if(pokers[j]===52){//大王一直往后移
               temp = pokers[j];
               pokers[j] = pokers[j + 1];
               pokers[j + 1] = temp;
         }
         if(pokers[j]===53 && pokers[j+1]!==52){//小王一直往后移,直到遇到大王
              temp = pokers[j];
              pokers[j] = pokers[j + 1];
              pokers[j + 1] = temp;
         }
       }
       i--;
   }
}
  • 显示牌
function showPoker(obj){
    var index;
    for(var j=0;j");
        singlePoker.addClass(pokerj);
        singlePoker.attr("data-value",index);
        singlePoker.css({
            "background-position": left + " " + top
        });
        $(".poker_me").append(singlePoker);
    }

    $(".poker_me .poker").click(function(){
        if($(this).hasClass('selected')){//已经被选择
            $(this).animate({
                "margin-top":"0px"
            });
            $(this).removeClass("selected");//移除属性
        }else {
            $(this).animate({//未选择
                "margin-top":"-20px"
            });
            $(this).addClass("selected");//添加属性,牌选中
        }
    });
}
  • 打牌--没有牌表示成功
function sendPoker(obj) {
    //发牌
    $("#sendPoker").click(function(){
        var count = 0;//每次发的牌的个数
        var sendPokerList = new Array();//发出去的牌
        var receivePokerList = new Array();//收到的牌
        //如果展示区域有牌,那么先清空牌
        if($(".pokerArea").children('.poker') !== null){  //展示区域有牌
            $(".pokerArea").children('.poker').each(function(){
                receivePokerList.push(parseInt($(this).attr("data-value")));//获取当前元素
            });
        }
        console.log("对方的牌");
        console.log(receivePokerList);

        for(var k=0;k<27;k++) {
            var index = ".me .pokerMe" + k;//我的牌
            if ($(index).hasClass('selected')) {
                sendPokerList[count] = parseInt($(index).attr("data-value"));
                obj.data.counts--;
                count++;
            }
        }

        console.log("发送的牌");
        console.log(sendPokerList);

        //开始发牌
        if(receivePokerList.length===0){
            $('.pokerArea').html("");//清空
            for(var k=0;k<27;k++) {
                var index = ".pokerMe" + k;
                if ($(index).hasClass('selected')) {
                    $(".pokerArea").append($(index));
                }
            }
            var sendPoker = $(".pokerArea").html();
            var type = getPokerType(sendPokerList).type;
            console.log(type);
            if(type=="ONE" || type == "TWO" || type == "TWO_2"
              || type == "THREE" || type == "THREE_2" || type == "THREE_3"
              || type == "FOUR" || type == "STRAIGHT"){
                socket.emit('send poker', obj, count, sendPoker);//发送牌到对方界面
            }else if(type=="ERROR"){
               alert("发送的牌不符合要求....")
            }
            $(".sendPoker").hide();//发送之后,给按钮移除disabled的属性
            $(".anstain").hide();
        }
        //发牌
        else if(comparePoker(sendPokerList, receivePokerList)){
            $('.pokerArea').html("");//清空
            for(var k=0;k<27;k++) {
                var index = ".pokerMe" + k;
                if ($(index).hasClass('selected')) {
                    $(".pokerArea").append($(index));
                }
            }
            var sendPoker = $(".pokerArea").html();
            socket.emit('send poker', obj, count, sendPoker);//发送牌到对方界面
            $(".sendPoker").hide();//发送之后,给按钮移除disabled的属性
            $(".anstain").hide();
        }else{//不能发牌
            alert("不能发送,请重新选择");
        }

    });
    //不出,弃权
    $("#anstain").click(function(){
        console.log("不出");
        socket.emit('send poker', obj, 0, "");//发送牌到数据库
        $(".sendPoker").hide();//发送之后,给按钮移除disabled的属性
        $(".anstain").hide();
    });
    $("#abandon").click(function(){
        obj.data.success = 0;
        obj.data.status = INIT;
        socket.emit('send abandon',obj);
        doInit();
    });
}
  • 收到牌
function recePoker(countFrd,sendPoker){
    $(".sendPoker").show();//发送之后,给按钮移除disabled的属性
    $(".anstain").show();
    $('.pokerArea').html("");//清空
    for(var i=0;i

你可能感兴趣的:(网页斗地主游戏)