1)2d笛卡爾座標
//創建一個正方形
auto rect = DrawNode::create();
rect->drawRect(Vec2(0,0), Vec2(50,50), Color4F(1.0,0,0,1.0));
//添加正方形到場景中
addChild(rect);
//創建一個點
auto dot = DrawNode::create();
dot->drawDot(Vec2(0,0), 5, Color4F(1.0,1.0,1.0,1.0));
//將點加入到正方形中
rect->addChild(dot);
//圍繞中心點旋轉
rect->setContentSize(Size(50,50));
rect->setAnchorPoint(Vec2(0.5,0.5f));//錨點
//居中
rect->setPosition(visibleSize/2);
//調節點的位置
dot->setPosition(Vec2(10,10));
//旋轉
schedule([dot,rect](float f){
//旋轉
rect->setRotation(rect->getRotation()+1);
//獲取世界座標
auto p = dot->convertToWorldSpace(Vec2(0,0));
//輸出世界座標
CCLOG("%f,%f",p.y,p.x);
},"Test");
2)三角函數例子
//通過三角函數使物體運動
_angle=0;
auto dot2 = DrawNode::create();
dot2->drawDot(Vec2(0,0), 10, Color4F(1.0,1.0,1.0,1.0));
addChild(dot2);
dot2->setPosition(visibleSize/2);
schedule([dot2,this,visibleSize](float f){
//通過修改y軸座標使得小球運動
dot2->setPositionY(visibleSize.height/2 + sin(_angle)*100.0);
//通過修改X軸座標使得小球運動發生變化
dot2->setPositionX(visibleSize.height/2 + cos(_angle)*100.0);
//角度自增0.1
_angle+=0.1;
},"Test");
3)小球向指定方向持續移動
_direction.set(random(-1.0f, 1.0f), random(-1.0f,1.0f));
_direction.normalize();//方向上的大小等於1,標準化
auto dot3 = DrawNode::create();
dot3->drawDot(Vec2(0,0), 10, Color4F(1.0,1.0,1.0,1.0));
addChild(dot3);
dot3->setPosition(visibleSize/2);
schedule([dot3,this,visibleSize](float f){
auto p = dot3->getPosition();
if (p.x<0||p.x>visibleSize.width) {
_direction.x*=-1;
}else if(p.y<0||p.y>visibleSize.height){
_direction.y*=-1;
}
dot3->setPosition(p+_direction*10);
},"Test");
4)遊戲設置
1->設計分辨率
//設計分辨率
AppDelegate::glview->setDesignResolutionSize(1280, 720, ResolutionPolicy::FIXED_HEIGHT);
2->橫屏豎屏修改
3->顯示對象的使用
// auto logo = Sprite::create("logo.png");
// addChild(logo);
// logo->setPosition(visibleSize/2);
//將圖片提前加載成2d紋理Texture2d
auto img = Director::getInstance()->getTextureCache()->addImage("logo.png");//可以提前異步加載圖片
//獲取圖片的大小
auto logoSize = img->getContentSize();
CCLOG("logo size : %f , %f",logoSize.width,logoSize.height);
//將2d紋理放入sprite對象中
auto logo = Sprite::createWithTexture(img);
addChild(logo);
logo->setPosition(visibleSize/2);
4->圖層的先後與場景的切換
auto layer1=Layer::create();
auto layer2=Layer::create();
auto layer3=Layer::create();
auto img1 = Sprite::create("layer1.png");
auto img2 = Sprite::create("layer2.png");
auto img3 = Sprite::create("layer3.png");
img1->setAnchorPoint(Vec2(0,0));
img2->setAnchorPoint(Vec2(0,0));
img3->setAnchorPoint(Vec2(0,0));
layer1->addChild(img1);
layer2->addChild(img2);
layer3->addChild(img3);
addChild(layer2);
addChild(layer1);
addChild(layer3);
layer1->setPosition(Vec2(100,-100));
layer1->setPosition(Vec2(500,-500));
layer1->setPosition(Vec2(900,-900));
scheduleOnce([visibleSize,this](float f){
//建立一個新的場景和圖層
auto scene2 = Scene::create();
auto scene2Layer = Layer::create();
//將圖層加入場景中
scene2->addChild(scene2Layer);
//定義一個新的logo,設置logo居中顯示
auto logo2 = Sprite::create("logo2.png");
logo2->setPosition(visibleSize/2);
scene2Layer->addChild(logo2);
//調用導演類替換圖層
Director::getInstance()->replaceScene(scene2);
}, 3,"delay");
5->自定義現實對象
LogoNode.hpp->
#ifndef LogoNode_hpp
#define LogoNode_hpp
#include <stdio.h>
#include "cocos2d.h"
USING_NS_CC;
class LogoNode:public Node{
protected:
Sprite* _logo;
Sprite* _cocosLogo;
public:
LogoNode();
virtual ~LogoNode();
virtual bool init();
CREATE_FUNC(LogoNode);
};
#endif /* LogoNode_hpp */
LogoNode.cpp->
#include "LogoNode.hpp"
LogoNode::LogoNode():_logo(nullptr),_cocosLogo(nullptr){}
LogoNode::~LogoNode(){}
bool LogoNode::init(){
//調用父類的init函數,如果調用失敗,則返回false;
if(!Node::init()){
return false;
}
_logo =Sprite::create("logo2.png");
_cocosLogo = Sprite::create("logo.png");
addChild(_logo);
addChild(_cocosLogo);
_cocosLogo->setVisible(false);
schedule([this](float f){
_logo->setVisible(!_logo->isVisible());
_cocosLogo->setVisible(!_cocosLogo->isVisible());
},1,"test");
return true;
}
GameScene.hpp->
#ifndef GameScene_hpp
#define GameScene_hpp
#include <stdio.h>
#include "cocos2d.h"
USING_NS_CC;
class GameScene:public Layer{
public:
GameScene();
virtual ~GameScene();
virtual bool init();
CREATE_FUNC(GameScene);
static Scene* createScene();
};
#endif /* GameScene_hpp */
GameScene.cpp->
#include "GameScene.hpp"
#include "LogoNode.hpp"
GameScene::GameScene(){}
GameScene::~GameScene(){}
bool GameScene::init(){
if (!Layer::init()) {
return false;
}
auto logo = LogoNode::create();
addChild(logo);
logo->setPosition(Director::getInstance()->getVisibleSize()/2);
return true;
}
Scene* GameScene::createScene(){
auto scene=Scene::create();
auto layer=GameScene::create();
scene->addChild(layer);
return scene;
}
AppDelegate.cpp->
auto scene = GameScene::createScene();
三 Action動畫與實現
1)基本動畫的實現
//創建一個Sprite
auto role = Sprite::create("role.png");
addChild(role);
role->setPosition(visibleSize/2);
role->setScale(1);
//開啓Action,1爲運行時間,Vec2爲移動到的座標
//role->runAction(MoveTo::create(1, Vec2(100,visibleSize.height-100)));
//連續執行Action
auto action1 = MoveBy::create(1, Vec2(100,100));
auto action2 = action1->reverse();//反轉函數,支持MoveBy函數。
//使用Sequence可以順序執行動畫
role->runAction(Sequence::create(action1,action2, NULL));
//並列執行動畫
auto action3 = ScaleTo::create(2, 0.2);
auto action4 = MoveBy::create(2, Vec2(200,0));
//使用Spawn函數並列執行動畫
role->runAction(Spawn::create(action3,action4, NULL));
//動畫執行完成回調,通過順序/並列執行動畫達到監聽Action動畫的效果,使用CallFunc函數回調
role->runAction(Sequence::create(Spawn::create(action3,action4, NULL),CallFunc::create([](){
CCLOG("Play Completed");
}) , NULL));
2) Action內置特效(NodeGrid)
實例代碼:
//建立NodeGrid對象,加入Sprite
auto role = NodeGrid::create();
role->addChild(Sprite::create("role.png"));
role->setPosition(visibleSize/2);
addChild(role);
//Shaky3D,ShakyTiles3D,ShuffleTiles,TurnOffTiles
/**ShakyTiles3D->10爲震動時間,Size爲網格大小,數值越大,網格越細,1爲震動幅度,false爲Z軸的深度
role->runAction(ShakyTiles3D::create(10, Size(10,10), 1, false));*/
/*爆炸效果->1爲爆炸時間,Size爲碎片大小,25爲爆炸的速度
role->runAction(ShuffleTiles::create(1, Size(50,50), 25));*/
/*先抖動後爆炸
auto shaky = ShakyTiles3D::create(1, Size(50,50), 5, false);
auto shuffle = ShuffleTiles::create(0.5, Size(50,50), 25);
role->runAction(Sequence::create(shaky,shuffle, NULL));*/
/*碎片消失
role->runAction(TurnOffTiles::create(1, Size(50,50)));*/
/*波浪效果->3爲持續時間,Size爲網格大小,5爲波紋幅度,40爲扭曲度
role->runAction(Waves3D::create(3, Size(50,50), 5, 40));*/
/*波浪震動後還原
auto wave1 = Waves3D::create(3, Size(15,10), 5, 40);
auto wave2 = Waves3D::create(3, Size(15,10), 5, 0);
role->runAction(Sequence::create(wave1,wave2, NULL));*/
3)場景切換特效:
實例代碼:
auto background= Sprite::create("a.png");
background->setPosition(visibleSize/2);
addChild(background);
//建立schedule替換場景
scheduleOnce([visibleSize](float f){
//創建新的場景
auto newScene = Scene::create();
auto newBackground = Sprite::create("b.png");
newBackground->setPosition(visibleSize/2);
newScene->addChild(newBackground);
/*創建場景替換動畫,TransitionCrossFade是淡入淡出
auto transition = TransitionCrossFade::create(1, newScene);*/
/*反轉動畫效果
auto transition = TransitionZoomFlipAngular::create(1, newScene);*/
/*翻頁效果
auto transition = TransitionPageTurn::create(1, newScene, true);*/
/*順時針切換
auto transition = TransitionProgressRadialCW::create(1, newScene);*/
/*左右切換
auto transition = TransitionSplitRows::create(1, newScene);*/
//替換場景
Director::getInstance()->replaceScene(newScene);
}, 2,"Test");
四,內存管理和數據結構
1)所有的現實對象,如果當前正在顯示,則不會被釋放內存。如果沒有在顯示,也沒有調用Ref::retain()函數,則會因爲索引爲0而倍自動釋放。 Ref::autoRelease() ->每一幀都會遍歷一次所有的對象,進行自動釋放。
obj->getReferenceCount() 可以查看引用的計數
記得使用對象時需要retain()和release(),或者直接autorelease();
2)Vector和Map ->自動管理對象,不能保存沒有繼承Ref的對象
//Vector 的正確用法
Vector<Label*> vec;
auto label1 = Label::create();
auto label2 = Label::create();
label1->setString("Label 1");
label2->setString("Label 2");
label1->setSystemFontSize(50);
label2->setSystemFontSize(50);
vec.pushBack(label1);
vec.pushBack(label2);
int i = 0;
for (auto label:vec) {
i++;
label->setPosition(Vec2(visibleSize.width/2,i*150));
addChild(label);
}
//Map的正確用法
Map<std::string,Label*> map;
auto label1 = Label::create();
auto label2 = Label::create();
label1->setString("Label 1");
label2->setString("Label 2");
label1->setSystemFontSize(50);
label2->setSystemFontSize(50);
label1->setPosition(Vec2(visibleSize.width/2,200));
label2->setPosition(Vec2(visibleSize.width/2,300));
map.insert("label1",label1);
map.insert("label2",label2);
addChild(map.at("label1"));
3)value
實例代碼:
//Value的使用
Value value1 = Value("abc");
Value value2 = Value(123);
Value value3 = Value(true);
//一般情況下通過以下代碼輸出
CCLOG("%s %d %s ",value1.asString().c_str(),value2.asInt(),value3.asBool()==true?"True":"False");
//萬能value輸出方式更自由
CCLOG("%s %s %s",value1.asString().c_str(),value2.asString().c_str(),value3.asString().c_str());
Value value4 = Value::Null;//將Value設置爲null
value4=value1;
value4=value2;
value4=value3;
//Value可以被重複賦值
CCLOG("%s %s",value4.getType()==Value::Type::BOOLEAN?"True":"False",value4.asString().c_str());
//ValueVector的使用,和打印
ValueVector vector;
vector.push_back(Value("Hello"));
vector.push_back(value1);
vector.push_back(value2);
for (auto v:vector) {
CCLOG("Vector %s",v.asString().c_str());
}
//ValueMap,先遍歷最後面的值?
ValueMap map;
map["a"]=value2;
map["b"]=value1;
for (auto m:map) {
CCLOG("%s = %s",m.first.c_str(),m.second.asString().c_str());
}
五,基本控件介紹
Director->Scene->Layer->Sprite
#錨點?->定位點,默認情況0.5,0.5
#Director::runWithScene();
#靜態方法: Sprite::create() ->Cocos2d-x的約定,這是一個靜態的方法,
#auto 是什麼意思?
消息框MessageBox()用法->
//消息框提示
MessageBox("hello world", "title");
文本標籤LabelTTF
//標籤
LabelTTF *label =LabelTTF::create();
label->setString("Hello World");
label->setFontSize(50);
label->setPosition(visibleSize.width/2,visibleSize.height/2);
addChild(label);
輸入文本框TextFieldTTF->
//新增輸入文本
TextFieldTTF *textfield = TextFieldTTF::textFieldWithPlaceHolder("在這裏輸入", "宋體", 20);
textfield->setPosition(visibleSize.width/2,visibleSize.height/2);
addChild(textfield);
//建立一個文本框的listener
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan=[textfield ](Touch *t,Event *event){
if (textfield->getBoundingBox().containsPoint(t->getLocation())) {
//彈出輸入鍵盤
textfield->attachWithIME();
}else{
//當點擊到別的地方時,隱藏輸入鍵盤
textfield->detachWithIME();
}
return false;
};
//註冊TextField的listener
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, textfield);
自定義類(與常用的C++類使用有差別)
Ball.cpp->
#include "Ball.hpp"
bool Ball::init(){
//調用Sprite類的initWithFile代碼
initWithFile("ball.png");
return true;
}
Ball.hpp->
#ifndef Ball_hpp
#define Ball_hpz
#include <stdio.h>
#include "cocos2d.h"
using namespace cocos2d;
class Ball:public Sprite{
public:
//在這裏做初始化的操作,比如加載圖片
virtual bool init();
// static Ball* create(){
// Ball * b = new Ball();
// b->init();
// b->autorelease();
// return b;
// }
//使用宏快速創建Ball,代碼與上面註釋的類似
CREATE_FUNC(Ball);
};
#endif /* Ball_hpp */
HelloWorldScene.cpp->
#include "Ball.hpp"
auto b = Ball::create();
b->setPosition(200,200);
addChild(b);
菜單Menu
實例代碼->可以添加多個菜單
//Menu菜單的使用
//創建一個菜單,通過 lambda表達式註冊回調函數
auto menu = Menu::create(MenuItemImage::create("unselect.png", "selected.png", [](Object* obj){
//函數回調
log("menu item touched");
}), NULL);
addChild(menu);
列表的使用:
HelloWorldScene.h->
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
//要使用列表必須引入以下頭文件
#include <cocos-ext.h>
USING_NS_CC;
//要使用列表必須使用以下命名空間
USING_NS_CC_EXT;
class HelloWorld : public cocos2d::Layer,TableViewDataSource,TableViewDelegate
{
public:
static cocos2d::Scene* createScene();
virtual bool init();
// a selector callback
void menuCloseCallback(cocos2d::Ref* pSender);
// implement the "static create()" method manually
CREATE_FUNC(HelloWorld);
public:
/**
* 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:
/**
* @js NA
* @lua NA
*/
virtual void scrollViewDidScroll(ScrollView* view) {};
/**
* @js NA
* @lua NA
*/
virtual void scrollViewDidZoom(ScrollView* view) {};
/**
* 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);
};
#endif // __HELLOWORLD_SCENE_H__
HelloWorldScene.cpp->
#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"
//使用列表必須要引入以下頭文件
#include <cocos-ext.h>
//比如要使用以下命名空間
USING_NS_CC_EXT;
USING_NS_CC;
Scene* HelloWorld::createScene()
{
// 'scene' is an autorelease object
auto scene = Scene::create();
// 'layer' is an autorelease object
auto layer = HelloWorld::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
// on "init" you need to initialize your instance
bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first
if ( !Layer::init() )
{
return false;
}
auto visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
//建立一個TableView,需要繼承兩個類:TableViewDataSource,TableViewDelegate
TableView * tv = TableView::create(this, Size(300,300));
tv->setAnchorPoint(Point(0,0));
tv->setPosition(50,50);
//註冊點擊監聽函數
tv->setDelegate(this);
addChild(tv);
return true;
}
//返回每一個列表項的大小
Size HelloWorld::cellSizeForTable(cocos2d::extension::TableView *table){
return Size(300,50);
}
//創建列表項,類似於android的getView()
TableViewCell* HelloWorld::tableCellAtIndex(cocos2d::extension::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(cocos2d::extension::TableView *table){
return 100;
}
//當label被點擊時的回調方法
void HelloWorld::tableCellTouched(cocos2d::extension::TableView *table, cocos2d::extension::TableViewCell *cell){
LabelTTF *label =(LabelTTF*) cell->getChildByTag(2);
log("%s",label->getString().c_str());
}
void HelloWorld::menuCloseCallback(Ref* pSender)
{
Director::getInstance()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
}