一、Cocos2d-x-2.2.3版本安装配置。
1、在Cocos2D-X 2.2.3目录下,点击cocos2d-win32.vc2010.sln。
由于我的电脑上安装了vs2019,点击后是用的vs2019打开的,打开后我也没多想什么就开始编译,编译完启动项目的时候就报错
错误C1189#error: Macro definition of snprintf conflicts with Standard Library function declaration libcocos2d
原因是,很多的库或者程序中将snprintf()函数定义为 _snprintf(),而在vs2015出现之前并不支持_snprintf()。然而,vs2019定义了 snprintf()。
这显然就导致了snprintf()的重定义。
解决的办法是,在你所有定义snpritf的文件中(可能你使用的是别人提供的库中出现冲突,那么这时候你就需要修改重新编译该库),找到如下定义:
#define snprintf _snprintf 将其替换为
#if defined(_MSC_VER) && _MSC_VER<1900
# define snprintf _snprintf
#endif
为了方便,我直接把项目放到了vs2010中编译,刚好我的电脑上也下载的VS2010。
由于在VS2019中编译过,再到VS2010中编译时会报下面的错误
无法找到 v142 的生成工具(平台工具集 =“v142”)
问题的原因
v142对应的是VS2019,项目之前的编译器是VS2019,现在换到了VS2010,所以报的这个错误。
v142–>VS2019
v141–>VS2017
v140–>VS2015
v120–>VS2013
修改成现在编译器对应的工具集,再重新编译
项目–>属性—>常规–>平台工具集–>选择对应的平台工具v100就是VS2010
如果还是不行,就将工程目录下的隐藏文件.vs删除,再重新编译
2、生成完成后,选择“HelloCpp”右键->设为启动项目,然后启动调试,项目就运行起来了
3、用Python命了来创建新项目
具体操作如下:
(1)下载安装Python2.7版本(cocos2d-x只支持python2不支持高版本的python)。
(2)然后配置环境变量,将 python的安装路径加入到环境变量Path中。
打开cmd命令符,输入python --version显示以下内容说明配置成功
进入到COCOS2D安装目录的tools/project-creator目录下
我的路径是F:\Cocos2d-x\cocos2d-x-2.2.3\cocos2d-x-2.2.3\tools\
project-creator
(3)用Python输入命令
python create_project.py -project FruitNinja-package com.eyu.helloword -language cpp
就成功创建了一个名为FruitNinja,语言为c++的新项目,而且各个版本的都有,而且它建的项目是在cocos2d-x2.2.3文件夹中的projects文文件夹里
(4)我们进入这个新创建的文件夹,可以看到各个平台的版本,我的项目是要在windows电脑上跑的,所以,打开.win32文件夹,点击里面的.sln文件,用VS2010打开
文章来源地址https://uudwc.com/A/GV5gZ
点击启动调试发现这个项目可以直接运行
二、实现水果忍者的第一个场景HelloWorld和第二个场景PrepaScene
1、修改HelloWorld场景
修改HelloWorld类的init()方法:用back.png创建一个图片精灵,添加到场景中当背景
文章来源:https://uudwc.com/A/GV5gZ
修改过后,HelloWorld场景就是下面显示的样子,仅仅只有一个背景图片
3、实现游戏的第二个场景
(1)创建一个新的层类PrepareScene,这个类也有一个创建静态场景的方法,PrepareScene层就添加在这个场景中,方法的实现和HelloWorld::scene相同
class PrepareScene : public CCLayer
{
public:
PrepareScene();
virtual bool init();
static cocos2d::CCScene* scene();
CREATE_FUNC(PrepareScene);
//把主界面的图片精灵添加到场景中
void loadlogo();
void loadtitle();
void loadmenu();
void scle_rotate(int i); //设置精灵旋转
int index;
private:
#define RING1_ROTATE 1
#define RING2_ROTATE 2
#define RING3_ROTATE 3
#define PEACH_ROTATE 4
#define SANDIA_ROTATE 5
#define BOOM_ROTATE 6
CCSize size; //记录屏幕大小
bool ifstart; //记录主界面状态,是否已经准备好
};
(2)类方法的实现
构造函数,初始化属性
PrepareScene::PrepareScene()
{
index = 0;
angel = 0;
ifstart = false;
}
init函数设置界面的背景图片,init函数中调用了loadlogo()设置界面的其他元素
bool PrepareScene::init()
{
size = CCDirector::sharedDirector()->getWinSize(); //获取屏幕大小
CCSprite* backsp = CCSprite::create("background.jpg"); //用图片创建精灵backsp
backsp->setPosition(ccp(size.width / 2, size.height / 2)); //把锚点设置在屏幕正中央
this->addChild(backsp, -1); //背景图片添加到最底层,负数代表最高优先级
loadlogo();
return true;
}
Loadlogo()函数实现添加主界面的横幅和logo元素,横幅成功添加到场景中后,通过函数调用动作callfun紧接着调用loadtitle方法
loadtitle函数实现与loadlogo函数相似,紧接着调用loadmenu函数
基本动作之持续动作CCActionInterval
CCJumpTo和CCJumpBy属于延时动作,即经过一段时间才能完成的动作
CCJumpTo:把某一CCSprite跳到某一位置
CCJumpBy:把某一CCSprite跳起一段距离,它有一个方法reverse,它让对象按原路径返回
关于To和By:
To:绝对动作。
By:相对动作。
如:当前对象的坐标为(20,20)。
CCMoveTo(50,50)后,移动到了(50,50)的位置。
CCMoveBy(50,50)后,则是相对当前坐标进行移动,最后坐标为(70,70)。
CCActionInstant继承于CCFiniteTimeAction,是一个持续执行的动作类。也就是说在一段时间间隔里,执行完成某个动作。
//几秒后移动到坐标点
CCMoveTo::create("时间","坐标");
CCMoveBy::create("时间","坐标");
//几秒后经过几次弹跳到指定位置
CCJumpTo::create("时间","目标位置","高度","到目标所需次数");
CCJumpBy::create("时间","目标位置","高度","到目标所需次数");
函数回调动作CCCallFunc
CCCallFunc也是瞬时动作CCActionInstant的子类。它主要有三种函数回调动作类。三种函数回调的区别在于所带的参数个数:0、1、2。
CCCallFunc::create('对象this', '回调函数'); //回调函数:不带参数
CCCallFuncN::create('对象this', '回调函数'); //回调函数:传递着本身作为参数(CCNode* node)
CCCallFuncND::create('对象this', '回调函数', '任意参数void'); //回调函数:带2个参数(CCNode* node,void* a)
组合动作
组合动作,顾名思义,就是将单一的动作组合起来,形成一个更加复杂的动作。
如在移动的同时又进行旋转,在弹跳后执行函数回调动作等等……
组合动作的类也是CCActionInterval的子类,主要分为两类:序列动作、重复动作。
- 序列动作:执行各个动作的先后顺序。
CCSpawn::create("action对象1", "action对象2", ..., NULL); //动作同时执行
CCSequence::create("action对象1", "action对象2", ..., NULL); //动作按顺序执行
设置水果上抛
可变速动作CCEaseAction
CCEaseAction也是CCActionInterval的子类。此类动作的特点在于动作执行的过程中速度是可以变化的。如:CCMoveTo,可以加速或减速的进行移动,也可以先加速再减速的移动。
有该类的存在,是因为游戏中有些动作并不是均匀执行的,就像自由落体的球,下落速度会越来越快,而不是匀速下落。所以cocos2dx引擎封装了一些常用的可变速度的类。
此类速度变化大致可分为三种:
(1)In : 由慢变快。
(2)Out : 由快变慢。
(3)InOut: 由慢变快,再变慢。
其中速度的快慢变化是依据物理学上的一些公式进行的。如正弦、指数等等。
值得注意的是:CCEaseAction变化的是某个持续性动作action动作执行过程中的速度,对于action动作执行的时间依旧是不会改变的。
其中关于CCEaseIn、CCEaseOut、CCEaseInOut的变化有点复杂。
Loadmenu函数:添加三个六个精灵元素到场景中,并使他们旋转,旋转速速都不相同
void PrepareScene::loadmenu()
{
CCSprite* scle1_dojo = CCSprite::create("dojo.png");
CCSprite* scle2_new = CCSprite::create("new-game.png");
CCSprite* scle3_quit = CCSprite::create("quit.png");
CCSprite* peach = CCSprite::create("peach.png");
CCSprite* sandia = CCSprite::create("sandia.png");
CCSprite* boom = CCSprite::create("boom.png");
scle1_dojo->setPosition(ccp(120, 180));
scle2_new->setPosition(ccp(350, 180));
scle3_quit->setPosition(ccp(550, 130));
peach->setPosition(ccp(120, 180));
sandia->setPosition(ccp(350, 180));
boom->setPosition(ccp(550, 130));
this->addChild(scle1_dojo);
this->addChild(scle2_new);
this->addChild(scle3_quit);
this->addChild(peach);
this->addChild(sandia);
this->addChild(boom);
//旋转效果
scle_rotate(RING1_ROTATE);
scle_rotate(RING2_ROTATE);
scle_rotate(RING3_ROTATE);
scle_rotate(PEACH_ROTATE);
scle_rotate(SANDIA_ROTATE);
scle_rotate(BOOM_ROTATE);
ifstart = true; //记录主界面已经准备好
}
实现精灵元素旋转的函数
(3)PrepareScene类实现后,我们修改AppDelegate类的函数
CCScene* pScene = PrepareScene::scene();修改为 CCScene* pScene = HelloWorld::scene();
语句的位置在以下函数体中
bool AppDelegate::applicationDidFinishLaunching() {
……
//创建一个场景HelloWorld,这是游戏程序的第一个界面
CCScene* pScene = HelloWorld::scene();
return true;
}
点击运行看看效果,如下图。那么第二个游戏场景也实现了部分
- 设置场景切换
1、修改HelloWorld类,添加loadScene(float dt);方法
class HelloWorld : public cocos2d::CCLayer
{
……
void loadScene(float dt);
};
void HelloWorld::loadScene(float dt)
{
CCScene* scene = PrepareScene::scene();
//CCTransitionCrossFade* pScene = CCTransitionCrossFade::create(0.1,scene);
CCDirector::sharedDirector()->replaceScene(scene);
}
loadScene(float dt);函数将HelloWorld场景替换成PrepaScene场景(游戏的菜单界面)
2、把对AppDelegate::applicationDidFinishLaunching函数做的修改撤销,并回到HelloWorld.cpp文件修改init函数,添加以下一行,设置一个一次性定时器,使1.5秒后执行HelloWorld::loadScene()函数实现场景的切换
bool HelloWorld::init()
{
……
//一次性定时器,延迟1.5秒后执行相应的刷新体函数,只执行一次,之后就不在刷新
this->scheduleOnce(schedule_selector(HelloWorld::loadScene), 1.5f);
this->setKeypadEnabled(true);
return true;
}