网页斗地主实现——(1)

简要说明

上头又派发了新任务,这次是完成斗地主,这一次的项目中,我加深了对nodejs工程的理解,学习了状态机的使用,顺便复习了下c语言(笑~)

对扑克牌的处理

pokes.png

这里采用的是将全部扑克合并成一张大图,然后通过截取的办法将扑克展现出来

.pokes{
      background-position: -xpx -ypx;
}

其中x和y都为正数,由于background-position一开始定位在图片的左上角即0px,0px,并且截图的容器窗口位置不动,所以如果需要将窗口定位到对应的扑克牌,需要将图片向左向上移动,即-xpx,-ypx

获取图片中的对应扑克牌的值和花色

这里采用先规定index再取value的方法.扑克牌一共有54张,将红桃A到红桃K的index设置为0到12.类似的梅花A到梅花K则是39到51,大小王取52、53.这样设置index比较容易通过计算取出对应的扑克牌,而比较大小和排序的时候需要获取value以及花色(有可能),所以为图方便,将index对应的value和花色存储在json文件里.

用c对文件进行写入
#include<iostream>
#include<fstream>
#include<string>

using namespace std;
using  std::string;
int main(){
    FILE *fout;
    fout = fopen("D:/json.txt", "w+");
    string str = "var data=[\n";
    string LEVER = "    {lever:";
    string VALUE = ",value:";
    string END = "},\n";
    for (int i = 0; i < 64; i++)
    {
        int lever = i / 13;
        int value = i % 13;
        if (lever == 4){
            if (value == 0){
                value = 16;
                str += LEVER + std::to_string(lever) + VALUE + std::to_string(value) + END;
            }
            else{
                value = 15;
                str += LEVER + std::to_string(lever) + VALUE + std::to_string(value) + END;
            }
            continue;
        }
        else{
            if (value <= 1){
                value += 13;
            }
            str += LEVER + std::to_string(lever) + VALUE + std::to_string(value) + END;
        }
    }
    str += "];";
    fprintf(fout, "%s", str.c_str());
    //fprintf只支持c语言的字符串,所以需要转型
    for each (char var in str)
    {
        printf("%c",var);
    }
    return 0;
}

以上代码完成了对A、2和大小王的value特殊处理,最后把txt文件改为js就好了.

如何处理服务器发送过来的扑克牌
var modalBox = {
        cardsSort:function (cards) {
            cards.sort(this.comp);
        },
        comp:function (a,b) {
            if(data[a].value>data[b].value){
                return false;
            }else if(data[a].value==data[b].value){
                if(data[a].lever>data[b].lever){
                    return true;
                }else{
                    return false;
                }
            }else {
                return true;
            }
        }
}
//将传进来的cards数组按照value从大到小排序,如果value一样则按照花色排序(这个不重要)

桌子上坐满人后再开始牌局

<div class="bc">
    <div class="selectTable">
        <div class="table">
        </div>
        <div class="seats">
            <div class="seat">
                <div class="place">
                </div>
            </div>
            <div class="seat">
                <div class="place">
                </div>
            </div>
            <div class="seat">
                <div class="place">
                </div>
            </div>
        </div>
    </div>
</div>
<script>
    window.scriptData = JSON.stringify({{{scriptData}}});
    window.scriptData=eval("("+window.scriptData+")");//转换为json对象
    console.log(window.scriptData);
</script>
<script src="/lib/myjs/myjs.js"></script>
<script src="/lib/card/netConnection.js"></script>

这是初始布局,后面的布局更新将用js进行实现而不是一次性预设多个布局通过display属性来控制.
myjs.js文件,绑定place点击事件

$(init);
var MODAL;
function init() {
    new modal();
}
var modal = function () {//modalBox是一个对象,里面创建了很多函数
    var ptrThis;
    var modalBox = {
    //省略部分代码
    init:function () {
            ptrThis = this;
            $("body").on("click",".place",function (e) {
                socketFun.sit($(this));
            })
    },
        insertImg:function ($this,obj) {
            var $img = $("<img>");
            $img.attr({
                src:obj.imgUrl,
            });
            $this.attr("data-id",obj.id);
//存储玩家id,用于以后的交互
            $this.empty();
            $this.append($img);
        },
        removeImg:function ($this) {
            $this.empty();
        },
    //省略部分代码
    }
    MODAL = modalBox;
    return modalBox.init();

netConnection.js文件,专门用于客户端与服务器后台进行收发操作

var socket = io.connect('http://localhost:3000');
    socket.on("connect",function () {
        socket.emit("addUser",X._id);                   //添加用户
    })
    socket.on("playerSit",function (obj) {
        MODAL.insertImg($(".seat").eq(obj.index).children(),obj);
    })
//服务器返回有玩家坐下
    socket.on("leave",function (index) {
        MODAL.removeImg($(".seat").eq(index).children());
    })
//服务器返回有玩家离开(某个座位)

//如果一个玩家从一个座位坐到另一个座位,则会得到playerSit和leave两个消息
var socketFun = {
    sit:function ($this) {
        /*
        $(".seat").each(function () {                   //这里不能用$this.parent()来追踪,因为$this.parent()只是找到三个seat中的一个而已,没卵用
            console.log($(this).children().attr("data-id"));
            if($(this).children().attr("data-id")==X._id){
                MODAL.removeImg($(this).children());
            }
        })
        */
        var obj = {
            id:X._id,
            index:$this.parent().index()
        }
        console.log(obj);
        socket.emit("sitSeat",obj);
    }
}

ioServer.js

var seats = {};
//用于存储三个座位的信息
var users = {};
//用于存储用户对应的socket
        socket.emit('connect');                     //建立连接后由服务器发送链接成功的消息
        socket.on("addUser",function (userId) {
            var obj = {};
            users[userId]=socket;
            async.each(array, function (item,callback) {
                if(seats.hasOwnProperty(item)&&seats[item].isSit==1){
                    User.findOne({_id:seats[item].id},function (err,doc) {
                        obj[item]={
                            id:doc._id,
                            imgUrl:doc.imgUrl,
                            index:item
                        }
                        //console.log(item);
                        //console.log(obj);
                        callback();
                    })
                }else{
                    callback();         //一:这里必须增加回调函数,否则无法使each的回调函数触发二:就算findOne里面已经发送过callback函数也不能再
                                        //下面继续发送callback,不然会发生错误,坑!
                }
            },function (err) {
                socket.emit("seatsInfo",obj)
//向第一次连接的用户发送座位信息,哪个座位有人坐,哪个没人坐
            });
        })
       socket.on("sitSeat",function (obj) {
            dbHelper.findUsrById(obj.id,function (success,doc) {
//dbHelper为对数据进行操作的封装,略去
                var msg = {
                    index:obj.index,
                    imgUrl:doc.imgUrl,
                    name:doc.username,
                    id:obj.id
                }
                if(!seats.hasOwnProperty(obj.index)||!seats[obj.index].isSit){        //没人坐
                    seats[obj.index] = {
                        isSit:1,
                        id:obj.id,
                        imgUrl:doc.imgUrl,
                        isReady:false
                    };
                    socket.broadcast.emit("playerSit",msg);
                    socket.emit("playerSit",msg);
                    //只有坐下新位置才能判断是否移除原来的位置
                    for(var i = 0;i<3;++i){
                        //不是index对应的座位并且有人坐
                        if(i!=obj.index){
                            if(seats.hasOwnProperty(i.toString())&&seats[i].isSit){
                                if(seats[i].id==obj.id){
                                    socket.broadcast.emit("leave",i);
                                    socket.emit("leave",i);
                                    seats[i].isSit = 0;

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

推荐阅读更多精彩内容