美文网首页前端社团
网页斗地主实现——(1)

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

作者: 折柳画马 | 来源:发表于2016-11-13 11:20 被阅读371次

    简要说明

    上头又派发了新任务,这次是完成斗地主,这一次的项目中,我加深了对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);
                })
            })
    

    相关文章

      网友评论

        本文标题:网页斗地主实现——(1)

        本文链接:https://www.haomeiwen.com/subject/ctccpttx.html