上一篇介绍了敌人类EnemySprite的实现,这篇来介绍下主角类的实现。在游戏中可以看到主角类的周围有一直在飞行的小猪,时刻跟在主角飞机的旁边,我们先介绍下PigSprite的实现,因为后面的主角飞机类要用到此类。
看PigSprite.h的实现:
#include "cocos2d.h" USING_NS_CC; class PigSprite : public cocos2d::Sprite { public: PigSprite(); ~PigSprite(); virtual bool init(); //精灵初始化 CREATE_FUNC(PigSprite);//create函数宏 void f_createAnimate(int count,int fps);//创建动画 void f_followPlane(float dt);//跟随飞机 Sprite *spritepig; }; ``` 接下来看PigSprite.cpp中的实现:#include "PigSprite.h" #include "PlaneLayer.h" PigSprite::PigSprite() {} PigSprite::~PigSprite() {} bool PigSprite::init() { if (!Sprite::init()) { return false; } Size winSize = Director::getInstance()->getWinSize(); spritepig = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("hero_01.png")); this->setPosition(Point(winSize.width / 2, winSize.height / 2)); this->addChild(spritepig); //设置缩放倍数为0.6,也就是变为原来的0.6 this->setScale(0.6); //穿件小猪飞行动画 f_createAnimate(3, 8); //时间调度函数,使每一帧都调用f_followPlane函数来保持小猪在飞机周围 this->schedule(schedule_selector(PigSprite::f_followPlane)); return true; } /** * 获取飞机的位置信息,使小猪的位置始终在飞机周围,函数中判断是否到达边界,以更新小猪 * 在飞机的左边还是右边 */ void PigSprite::f_followPlane(float dt) { Size winSize = Director::getInstance()->getWinSize(); auto PlanePos = PlaneLayer::sharedPlane->getChildByTag(AIRPLANE)->getPosition(); if (PlanePos.x + 60 + spritepig->getContentSize().width <= winSize.width) { this->setPosition(Point(PlanePos.x + 60 + spritepig->getContentSize().width / 2,PlanePos.y)); } else { this->setPosition(Point(PlanePos.x - 60 - spritepig->getContentSize().width / 2,PlanePos.y)); } } /** * 创建小猪飞行的动画,count为帧动画的数量,fps为每帧的间隔时间, * RepeatForever创建无限重复动画,让spritepig来执行这个动画 */ void PigSprite::f_createAnimate(int count, int fps) { char buff; Animation *panimation = Animation::create(); panimation->setDelayPerUnit(1.0 / fps); for (int id = 1; id <= count; id++) { sprintf(buff, "hero_0%d.png", id); panimation->addSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName(buff)); } spritepig->runAction(RepeatForever::create(Animate::create(panimation))); } ``` 在此不做太多的解释,代码中都有详细的注释,没有特别难的地方,在小猪跟随飞机的函数中,用到了飞机的单例类来获取飞机的位置信息,飞机的单例类在下面实现。 单例飞机类继承Layer层,在这个层中会添加跟随的小猪精灵PigSprite,看下PlaneLayer.h的实现:#include "cocos2d.h" #include "PigSprite.h" USING_NS_CC; enum Enum_Plane { AIRPLANE = 1, }; class PlaneLayer: public cocos2d::Layer { public: static cocos2d::Scene* createScene();//创建场景,返回所创建的场景 virtual bool init();//init初始化函数 void menuCloseCallback(cocos2d::Ref* pSender);//menu回调函数 static PlaneLayer* create();//create静态函数,在其中设置单例,并调用init方法 public: PigSprite *mp_pig;//跟随的小猪精灵 static PlaneLayer* sharedPlane;//全局单例标志,以此来返回单例 void f_createSprite();//创建飞机精灵函数 public: bool onTouchBegan(Touch* touch, Event* pEvent);//点击开始事件响应函数 void onTouchMoved(Touch *touch, Event *pEvent);//点击移动事件响应函数 }; ``` 各个函数功能都有详细介绍,接下来看一下PlaneLayer.cpp的实现:#include "PlaneLayer.h" #include "BulletSprite.h" USING_NS_CC; /** * 静态单例变量初始化 */ PlaneLayer *PlaneLayer::sharedPlane = NULL; /** * 创建场景,并添加PlaneLayer层 */ Scene* PlaneLayer::createScene() { auto scene = Scene::create(); auto layer = PlaneLayer::create(); scene->addChild(layer); return scene; } /** * 创建层,并将创建的层赋值给单例变量 */ PlaneLayer* PlaneLayer::create() { PlaneLayer *pRet = new PlaneLayer(); if (pRet && pRet->init()) { pRet->autorelease(); sharedPlane = pRet;//赋值给单例变量 return pRet; } else { CC_SAFE_DELETE(pRet); return NULL; } } bool PlaneLayer::init() { if (!Layer::init()) { return false; } /** * 加载缓存类图片,图片用TexturePacker进行打包处理, * 加载生成的plist文件,也即xml文件 * SpriteFrameCache缓存类会根据plist中的键值对应的图片进行加载并缓存到系统中 * 方便从缓存中获取相应图片 */ SpriteFrameCache::getInstance()->addSpriteFramesWithFile("pig.plist"); SpriteFrameCache::getInstance()->addSpriteFramesWithFile("bullet.plist"); SpriteFrameCache::getInstance()->addSpriteFramesWithFile("wsparticle_p01.plist"); SpriteFrameCache::getInstance()->addSpriteFramesWithFile("nplane.plist"); Size visibleSize = Director::getInstance()->getVisibleSize(); Point origin = Director::getInstance()->getVisibleOrigin(); //创建closemenu auto closeItem = MenuItemImage::create("CloseNormal.png","CloseSelected.png", CC_CALLBACK_1(PlaneLayer::menuCloseCallback, this)); closeItem->setPosition(Point(origin.x + visibleSize.width- closeItem->getContentSize().width / 2, origin.y + closeItem->getContentSize().height / 2)); auto menu = Menu::create(closeItem, NULL); menu->setPosition(Point::ZERO); this->addChild(menu, 1); //调用创建精灵函数 f_createSprite(); return true; } /** * 创建飞机精灵,并添加小猪精灵,同时注册点击事件 */ void PlaneLayer::f_createSprite() { Size winSize = Director::getInstance()->getWinSize(); //创建飞机精灵 auto plane = Sprite::create("mplane.png"); plane->setTag(AIRPLANE); plane->setScale(0.7f); plane->setPosition(Point(winSize.width / 2 - plane->getContentSize().width / 2,winSize.height / 7)); this->addChild(plane); //用先前实现的小猪类来创建小猪精灵,并添加到层中 mp_pig = PigSprite::create(); this->addChild(mp_pig); /** * 注册点击响应事件 */ auto touchListener = EventListenerTouchOneByOne::create(); touchListener->setSwallowTouches(true);//不向下传递触摸事件 touchListener->onTouchBegan = CC_CALLBACK_2(PlaneLayer::onTouchBegan, this);//触摸开始 touchListener->onTouchMoved = CC_CALLBACK_2(PlaneLayer::onTouchMoved, this);//触摸移动 _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener,plane);//飞机精灵注册触摸事件 } /** * 触摸开始事件, * 主要设置飞机移动到触摸的位置 */ void PlaneLayer::onTouchMoved(Touch *touch, Event *pEvent) { auto target = static_cast(pEvent->getCurrentTarget()); target->setPosition(touch->getLocation()); } /** * 触摸移动事件,飞机跟随手指的移动进行移动到相应位置 */ bool PlaneLayer::onTouchBegan(Touch* touch, Event* pEvent) { auto target = static_cast(pEvent->getCurrentTarget()); Point locationInNode = target->convertToNodeSpace(touch->getLocation()); target->setPosition(touch->getLocation()); return true; } /** * closemenu回调函数,结束游戏 */ void PlaneLayer::menuCloseCallback(Ref* pSender) { #if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert"); return; #endif Director::getInstance()->end(); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) exit(0); #endif } ``` 上述的介绍中添加了创建了飞机精灵同时添加了跟随的小猪精灵,也为触摸屏幕添加了相应的响应回调函数,基本上没有难度,在上述以及前几篇的工作都做好后,最后就该介绍最重要的游戏主要场景和主要层中的逻辑了。 下一篇介绍游戏主要场景,并添加游戏中的主要逻辑,即可实现游戏的主要功能了。