首页 > 代码库 > Cocos2d-x基础知识
Cocos2d-x基础知识
本人在Visual Studio 2013用C++编写。运行时如果出现中文乱码,可在HelloWorldScene.cpp中加入 #pragma execution_character_set("utf-8") 。
显示对象Sprite:
1 //加载图片 2 //方法一 3 /*auto logo = Sprite::create("icon.png");*/ 4 5 //方法二 6 7 auto img = Director::getInstance()->getTextureCache()->addImage("icon.png"); 8 9 auto logoSize = img->getContentSize(); 10 CCLOG("logo size:%f %f", logoSize.width, logoSize.height); 11 12 auto logo = Sprite::createWithTexture(img); 13 14 logo->setPosition(visibleSize / 2); 15 16 addChild(logo);
加载多个图层:
1 auto layer1 = Layer::create(); 2 auto layer2 = Layer::create(); 3 auto layer3 = Layer::create(); 4 5 auto img1 = Sprite::create("layer1.jpg"); 6 auto img2 = Sprite::create("layer2.jpg"); 7 auto img3 = Sprite::create("layer3.jpg"); 8 img1->setAnchorPoint(Vec2(0, 0)); 9 img2->setAnchorPoint(Vec2(0, 0)); 10 img3->setAnchorPoint(Vec2(0, 0)); 11 12 layer1->addChild(img1); 13 layer2->addChild(img2); 14 layer3->addChild(img3); 15 16 addChild(layer1); 17 addChild(layer2); 18 addChild(layer3); 19 20 layer1->setPosition(Vec2(100, 100)); 21 layer2->setPosition(Vec2(200, 200)); 22 layer3->setPosition(Vec2(300, 300)); 23 24 scheduleOnce([visibleSize, this](float f){ 25 auto scence2 = Scene::create(); 26 auto scence2Layer = Layer::create(); 27 scence2->addChild(scence2Layer); 28 29 auto logo = Sprite::create("icon.png"); 30 logo->setPosition(visibleSize / 2); 31 scence2Layer->addChild(logo); 32 33 Director::getInstance()->replaceScene(scence2); 34 }, 3, "Test");
自定义显示对象:
GameScene.h
1 #pragma once 2 3 #include "cocos2d.h" 4 5 USING_NS_CC; 6 7 class GameScene:public Layer 8 { 9 public: 10 GameScene();//构造函数 11 virtual ~GameScene();//析构函数 12 13 virtual bool init();//初始化函数 14 15 CREATE_FUNC(GameScene);//CREATE宏函数 16 17 static Scene* createScene();//场景创建 18 };
GameScene.cpp
1 #include "GameScene.h" 2 #include "LogoNode.h" 3 4 GameScene::GameScene() 5 { 6 7 } 8 GameScene::~GameScene() 9 { 10 11 } 12 13 bool GameScene::init() 14 { 15 if (!Layer::init()) 16 { 17 return false; 18 } 19 auto logo = LogoNode::create(); 20 addChild(logo); 21 22 logo->setPosition(Director::getInstance()->getVisibleSize() / 2); 23 24 return true; 25 } 26 27 28 Scene* GameScene::createScene() 29 { 30 auto scene = Scene::create(); 31 auto layer = GameScene::create(); 32 33 scene->addChild(layer); 34 35 return scene; 36 }
将 AppDelegate.cpp 中 auto scene = HelloWorld::createScene(); 替换 GameScene 。
常用控件:
//Log log("Hello Cocos2dx %d", 200);//跨平台*/ //MessageBox MessageBox("消息内容", "消息标题");*/ //Cocos2d-x之LabelTTF LabelTTF *label = LabelTTF::create(); label->setString("Hello Cocos"); label->setFontSize(36); label->setPosition(visibleSize / 2); addChild(label);*/ //TextFieldTTF TextFieldTTF *tf = TextFieldTTF::textFieldWithPlaceHolder( "在这里输入", "宋体", 20); tf->setPosition(visibleSize / 2); addChild(tf); //添加侦听用于连接输入IME auto listen = EventListenerTouchOneByOne::create(); listen->onTouchBegan = [tf](Touch *t, Event *event){ if (tf->getBoundingBox().containsPoint(t->getLocation())) { log(">>>>>>>>>>>>>>>>>>>"); tf->attachWithIME(); } else { tf->detachWithIME(); } return false; }; Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listen, tf);*/ //Menu auto menu = Menu::create(MenuItemImage::create( "normal.png", "selected.png", [](Object* obj){ log("menu item touched"); }), NULL); addChild(menu);
TableView:
bool HelloWorld::init() { ////////////////////////////// // 1. super init first if ( !Layer::init() ) { return false; } Size visibleSize = Director::getInstance()->getVisibleSize(); Vec2 origin = Director::getInstance()->getVisibleOrigin(); //引入头文件及命名空间,同时Hello头文件需继承TableViewDataSource并重写方法 TableView *tv = TableView::create(this, Size(300, 300)); tv->setAnchorPoint(Vec2(0, 0)); tv->setPosition(Vec2(200, 0)); tv->setDelegate(this); addChild(tv); return true; }
头文件: class HelloWorld : public cocos2d::Layer,TableViewDataSource,TableViewDelegate
public: //重写TableViewDataSource方法------列表 /** * cell height for a given table. * * @param table table to hold the instances of Class * @return cell size */ virtual Size cellSizeForTable(TableView *table); /** * a cell instance at a given index * * @param idx index to search for a cell * @return cell found at idx */ virtual TableViewCell* tableCellAtIndex(TableView *table, ssize_t idx); /** * Returns number of cells in a given table view. * * @return number of cells */ virtual ssize_t numberOfCellsInTableView(TableView *table); public: //重写TableViewDelegate方法------列表点击监听 /** * Delegate to respond touch event * * @param table table contains the given cell * @param cell cell that is touched * @js NA * @lua NA */ virtual void tableCellTouched(TableView* table, TableViewCell* cell); /** * @js NA * @lua NA */ virtual void scrollViewDidScroll(ScrollView* view) {}; /** * @js NA * @lua NA */ virtual void scrollViewDidZoom(ScrollView* view) {};
cpp文件:
//实现头文件中重写TableViewDataSource的三个方法------列表 Size HelloWorld::cellSizeForTable(TableView *table){ return Size(300, 50); } TableViewCell* HelloWorld::tableCellAtIndex(TableView *table, ssize_t idx){ TableViewCell *cell = table->dequeueCell(); LabelTTF *label; if (cell == NULL) { cell = TableViewCell::create(); label = LabelTTF::create(); label->setTag(2); label->setFontSize(20); label->setAnchorPoint(Point(0, 0)); cell->addChild(label); } else { label = (LabelTTF*)cell->getChildByTag(2); } label->setString(StringUtils::format("Label %ld", idx)); return cell; } ssize_t HelloWorld::numberOfCellsInTableView(TableView *table){ return 100; } //实现头文件重写的TableViewDelegate方法------列表点击监听 void HelloWorld::tableCellTouched(TableView* table, TableViewCell* cell){ LabelTTF *label = (LabelTTF*)cell->getChildByTag(2); log("%s", label->getString().c_str()); }
UIVideoPlayer/UI Web View:
#include "ui/CocosGUI.h" #include "ui/UIVideoPlayer.h" #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) auto videoPlayer = cocos2d::experimental::ui::VideoPlayer::create(); videoPlayer->setContentSize(visibleSize); videoPlayer->setPosition(visibleSize/2); videoPlayer->setFileName("video.mp4"); videoPlayer->play(); addChild(videoPlayer); #endif #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) auto webview = cocos2d::experimental::ui::WebView::create(); webview->setContentSize(visibleSize); webview->setPosition(visibleSize / 2); webview->loadURL("http://baidu.com"); addChild(webview); #endif
场景切换特效:
LabelTTF *label = LabelTTF::create("Show Next Scene", "Courier", 36); addChild(label); label->setPosition(visibleSize / 2); EventListenerTouchOneByOne *listener = EventListenerTouchOneByOne::create(); listener->onTouchBegan = [label](Touch *t, Event *event){ if (label->getBoundingBox().containsPoint(t->getLocation())) { // 普通切换 //Director::getInstance()->replaceScene(ImageScene::createScene()); //场景切换特效 Director::getInstance()->replaceScene(TransitionFadeBL::create(1, ImageScene::createScene())); } return false; }; Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, label); //渐变切换 //auto transition = TransitionCrossFade::create(1, newScene); // 反转切换 //auto transition = TransitionZoomFlipAngular::create(1, newScene); //翻页切换 //auto transition = TransitionPageTurn::create(1, newScene,false);//---fals 类似书向后翻页 ---true 向前翻 //顺逆时针切换 //auto transition = TransitionProgressRadialCCW::create(1, newScene);//---CCW顺时针 ---CW逆时针 //左右切换 //auto transition = TransitionSplitRows::create(1, newScene); //auto transition = TransitionSplitCols::create(1, newScene);//Rows 上下两部分左右拉开 Cols 左中右三部分上下拉开
动作:
auto label = LabelTTF::create("Cocos2d-X", "Courier", 30); label->setPosition(visibleSize / 2); addChild(label); auto listener = EventListenerTouchOneByOne::create(); listener->onTouchBegan = [label](Touch *t, Event *e){ if (label->getBoundingBox().containsPoint(t->getLocation())) { //label->runAction(MoveTo::create(1, Point(100, 100))); //label->runAction(MoveBy::create(1, Point(-10, -10))); //动作反转 //label->runAction(MoveBy::create(1, Point(-10, -10))->reverse ()); //动作混合---同时 //label->runAction(Spawn::create(MoveBy::create(1, Point(100, 100)), RotateBy::create(1, 360), NULL)); //动作序列---顺序 label->runAction(Sequence::create(MoveBy::create(1, Point(100, 100)), RotateBy::create(1, 360), NULL)); //动作侦听CallFunc label->runAction(Sequence::create(MoveBy::create(1, Point(100, 100)), RotateBy::create(1, 360), CallFunc::create([](){ MessageBox("Action complete", "complete"); }), NULL)); } return false; }; Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, label); //动作重复 //label->runAction(Repeat::create(RotateBy::create(1, 180), 3)); //label->runAction(RepeatForever::create(RotateBy::create(1, 180)));
逐帧动画:
auto cache = SpriteFrameCache::getInstance(); cache->addSpriteFramesWithFile("anim.plist"); Vector<SpriteFrame*> vec; char name[15]; memset(name, 0, 15); for (int i = 0; i < 20; i++) { sprintf(name, "anim%04d", i); vec.pushBack(cache->getSpriteFrameByName(name)); } Animation *animation = Animation::createWithSpriteFrames(vec, 0.1f); Animate *animate = Animate::create(animation); auto sprite = Sprite::create(); addChild(sprite); sprite->setPosition(visibleSize / 2); sprite->runAction(RepeatForever::create(animate));
单点触摸:
auto label = LabelTTF::create("Click me", "Courier", 30); label->setPosition(visibleSize / 2); addChild(label); auto listener = EventListenerTouchOneByOne::create(); //Cocos2d-x事件传递 listener->onTouchBegan = [label](Touch *t, Event *e){ //Cocos2d-x触摸目标判断 if (label->getBoundingBox().containsPoint(t->getLocation())) { log("onTouchBegan"); } return true;//当返回值为true 才能执行onTouchMoved onTouchEnded }; listener->onTouchMoved = [](Touch *t, Event *e){ log("onTouchMoved"); }; listener->onTouchEnded = [](Touch *t, Event *e){ log("onTouchEnded"); }; Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, label);
多点触摸:
auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesBegan = [](std::vector<Touch*> ts, Event *e){ log("onTouchesBegan"); }; listener->onTouchesMoved = [](std::vector<Touch*> ts, Event *e){ log("Touches Moved ,and touch count is %ld", ts.size()); }; Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
加速度传感器:
Device::setAccelerometerEnabled(true); Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority( EventListenerAcceleration::create( [](Acceleration *a, Event *e){ log("x:%g, y:%g, z:%g ", a->x, a->y, a->z); }), this);
物理按键交互:
auto listener = EventListenerKeyboard::create(); listener->onKeyReleased = [](EventKeyboard::KeyCode code, Event *e){ log("key code : %d", code); switch (code) { case EventKeyboard::KeyCode::KEY_BACKSPACE: Director::getInstance()->end(); break; default: break; } }; Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
计时器:
重写update方法,随帧频执行,在h文件中 //update方法 virtual void update(float dt); ,在cpp实现:
//重写update方法 --- 每帧都会执行 void HelloWorld::update(float dt){ label->setPosition(label->getPosition() + Point(1, 1)); if (label->getPositionX()>500) { //停止update方法 unscheduleUpdate(); } }
在init调用:
label = LabelTTF::create("Cocos2d-X", "Courier", 30); addChild(label); scheduleUpdate();
也可以用schedule按照想要的时间执行,写一个方法,让他每秒执行一次:
方法:h中 void timerHandler(float dt); ,cpp中 void HelloWorld::timerHandler(float dt){ log(">>>>>>>>>>>>>>>>>>>"); }
调用 schedule(schedule_selector(HelloWorld::timerHandler), 1);
首选项数据读写:
//设置首选项 //UserDefault::getInstance()->setStringForKey("data", "Hello Cocos2d"); //读取首选项 log("%s", UserDefault::getInstance()->getStringForKey("data", "Hello CPP").c_str());
文件读写:
auto fu = FileUtils::getInstance(); //log("%s", fu->getWritablePath().c_str());文件写入的目录 //写入 FILE *f = fopen(fu->fullPathFromRelativeFile("data.txt", fu->getWritablePath()).c_str(), "w"); fprintf(f, "Hello Cocos\n"); fclose(f); //读取 Data d = fu->getDataFromFile(fu->fullPathFromRelativeFile("data.txt", fu->getWritablePath())); log("%s", d.getBytes());
//plist文件操作
auto fu = FileUtils::getInstance();
ValueMap vm = fu->getValueMapFromFile("data.plist");
log("%s", vm["name"].asString().c_str());
xml数据操作 --- #include <tinyxml2\tinyxml2.h>:
auto doc = new tinyxml2::XMLDocument(); doc->Parse(FileUtils::getInstance()->getStringFromFile("data.xml").c_str()); auto root = doc->RootElement(); for (auto e = root->FirstChildElement(); e; e = e->NextSiblingElement()) { std::string str; for (auto attr = e->FirstAttribute(); attr; attr = attr->Next()) { str += attr->Name(); str += ":"; str += attr->Value(); str += " ,"; } log("%s", str.c_str()); }
json数据操作 --- #include <json\document.h>:
rapidjson::Document d; d.Parse<0>(FileUtils::getInstance()->getStringFromFile("data.json").c_str()); log("%s", d[(int)0]["name"].GetString());
TMX 地图解析:
//加载地图 auto map = TMXTiledMap::create("map.tmx");//加载地图 addChild(map); map->setScale(0.5); map->setAnchorPoint(Vec2(0.5, 0.5)); map->setPosition(visibleSize / 2); auto mapProperties = map->getProperties();//获取地图属性 auto str = mapProperties["type"].asString(); CCLOG("map pro :%s", str.c_str()); auto sceneLayer = map->getLayer("scene");//获取图层 auto layerProperties = sceneLayer->getProperties();//获取图层属性 CCLOG("layer pro :%s", layerProperties["type"].asString().c_str()); auto tilePro = map->getPropertiesForGID(1).asValueMap();//获取图块属性 CCLOG("tile pro :%s", tilePro["type"].asString().c_str()); auto objectGroup = map->getObjectGroup("object");//获取对象组 auto obj = objectGroup->getObject("player");//获取player对象 CCLOG("obj pro :%s", obj["type"].asString().c_str()); //根据地图对象改操作地图 auto colorObj = objectGroup->getObject("color");//获取对象组中的color对象 //color的属性 auto colorObjX = colorObj["x"].asInt() / 32; auto colorObjY = colorObj["y"].asInt() / 32; auto colorObjW = colorObj["width"].asInt() / 32; auto colorObjH = colorObj["height"].asInt() / 32; //遍历color坐标修改其颜色 --- Y方向需要修改 ------ map->getMapSize().height - y for (int x = colorObjX; x < colorObjX + colorObjW; x++) { for (int y = colorObjY; y < colorObjY + colorObjH; y++) { auto sprite = sceneLayer->getTileAt(Vec2(x, map->getMapSize().height - y)); sprite->setColor(Color3B(255, 0, 0)); } } auto playerBall = Sprite::create("c.png");//创建一个小球图像 playerBall->setPosition(obj["x"].asFloat(), obj["y"].asFloat());//将小球的位置放入地图的player对象位置 map->addChild(playerBall); //根据 Tiled 属性判断碰撞 auto eventListener = EventListenerTouchOneByOne::create(); eventListener->onTouchBegan = [map, sceneLayer, playerBall](Touch *touch, Event *e){ auto point = map->convertToNodeSpace(touch->getLocation()); point.x = static_cast<int>(point.x / 32); point.y = map->getMapSize().height - static_cast<int>(point.y / 32) - 1; auto t = sceneLayer->getTileAt(point); //t->setColor(Color3B(255, 0, 0)); auto gid = sceneLayer->getTileGIDAt(point); auto p = map->getPropertiesForGID(gid).asValueMap(); if (p["move"].isNull() != true && p["move"].asBool() == true) { playerBall->setPosition(t->getPosition().x, t->getPosition().y); } return false; }; _eventDispatcher->addEventListenerWithSceneGraphPriority(eventListener, map);
3D功能:
auto s = Sprite3D::create("tortoise.c3b");//加载3D对象 //auto s = Sprite3D::create("tortoise.c3b", "tortoise.png");//模型与材质名字不一样 s->setScale(0.1); s->setPosition(visibleSize / 2); addChild(s); //s->runAction(RepeatForever::create(RotateBy::create(1, Vec3(45, 45, 0))));//动画效果 //auto anim = Animate3D::create(Animation3D::create("tortoise.c3b"));//3D效果 --- 3D对象含有的所有的动画效果 //s->runAction(anim); auto anim = Animate3D::create(Animation3D::create("tortoise.c3b"), 0, 1.93);//取得3D对象特定时间点的3D动作 --- 游泳 s->runAction(RepeatForever::create(anim)); //添加光源 auto l = DirectionLight::create(Vec3(0, 0, -1000), Color3B(255, 255, 255));//平行光源 addChild(l);
Cocos2d-x基础知识