cocos2dx-js 游戏消息列表

先上图


游戏中常常见到一个富文本的列表,不停地显示游戏相应的消息.每添加一个消息,则向列表底部添加一个项.当消息项超过列表可见区域底部时列表会自动向上移动使最新消息项永远保持在可见区域内.

下面是实现:

var GameMsgList = cc.Node.extend({

    ctor : function(view_size) {
        this._super();
        this.init(view_size);
    },
    init : function(view_size) {
        this._itemData = [];    //项数据
        this._itemMax = 30;     //项上限
        this.m_sFonts = "res/fonts/tengxiangyuan.ttf";
        this.m_nFontSize = 20;
        this.m_pColorDefault = cc.color(255, 255, 255); //默认颜色
        this.m_pColorConfig = {};   //颜色配置,可以外部添加
        this.m_pColorConfig.red = cc.color(255, 0, 0);
        this.m_pColorConfig.green = cc.color(0, 255, 0);
        this.m_pColorConfig.blue = cc.color(0, 0, 255);
        this.m_pColorConfig.white = cc.color(255, 255, 255);
        this.m_pColorConfig.black = cc.color(0, 0, 0);
        //this.m_pRegExp = new RegExp("<[a-z]+>[\s|\S]+</[a-z]+>");
        this.m_pTVSize = view_size;
        this.setContentSize(this.m_pTVSize);


        this.m_pTView = new ccui.ListView();
        this.m_pTView.setDirection(ccui.ScrollView.DIR_VERTICAL);
        this.m_pTView.setTouchEnabled(true);
        this.m_pTView.setBounceEnabled(true);
        this.m_pTView.setItemsMargin(5);
        //this.m_pTView.setBackGroundColorType(ccui.Layout.BG_COLOR_SOLID);
        //this.m_pTView.setBackGroundColor(cc.color(128, 128, 128));
        //this.m_pTView.setBackGroundColorOpacity(128);
        this.m_pTView.setContentSize(this.m_pTVSize);
        //this.m_pTView.setScrollBarEnabled(true);  //h5 undefined
        //this.m_pTView.setScrollBarOpacity(204);   //h5 undefined
        //this.m_pTView.setScrollBarAutoHideEnabled(false); //h5 undefined
        //this.m_pTView.setScrollBarWidth(4);       //h5 undefined
        //this.m_pTView.setScrollBarColor(cc.color(164, 160, 122)); //h5 undefined
        //this.m_pTView.setScrollBarPositionFromCornerForVertical(cc.p(4, 4));  //h5 undefined
        this.addChild(this.m_pTView);
    },
    setColorDefault : function (color) {
        this.m_pColorDefault = color;
    },
    setColor : function (key, color) {
        this.m_pColorConfig[key] = color;
    },
    getColor : function (key) {
        var color = this.m_pColorConfig[key];
        if (!color) {
            return this.m_pColorDefault;
        }
        return color;
    },
    setFonts : function (file, size) {
        this.m_sFonts = file;
        this.m_nFontSize = size;
    },
    reloadData: function(dataSet) {
        var _sourceData = !dataSet ? [] : dataSet;
        this._itemData = [];
        for(var i = 0, len = _sourceData.length; i < this._itemMax && i < len; ++i) {
            var temp = _sourceData[len - i - 1];
            this._itemData.push(temp);
        }
        this._itemData.reverse();
        this.reloadItems();
    },
    reloadItems : function () {
        this.m_pTView.removeAllItems();
        for(var i = 0, s = this._itemData.length; i < s; ++i) {
            this.addItem(this._itemData[i], false);
        }
        this.m_pTView.jumpToBottom();
    },
    addItem : function (data, tag) {
        var richText = new ccui.RichText();
        richText.ignoreContentAdaptWithSize(false);
        richText.setContentSize(this.m_pTVSize.width, 0);
        //richText.setAnchorPoint(cc.p(0, 0)); //H5版本默认为(0.5,0)
        //parse text
        var txt_arr = this.parseText(data.toString());
        var txt_arr_len = txt_arr.length;
        for(var i = 0; i < txt_arr_len; ++i) {
            var txt_obj = txt_arr[i];
            //每个数据格式 {text:"***", color:"red"}
            var r_text_color = this.getColor(txt_obj.color);
            //cc.log("txt_obj.text=1#" + txt_obj.text + "#2");
            var r_text = new ccui.RichElementText(i, r_text_color, 255, txt_obj.text, this.m_sFonts, this.m_nFontSize);
            richText.pushBackElement(r_text);
        }
        richText.formatText(); //修改引擎RichText::formatRenderers()
        this.m_pTView.pushBackCustomItem(richText);
        if(tag) {
            this._itemData.push(data);
            if(this._itemMax < this._itemData.length) {
                this._itemData.splice(0, 1);
                this.m_pTView.removeItem(0);
            }
            this.m_pTView.jumpToBottom();
        }
    },
    parseText : function (text) {
        var txt_arr = [];
        var txt_val_temp = text;
        var txt_obj;
        var txt_str = "";
        while(0 < txt_val_temp.length) {
            var ret = txt_val_temp.match(/<[a-z]+>/); //开头
            if(ret) {
                //KKVS.INFO_MSG(ret[0]);
                //KKVS.INFO_MSG(ret["index"]);
                //KKVS.INFO_MSG(ret["input"]);
                var match_str_start = ret[0];
                var match_ind_start = ret["index"];
                //cc.log("->匹配头:" + match_str_start + " match_ind_start=" + match_ind_start);
                if (0 < match_ind_start) {
                    txt_str += txt_val_temp.slice(0, match_ind_start);
                }
                txt_val_temp = txt_val_temp.slice((match_ind_start + match_str_start.length));
                if (txt_val_temp.length == 0) {
                    txt_str += match_str_start;
                    break;
                }
                var match_str_key = match_str_start.slice(1, (match_str_start.length - 1));
                var match_str_end = "</" + match_str_key + ">";
                var end_ret = txt_val_temp.match(match_str_end);
                if (end_ret) {
                    //cc.log("->匹配尾:" + match_str_end);
                    if(0 < txt_str.length) {
                        txt_obj = {text : txt_str};
                        txt_arr.push(txt_obj);
                    }
                    var match_ind_end = end_ret["index"];
                    if(0 < match_ind_end) {
                        txt_str = txt_val_temp.slice(0, match_ind_end);
                        txt_obj = {text : txt_str, color : match_str_key};
                        txt_arr.push(txt_obj);
                    }
                    txt_str = "";
                    txt_val_temp = txt_val_temp.slice((match_ind_end + match_str_end.length));
                } else {
                    txt_str += match_str_start + txt_val_temp;
                    break;
                }
            } else {
                txt_str += txt_val_temp;
                break;
            }
        }
        if(0 < txt_str.length) {
            txt_obj = {text : txt_str};
            txt_arr.push(txt_obj);
        }


        return txt_arr;
    }
});


示例调用:

var gamemsgsize = cc.size(200, 100);
var dataSet = [];
dataSet.push("<red>[系统消息]</red>欢迎<green>骨头专用号</green>进入'奖金牛牛'游戏,祝游戏愉快!");
dataSet.push("<red>[系统消息]</red>游戏结算中...");
dataSet.push("玩家<green>带原子弹的皮卡丘</green>输了2000");
dataSet.push("玩家<green>似雨似雾又似风</green>输了1960");
dataSet.push("<red>[系统消息]</red>游戏已经结束.");

this.m_pGameMsgList = new GameMsgList(gamemsgsize);
this.m_pGameMsgList.reloadData(dataSet);
this.m_pGameMsgList.setPosition(10, 10);
sysmsg.addChild(this.m_pGameMsgList);
...

this.m_pGameMsgList.addItem("玩家<green>似雨似雾又似风</green>已经准备", false);
this.m_pGameMsgList.addItem("玩家<green>带原子弹的皮卡丘</green>已经准备", true);

当然,你也可以通过调用下面语句来设置字体:

this.m_pGameMsgList.setFonts("res/.../test.ttf", 20);

可以修改默认字体颜色:

this.m_pGameMsgList.setColorDefault(cc.color(128, 128, 128));

这样的话,上面的"玩家<green>带原子弹的皮卡丘</green>输了2000"中的"玩家"两个字就不再是默认颜色(白色)了,而是cc.color(128, 128, 128).

可以修改配置的字体颜色:

this.m_pGameMsgList.setColor("green", cc.color(128, 0, 0));

使用上面语句则使用"玩家<green>带原子弹的皮卡丘</green>输了2000"中的"带原子弹的皮卡丘"几个字不再是原先的绿色了,而是cc.color(128, 0, 0).

默认配置中存在的颜色有 red, green, blue, white, black, 如果这些颜色满足不了需求,这里允许自由增加配置颜色.如想要增加特定的颜色:

this.m_pGameMsgList.setColor("mycolor_1", cc.color(64, 0, 0));
this.m_pGameMsgList.setColor("mycolor_2", cc.color(64, 64, 0));
this.m_pGameMsgList.setColor("mycolor_3", cc.color(64, 64, 64));

...

可自由定义颜色名字,然后像这样使用它:

this.m_pGameMsgList.addItem("颜色样式:<mycolor_1>颜色1</mycolor_1><mycolor_2>颜色2</mycolor_2><mycolor_3>颜色3</mycolor_3>", true);

补充: UIRichText.cpp中443行添加一句: _customSize.height = newContentSizeHeight;



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值