[cocos2dx 3.0 (五)] 使用游戏控制台Console + 添加用户自定义控制台命令

时间:2023-02-06 22:38:05

cocos2dx 3.0又出了新版本rc0,在beta2版本中使用Console在vs2012上存在bug,在rc0中已经都修复了,而且加了不少的新的控制台命令。游戏控制台是通过TCP来连接控制的,使用可以让游戏的调试更加方便。

1.使用控制台

先来看一下Console类的一些定义

/** 
控制台通过TCP连接可以让开发者更好的控制游戏。
它会创建一个新线程去侦听指定的TCP端口。
它拥有一个指令分析器,每个指令与一个 std::function<void(int)>相关联。
如果这个std::function<>需要使用cocos2d的API,它必须是以下面的形式调用:

```
scheduler->performFunctionInCocosThread( ... );
//使用cocos2d API的部分必须用performFunctionInCocosThread调用
```

*/
class CC_DLL Console
{
public:
//命令结构:名称、帮助和回调函数
struct Command {
const char *name;
const char *help;
std::function<void(int, const std::string&)> callback;
};

/** Constructor */
Console();

/** Destructor */
virtual ~Console();

/** 开始侦听指定端口 */
bool listenOnTCP(int port);

/** 从指定描述符开始侦听 */
bool listenOnFileDescriptor(int fd);

/** 停止控制台 */
void stop();

/** 添加用户控制台命令 */
void addCommand(const Command& cmd);

/** log something in the console */
void log(const char *buf);

protected:
......

}
所以使用控制台只需加入一句代码就可以了:

Director::getInstance()->getConsole()->listenOnTCP(5678);
端口号可以随意。


然后就可以使用telnet工具来连接使用控制台了。工具在windows系统中也是自带的,但是经过测试后发现,使用这些telnet工具在控制台获取数据时因为格式问题会输出显示的特别乱,所以就自己写了个控制台的客户端,其实很简单:

#include <stdio.h>
#include <thread>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")

#define MAXLEN 256

void wRevc(SOCKET s)
{
char recData[MAXLEN];
int len;
while(true)
{
len=recv(s, recData, MAXLEN-1, 0);
if(len==-1)
break;
else if(len==0)
{
return ;
}
else
{
recData[len] = 0x00;
printf(recData);
}
}
printf("已退出连接!\n");
}
int main()
{

printf("Cocos2dx Console Client\n请输入控制台端口号:");
short port;
scanf("%d",&port);
WORD sockVersion = MAKEWORD(2,2);
WSADATA data;
if(WSAStartup(sockVersion, &data) != 0)
{
return 0;
}

SOCKET sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sclient == INVALID_SOCKET)
{
printf("invalid socket! ");
system("pause");
return 0;
}

sockaddr_in serAddr;
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(port);
serAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
if (connect(sclient, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)
{
printf("连接console失败!\n");
closesocket(sclient);
system("pause");
return 0;
}
printf("连接console成功!\n");
printf("输入\"help\"获取控制台帮助!\n");
std::thread t(&wRevc,sclient);
t.detach();
char sendData[MAXLEN];
getchar();
while(true)
{
//printf("Enter CocosConsole Command:\n");
gets(sendData);
if(strcmp(sendData,"consoleExit")==0)
{
printf("退出ConsoleClient!\n");
break;
}
if(strcmp(sendData,"consoleClear")==0)//clear屏幕
{
system("cls");
printf("> ");
continue;
}
strcat(sendData, "\n");
send(sclient, sendData, strlen(sendData),NULL);
//if(!wRevc(sclient))
//break;
}
closesocket(sclient);
WSACleanup();
system("pause");
return 0;
}


上两张测试的图片:

1.查看控制台帮助:

[cocos2dx 3.0 (五)] 使用游戏控制台Console + 添加用户自定义控制台命令

2.查看FileUtils中的数据:

[cocos2dx 3.0 (五)] 使用游戏控制台Console + 添加用户自定义控制台命令


cocos2dx已经定义了很多命令,具体可以看help。

2.添加控制台命令

其实是使用游戏控制台最重要的是定义自己的控制台命令,比如 设置主角的属性,无敌状态,制造物品,查看各种细节数据等等;  这些在调试复杂游戏的时候都是必须的,首先就是要先定义自己的控制台命令。

添加新命令当然也很简单:

 #include "cocos2d.h"
...
Director::getInstance()->getConsole()->listenOnTCP(5678);
...
Console::Command commands={
"hello",//命令名称
"This is just a user generated command", //说明
/*
回调函数的第一个参数其实就是socket的句柄,使用send向client发送数据,
第2个参数是命令所带的参数字符串。
*/
[](int fd, const std::string& args)
{
const char msg[] = "how are you?\nArguments passed: ";
send(fd, msg, sizeof(msg),0);
send(fd, args.c_str(), args.length(),0);
send(fd, "\n",1,0);
/*
如果回调函数中需要使用cocos2d的api就必须在
performFunctionInCocosThread函数中调用。

...
Director::getInstance()->getScheduler()->performFunctionInCocosThread([]{...});
...

*/
}
};
Director::getInstance()->getConsole()->addCommand(commands);
...

测试结果:

[cocos2dx 3.0 (五)] 使用游戏控制台Console + 添加用户自定义控制台命令

[cocos2dx 3.0 (五)] 使用游戏控制台Console + 添加用户自定义控制台命令cocos2dx的console就学习到这里了!