版本:cocos2d-x 3.10 语言:C++
昨天做了一天的功能,简直没时间,不过学到的挺多的。主要是一个RenderTexture制作一个橡皮擦功能,网上有教程,但是不够简洁明白,有一些内部原理没有讲清,下一节的话给大家介绍一下。
这一节给大家带来的一个小小的坐标编辑器,是之前凌晨12点半熬夜熬到2点多做出来的,主要是项目组什么工具都没有,也没有用CocosStudio,所以所有的UI界面都得程序弄出来。
这次又要做一个伪随机坐标的效果,我想着就自己做了个小编辑器。
内部原理很简单,大家基本上学完cocos2d-x基础就能做了,代码的打包就不发了,有需要的话联系我吧,或者一起来学习学习加个好友也行:QQ542155386。
然后进入正题,一个坐标编辑器,首先我这个只有一个背景加上一个要添加的图片(需要生成多个),要在里面手动的添加坐标,就先得读取背景图片的大小,然后生成窗口,但是失败了,不能AppDelegate中创建精灵,算了先直接写死吧:
static cocos2d::Size designResolutionSize = cocos2d::Size(439, 236);
static cocos2d::Size smallResolutionSize = cocos2d::Size(439, 236);
有需要的话得过来调,稍微有点麻烦,暂时就这样。
基本的场景类写好,然后添加一个按钮作用是添加一个要设置坐标的精灵,我这边用Button控件了:
Button* buttonAddSprite = Button::create("CloseNormal.png", "CloseSelected.png");
buttonAddSprite->addTouchEventListener(CC_CALLBACK_2(InitPointScene::addSprite, this)); //添加监听事件
buttonAddSprite->setPosition(Vec2(visibleSize.width-40, visibleSize.height-40));
this->addChild(buttonAddSprite, 1);
buttons.push_back(buttonAddSprite); //把button保存到一个容器中,以后有用哦
创建一个坐标后,监听本类的addSprite事件:
void InitPointScene::addSprite(Ref* obj, Widget::TouchEventType type)
{
if (type != Widget::TouchEventType::ENDED)
return;
Size visibleSize = Director::getInstance()->getVisibleSize();
Sprite* sprite = createSprite(); //创建一个需要的精灵
this->addChild(sprite);
sprites.push_back(sprite);
sprite->setPosition(visibleSize.width / 2, visibleSize.height / 2);
labelNum->setString(Value((int)sprites.size()).asString()); //每添加一个精灵刷新一次界面的数字显示标签,表明已经有多少个精灵了
}
很简单,当玩家松开按钮的时候创建一个精灵,然后加入子节点,再把他们放到一个容器中以便以后读取坐标方便。
再来看看具体的createSprite方法内容:
Sprite* InitPointScene::createSprite()
{
Size visibleSize = Director::getInstance()->getVisibleSize();
Sprite* sprite = Sprite::create("5.png"); //创建一个精灵,这边固定直接写了
//事件监听
auto listener = EventListenerTouchOneByOne::create();
listener->setSwallowTouches(true); //吞掉事件,否则叠加在一起的精灵会一起动
listener->onTouchBegan = [sprite](Touch* touch, Event* event)
{
if (!sprite->getBoundingBox().containsPoint(touch->getLocation()))
return false;
sprite->setScale(1.1f); //选中移动的精灵会放大
return true;
};
listener->onTouchMoved = [sprite](Touch* touch, Event* evnet)
{
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 pos = touch->getLocation();
int x = pos.x, y = pos.y;
x = std::min(std::max(x, 0), (int)visibleSize.width); //不让精灵移出背景框
y = std::min(std::max(y, 0), (int)visibleSize.height);
sprite->setPosition(x, y); //设置到鼠标移动的坐标
};
listener->onTouchEnded = [sprite](Touch* touch, Event* event)
{
sprite->setScale(1.0f); //回到原来的大小
};
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, sprite); //注册事件
return sprite;
}
核心代码就一句话sprite->setPostion(x, y),也没有复杂的逻辑,不过还是要对cocos2d-x常用的东西比较熟悉了。
以上代码就能实现创建一个精灵,并在背景内随意拖动的效果了,来看看我的吧:
嗯,效果不错,左上角数字标签,玩家们自己创建一个吧。
最后是生成坐标序列,因为不打算存到文件中读取,直接把坐标内容放到C++文件中,所以生成坐标序列就OK。一样,先添加个Button:
Button* buttonInitPoint = Button::create("CloseNormal.png", "CloseSelected.png");
buttonInitPoint->addClickEventListener(CC_CALLBACK_1(InitPointScene::initPoint, this)); //监听事件
buttonInitPoint->setPosition(Vec2(visibleSize.width - 40, visibleSize.height - 80));
this->addChild(buttonInitPoint, 1);
buttons.push_back(buttonInitPoint);
这次用Click,然后来看看具体监听的内容:
void InitPointScene::initPoint(Ref* obj)
{
std::string str_x = "{ ";
std::string str_y = "{ ";
bool first = true;
for (auto sprite : sprites)
{
int x = sprite->getPositionX(); //获取每一个精灵的坐标,存入相应的字符串
int y = sprite->getPositionY();
if (first)
{
str_x.append(StringUtils::format("%d", x));
str_y.append(StringUtils::format("%d", y));
first = false;
}
else
{
str_x.append(StringUtils::format(", %d", x));
str_y.append(StringUtils::format(", %d", y));
}
}
str_x.append(" }");
str_y.append(" }");
CCLOG(str_x.c_str()); //打印字符串
CCLOG(str_y.c_str());
}
点击一下按钮,我们就获取到了想要的东西了:
然后我还做了数据的持久化,把坐标内容保存磁盘中,退出再回到编辑器的时候会读取该内容。还有按钮的隐藏和显示。详细的就不介绍了。
如果有空把这个坐标编辑器做得更加的适用于多种情况,可以手动导入图片、背景,设置坐标,我就再再写一节内容,敬请期待。
做Cocos开发真心还是挺有趣的,之前是学的JavaWeb、然后是CCIE、最后转到游戏开发的,到现在也就半年功夫吧,知识很多,准备接下来深入底层。大家有空来逛逛交流交流。