模仿斗地主2

实现功能:

  1. 登陆界面,点击登陆按钮;
  • 如果只有一个用户,进入到等待界面;
  • 如果是两个用户,进入到打牌界面
登陆界面,只有一个登陆按钮
  1. 等待界面: 显示等待另外一个用户登陆
等待界面
  1. 打牌界面:界面分为4块,分别是对方牌的区域,显示打出的牌,控制按钮区域,自己的牌的区域
  • 如果点击打牌,选中的牌会向上移,
    然后点击打牌,自己和对方都会收到这个牌,并显示在中间的区域;
    此时隐藏自己的操作按钮,将选择权交给对方。
  • 点击退出游戏,对方窗口弹出提示信息;
  • 一方的牌打完之后,会给双方都发送提示信息。
发送方

接收方

服务器端www文件

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

var config = require('../config');
//socket.io部分
var onlineList = [];//在线用户列表
//服务器端引入socket.io
var io = require('socket.io').listen(server);
var count = 0;
var user = {};
var me;
var frd;
var meObj = {};
var frdObj = {};
io.on('connection', function(socket){
   var user;
   //用户上线
   socket.on('startGame', function(obj){
      user = obj.data.from;
      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");
    });

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

客户端 poker.js

INIT=0;
WAITING=1;
DISCARD=2;
GAMEOVER=3;
var htmlInit = "<div class='init'><button type='button' id='startGame'></button></div>";
var htmlWaiting = "<div class='waiting' id='waiting'><h2>等待另一个人加入...</h2></div>";
var htmlDiscard = "<div class='discard' id='discard'> <div class='friend'> <div class='image_frd'></div> <div class='poker_frd'> </div> </div> <div class='playArea'> <main class='pokerArea'> </main> </div> <div class='menu'> <button class='sendPoker' id='sendPoker'></button> <button class='anstain' id='abstain'></button><button class='abandon' id='abandon'></button> </div> <div class='me'> <div class='image_me'></div> <div class='poker_me'> </div> </div> </div>";

var socket = io();
var pkObj= {
    data: {
        type: 0,  //牌的类型
        from: 'Alice',
        to: '',
        pokers: [],//数组
        status: INIT,//状态
        counts: 27,
        success: 0
    },
    init: function() {
        pkObj.data.from += parseInt(Math.random() * 10);
        //初始化
        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("人满了...");
        })
    }
};

$(init);

function init() {
    pkObj.init();
    // $("body").on("click", statusMachine);
    $("body").on('click', '#startGame', startGame);//点击按钮,开始跳转
}

function statusMachine(e){
    var tag = e.target;
    switch(pkObj.data.status){
        case INIT:
            doInit(tag);
            break;
        case WAITING:
            doWaiting(tag);
            break;
        case DISCARD:
            doDiscard(tag);
            break;
        case GAMEOVER:
            doRestart(tag);
            break;
    }
}

//初始化
function doInit(tag) {
    $(".wrapper").html("");
    $(".wrapper").append(htmlInit);
}
//开始游戏
function startGame(){
    socket.emit('startGame',pkObj);//开始游戏
}
//等待
function doWaiting(tag){
    $(".wrapper").html("");
    $(".wrapper").append(htmlWaiting);
}
//发牌
function doDiscard(tag){
    $(".wrapper").html("");
    $(".wrapper").append(htmlDiscard);
}
//重新开始
function doRestart(tag){
    $(".wrapper").html("");
    $(".wrapper").append(htmlInit);
}

function showPoker(obj){
    for(var j=0;j<obj.data.counts;j++) {
        var x = obj.data.pokers[j] % 13 * (-90);
        var y = parseInt(obj.data.pokers[j] / 13) * (-120);
        var left = x + "px";
        var top = y + "px";
        var pokerj = "pokerMe" + j;
        var singlePoker = $("<button class='poker'></button>");
        singlePoker.addClass(pokerj);
        singlePoker.css({
            "background-position": left + " " + top
        });
        $(".poker_me").append(singlePoker);
    }

    $(".poker_me .poker").click(function(){
        if($(this).hasClass('selected')){//已经被选择
            $(this).animate({
                "margin-top":"+20px"
            });
            $(this).removeClass("selected");//移除属性
        }else {
            $(this).animate({//未选择
                "margin-top":"-20px"
            });
            $(this).addClass("selected");//添加属性,牌选中
        }
    });
}

function showPokerFrd(countsFrd){
    for(var j=0;j<countsFrd;j++) {
        var singlePoker = $("<button class='poker'></button>");
        singlePoker.css({
            "background-position": "-180px -480px "
        });
        $(".poker_frd").append(singlePoker);
    }
}

//打牌--没有牌表示成功
function sendPoker(obj) {
    //发牌
    $("#sendPoker").click(function(){
        var count = 0;//每次发的牌的个数
        if($(".pokerArea").children('.poker') != null){  //展示区域有牌
            $('.pokerArea').html("");//清空
        }
        for(var k=0;k<27;k++) {
            var index = ".pokerMe" + k;
            if ($(index).hasClass('selected')) {
                $(".pokerArea").append($(index));
                obj.data.counts--;
                count++;
            }
        }
        var sendPoker = $(".pokerArea").html();
       // $(".sendPoker").attr("disabled", "disabled");//发送之后,给按钮移除disabled的属性
       //  $(".anstain").attr("disabled", "disabled");
        $(".sendPoker").hide();//显示按钮
        $(".anstain").hide();
        socket.emit('send poker', obj, count, sendPoker);//发送牌到数据库
    });
    //不出,弃权
    $("#anstain").click(function(){
    });
    $("#abandon").click(function(){
        obj.data.success = 0;
        obj.data.status = INIT;
        socket.emit('send abandon',obj);
        doInit();
    });
}

//收到牌
function recePoker(countFrd,sendPoker){
    console.log("发送之后,给按钮移除disabled的属性");
    // $(".sendPoker").attr("disabled", "");//发送之后,给按钮移除disabled的属性
    // $(".anstain").attr("disabled", "");
    $(".sendPoker").show();//发送之后, 隐藏按钮
    $(".anstain").show();
    $('.pokerArea').html("");//清空
    for(var i=0;i<countFrd;i++){
        $(".poker_frd .poker:first").remove();
    }
    $(".pokerArea").append(sendPoker);//收到牌
}

css使用flex语法

button {
    border: none;
    border-radius: 5px;
    cursor: pointer;
}
.wrapper {
    width: 100%;
    height: 100%;
    min-height: 100vh;
    background-color: #1D4F84!important;
}
.init {
    width: 100%;
    height: 100%;
    min-height: 100vh;
    background-image: url("../images/bg_2.png") ;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}
.init #startGame {
    align-items: center;
    justify-content: space-between;
    background-image: url("../images/button.png");
    background-position: -1330px 0%;
    width: 160px;
    height: 40px;
}
.discard {
    width: 100%;
    height: 100%;
    background-image: url("../images/bg_1.png");
    display: flex;
    min-height: 100vh;
    flex-direction: column;
}
.discard .me , .friend{
    flex: 1;
    display: flex;
    flex-direction: row;
    align-items: center;
}
.discard .image_me {
    /*头像放到最右边*/
    flex: 0 0 6em;
    order: -1;
    width: 80px;
    height: 80px;
    background-image: url("../images/icon.png");
    background-position: -80px 0%;
}
.discard .image_frd {
    /*头像放到最右边*/
    flex: 0 0 6em;
    order: -1;
    width: 80px;
    height: 80px;
    background-image: url("../images/icon.png");
    background-position: -160px 0%;
}
.discard .poker_me,.poker_frd{
    flex: 10;
    display: flex;
    flex-direction: row;
    justify-content: center;
    padding-top: 10px;
}
.discard .playArea{
    flex: 1;
    justify-content: space-between;
}
.discard .pokerArea{
    padding-top: 10px;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
}
.poker {
    width: 90px;
    height: 120px;
    margin-right: -50px;
    background-image: url("../images/poker.png");
}
.discard .menu {
    flex: 1;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-around;
}
.sendPoker {
    background-image: url("../images/button.png");
    background-position: -1165px 0%;
    width: 80px;
    height: 40px;
    border: none;
    cursor: pointer;
}
.anstain {
    background-image: url("../images/button.png");
    background-position: -990px 0%;
    width: 80px;
    height: 40px;
    border: none;
    cursor: pointer;
}
.abandon {
    background-image: url("../images/button.png");
    background-position: -1490px 0%;
    width: 160px;
    height: 40px;
    border: none;
    cursor: pointer;
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,133评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,682评论 3 390
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,784评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,508评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,603评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,607评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,604评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,359评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,805评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,121评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,280评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,959评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,588评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,206评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,193评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,144评论 2 352

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,016评论 25 707
  • 吃货地图产品需求文档 V1.0-2015/03/30 1概述 1.1产品概述及目标 概述:“吃货地图”是一款基于i...
    michaelshan阅读 5,849评论 1 46
  • 两人斗地主 一、体系结构图 通讯模型 大功能模块切换关系 二、逻辑流程图 登录login.PNG 主页面开始界面....
    wuyumumu阅读 500评论 0 0
  • 是暗流汹涌 还是白浪滔天 是鼠狼之间 还是雾霾成仙 是回音寥寥 还是恍若西天 是阴雨绵绵 还是老天有意垂怜 我被罩...
    澄默时节阅读 534评论 5 11
  • 1. 最简单的二分查找有什么用## 对于一个有序数列,查找某一个特定值。 二分查找需要保持数组的有序性### 如果...
    tdeblog阅读 325评论 1 1