记录:牛牛游戏开发笔记

玩游戏的大小孩开发整理笔记:平台cocos2d-x 2.2.6,第一个游戏速度略慢,服务器逻辑+客户端逻辑共两个礼拜,各种调试改界面两个礼拜多一点。
15/07/14结笔
游戏模式:服务器为主逻辑区,客户端响应服务器的各种消息事件,出牌、牛、出现叫庄按钮等
协议如下:部分

// user status----need
#define USER_STATUS_NULL            0
#define USER_STATUS_LOOK            1
#define USER_STATUS_PALY            2
#define USER_STATUS_ROB             3
#define USER_STATUS_NO_ROB          4
#define USER_STATUS_MULTIPLE        5
#define USER_STATUS_NIU             6
#define USER_STATUS_NO_NIU          7

// power--各类按钮
#define BUTTON_POWER_START          0x00000001
#define BUTTON_POWER_WAITNEXT       0x00002000

protocol--s-c发送协议
#define SUB_S_BUTTON_POWER          100
#define SUB_S_SEND_BET          122
//c-s响应协议
#define SUB_C_ROB           1001
#define SUB_C_SEND_GIFT    1007
// game state
#define GAME_STATUS_FREE            0
#define GAME_STATUS_ROB             1   
#define GAME_STATUS_MULTIPLE        2   
#define GAME_STATUS_CONTEST         3
#define GAME_STATUS_OVER            4

服务器注意点:断线重连,引入状态机概念,根据游戏状态和掉线玩家的玩家状态去发送当前应该显示的场景给玩家。
时间函数,时间到时应做好强制状态转换。同理客户端
客户端
问题一:
游戏昵称过长不好显示(如旺旺仔仔牛牛奶奶很很好好喝喝) 显示为xxx..(旺旺仔仔…)这里有字符编码问题,utf8是1~4个字节编码utf8传送门
字符需要转化。

代码转化代码如下

void layer_game::setTextEx(UILabel* l_uilabel,const std::string& text, int twidth){
        l_uilabel->setText(text);
        if (twidth <l_uilabel->getContentSize().width){
            char fulline[100];
            strcpy(fulline, text.c_str());
            int sum = strlen(fulline);
            std::string lines, s_name;
            for (int cur = 0; cur < sum; cur++)
            {
                char t = fulline[cur];
                if ((t & 0xF0) == 0xF0){                //4byte
                    lines = lines + t + fulline[cur + 1] + fulline[cur + 2] + fulline[cur + 3];
                    cur += 3;
                }
                if ((t & 0xE0) == 0xE0){                //3byte
                    lines = lines + t + fulline[cur + 1] + fulline[cur + 2];
                    cur += 2;
                }
                else if ((t & 0xC0) == 0xC0){       //2byte
                    lines = lines + t + fulline[cur + 1];
                    cur++;
                }
                else{                                   //1byte
                    lines = lines + t;
                }
                l_uilabel->setText(lines + "...");
                if (twidth <= l_uilabel->getContentSize().width){
                    break;
                }
                s_name = lines;
            }
            l_uilabel->setText(s_name + "...");
        }
        else
            l_uilabel->setText(text);
    }

遇到的问题二:

聊天的话,需要有聊天记录框,根据记录长短分成一条或两条,uilabel据说有自动分行,然并软。还是得自己来设置,重要代码片段如下:

        for (int i = 0; p != NULL; i++)
        {
            if (i > int_chat_temp_count)
                break;
            CCString* str = CCString::createWithFormat("%s:%s", p->_str_name.c_str(), p->_str_chat.c_str());
            std::cout << str->getCString();
            m_text_chat[i]->ignoreContentAdaptWithSize(true);
            m_text_chat[i]->setText(str->getCString());
            CCSize the_text_size = m_text_chat[i]->getSize();
            m_int_text_height[i]= the_text_size.width / 350;
            if (((int)the_text_size.width) % 350 != 0)
                m_int_text_height[i] += 1;
            sum_item_count += m_int_text_height[i];
            m_text_chat[i]->ignoreContentAdaptWithSize(false);
            m_text_chat[i]->setSize(CCSizeMake(350, m_int_text_height[i] * 30));
            m_text_chat[i]->setTextAreaSize(CCSizeMake(350, m_int_text_height[i] * 30));
            p = p->next;
        }

问题三:
表情动画类作为方便统一管理,外部文件的形式来加加载动画。这里主要用到CCFileUtils,json数据存储json用法传送门

void UIGameChatPlay::play_emotion(int int_view_id, int int_emotion_id)
{
    CCString* ptr_str_png_filename = CCString::createWithFormat("emotion/%d.png", int_emotion_id);
    CCString* ptr_str_json_filename = CCString::createWithFormat("emotion/%d.json", int_emotion_id);

    std::string str_png_filename = CCFileUtils::sharedFileUtils()->fullPathForFilename(ptr_str_png_filename->getCString());
    std::string str_json_filename = CCFileUtils::sharedFileUtils()->fullPathForFilename(ptr_str_json_filename->getCString());

    unsigned long size;
    char *pFileContent = (char*)CCFileUtils::sharedFileUtils()->getFileData(str_json_filename.c_str(), "rb", &size);
    if (pFileContent == NULL)
    {
        return;
    }

    Json::Reader    the_reader;
    Json::Value     the_value;
    if (the_reader.parse(pFileContent, the_value, false) == false)
        return;

    delete[] pFileContent;

    float float_width   = the_value["width"].asFloat();
    float float_height  = the_value["height"].asFloat();
    int int_count       = the_value["count"].asInt();
    int int_turn        = the_value["turn"].asInt();
    float float_time    = the_value["time"].asFloat();

    CCAnimation* ptr_animation = CCAnimation::create();
    CCSpriteFrame* ptr_sprite_frame = 0;

    for(int i=0; i<int_turn; i++)
    {
        for(int j=0; j<int_count; j++)
        {
            ptr_sprite_frame = CCSpriteFrame::create(ptr_str_png_filename->getCString(), CCRectMake(float_width*j, 0, float_width, float_height));
            ptr_animation->addSpriteFrame(ptr_sprite_frame);
        }
    }
    // should last 2.8 seconds. And there are 14 frames.
    ptr_animation->setDelayPerUnit(float_time / (float)(int_count * int_turn));
    ptr_animation->setRestoreOriginalFrame(true);

    _ptr_sprite_emotion[int_view_id]->stopAllActions();

    CCCallFuncN* ptr_emotion_start = CCCallFuncN::create(this, callfuncN_selector(UIGameChatPlay::on_emotion_start));
    CCAnimate* ptr_action = CCAnimate::create(ptr_animation);
    CCCallFuncN* ptr_emotion_finish = CCCallFuncN::create(this, callfuncN_selector(UIGameChatPlay::on_emotion_finish));
    _ptr_sprite_emotion[int_view_id]->runAction(CCSequence::create(ptr_emotion_start, ptr_action, ptr_emotion_finish, NULL));
}

客户端其他关注点:定时器设置,动画同步性,点击事件层级设置,判断是否为点击区域
bool Layout::hitTest(const CCPoint &pt)

void UIGameMenu::on_touch_event(CCObject* object, TouchEventType type)
    {
        if (type != TOUCH_EVENT_ENDED)
            return;
        CCPoint the_point = getTouchEndPos();
        if (m_panel_menu->hitTest(the_point) == false)
        {
                setTouchEnabled(false);
                widget->setTouchEnabled(false);
        }
    }

编码问题; win中和linux服务器一般直接生成的中文为GBK,IOS和安卓和通过cocos输入得到的字体为UTF8,用cocos自带的转码UTF8和GBK2UTF8坑爹啊(刚开始没进去看代码导致问题产生),win下没区别,其他有区别。
吐槽:IOS中输入函数不能实时显示,真是坑爹。写过程序加美工的图片命名,英文渣表示中文无爱,还是英语好。产品神奇般的对像素移动位置也是醉的不行,不行的。
有帮助博客动作详解传送门字体讲解传送门
已发布—后续维护更新维护内容。
下个游戏:捕鱼达人

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值