最终效果图:
环境版本:cocos2d-x-3.3beta0 使用内置的物理引擎
游戏主场景
- //
- // HeroScene.h
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- //
- #ifndef __HeroScene_SCENE_H__
- #define __HeroScene_SCENE_H__
-
- #include "cocos2d.h"
- #include "GameCtrl.h"
- // 继承自 有颜色的Layer
- class HeroScene : public cocos2d::LayerColor
- {
- private:
- // 屏幕尺寸
- Size winSize;
- // 数组 不同的层 对应不同的控制器
- cocos2d::Vector<GameCtrl*> gameCtrlArr;
-
- public:
- // 宏定义的Create方法,内部会调用init方法
- CREATE_FUNC(HeroScene);
- // 供外界调用的 实例化场景的方法
- static cocos2d::Scene* createScene();
- // 初始化方法
- virtual bool init();
- // 时钟方法
- // 在场景的时钟方法中,更新\控制 每一个游戏控制器的时钟方法
- virtual void update(float dt);
- };
-
- #endif // __HeroScene_SCENE_H__
- //
- // HeroScene.h
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- //
- #include "HeroScene.h"
- #include "GameOverScene.h"
-
- USING_NS_CC;
- #pragma mark - 生命周期方法
- Scene* HeroScene::createScene()
- {
- // 使用cocos2d 内置的物理引擎
- auto scene = Scene::createWithPhysics();
- // 显示 调试用的 刚体 边线
- // scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
- // 调整重力加速度
- scene->getPhysicsWorld()->setGravity(Vec2(0,-1000));
- // 标准代码 通过静态的create方法创建Layer,添加到场景,并返回场景
- auto layer = HeroScene::create();
- scene->addChild(layer);
- return scene;
- }
- // 实例化特有的对象
- bool HeroScene::init()
- {
- // 创建一个白色的Layer
- if ( !LayerColor::initWithColor(Color4B(255,255,255)) ) return false;
- // 屏幕尺寸
- winSize = Director::getInstance()->getVisibleSize();
- log("winSize:%f,%f",winSize.width,winSize.height);
-
- // 创建2个 GameCtrl (2层)
- gameCtrlArr.insert(0,GameCtrl::create(this,30));
- if(rand()%2 == 0){
- gameCtrlArr.insert(0,250));
- }
-
- // 开启消息调度
- scheduleUpdate();
- // ********************************************
- // 物理碰撞检测 「PhysicsContact」
- auto listener = EventListenerPhysicsContact::create();
- // 开始碰撞 游戏结束
- listener->onContactBegin = [this](PhysicsContact & contact){
- // 取消 消息调度
- this->unscheduleUpdate();
- // 切换至Game Over场景
- Director::getInstance()->replaceScene(GameOverScene::createScene());
- return true;
- };
- // 向事件分发器,注册listener
- Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraPHPriority(listener,this);
- // ********************************************
- // 用户单点触摸 jump high 【TouchOneByOne】
- auto touchListener = EventListenerTouchOneByOne::create();
- // 开始触摸 原地 跳一下
- touchListener->onTouchBegan = [this](Touch * t,Event * e){
- // 每一个游戏控制器 都执行一下 方法
- for (auto it = gameCtrlArr.begin(); it!=gameCtrlArr.end(); it++)
- {
- // 解引用 就可以获得数组成员对象了
- // 如果 是点在自己的那一层 才执行 跳高动作
- if ((*it)->hitTestPoint(t->getLocation()))
- {
- (*it)->onUserTouch();
- break;
- }
- }
- return false;
- };
- // 向事件分发器,注册listener
- Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraPHPriority(touchListener,this);
- return true;
- }
-
- #pragma mark - 时钟方法
- void HeroScene::update(float dt)
- {
- // 在场景的时钟方法中,更新\控制 每一个游戏控制器的时钟方法
- for (auto it = gameCtrlArr.begin(); it!=gameCtrlArr.end(); it++)
- {
- // 解引用 就可以获得数组成员对象了
- // 每一个游戏控制器 开启时钟方法
- (*it)->startUpdate(dt);
- }
-
- }
-
游戏结束时的场景
- //
- // GameOverScene.h
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- //
-
- #include <cocos2d.h>
- #include "MainScene.h"
- using namespace cocos2d;
- // 继承自 有颜色的Layer
- class GameOverScene:public LayerColor {
-
- private:
- Size winSize;
-
- public:
- // 供外界调用
- static Scene* createScene()
- {
- auto s = Scene::create();
- auto l = GameOverScene::create();
- s->addChild(l);
- return s;
- };
-
- // 宏定义的Create方法,内部会调用init方法
- CREATE_FUNC(GameOverScene);
-
- // 初始化,自己用
- virtual bool init()
- {
- // 父类的init方法
- LayerColor::initWithColor(Color4B::WHITE);
- // 屏幕大小
- winSize = Director::getInstance()->getVisibleSize();
- // 创建一个Label
- auto label = Label::create();
- label->setString("Game Over");
- label->setSystemFontSize(40);
- label->setName("label");
- label->setColor(Color3B::BLACK);
- label->setPosition(winSize.width/2,winSize.height/2);
- // 添加到Layer
- addChild(label);
-
-
- // 添加一个事件,点击 Label,返回到主场景的事件
- // 2.触摸Label,开启 时钟updatePosition
- // 实例化一个触摸监听器 对象
- auto listener = EventListenerTouchOneByOne::create();
- // 当触摸开始时,绑定一个闭包函数;
- // 【】表示 要传入的外界对象,此处是this
- // ()表示参数
- listener->onTouchBegan = [this](Touch *t,Event *e){
- // 如果 点击 了label,才每隔一秒执行一次 更新位置方法
- Label *label =(Label *) e->getCurrentTarget()->getChildByName("label");
- if (label->getBoundingBox().containsPoint(t->getLocation())) {
- // 回到主场景
- // 创建场景,自动释放 it's an autorelease object
- auto scene = MainScene::createScene();
- // 替换场景
- Director::getInstance()->replaceScene(scene);
- }
- return false;
- };
- // 5、获取事件分发器,添加一个事件监听器,到this身上;即监听的是this对象【整个图层Layer】
- Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraPHPriority(listener,this);
- return true;
- };
-
-
- };
一个游戏控制器实例
对应一层子游戏
【
核心
】
- //
- // GameCtrl.h
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- //
-
- #ifndef ___1_cocos2d_x__GameCtrl__
- #define ___1_cocos2d_x__GameCtrl__
- #include <cocos2d.h>
- // 全屏的边框
- #include "Boundary.h"
-
- #include "Hero.h"
- #include "Block.h"
- USING_NS_CC;
- // 继承自 Ref,就自动拥有了 释放机制
- class GameCtrl:public Ref
- {
- private:
- // 屏幕尺寸
- Size winSize;
- // 边界 边框,用成员变量记住,是因为 碰撞检测要用到
- Boundary * boundary;
- Hero * hero;
-
- // 重要~~~Layer就相当于HeroScene场景,因为所有的子精灵 全添加到Layer中,所以需要传入Layer
- // 成员变量记住(其他方法中要用到)
- Layer * _layer;
- float _positionY;
-
- // 临时变量,用于累计 记录 流逝的时间
- int tempTimeDelta;
- // 总共的时间间隔 (即 时间delta累计到 该间隔时,创建并添加一个障碍物)
- int totalIntervalTime;
-
-
- private:
- // 每添加一个新的障碍物之后,需重置 用于累计 记录 流逝的时间 的变量
- void resetTempTimeDelta();
- // 每隔 随机的时间,创建并添加一个障碍物
- void addBlock();
-
- public:
- // 重要~~~这个Layer就相当于HeroScene场景,所以需要传入Layer
- // 参数 就是在屏幕的y值
- // 供外界
- static GameCtrl* create(Layer *layer,float positionY);
- // 自己初始化
- virtual bool init(Layer * layer,float positionY);
- // 供场景调用,让场景来 开启和关闭 游戏控制器 中的 时钟方法
- void startUpdate(float dt);
-
-
- // 当被用户触摸了 时侯调用,给英雄一个向上的速度
- void onUserTouch();
- bool hitTestPoint(Vec2 point);
-
-
-
- };
-
- #endif /* defined(___1_cocos2d_x__GameCtrl__) */
- //
- // GameCtrl.cpp
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- //
-
- #include "GameCtrl.h"
- // 重要~~~这个Layer就相当于HeroScene场景,所以需要传入Layer
- // 参数 就是在屏幕的y值
- // 供外界
- GameCtrl* GameCtrl::create(cocos2d::Layer *layer,float positionY)
- {
- auto gameCtrl = new GameCtrl();
- // 调用自己的init初始化,将参数 传递过去
- gameCtrl->init(layer,positionY);
- // 自动释放
- gameCtrl->autorelease();
- return gameCtrl;
- }
- // 自己初始化
- bool GameCtrl::init(cocos2d::Layer *layer,float positionY)
- {
- // 成员变量记住,其他方法中 要用到
- _layer = layer;
- _positionY = positionY;
- // 全屏
- winSize = Director::getInstance()->getVisibleSize();
- //**************************************
- // 1、添加游戏的边框、边界
- boundary = Boundary::create();
- // 居中 (注意 不同的控制器,可能在不同的层 其y值不同 高度也不同)
- boundary->setPosition(winSize.width/2,winSize.height/2+positionY);
-
- // 全屏
- boundary->setContentSize(winSize);
- // 添加到Layer
- layer->addChild(boundary);
- //**************************************
- // 2、添加地板 (不需要关联物理世界)
- auto ground = Sprite::create();
- ground->setColor(Color3B(0,0));
- ground->setTextureRect(Rect(0,3));
- // (注意 不同的控制器,可能在不同的层 其y值不同) 3 和1.5
- ground->setPosition(winSize.width/2,1.5+positionY);
- // 添加到Layer
- layer->addChild(ground);
- //**************************************
- // 3、添加Hero
- hero = Hero::create();
- // (注意 不同的控制器,可能在不同的层 其y值不同)
- hero->setPosition(50,hero->getContentSize().height/2+positionY);
- // 添加到Layer
- layer->addChild(hero);
-
- // 每添加一个新的障碍物之后,需重置 用于累计 记录 流逝的时间 的变量
- resetTempTimeDelta();
- return true;
- }
-
- #pragma mark - 供外界场景调用
- // 供场景调用,让场景来 开启和关闭 游戏控制器 中的 时钟方法
- void GameCtrl::startUpdate(float dt)
- {
- // 临时变量,用于累计 记录 流逝的时间
- tempTimeDelta++;
- // 总共的时间间隔 (即 时间delta累计到 该间隔时,创建并添加一个障碍物)
- if (tempTimeDelta >= totalIntervalTime)
- {
- // 每添加一个新的障碍物之后,需重置 用于累计 记录 流逝的时间 的变量
- resetTempTimeDelta();
- // 每隔 随机的时间,创建并添加一个障碍物
- addBlock();
- }
- }
- // 每添加一个新的障碍物之后,需重置 用于累计 记录 流逝的时间 的变量
- void GameCtrl::resetTempTimeDelta()
- {
- tempTimeDelta = 0;
- totalIntervalTime = (rand()%120) + 100;
- }
-
- // 创建 并 添加 障碍物 (在随机的 时间 间隔 之后 )
- void GameCtrl::addBlock()
- {
- auto b = Block::create();
- _layer->addChild(b);
- // 注意 障碍物的y值是 和当前游戏控制器 自己的y值 相同的
- // 即 block的半高 + 当前控制器自己的y
- b->setPositionY(b->getContentSize().height/2 + _positionY);
- }
-
-
- #pragma mark - 触摸事件
- // 当被用户触摸了 时侯调用,给英雄一个向上的速度
- void GameCtrl::onUserTouch()
- {
- hero->getPhysicsBody()->setVelocity(Vec2(0,400));
- }
-
- bool GameCtrl::hitTestPoint(cocos2d::Vec2 point)
- {
- return boundary->getBoundingBox().containsPoint(point);
- }
边框、边界
- //
- // Boundary.h
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- // 边框、边界,其大小和winSize一样
-
- #ifndef __Boundary__
- #define __Boundary__
-
-
-
- #include <cocos2d.h>
-
- USING_NS_CC;
-
- class Boundary:public Node {
- public:
- // 宏定义 一个静态的create方法,内部会调用init方法
- CREATE_FUNC(Boundary);
- // 初始化方法
- virtual bool init();
- };
-
- #endif /* defined(__Boundary__) */
- //
- // Boundary.h
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- // 边框、边界,其大小和winSize一样
-
- #include "Boundary.h"
-
-
- bool Boundary::init(){
- // 父类的init方法,内部 直接返回一个true
- Node::init();
-
- // 960 * 640
- Size winSize = Director::getInstance()->getVisibleSize();
- // 设置Node大小 全屏
- setContentSize(winSize);
-
- // 设置物理刚体body,大小和winSize一样
- setPhysicsBody(PhysicsBody::createEdgeBox(winSize));
-
- return true;
- }
Hero主角
- //
- // Hero.h
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- // 主角,继承自Sprite,奔跑的小人
-
- #ifndef ___1_cocos2d_x__Hero__
- #define ___1_cocos2d_x__Hero__
-
- #include <cocos2d.h>
-
- USING_NS_CC;
-
- class Hero:public Sprite {
-
- public:
- // 宏,静态的create方法,内部会调用init方法
- CREATE_FUNC(Hero);
- virtual bool init();
-
- };
-
-
- #endif /* defined(___1_cocos2d_x__Hero__) */
- //
- // Hero.cpp
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- // 主角,奔跑的小人
-
- #include "Hero.h"
-
- #include "FlashTool.h"
-
-
- bool Hero::init()
- {
- // 父类的init方法
- Sprite::init();
- // 执行 帧动画 一直奔跑 RepeatForever
- runAction(RepeatForever::create(FlashTool::animateFromJsonFile("Hero.json",0.2f)));
-
- // Json中的尺寸
- Size s = Size(44,52);
- // 精灵的大小
- setContentSize(s);
-
- // 设置物理世界的刚体body
- setPhysicsBody(PhysicsBody::createBox(s));
- // 刚体不允许 旋转
- getPhysicsBody()->setRotationEnable(false);
- // 重要~~~若想参与 碰撞,必须绑定一个碰撞标识
- getPhysicsBody()->setContactTestBitmask(1);
-
- return true;
- }
障碍物
- //
- // Block.h
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- //
-
- #ifndef ___1_cocos2d_x__Block__
- #define ___1_cocos2d_x__Block__
-
- #include <cocos2d.h>
-
- USING_NS_CC;
-
- class Block:public Sprite {
- public:
- // 宏,内部会调用init方法
- CREATE_FUNC(Block);
- virtual bool init();
- // 时钟方法,内部会 让 障碍物不断地向左移动
- virtual void update(float dt);
-
- };
-
- #endif /* defined(___1_cocos2d_x__Block__) */
- //
- // Block.cpp
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- //
-
- #include "Block.h"
-
- bool Block::init()
- {
- // 父类的init方法
- Sprite::init();
- // 屏幕大小
- Size winSize = Director::getInstance()->getVisibleSize();
- // 放在屏幕的外边
- setPositionX(winSize.width);
- // 黑色 障碍物
- setColor(Color3B(0,0));
-
- Size size = Size((rand()%20)+5,(rand()%30)+10);
- // 随机生成 不同大小的 障碍物
- setContentSize(size);
- // 黑色的方块区域
- setTextureRect(Rect(0,size.width,size.height));
- // ***************************************
- // 设置 物理刚体
- setPhysicsBody(PhysicsBody::createBox(size));
- // 不是动态的刚体 即:是静态的刚体
- getPhysicsBody()->setDynamic(false);
- // 重要~~~若想参与 碰撞,必须绑定一个碰撞标识
- getPhysicsBody()->setContactTestBitmask(1);
- // ***************************************
- // 开启时钟方法
- scheduleUpdate();
- return true;
- }
- #pragma mark - 时钟方法
- // 时钟方法,内部会 让 障碍物不断地向左移动
- void Block::update(float dt){
-
- this->setPositionX(getPositionX()-8);
- // 移动到屏幕外边时,就停止消息调度,并且移除
- if (getPositionX()<0)
- {
- unscheduleUpdate();
- removeFromParent();
- }
-
- }
- //
- // FlashTool.h
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- //
-
- #ifndef ___1_cocos2d_x__FlashTool__
- #define ___1_cocos2d_x__FlashTool__
-
- #include <cocos2d.h>
-
- USING_NS_CC;
-
- class FlashTool {
-
- public:
- // 通过解析flash cc 导出的Json文件+大图片,生成一个Animate对象,用于执行序列帧动画
- static Animate * animateFromJsonFile(std::string jsonFile,float delayPerUnit);
- };
-
- #endif /* defined(___1_cocos2d_x__FlashTool__) */
- //
- // FlashTool.cpp
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- //
-
- #include "FlashTool.h"
- // Json解析 使用cocos2d 内置的rapidJson库
- #include <json/document.h>
-
- // 通过解析flash cc 导出的Json文件+大图片,用于执行序列帧动画
- Animate * FlashTool::animateFromJsonFile(std::string jsonFile,float delayPerUnit)
- {
- // 文档 对象
- rapidjson::Document doc;
- // FileUtils工具类 读入json文件
- std::string fileContent = FileUtils::getInstance()->getStringFromFile(jsonFile);
- //
- fileContent.erase(0,fileContent.find_first_of('{'));
- // 标记默认为 0,开始解析
- doc.Parse<0>(fileContent.c_str());
- // 得到大图片的 图片名
- std::string imgFileName = doc["Meta"]["image"].GetString();
-
- auto &frames = doc["frames"];
- // 精灵帧缓存
- auto sfc = SpriteFrameCache::getInstance();
- // 容器用于 存放所有的 动画帧
- Vector<AnimationFrame*> animFrames;
- // 遍历,裁剪,创建,添加到容器
- for (auto m=frames.MemberonBegin(); m!=frames.MemberonEnd(); m++) {
- auto frameName = m->name.GetString();
- auto & frameProperties = m->value["frame"];
- auto & spriteSourceSize = m->value["spriteSourceSize"];
-
- auto sf = sfc->getSpriteFrameByName(frameName);
- if (!sf) {
- sf = SpriteFrame::create(imgFileName,Rect(frameProperties["x"].GetInt(),frameProperties["y"].GetInt(),frameProperties["w"].GetInt(),frameProperties["h"].GetInt()),m->value["rotated"].GetBool(),Vec2(spriteSourceSize["x"].GetInt(),spriteSourceSize["y"].GetInt()),Size(spriteSourceSize["w"].GetInt(),spriteSourceSize["h"].GetInt()));
- sfc->addSpriteFrame(sf,frameName);
- }
- animFrames.pushBack(AnimationFrame::create(sf,delayPerUnit,ValueMapNull));
- }
- // 生成用于Action的Animate
- Animation * animation = Animation::create(animFrames,delayPerUnit);
- return Animate::create(animation);
- }
- {"frames": {
-
- "hero0000":
- {
- "frame": {"x":0,"y":0,"w":44,"h":52},"rotated": false,"trimmed": false,"spriteSourceSize": {"x":0,"sourceSize": {"w":44,"h":52}
- },"hero0001":
- {
- "frame": {"x":44,"w":42,"trimmed": true,"spriteSourceSize": {"x":2,"hero0002":
- {
- "frame": {"x":86,"hero0003":
- {
- "frame": {"x":0,"y":52,"hero0004":
- {
- "frame": {"x":42,"h":52}
- }},"Meta": {
- "app": "Adobe Flash Professional","version": "13.1.0.226","image": "Hero.png","format": "RGBA8888","size": {"w":128,"h":128},"scale": "1"
- }
- }
- //
- // HeroScene.h
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- //
- #ifndef __HeroScene_SCENE_H__
- #define __HeroScene_SCENE_H__
- #include "cocos2d.h"
- #include "GameCtrl.h"
- // 继承自 有颜色的Layer
- class HeroScene : public cocos2d::LayerColor
- {
- private:
- // 屏幕尺寸
- Size winSize;
- // 数组 不同的层 对应不同的控制器
- cocos2d::Vector<GameCtrl*> gameCtrlArr;
- public:
- // 宏定义的Create方法,内部会调用init方法
- CREATE_FUNC(HeroScene);
- // 供外界调用的 实例化场景的方法
- static cocos2d::Scene* createScene();
- // 初始化方法
- virtual bool init();
- // 时钟方法
- // 在场景的时钟方法中,更新\控制 每一个游戏控制器的时钟方法
- virtual void update(float dt);
- };
- #endif // __HeroScene_SCENE_H__
- //
- // HeroScene.h
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- //
- #include "HeroScene.h"
- #include "GameOverScene.h"
- USING_NS_CC;
- #pragma mark - 生命周期方法
- Scene* HeroScene::createScene()
- {
- // 使用cocos2d 内置的物理引擎
- auto scene = Scene::createWithPhysics();
- // 显示 调试用的 刚体 边线
- // scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
- // 调整重力加速度
- scene->getPhysicsWorld()->setGravity(Vec2(0,-1000));
- // 标准代码 通过静态的create方法创建Layer,添加到场景,并返回场景
- auto layer = HeroScene::create();
- scene->addChild(layer);
- return scene;
- }
- // 实例化特有的对象
- bool HeroScene::init()
- {
- // 创建一个白色的Layer
- if ( !LayerColor::initWithColor(Color4B(255,255,255)) ) return false;
- // 屏幕尺寸
- winSize = Director::getInstance()->getVisibleSize();
- log("winSize:%f,%f",winSize.width,winSize.height);
- // 创建2个 GameCtrl (2层)
- gameCtrlArr.insert(0,GameCtrl::create(this,30));
- if(rand()%2 == 0){
- gameCtrlArr.insert(0,250));
- }
- // 开启消息调度
- scheduleUpdate();
- // ********************************************
- // 物理碰撞检测 「PhysicsContact」
- auto listener = EventListenerPhysicsContact::create();
- // 开始碰撞 游戏结束
- listener->onContactBegin = [this](PhysicsContact & contact){
- // 取消 消息调度
- this->unscheduleUpdate();
- // 切换至Game Over场景
- Director::getInstance()->replaceScene(GameOverScene::createScene());
- return true;
- };
- // 向事件分发器,注册listener
- Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraPHPriority(listener,this);
- // ********************************************
- // 用户单点触摸 jump high 【TouchOneByOne】
- auto touchListener = EventListenerTouchOneByOne::create();
- // 开始触摸 原地 跳一下
- touchListener->onTouchBegan = [this](Touch * t,Event * e){
- // 每一个游戏控制器 都执行一下 方法
- for (auto it = gameCtrlArr.begin(); it!=gameCtrlArr.end(); it++)
- {
- // 解引用 就可以获得数组成员对象了
- // 如果 是点在自己的那一层 才执行 跳高动作
- if ((*it)->hitTestPoint(t->getLocation()))
- {
- (*it)->onUserTouch();
- break;
- }
- }
- return false;
- };
- // 向事件分发器,注册listener
- Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraPHPriority(touchListener,this);
- return true;
- }
- #pragma mark - 时钟方法
- void HeroScene::update(float dt)
- {
- // 在场景的时钟方法中,更新\控制 每一个游戏控制器的时钟方法
- for (auto it = gameCtrlArr.begin(); it!=gameCtrlArr.end(); it++)
- {
- // 解引用 就可以获得数组成员对象了
- // 每一个游戏控制器 开启时钟方法
- (*it)->startUpdate(dt);
- }
- }
- //
- // GameOverScene.h
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- //
- #include <cocos2d.h>
- #include "MainScene.h"
- using namespace cocos2d;
- // 继承自 有颜色的Layer
- class GameOverScene:public LayerColor {
- private:
- Size winSize;
- public:
- // 供外界调用
- static Scene* createScene()
- {
- auto s = Scene::create();
- auto l = GameOverScene::create();
- s->addChild(l);
- return s;
- };
- // 宏定义的Create方法,内部会调用init方法
- CREATE_FUNC(GameOverScene);
- // 初始化,自己用
- virtual bool init()
- {
- // 父类的init方法
- LayerColor::initWithColor(Color4B::WHITE);
- // 屏幕大小
- winSize = Director::getInstance()->getVisibleSize();
- // 创建一个Label
- auto label = Label::create();
- label->setString("Game Over");
- label->setSystemFontSize(40);
- label->setName("label");
- label->setColor(Color3B::BLACK);
- label->setPosition(winSize.width/2,winSize.height/2);
- // 添加到Layer
- addChild(label);
- // 添加一个事件,点击 Label,返回到主场景的事件
- // 2.触摸Label,开启 时钟updatePosition
- // 实例化一个触摸监听器 对象
- auto listener = EventListenerTouchOneByOne::create();
- // 当触摸开始时,绑定一个闭包函数;
- // 【】表示 要传入的外界对象,此处是this
- // ()表示参数
- listener->onTouchBegan = [this](Touch *t,Event *e){
- // 如果 点击 了label,才每隔一秒执行一次 更新位置方法
- Label *label =(Label *) e->getCurrentTarget()->getChildByName("label");
- if (label->getBoundingBox().containsPoint(t->getLocation())) {
- // 回到主场景
- // 创建场景,自动释放 it's an autorelease object
- auto scene = MainScene::createScene();
- // 替换场景
- Director::getInstance()->replaceScene(scene);
- }
- return false;
- };
- // 5、获取事件分发器,添加一个事件监听器,到this身上;即监听的是this对象【整个图层Layer】
- Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraPHPriority(listener,this);
- return true;
- };
- };
- //
- // GameCtrl.h
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- //
- #ifndef ___1_cocos2d_x__GameCtrl__
- #define ___1_cocos2d_x__GameCtrl__
- #include <cocos2d.h>
- // 全屏的边框
- #include "Boundary.h"
- #include "Hero.h"
- #include "Block.h"
- USING_NS_CC;
- // 继承自 Ref,就自动拥有了 释放机制
- class GameCtrl:public Ref
- {
- private:
- // 屏幕尺寸
- Size winSize;
- // 边界 边框,用成员变量记住,是因为 碰撞检测要用到
- Boundary * boundary;
- Hero * hero;
- // 重要~~~Layer就相当于HeroScene场景,因为所有的子精灵 全添加到Layer中,所以需要传入Layer
- // 成员变量记住(其他方法中要用到)
- Layer * _layer;
- float _positionY;
- // 临时变量,用于累计 记录 流逝的时间
- int tempTimeDelta;
- // 总共的时间间隔 (即 时间delta累计到 该间隔时,创建并添加一个障碍物)
- int totalIntervalTime;
- private:
- // 每添加一个新的障碍物之后,需重置 用于累计 记录 流逝的时间 的变量
- void resetTempTimeDelta();
- // 每隔 随机的时间,创建并添加一个障碍物
- void addBlock();
- public:
- // 重要~~~这个Layer就相当于HeroScene场景,所以需要传入Layer
- // 参数 就是在屏幕的y值
- // 供外界
- static GameCtrl* create(Layer *layer,float positionY);
- // 自己初始化
- virtual bool init(Layer * layer,float positionY);
- // 供场景调用,让场景来 开启和关闭 游戏控制器 中的 时钟方法
- void startUpdate(float dt);
- // 当被用户触摸了 时侯调用,给英雄一个向上的速度
- void onUserTouch();
- bool hitTestPoint(Vec2 point);
- };
- #endif /* defined(___1_cocos2d_x__GameCtrl__) */
- //
- // GameCtrl.cpp
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- //
- #include "GameCtrl.h"
- // 重要~~~这个Layer就相当于HeroScene场景,所以需要传入Layer
- // 参数 就是在屏幕的y值
- // 供外界
- GameCtrl* GameCtrl::create(cocos2d::Layer *layer,float positionY)
- {
- auto gameCtrl = new GameCtrl();
- // 调用自己的init初始化,将参数 传递过去
- gameCtrl->init(layer,positionY);
- // 自动释放
- gameCtrl->autorelease();
- return gameCtrl;
- }
- // 自己初始化
- bool GameCtrl::init(cocos2d::Layer *layer,float positionY)
- {
- // 成员变量记住,其他方法中 要用到
- _layer = layer;
- _positionY = positionY;
- // 全屏
- winSize = Director::getInstance()->getVisibleSize();
- //**************************************
- // 1、添加游戏的边框、边界
- boundary = Boundary::create();
- // 居中 (注意 不同的控制器,可能在不同的层 其y值不同 高度也不同)
- boundary->setPosition(winSize.width/2,winSize.height/2+positionY);
- // 全屏
- boundary->setContentSize(winSize);
- // 添加到Layer
- layer->addChild(boundary);
- //**************************************
- // 2、添加地板 (不需要关联物理世界)
- auto ground = Sprite::create();
- ground->setColor(Color3B(0,0));
- ground->setTextureRect(Rect(0,3));
- // (注意 不同的控制器,可能在不同的层 其y值不同) 3 和1.5
- ground->setPosition(winSize.width/2,1.5+positionY);
- // 添加到Layer
- layer->addChild(ground);
- //**************************************
- // 3、添加Hero
- hero = Hero::create();
- // (注意 不同的控制器,可能在不同的层 其y值不同)
- hero->setPosition(50,hero->getContentSize().height/2+positionY);
- // 添加到Layer
- layer->addChild(hero);
- // 每添加一个新的障碍物之后,需重置 用于累计 记录 流逝的时间 的变量
- resetTempTimeDelta();
- return true;
- }
- #pragma mark - 供外界场景调用
- // 供场景调用,让场景来 开启和关闭 游戏控制器 中的 时钟方法
- void GameCtrl::startUpdate(float dt)
- {
- // 临时变量,用于累计 记录 流逝的时间
- tempTimeDelta++;
- // 总共的时间间隔 (即 时间delta累计到 该间隔时,创建并添加一个障碍物)
- if (tempTimeDelta >= totalIntervalTime)
- {
- // 每添加一个新的障碍物之后,需重置 用于累计 记录 流逝的时间 的变量
- resetTempTimeDelta();
- // 每隔 随机的时间,创建并添加一个障碍物
- addBlock();
- }
- }
- // 每添加一个新的障碍物之后,需重置 用于累计 记录 流逝的时间 的变量
- void GameCtrl::resetTempTimeDelta()
- {
- tempTimeDelta = 0;
- totalIntervalTime = (rand()%120) + 100;
- }
- // 创建 并 添加 障碍物 (在随机的 时间 间隔 之后 )
- void GameCtrl::addBlock()
- {
- auto b = Block::create();
- _layer->addChild(b);
- // 注意 障碍物的y值是 和当前游戏控制器 自己的y值 相同的
- // 即 block的半高 + 当前控制器自己的y
- b->setPositionY(b->getContentSize().height/2 + _positionY);
- }
- #pragma mark - 触摸事件
- // 当被用户触摸了 时侯调用,给英雄一个向上的速度
- void GameCtrl::onUserTouch()
- {
- hero->getPhysicsBody()->setVelocity(Vec2(0,400));
- }
- bool GameCtrl::hitTestPoint(cocos2d::Vec2 point)
- {
- return boundary->getBoundingBox().containsPoint(point);
- }
- //
- // Boundary.h
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- // 边框、边界,其大小和winSize一样
- #ifndef __Boundary__
- #define __Boundary__
- #include <cocos2d.h>
- USING_NS_CC;
- class Boundary:public Node {
- public:
- // 宏定义 一个静态的create方法,内部会调用init方法
- CREATE_FUNC(Boundary);
- // 初始化方法
- virtual bool init();
- };
- #endif /* defined(__Boundary__) */
- //
- // Boundary.h
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- // 边框、边界,其大小和winSize一样
- #include "Boundary.h"
- bool Boundary::init(){
- // 父类的init方法,内部 直接返回一个true
- Node::init();
- // 960 * 640
- Size winSize = Director::getInstance()->getVisibleSize();
- // 设置Node大小 全屏
- setContentSize(winSize);
- // 设置物理刚体body,大小和winSize一样
- setPhysicsBody(PhysicsBody::createEdgeBox(winSize));
- return true;
- }
- //
- // Hero.h
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- // 主角,继承自Sprite,奔跑的小人
- #ifndef ___1_cocos2d_x__Hero__
- #define ___1_cocos2d_x__Hero__
- #include <cocos2d.h>
- USING_NS_CC;
- class Hero:public Sprite {
- public:
- // 宏,静态的create方法,内部会调用init方法
- CREATE_FUNC(Hero);
- virtual bool init();
- };
- #endif /* defined(___1_cocos2d_x__Hero__) */
- //
- // Hero.cpp
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- // 主角,奔跑的小人
- #include "Hero.h"
- #include "FlashTool.h"
- bool Hero::init()
- {
- // 父类的init方法
- Sprite::init();
- // 执行 帧动画 一直奔跑 RepeatForever
- runAction(RepeatForever::create(FlashTool::animateFromJsonFile("Hero.json",0.2f)));
- // Json中的尺寸
- Size s = Size(44,52);
- // 精灵的大小
- setContentSize(s);
- // 设置物理世界的刚体body
- setPhysicsBody(PhysicsBody::createBox(s));
- // 刚体不允许 旋转
- getPhysicsBody()->setRotationEnable(false);
- // 重要~~~若想参与 碰撞,必须绑定一个碰撞标识
- getPhysicsBody()->setContactTestBitmask(1);
- return true;
- }
- //
- // Block.h
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- //
- #ifndef ___1_cocos2d_x__Block__
- #define ___1_cocos2d_x__Block__
- #include <cocos2d.h>
- USING_NS_CC;
- class Block:public Sprite {
- public:
- // 宏,内部会调用init方法
- CREATE_FUNC(Block);
- virtual bool init();
- // 时钟方法,内部会 让 障碍物不断地向左移动
- virtual void update(float dt);
- };
- #endif /* defined(___1_cocos2d_x__Block__) */
- //
- // Block.cpp
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- //
- #include "Block.h"
- bool Block::init()
- {
- // 父类的init方法
- Sprite::init();
- // 屏幕大小
- Size winSize = Director::getInstance()->getVisibleSize();
- // 放在屏幕的外边
- setPositionX(winSize.width);
- // 黑色 障碍物
- setColor(Color3B(0,0));
- Size size = Size((rand()%20)+5,(rand()%30)+10);
- // 随机生成 不同大小的 障碍物
- setContentSize(size);
- // 黑色的方块区域
- setTextureRect(Rect(0,size.width,size.height));
- // ***************************************
- // 设置 物理刚体
- setPhysicsBody(PhysicsBody::createBox(size));
- // 不是动态的刚体 即:是静态的刚体
- getPhysicsBody()->setDynamic(false);
- // 重要~~~若想参与 碰撞,必须绑定一个碰撞标识
- getPhysicsBody()->setContactTestBitmask(1);
- // ***************************************
- // 开启时钟方法
- scheduleUpdate();
- return true;
- }
- #pragma mark - 时钟方法
- // 时钟方法,内部会 让 障碍物不断地向左移动
- void Block::update(float dt){
- this->setPositionX(getPositionX()-8);
- // 移动到屏幕外边时,就停止消息调度,并且移除
- if (getPositionX()<0)
- {
- unscheduleUpdate();
- removeFromParent();
- }
- }
- //
- // FlashTool.h
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- //
- #ifndef ___1_cocos2d_x__FlashTool__
- #define ___1_cocos2d_x__FlashTool__
- #include <cocos2d.h>
- USING_NS_CC;
- class FlashTool {
- public:
- // 通过解析flash cc 导出的Json文件+大图片,生成一个Animate对象,用于执行序列帧动画
- static Animate * animateFromJsonFile(std::string jsonFile,float delayPerUnit);
- };
- #endif /* defined(___1_cocos2d_x__FlashTool__) */
- //
- // FlashTool.cpp
- // 01_cocos2d-x
- //
- // Created by beyond on 14-10-6.
- //
- //
- #include "FlashTool.h"
- // Json解析 使用cocos2d 内置的rapidJson库
- #include <json/document.h>
- // 通过解析flash cc 导出的Json文件+大图片,用于执行序列帧动画
- Animate * FlashTool::animateFromJsonFile(std::string jsonFile,float delayPerUnit)
- {
- // 文档 对象
- rapidjson::Document doc;
- // FileUtils工具类 读入json文件
- std::string fileContent = FileUtils::getInstance()->getStringFromFile(jsonFile);
- //
- fileContent.erase(0,fileContent.find_first_of('{'));
- // 标记默认为 0,开始解析
- doc.Parse<0>(fileContent.c_str());
- // 得到大图片的 图片名
- std::string imgFileName = doc["Meta"]["image"].GetString();
- auto &frames = doc["frames"];
- // 精灵帧缓存
- auto sfc = SpriteFrameCache::getInstance();
- // 容器用于 存放所有的 动画帧
- Vector<AnimationFrame*> animFrames;
- // 遍历,裁剪,创建,添加到容器
- for (auto m=frames.MemberonBegin(); m!=frames.MemberonEnd(); m++) {
- auto frameName = m->name.GetString();
- auto & frameProperties = m->value["frame"];
- auto & spriteSourceSize = m->value["spriteSourceSize"];
- auto sf = sfc->getSpriteFrameByName(frameName);
- if (!sf) {
- sf = SpriteFrame::create(imgFileName,Rect(frameProperties["x"].GetInt(),frameProperties["y"].GetInt(),frameProperties["w"].GetInt(),frameProperties["h"].GetInt()),m->value["rotated"].GetBool(),Vec2(spriteSourceSize["x"].GetInt(),spriteSourceSize["y"].GetInt()),Size(spriteSourceSize["w"].GetInt(),spriteSourceSize["h"].GetInt()));
- sfc->addSpriteFrame(sf,frameName);
- }
- animFrames.pushBack(AnimationFrame::create(sf,delayPerUnit,ValueMapNull));
- }
- // 生成用于Action的Animate
- Animation * animation = Animation::create(animFrames,delayPerUnit);
- return Animate::create(animation);
- }
- {"frames": {
- "hero0000":
- {
- "frame": {"x":0,"y":0,"w":44,"h":52},"rotated": false,"trimmed": false,"spriteSourceSize": {"x":0,"sourceSize": {"w":44,"h":52}
- },"hero0001":
- {
- "frame": {"x":44,"w":42,"trimmed": true,"spriteSourceSize": {"x":2,"hero0002":
- {
- "frame": {"x":86,"hero0003":
- {
- "frame": {"x":0,"y":52,"hero0004":
- {
- "frame": {"x":42,"h":52}
- }},"Meta": {
- "app": "Adobe Flash Professional","version": "13.1.0.226","image": "Hero.png","format": "RGBA8888","size": {"w":128,"h":128},"scale": "1"
- }
- }