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
}