首页 > 代码库 > cocos2d-x v3.2 FlappyBird 各个类对象具体代码分析(3)
cocos2d-x v3.2 FlappyBird 各个类对象具体代码分析(3)
今天介绍两个比较简单的类
GameBegin.h
LandLayer.h
需要注意的有两点,一个是草地的滚动,还有一个是物理模型,都在LandLayer.h中实现,分析都在代码注释中。
先上GameBegin场景的效果图
这张图可以解析为
背景图的添加
游戏名字
小鸟以及小鸟飞行动画
按钮
草地(草地是会滚动的)
//GameBegin.h #pragma once #include "cocos2d.h" class GameBegin:public cocos2d::Layer { public: GameBegin(); ~GameBegin(); static cocos2d::Scene * createScene(); bool init(); void landMove(float); void startGame(); CREATE_FUNC(GameBegin); private: cocos2d::Sprite * land1; cocos2d::Sprite * land2; };
//GameBegin.cpp #include "GameBegin.h" #include "define.h" #include "GameLayer.h" USING_NS_CC; GameBegin::GameBegin() { } GameBegin::~GameBegin() { } cocos2d::Scene * GameBegin::createScene() { auto scene=Scene::create(); auto gameLayer=GameBegin::create(); scene->addChild(gameLayer); return scene; } bool GameBegin::init() { if (!Layer::init()) { return false; } //获取 OpenGL 视图的初始化时的可见大小 auto origin=Director::getInstance()->getVisibleOrigin(); auto visibleSize=Director::getInstance()->getVisibleSize(); //背景图片,根据时间加载晚上和白天的图片,这个功能是来自原作者 time_t t=time(NULL); tm * lt=localtime(&t); int hour=lt->tm_hour; Sprite * bg; if (hour>=6&&hour<=17) { bg=Sprite::createWithSpriteFrameName("bg_day.png"); } else { bg=Sprite::createWithSpriteFrameName("bg_night.png"); } bg->setPosition(Point(origin.x+visibleSize.width/2,origin.y+visibleSize.height/2)); this->addChild(bg); //游戏草坪的移动,这边的草地移动是没有物理模型的 //所有的草地移动都在LandLayer类中介绍,这里不介绍了 //这个类和LandLayer类是没有任何联系的,这里的草地移动和那边的草地移动也是不一样的 //至于为什么不直接调用那个类,只能怪我刚开始写的时候没有策划好 //那个LandLayer类是后面补上去给,别的类使用的,所以这边没有改 land1=Sprite::createWithSpriteFrameName("land.png"); land1->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT); land1->setPosition(Point::ZERO); land1->getTexture()->setAliasTexParameters(); this->addChild(land1); land2=Sprite::createWithSpriteFrameName("land.png"); land2->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT); land2->setPosition(Point(origin.x+land1->getPositionX()+land1->getContentSize().width-2,origin.y)); land2->getTexture()->setAliasTexParameters(); this->addChild(land2); this->schedule(schedule_selector(GameBegin::landMove),LAND_VELOCITY); //游戏名字 auto title=Sprite::createWithSpriteFrameName("title.png"); title->setPosition(Point(origin.x+visibleSize.width/2,origin.y+visibleSize.height*0.8)); this->addChild(title); //小鸟 auto bird=Sprite::createWithSpriteFrameName("bird0_0.png"); bird->setPosition(Point(origin.x+visibleSize.width/2,origin.y+visibleSize.height*0.65));
<span style="white-space:pre"> </span>//小鸟的动画就是我们存在缓存中的,今天拿来用 bird->runAction(RepeatForever::create(Animate::create(AnimationCache::getInstance()->getAnimation(BIRDANIMATION_0)))); this->addChild(bird); //开始按钮 auto start_sprite=Sprite::createWithSpriteFrameName("button_play.png"); //按钮这里一共有2中状态,一是弹起状态 //二是按下状态,下面的第一个参数和第二个参数就表示这两中状态 //第三个参数就是按钮的回调函数 auto start_button=MenuItemSprite::create(start_sprite,start_sprite,CC_CALLBACK_0(GameBegin::startGame,this)); start_button->setPosition(Point(origin.x+visibleSize.width/2,origin.y+visibleSize.height*0.5)); //这个是按钮菜单 auto menu=Menu::create(start_button,NULL); menu->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT); menu->setPosition(Point::ZERO); this->addChild(menu); return true; } void GameBegin::landMove(float) { land1->setPositionX(land1->getPositionX()-2); land2->setPositionX(land1->getPositionX()+land1->getContentSize().width-2); if (land2->getPositionX()==0) { land1->setPositionX(0); } } //按钮回调 void GameBegin::startGame() { //场景切换 Director::getInstance()->replaceScene(TransitionFade::create(CHANGESCENE_TIME,GameLayer::createScene())); log("replaceScene"); }
//LandLayer.h #pragma once #include "cocos2d.h" class LandLayer:public cocos2d::Layer { public: LandLayer(); ~LandLayer(); bool init(); //草地移动 void landMove(float); //草地停止移动 void stopLand(); CREATE_FUNC(LandLayer); private: //草地精灵1 cocos2d::Sprite * land1; //草地精灵2 cocos2d::Sprite * land2; };
//LandLayer.cpp #include "LandLayer.h" #include "define.h" USING_NS_CC; LandLayer::LandLayer() { } LandLayer::~LandLayer() { } bool LandLayer::init() { if (!Layer::init()) { return false; } auto origin=Director::getInstance()->getVisibleOrigin(); auto visibleSize=Director::getInstance()->getVisibleSize(); //游戏草坪的移动 land1=Sprite::createWithSpriteFrameName("land.png"); land1->setPosition(Point(origin.x+land1->getContentSize().width/2,origin.y+land1->getContentSize().height/2)); //下面这个接口是防止两个精灵叠加时出现黑边 land1->getTexture()->setAliasTexParameters(); //下面是草地的物理模型 //因为猪脚在飞的过程中会撞到两种东西 //一是管子 //二就是草地 //所以我们要给草地添加物理模型,刚开始写的时候我是没有接触过物理模型 //所以翻了很多资料,包括原作者的,百度的,研究了好长时间 //现在也就懂了点皮毛 //创造一个物理body,是不是应该叫刚体 auto body1=PhysicsBody::create(); //给body一个框架(外壳???),这里我们就是草地的对应的长方形 auto shape_1=PhysicsShapeBox::create(land1->getContentSize()); //把这个外壳给那个物理body body1->addShape(shape_1); //把刚体设为静态的 //如果是动态刚体,它会受到力的作用 //如果用另个刚体碰撞它的话,这个动态刚体就会运动或者旋转什么的 //做为草地,它只能是一个安静的美男子......所以我们设为静态的 body1->setDynamic(false); //这个是把重力取消掉,草地时没有重力的 body1->setGravityEnable(false); //下面三个函数很复杂,我也是不怎么懂,网上的资料也不多 //就是说要添加上去,貌似是碰撞检测要用到的 body1->setCategoryBitmask(1); body1->setCollisionBitmask(-1); body1->setContactTestBitmask(-1); //下面的叫线性阻尼,我把它理解成摩擦力吧 body1->setLinearDamping(0.7f); //把刚体付给草地 land1->setPhysicsBody(body1); this->addChild(land1,2); land2=Sprite::createWithSpriteFrameName("land.png"); //把草地2接在草地1的后面,这边减去2个像素,是为了防止移动过程出现黑边 //因为,我们每移动一次的像素就是2 land2->setPosition(Point(origin.x+land1->getPositionX()+land1->getContentSize().width-2,land1->getPositionY())); land2->getTexture()->setAliasTexParameters(); auto body2=PhysicsBody::create(); auto shape_2=PhysicsShapeBox::create(land1->getContentSize()); body2->addShape(shape_2); body2->setDynamic(false); body2->setGravityEnable(false); body2->setCategoryBitmask(1); body2->setCollisionBitmask(-1); body2->setContactTestBitmask(-1); body2->setLinearDamping(0.7f); land2->setPhysicsBody(body2); this->addChild(land2,2); this->schedule(schedule_selector(LandLayer::landMove),LAND_VELOCITY); return true; } //草地滚动的实现 //如何实现草地滚动,在上面我们实例了两个草地精灵 //并且这两个草地的首尾接在了一起(具体看他们坐标X,草地2是接在草地1后面的) //在定时器运行过程中,每执行一次函数,草地1和草地2的X坐标就减去2 //并且检测草地2的坐标有没有超过限定值(这里就是草地1起始的坐标值) //如果超过,就重置两个草地的坐标 void LandLayer::landMove( float ) { land1->setPositionX(land1->getPositionX()-2); land2->setPositionX(land1->getPositionX()+land1->getContentSize().width-2); if (land2->getPositionX()==land2->getContentSize().width/2) { land1->setPositionX(land2->getContentSize().width/2); } } //草地停止移动,以后要用到 void LandLayer::stopLand() { this->unschedule(schedule_selector(LandLayer::landMove)); }
cocos2d-x v3.2 FlappyBird 各个类对象具体代码分析(3)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。