豪华版飞机大战系列(四)

上一篇介绍了敌人类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
}
```



上述的介绍中添加了创建了飞机精灵同时添加了跟随的小猪精灵,也为触摸屏幕添加了相应的响应回调函数,基本上没有难度,在上述以及前几篇的工作都做好后,最后就该介绍最重要的游戏主要场景和主要层中的逻辑了。


下一篇介绍游戏主要场景,并添加游戏中的主要逻辑,即可实现游戏的主要功能了。

thank you, 支持分享

:4: :4: :4: :4: :4: :4: :4: :4:

此贴给我帮助很大呀~

:2::2::2::2::2::2::2:

图片哪里下载