提要:
学习Cocos2dx编程书上的游戏案例,跳跳跳跳,没了~
初始化游戏
-
先在工程添加筛选器,添加一个Game筛选器,里面又有包含关卡的场景筛选器以及玩家和食物的实体筛选器。
-
在实体筛选器书写food.cpp和food.h文件,作用是提供精灵获取和绑定功能的类,如下。
-
在实体筛选器书写Player.cpp和Player.h文件如下。
-
在场景筛选器书写guanScene.cpp和guanScene.h文件如下,即关场景,关卡场景。
-
需要注意的是必须去AppDelegate.cpp中修改默认启动场景。
-
在AppDelegate.cpp中先添加#include "guanScene.h"头文件,在修改如下参数。
bool AppDelegate::applicationDidFinishLaunching() { ...... //省略上面 // create a scene. it's an autorelease object // auto scene = HelloWorld::createScene(); 默认启动的场景 auto scene = guanScene::createScene(); //自己创建的游戏关卡场景 // run director->runWithScene(scene); return true; }
-
再次记录在AppDelegate.cpp下修改窗口大小如下。
bool AppDelegate::applicationDidFinishLaunching() { // initialize director auto glview = director->getOpenGLView(); if(!glview) { //... } glview->setFrameSize(960, 640); //设置窗口大小 //... return true; }
无限滚动地图
-
了解update函数。
-
实现代码:this->scheduleUpdate();效果如下。
//首先在场景头文件中声明一个update函数 virtual void update(float u); //定义一个update函数来实现重写 //再在场景.cpp文件中进行重写定义 void guanScene::update(float u) { log("update is good"); //场景每帧运行的线程都会打印一次这个日志 }
3. 重写update函数,实现连续滚动效果。
void guanScene::update(float u)
{
int PosX1 = mybgSprite1->getPositionX(); //获取背景1的X坐标
int PosX2 = mybgSprite2->getPositionX(); //获取背景2的X坐标
int bgspeed = 1; //背景滚动速度
//两张图片向左滚动,X坐标每次都减1
PosX1 -= bgspeed;
PosX2 -= bgspeed;
//获取背景图片的大小
Size bgSize = mybgSprite1->getContentSize();
//当第一个地图完全离开屏幕时,第二个地图刚好出现在屏幕上,让他们紧贴在一起
if (PosX1 <= -bgSize.width / 2) //coco2dx对象描点是图片中间
{
PosX1 = bgSize.width + bgSize.width / 2;
}
//当第二个地图完全离开屏幕时,第一个地图刚好出现在屏幕上,让他们紧贴在一起
if (PosX2 <= -bgSize.width / 2)
{
PosX2 = bgSize.width + bgSize.width / 2;
}
mybgSprite1->setPositionX(PosX1);
mybgSprite2->setPositionX(PosX2);
}
解锁会动的角色
-
在头文件声明两个函数,一个是跳跃按钮函数一个是按钮回调函数。
void createJump(); //跳跃按钮函数 void starMenuCallback(cocos2d::Ref* p); //按钮回调
-
在.cpp文件中定义。
void guanScene::createJump() { Size getSize = Director::getInstance()->getVisibleSize(); //使用类 MenuItemImage 来创建一个菜单项,第一个参数是按钮没有被单击图片,第二个参数是按钮被单击图片 //第三个参数是为按钮的点击事件指定了一个回调函数 MenuItemImage* starMenuItem = MenuItemImage::create("CloseNormal.png","CloseSelected.png", this, menu_selector(guanScene::starMenuCallback)); //创建一个Menu来包含这个按钮 Menu* newMenu = Menu::create(starMenuItem, NULL); newMenu->setPosition(Point(getSize.width-60,getSize.height-230)); this->addChild(newMenu, 1); } void guanScene::starMenuCallback(Ref* p) { //创建跳跃动作 auto jump = JumpBy::create(0.5f, Point(0, 0), 40, 1); //执行动作 this->myPlayer->runAction(jump); }
-
实现效果。
创建金币
-
创建金币对象的文件,如下。
//zhufood.h #ifndef _ZHUFOOD_H_ #define _ZHUFOOD_H_ #include "food.h" class zhufood :public food { public: zhufood(); ~zhufood(); CREATE_FUNC(zhufood); virtual bool zhufoodinit(); void show(); void hide(); //隐藏 void reboot(); //重置 bool isAlive(); //判断是否为活动状态 private: bool myAlive; //标记金币活动状态 }; #endif //zhufood.cpp #include "zhufood.h" zhufood::zhufood() { myAlive = false; } zhufood::~zhufood(){} bool zhufood::zhufoodinit() { return true; } void zhufood::show() { if (getSprite()!= NULL) { setVisible(true); //设置为可见 myAlive = true; } } void zhufood::hide() { if (getSprite()!= NULL) { setVisible(false); //设置为不可见 reboot(); //重置 myAlive = false; } } void zhufood::reboot() { if (getSprite()!= NULL) { //初始化金币坐标, CCRANDOM_0_1随机数 setPosition(Point(800 + CCRANDOM_0_1() * 2000, 200 - CCRANDOM_0_1() * 100)); } } bool zhufood::isAlive() { return myAlive; }
-
为实现更好的管理金币这一事务,创建一个管理它的类。
-
创建金币管理类,如下。
//zhufoodManager.h #ifndef _ZHUFOODMANAGER_H_ #define _ZHUFOODMANAGER_H_ #include "cocos2d.h" #include "zhufood.h" USING_NS_CC; #define MAX_ZHUFOOD 10 //最大数量 class zhufoodManager :public Node { public: CREATE_FUNC(zhufoodManager); virtual bool init(); virtual void update(float a); //重写update函数 private: void createZhuFood(); //创建金币对象zhufood Vector<zhufood*> myzhufoodlist; //存放zhufood对象的列表 }; #endif //zhufoodManager.cpp #include "zhufoodManager.h" #include "Player.h" #include "zhufood.h" bool zhufoodManager::init() { createZhuFood(); //创建对象 this->scheduleUpdate(); //开启update函数的调用 return true; } void zhufoodManager::createZhuFood() { zhufood* zhu = NULL; Sprite* sprite = NULL; for (int i = 0; i < MAX_ZHUFOOD; i++) { //创建金币对象zhufood zhu = zhufood::create(); zhu->bangSprite(Sprite::create("100yuan.jpg")); //绑定对象,在food.h中声明了 zhu->setScale(0.25f); //缩小到0.25倍大小 zhu->reboot(); //添加金币对象 this->addChild(zhu); //保存金币对象到列表中 myzhufoodlist.pushBack(zhu); } } void zhufoodManager::update(float a) { for (auto zhufood : myzhufoodlist) { //如果金币处于活动状态 if (zhufood->isAlive()) { zhufood->setPositionX(zhufood->getPositionX() - 4); //如果金币X坐标小于0,则超出了屏幕范围,则隐藏起来 if (zhufood->getPositionX() < 0) zhufood->hide(); } else { //金币处于非活动状态则让金币出场 zhufood->show(); } } }
-
在场景.cpp文件的init函数中进行创建金币管理类对象。
//记得在场景.cpp中添加zhufoodManager.h头文件 bool guanScene::init() { //... //创建金币管理器 zhufoodManager* manager = zhufoodManager::create(); this->addChild(manager,4); //初始化背景图片 initBG(); this->scheduleUpdate(); //启动update函数 return true; }
主角静态变动态(GIF的实现和应用)
-
前提:找一组GIF动画用PS打开把每个图层都导出为png图片并给予编号,如下。
-
在项目的资源文件夹(Resources)下新建一个zhujue名称的文件夹以存放动作图片,如下。
-
两种实现方法,均在场景.cpp文件的init函数实现即可,如下。
//第一种是使用Animation类创建一个动画效果 //使用Animation类创建一个动画效果,每一个动作就是一个Asnimate对象,借用精灵实现 //注意:首先应在场景.h头文件定义一个Sprite* mysprite;以便让精灵实现动作 bool guanScene::init() { //... mysprite = Sprite::create("zhujue/bashen1.png"); //创建精灵 mysprite->setPosition(Point(getSize.width/2, getSize.height / 2)); this->addChild(mysprite, 1); //加入层显示,设置为1保证提前绘画 auto myAnimation = Animation::create(); //创建序列帧动画 for (int a = 1; a < 8; a++) { char nameSize[66] = { 0 }; //设置主角名称数组的长度 sprintf(nameSize, "zhujue/bashen%d.png", a); //利用for循环进行遍历 myAnimation->addSpriteFrameWithFile(nameSize); //加入到序列帧动画中 } myAnimation->setDelayPerUnit(0.05f); //设置两帧动画之间的间隔时间 myAnimation->setLoops(-1); //设置循环次数,-1为无限循环 myAnimation->setRestoreOriginalFrame(true); //设置在动画播放结束恢复到第一帧图片 auto myAnimate = Animate::create(myAnimation); //创建动画播放的对象Animate mysprite->runAction(myAnimate); //执行Animate对象 //第二种是coco2dx提供的图片帧的实现方式,第一种比较方便,第二种留下备忘 //... return true; }
-
让主角跳起来,应重写回调函数starMenuCallback(Ref* p),如下。
void guanScene::starMenuCallback(Ref* p) { //创建跳跃动作 auto jump = JumpBy::create(0.5f, Point(0, 0), 40, 1); //执行动作 this->mysprite->runAction(jump); }
-
效果如下,当然背景换了个金币图片,在创建金币的第三条代码里有写入,同时也换了张背景。
-
完成。
吃金币,碰撞检测的实现
-
既然使用了GIF动画实现主角效果了,那么就可以完全删除Player.h和Player.cpp文件了,把主角的相关操作都放在金币文件zhufood.h进行管理,如下。
//zhufood.h #ifndef _ZHUFOOD_H_ #define _ZHUFOOD_H_ #include "food.h" //提供精灵绑定与获取 class zhufood :public food { public: //... //新增碰撞检测函数,因为GIF主角是Sprite实现的所以提供Sprite*对象 bool pengzhuang(Sprite* player); //碰撞检测 void eat(Sprite* player); //碰撞功能实现 private: bool myAlive; //标记金币活动状态 }; #endif //zhufood.cpp #include "zhufood.h" //... zhufood::zhufood() { myAlive = false; myHp = 100; //将主角初始血量设为100; } //... bool zhufood::pengzhuang(Sprite* player) //碰撞检测 { //获取碰撞检查的对象,Node对象或继承了Node的类都拥有一个getBoundingBox()函数, //getBoundingBox()会返回一个矩形,这个矩形就是Node对象的图片外围矩形 Rect nowPlayer = player->getBoundingBox(); Point getPos = getPosition(); //判断BoundingBox和金币中心点是否相交 return nowPlayer.containsPoint(getPos); } void zhufood::eat(Sprite* player) { if (getSprite() == NULL) //判断精灵是否存在 { return; } myHp -= 10; if (myHp < 0) { myHp == 0; } } //zhufoodManager.cpp 在update函数定义中实现金币消失的功能及主角受伤 #include "zhufoodManager.h" #include "zhufood.h" //... void zhufoodManager::update(float a) { //... //如果金币X坐标小于0则隐藏金币 if (zhufood->getPositionX() < 0) zhufood->hide(); else if (zhufood->pengzhuang(myPlayer)) { zhufood->eat(myPlayer); //主角受伤 zhufood->hide(); //金币隐藏 } } } //... //最终在场景.cpp文件中进行碰撞(主角和金币接触,金币消失)的实现 bool guanScene::init() { //... //创建金币管理器 zhufoodManager* manager = zhufoodManager::create(); this->addChild(manager,4); manager->bangPlayer(mysprite); //... return true; }
-
碰撞检测完成。
游戏进度条功能及标签功能
-
首先在场景.h文件中顶下如下。
class guanScene :public Scene { //... public: void createJindu(); //创建进度条 private: //创建进度条 ProgressTimer* progressTimer; //声明进度条指针 LabelTTF* labelTTF; //声明标签指针 };
-
在场景.cpp文件中进行定义,如下。
void guanScene::createJindu() { //创建一个进程条和进度条边框 Vec2 vec2 = Director::getInstance()->getVisibleOrigin(); //Vec2(原名Point)可二维坐标可维度 Size getSize = Director::getInstance()->getVisibleSize(); //创建一个进度条精灵边框 auto progressbgSp = Sprite::create("bgjindu.png"); progressbgSp->setScale(0.8f); //缩小到0.8倍大小 progressbgSp->setPosition(Vec2(vec2.x + getSize.width / 4, vec2.y + getSize.height / 4)); this->addChild(progressbgSp, 3); //创建一个进度条精灵 auto progressSp = Sprite::create("jindu.png"); progressSp->setScale(0.8f); //缩小到0.8倍大小 progressTimer = ProgressTimer::create(progressSp); progressTimer->setType(kCCProgressTimerTypeBar); progressTimer->setPosition(Vec2(vec2.x + getSize.width / 4, vec2.y + getSize.height / 4)); //进度动画方向 progressTimer->setMidpoint(Vec2(0, 0)); //进度条宽高变化 progressTimer->setBarChangeRate(Vec2(1, 0)); progressTimer->setPercentage(0); //设置进度为0% this->addChild(progressTimer, 3); //创建标签 labelTTF = CCLabelTTF::create("0", "Thonburi", 20); labelTTF->setPosition(vec2.x + getSize.width / 4, vec2.y + getSize.height / 4); this->addChild(labelTTF, 3); }
-
实现角色上下左右移动功能,如下。
//首先在场景.h文件里进行声明 class guanScene :public Scene { public: //... void onClickUp(Ref*, TouchEventType type); //单击监听事件 void onClickDown(Ref*, TouchEventType type); //单击监听事件 void onClickLeft(Ref*, TouchEventType type); //单击监听事件 void onClickRight(Ref*, TouchEventType type); //单击监听事件 }; //再在场景.cpp文件中进行定义 void guanScene::onClickUp(Ref*, TouchEventType type) //单击监听事件 { Point pos = mysprite->getPosition(); switch (type) { case ui::TouchEventType::TOUCH_EVENT_BEGAN: //单击事件开始时触发(按下的时候) break; case TouchEventType::TOUCH_EVENT_MOVED: //按下之后进行移动操作时触发 mysprite->setPosition(Point(pos.x, pos.y + 1)); break; case ui::TouchEventType::TOUCH_EVENT_ENDED: //按下之后然后松开之后触发 //mysprite->setPosition(Point(pos.x,pos.y+5)); break; } } void guanScene::onClickDown(Ref*, TouchEventType type) //单击监听事件 { Point pos = mysprite->getPosition(); switch (type) { case TouchEventType::TOUCH_EVENT_MOVED: //按下之后进行移动操作时触发 mysprite->setPosition(Point(pos.x, pos.y - 1)); break; } } void guanScene::onClickLeft(Ref*, TouchEventType type) //单击监听事件 { Point pos = mysprite->getPosition(); switch (type) { case TouchEventType::TOUCH_EVENT_MOVED: //按下之后进行移动操作时触发 mysprite->setPosition(Point(pos.x-1, pos.y)); break; } } void guanScene::onClickRight(Ref*, TouchEventType type) //单击监听事件 { Point pos = mysprite->getPosition(); switch (type) { case TouchEventType::TOUCH_EVENT_MOVED: //按下之后进行移动操作时触发 mysprite->setPosition(Point(pos.x+1, pos.y)); break; } } //创建按钮显示出来在场景.cpp文件的init函数中实现 bool guanScene::init() { //... //上下左右四个按钮 Button* a = Button::create(); a->setTitleText("Up"); a->setPosition(Point(50, 180)); a->addTouchEventListener(this,toucheventselector(guanScene::onClickUp)); this->addChild(a,2); Button* b = Button::create(); b->setTitleText("Down"); b->setPosition(Point(50, 160)); b->addTouchEventListener(this, toucheventselector(guanScene::onClickDown)); this->addChild(b, 2); Button* c = Button::create(); c->setTitleText("Left"); c->setPosition(Point(30, 170)); c->addTouchEventListener(this, toucheventselector(guanScene::onClickLeft)); this->addChild(c, 2); Button* d = Button::create(); d->setTitleText("Right"); d->setPosition(Point(70, 170)); d->addTouchEventListener(this, toucheventselector(guanScene::onClickRight)); this->addChild(d, 2); //... }
-
效果截图
-
完成。
全代码汇总
-
就先这样存起来吧。
-
项目工程总览。
-
guanScene.h
#ifndef _GUANSCENE_H_ #define _GUANSCENE_H_ #include "cocos2d.h" #include "food.h" #include "ui/CocosGUI.h" USING_NS_CC; using namespace cocos2d::ui; class zhufoodManager; class guanScene :public Scene { //继承Layer层 场景➡层 public: static cocos2d::Scene* createScene(); virtual bool init(); CREATE_FUNC(guanScene); //创建场景回调 void createJindu(); //创建进度条 void onClickUp(Ref*, TouchEventType type); //单击监听事件 void onClickDown(Ref*, TouchEventType type); //单击监听事件 void onClickLeft(Ref*, TouchEventType type); //单击监听事件 void onClickRight(Ref*, TouchEventType type); //单击监听事件 private: void initBG(); //初始化关卡背景 Sprite* mybgSprite1; //背景精灵1 Sprite* mybgSprite2; //背景精灵2 //Player* myPlayer; //主角 virtual void update(float u); //定义一个update函数来实现重写 /* 1. LabelTTF适合于一次性创建文本后不再改变显示信息的情况。 2. CCLabelBMFont适合于需要频繁更新的文本内容的情况。 3. CCLabelAtlas适合于显示数字信息,如计分板,排行榜。 */ Sprite* mysprite; void createJump(); //跳跃按钮函数 void createdirection(); //方向函数 void benpaoAciton(); //主角奔跑GIF实现 void starMenuCallback(cocos2d::Ref* p); //按钮回调 private: //创建进度条 ProgressTimer* progressTimer; //声明进度条指针 LabelTTF* labelTTF; //声明标签指针 }; #endif
-
guanScene.cpp
#include "guanScene.h" #include "zhufoodManager.h" using namespace cocos2d; Scene* guanScene::createScene() { return guanScene::create(); } void guanScene::initBG() { Size getSize = Director::getInstance()->getVisibleSize(); mybgSprite1 = Sprite::create("bg.png"); mybgSprite1->setPosition(getSize.width / 2, getSize.height / 2); this->addChild(mybgSprite1, 0); //第二个参数表示绘制层次,数值越大对象层次越高(越迟被绘制) mybgSprite2 = Sprite::create("bg.png"); mybgSprite2->setPosition(getSize.width +getSize.width+260, getSize.height / 2); mybgSprite2->setFlippedX(true); //水平翻转精灵 this->addChild(mybgSprite2, 0); } void guanScene::update(float u) { int PosX1 = mybgSprite1->getPositionX(); //获取背景1的X坐标 int PosX2 = mybgSprite2->getPositionX(); //获取背景2的X坐标 int bgspeed = 1; //背景滚动速度 //两张图片向左滚动,X坐标每次都减1 PosX1 -= bgspeed; PosX2 -= bgspeed; //获取背景图片的大小 Size bgSize = mybgSprite1->getContentSize(); //当第一个地图完全离开屏幕时,第二个地图刚好出现在屏幕上,让他们紧贴在一起 if (PosX1 <= -bgSize.width / 2) //coco2dx对象描点是图片中间 { PosX1 = bgSize.width + bgSize.width / 2; } //当第二个地图完全离开屏幕时,第一个地图刚好出现在屏幕上,让他们紧贴在一起 if (PosX2 <= -bgSize.width / 2) { PosX2 = bgSize.width + bgSize.width / 2; } mybgSprite1->setPositionX(PosX1); mybgSprite2->setPositionX(PosX2); //进度条 float c = progressTimer->getPercentage(); //获取当前百分比 c+=0.01f; //给进度条进度每次加0.1% progressTimer->setPercentage(c); if (c <= 100) //如果进度小于等于100% { auto str1 = String::createWithFormat("%.2f%%", c); labelTTF->setString(str1->getCString()); //设置标签显示内容 } } void guanScene::createJump() { Size getSize = Director::getInstance()->getVisibleSize(); //使用类 MenuItemImage 来创建一个菜单项,第一个参数是按钮没有被单击图片,第二个参数是按钮被单击图片 //第三个参数是为按钮的点击事件指定了一个回调函数 MenuItemImage* starMenuItem = MenuItemImage::create("CloseNormal.png","CloseSelected.png", this, menu_selector(guanScene::starMenuCallback)); //创建一个Menu来包含这个按钮 Menu* newMenu = Menu::create(starMenuItem, NULL); newMenu->setPosition(Point(getSize.width-60,getSize.height-230)); this->addChild(newMenu, 1); } void guanScene::benpaoAciton() //主角奔跑GIF实现 { auto myAnimation = Animation::create(); //创建序列帧动画 for (int a = 1; a < 7; a++) { char nameSize[66] = { 0 }; //设置主角名称数组的长度 sprintf(nameSize, "zhujue/bashen%d.png", a); //利用for循环进行遍历 myAnimation->addSpriteFrameWithFile(nameSize); //加入到序列帧动画中 } myAnimation->setDelayPerUnit(0.05f); //设置两帧动画之间的间隔时间 myAnimation->setLoops(-1); //设置循环次数,-1为无限循环 myAnimation->setRestoreOriginalFrame(true); //设置在动画播放结束恢复到第一帧图片 auto myAnimate = Animate::create(myAnimation); //创建动画播放的对象Animate mysprite->runAction(myAnimate); //执行Animate对象 } bool guanScene::init() { if (!Scene::init()) { return false; } Size getSize = Director::getInstance()->getVisibleSize(); //label auto gametitle = Label::createWithSystemFont("Naruto Ultimate Storm", "Arial", 20); gametitle->setPosition(getSize.width/2, getSize.height-20); gametitle->setColor(Color3B(255,0,0)); this->addChild(gametitle, 3); //创建主角 /* myPlayer = Player::create(); myPlayer->bangSprite(Sprite::create("zhujue.png")); myPlayer->setPosition(Point(100, getSize.height / 2)); this->addChild(myPlayer, 3); */ //使用Animation类创建一个动画效果,每一个动作就是一个Animate对象,借用精灵实现 mysprite = Sprite::create("zhujue/bashen1.png"); //创建精灵 mysprite->setPosition(Point(getSize.width/2, getSize.height / 2));//Vec2(Point)可以是一个二维坐标点,也可以是一个二维向量。 this->addChild(mysprite, 1); //加入层显示,设置为1保证提前绘画 benpaoAciton(); //奔跑动作 createJump(); //调用跳跃动作函数 createJindu(); //创建进度条 //上下左右四个按钮 Button* a = Button::create(); a->setTitleText("Up"); a->setPosition(Point(50, 180)); a->addTouchEventListener(this,toucheventselector(guanScene::onClickUp)); this->addChild(a,2); Button* b = Button::create(); b->setTitleText("Down"); b->setPosition(Point(50, 160)); b->addTouchEventListener(this, toucheventselector(guanScene::onClickDown)); this->addChild(b, 2); Button* c = Button::create(); c->setTitleText("Left"); c->setPosition(Point(30, 170)); c->addTouchEventListener(this, toucheventselector(guanScene::onClickLeft)); this->addChild(c, 2); Button* d = Button::create(); d->setTitleText("Right"); d->setPosition(Point(70, 170)); d->addTouchEventListener(this, toucheventselector(guanScene::onClickRight)); this->addChild(d, 2); //创建金币管理器 zhufoodManager* manager = zhufoodManager::create(); this->addChild(manager,4); manager->bangPlayer(mysprite); //初始化背景图片 initBG(); this->scheduleUpdate(); //启动update函数 return true; } void guanScene::starMenuCallback(Ref* p) { //创建跳跃动作 auto jump = JumpBy::create(0.5f, Point(0, 0),50, 1); //执行动作 this->mysprite->runAction(jump); } void guanScene::createJindu() { //创建一个进程条和进度条边框 Vec2 vec2 = Director::getInstance()->getVisibleOrigin(); //Vec2(原名Point)可二维坐标可维度 Size getSize = Director::getInstance()->getVisibleSize(); //创建一个进度条精灵边框 auto progressbgSp = Sprite::create("bgjindu.png"); progressbgSp->setScale(0.8f); //缩小到0.8倍大小 progressbgSp->setPosition(Vec2(vec2.x + getSize.width / 4, vec2.y + getSize.height / 4)); this->addChild(progressbgSp, 3); //创建一个进度条精灵 auto progressSp = Sprite::create("jindu.png"); progressSp->setScale(0.8f); //缩小到0.8倍大小 progressTimer = ProgressTimer::create(progressSp); progressTimer->setType(kCCProgressTimerTypeBar); progressTimer->setPosition(Vec2(vec2.x + getSize.width / 4, vec2.y + getSize.height / 4)); //进度动画方向 progressTimer->setMidpoint(Vec2(0, 0)); //进度条宽高变化 progressTimer->setBarChangeRate(Vec2(1, 0)); progressTimer->setPercentage(0); //设置进度为0% this->addChild(progressTimer, 3); //创建标签 labelTTF = CCLabelTTF::create("0", "Thonburi", 20); labelTTF->setPosition(vec2.x + getSize.width / 4, vec2.y + getSize.height / 4); this->addChild(labelTTF, 3); } void guanScene::onClickUp(Ref*, TouchEventType type) //单击监听事件 { Point pos = mysprite->getPosition(); switch (type) { case ui::TouchEventType::TOUCH_EVENT_BEGAN: //单击事件开始时触发(按下的时候) break; case TouchEventType::TOUCH_EVENT_MOVED: //按下之后进行移动操作时触发 mysprite->setPosition(Point(pos.x, pos.y + 1)); break; case ui::TouchEventType::TOUCH_EVENT_ENDED: //按下之后然后松开之后触发 //mysprite->setPosition(Point(pos.x,pos.y+5)); break; } } void guanScene::onClickDown(Ref*, TouchEventType type) //单击监听事件 { Point pos = mysprite->getPosition(); switch (type) { case TouchEventType::TOUCH_EVENT_MOVED: //按下之后进行移动操作时触发 mysprite->setPosition(Point(pos.x, pos.y - 1)); break; } } void guanScene::onClickLeft(Ref*, TouchEventType type) //单击监听事件 { Point pos = mysprite->getPosition(); switch (type) { case TouchEventType::TOUCH_EVENT_MOVED: //按下之后进行移动操作时触发 mysprite->setPosition(Point(pos.x-1, pos.y)); break; } } void guanScene::onClickRight(Ref*, TouchEventType type) //单击监听事件 { Point pos = mysprite->getPosition(); switch (type) { case TouchEventType::TOUCH_EVENT_MOVED: //按下之后进行移动操作时触发 mysprite->setPosition(Point(pos.x+1, pos.y)); break; } }
-
food.h
#ifndef _FOOD_H_ #define _FOOD_H_ #include "cocos2d.h" USING_NS_CC; class food :public Node { public: food(); ~food(); Sprite* getSprite(); //获取精灵 void bangSprite(Sprite* a); //绑定精灵 private: Sprite* mySprite; }; #endif
-
food.cpp
#include "food.h" food::food() { mySprite = NULL; } food::~food() { } Sprite* food::getSprite() { return this->mySprite; } void food::bangSprite(Sprite* a) { this->mySprite = a; this->addChild(mySprite); }
-
word.h
#ifndef __WORD_H__ #define __WORD_H__ #include "cocos2d.h" USING_NS_CC; class word :public CCNode { public: word(); ~word(); CREATE_FUNC(word); virtual bool init(); public: void showWord(const char* text, CCPoint pos); void flowEnd(); private: CCLabelTTF* mylabeltext; }; #endif
-
word.cpp
#include "word.h" word::word() {} word::~word() {} bool word::init() { mylabeltext = CCLabelTTF::create("", "Arial", 30); //使用系统字体 mylabeltext->setColor(ccc3(255,0,0)); //设置为红色 mylabeltext->setVisible(false); //初始化不显示 this->addChild(mylabeltext); return true; } void word::showWord(const char* str, CCPoint pos) { mylabeltext->setVisible(true); //设置可见 mylabeltext->setString(str); mylabeltext->setPosition(pos); //设置显示坐标 mylabeltext->setAnchorPoint(ccp(1,0)); //先放大后缩小 CCActionInterval* scaleLarge = CCScaleTo::create(0.3f, 2.5f, 2.5f); CCActionInterval* scaleSmall = CCScaleTo::create(0.4f, 0.5f, 0.5f); //回调动作,移除动画效果 CCCallFunc* callFunc = CCCallFunc::create(this, callfunc_selector(word::flowEnd)); //组合动作 CCActionInterval* actions = CCSequence::create(scaleLarge, scaleSmall, callFunc, NULL); mylabeltext->runAction(actions); } void word::flowEnd() { mylabeltext->setVisible(false); //true:移除节点的动作和回调函数 mylabeltext->removeFromParentAndCleanup(true); }
-
zhufood.h
#ifndef _ZHUFOOD_H_ #define _ZHUFOOD_H_ #include "food.h" //提供精灵绑定与获取 #include "word.h" #include "guanScene.h" class zhufood :public food { public: zhufood(); ~zhufood(); CREATE_FUNC(zhufood); virtual bool zhufoodinit(); void show(); void hide(); //隐藏 void reboot(); //重置 bool isAlive(); //判断是否为活动状态 bool pengzhuang(Sprite* player); //碰撞检测 void eat(Sprite* player); //碰撞功能实现 private: bool myAlive; //标记金币活动状态 }; #endif
-
zhufood.cpp
#include "zhufood.h" zhufood::zhufood() { myAlive = false; } zhufood::~zhufood(){} bool zhufood::zhufoodinit() { return true; } void zhufood::show() { if (getSprite()!= NULL) { setVisible(true); //设置为可见 myAlive = true; } } void zhufood::hide() { if (getSprite()!= NULL) { setVisible(false); //设置为不可见 reboot(); //重置 myAlive = false; } } void zhufood::reboot() { if (getSprite()!= NULL) { //初始化金币坐标, CCRANDOM_0_1随机数 setPosition(Point(800 + CCRANDOM_0_1() * 2000, 200 - CCRANDOM_0_1() * 100)); } } bool zhufood::isAlive() { return myAlive; } bool zhufood::pengzhuang(Sprite* player) //碰撞检测 { //获取碰撞检查的对象,Node对象或继承了Node的类都拥有一个getBoundingBox()函数, //getBoundingBox()会返回一个矩形,这个矩形就是Node对象的图片外围矩形 Rect nowPlayer = player->getBoundingBox(); Point getPos = getPosition(); //判断BoundingBox和金币中心点是否相交 return nowPlayer.containsPoint(getPos); } void zhufood::eat(Sprite* player) { if (getSprite() == NULL) //判断精灵是否存在 { return; } //添加不要命显示功能 word* myword = word::create(); player->addChild(myword); myword->showWord("+100", player->getPosition()/2); //输出显示+100 //创建多种动作 auto back = MoveBy::create(0.1f, Point(-15, 0)); auto forward = MoveBy::create(0.1f, Point(15, 0)); auto backRotate = RotateBy::create(0.1f, -15, 0); auto forwardRotate = RotateBy::create(0.1f, 15, 0); //组合动作,实现后坐力效果 auto backend = Spawn::create(back, backRotate, NULL); auto forwardend = Spawn::create(forward, forwardRotate, NULL); auto actionend = Sequence::create(backend, forwardend, NULL); //先停止所有的动作及其更新函数 player->pauseSchedulerAndActions(); //执行动作 player->runAction(actionend); //动作恢复,恢复所有动作及其更新函数 player->resumeSchedulerAndActions(); }
-
zhufoodManager.h
#ifndef _ZHUFOODMANAGER_H_ #define _ZHUFOODMANAGER_H_ #include "cocos2d.h" #include "zhufood.h" USING_NS_CC; #define MAX_ZHUFOOD 10 //最大数量 class zhufoodManager :public Node { public: CREATE_FUNC(zhufoodManager); virtual bool init(); virtual void update(float a); //重写update函数 void bangPlayer(Sprite* player); //绑定玩家对象 Sprite* myPlayer; //玩家对象 private: void createZhuFood(); //创建金币对象zhufood Vector<zhufood*> myzhufoodlist; //存放zhufood对象的列表 }; #endif
-
zhufoodManager.cpp
#include "zhufoodManager.h" #include "zhufood.h" bool zhufoodManager::init() { createZhuFood(); //创建对象 this->scheduleUpdate(); //开启update函数的调用 return true; } void zhufoodManager::createZhuFood() { zhufood* zhu = NULL; Sprite* sprite = NULL; for (int i = 0; i < MAX_ZHUFOOD; i++) { //创建金币对象zhufood zhu = zhufood::create(); zhu->bangSprite(Sprite::create("100yuan.jpg")); //绑定对象,在food.h中声明了 zhu->setScale(0.25f); //缩小到0.25倍大小 zhu->reboot(); //添加金币对象 this->addChild(zhu); //保存金币对象到列表中 myzhufoodlist.pushBack(zhu); } } void zhufoodManager::update(float a) { for (auto zhufood : myzhufoodlist) //从存放zhufood对象的列表里取出对象 { //如果金币处于活动状态 if (zhufood->isAlive()) { zhufood->setPositionX(zhufood->getPositionX() - 4); //如果金币X坐标小于0,则超出了屏幕范围,则隐藏起来 if (zhufood->getPositionX() < 0) zhufood->hide(); } else { //金币处于非活动状态则让金币出场 zhufood->show(); } //如果金币X坐标小于0则隐藏金币 if (zhufood->getPositionX() < 0) zhufood->hide(); else if (zhufood->pengzhuang(myPlayer)) { zhufood->eat(myPlayer); //碰撞实现的效果 zhufood->hide(); //金币隐藏 } } } void zhufoodManager::bangPlayer(Sprite* player) { myPlayer = player; }
-
结束。
-
记录下功能实现的点点滴滴。
End
总结:多看文档多查资源,一种功能的实现不只一种方法。
~