? ? ? ? 在上一篇中,我們實現了游戲的開始界面,接下來要實現游戲的主界面,主界面包含地圖、我方飛機、敵機等
? ? ? ? 先來實現我方飛機
我方飛機具有哪些屬性呢? 飛機要具有生命值、要有動畫效果(尾部噴氣),飛機不能夠飛出邊界,所以要進行邊界檢測,當飛機生命值為0時,飛機會爆炸,然后被移除。
.h文件
~~~
//飛機動畫
Animate* planeFly();
//邊界檢測
void borderCheck(float dt);
//飛機爆炸
void blowUp();
//移除飛機
void removePlane();
//獲取生命值
int getAlive();
//設定生命值
void loseAlive();
// 更新生命值
void updateAlive(int alive);
~~~
這個變量在create()函數中初始化,方便其他層調用我方飛機的相關數據
~~~
static MyPlane* instancePlane; //飛機實例
~~~
我方飛機的生命值直接在這里顯示、更新,不受控制器的控制
~~~
private:
int m_alive;
Label* aliveItem1;
Label* aliveItem2;
~~~
.cpp文件
~~~
/*
************************************************************************
*
* MyPlane.cpp
* 杜星飛 2015年8月13日
* 描述: 包含飛機的屬性、功能等
*
************************************************************************
*/
#include "MyPlane.h"
#include "SimpleAudioEngine.h"
MyPlane::MyPlane() :m_alive(5)
{
}
MyPlane::~MyPlane()
{
}
MyPlane* MyPlane::instancePlane = NULL;
MyPlane* MyPlane::create()
{
MyPlane* m_plane = NULL;
do
{
m_plane = new MyPlane();
CC_BREAK_IF(!m_plane);
if (m_plane && m_plane->init())
{
m_plane->autorelease();
instancePlane = m_plane;
}
else
CC_SAFE_DELETE(m_plane);
} while (0);
return m_plane;
}
//飛機動畫
Animate* MyPlane::planeFly()
{
Vector<SpriteFrame *> vector;
for (int i = 0; i < 2; i++)
{
auto frameName = __String::createWithFormat("chinaFly%d.png", i + 1);
auto temSpriteFrame = SpriteFrameCache::getInstance()->getSpriteFrameByName(frameName->getCString());
vector.pushBack(temSpriteFrame);
}
//設置不斷播放飛機的動畫
auto animation = Animation::createWithSpriteFrames(vector, 0.2f, -1);
auto animate = Animate::create(animation);
return animate;
}
bool MyPlane::init()
{
if(!Layer::init())
return false;
Size winSize = Director::getInstance()->getWinSize();
//添加飛機
auto m_planeSprite = Sprite::createWithSpriteFrameName("chinaFly1.png");
m_planeSprite->setPosition(Point(winSize.width / 2, m_planeSprite->getContentSize().height / 2));
m_planeSprite->setTag(AIRPLANE);
this->addChild(m_planeSprite);
m_planeSprite->runAction(this->planeFly());
// 飛機觸摸
auto listener = EventListenerTouchOneByOne::create();
listener->setSwallowTouches(true); //吞噬觸摸事件
//對觸摸事件的監聽過程直接寫在這里
listener->onTouchBegan = [](Touch* touch, Event *event)
{
auto target = static_cast<Sprite*>(event->getCurrentTarget());
Point locationInNode = target->convertToNodeSpace(touch->getLocation());
Size s = target->getContentSize();
Rect rect = Rect(0, 0, s.width, s.height);
if (rect.containsPoint(locationInNode))
return true;
else
return false;
};
listener->onTouchMoved = [](Touch* touch, Event *event)
{
auto target = static_cast<Sprite*>(event->getCurrentTarget());
target->setPosition(target->getPosition() + touch->getDelta());
};
listener->onTouchEnded = [](Touch* touch, Event* event)
{
};
//將觸摸監聽添加到eventDispacher中去
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, m_planeSprite);
//初始化生命值
//設置標簽 并 獲取中文文本
auto dictionary = Dictionary::createWithContentsOfFile("fonts/AboutMe.xml");
aliveItem1 = Label::createWithTTF(
(((__String*)(dictionary->objectForKey("alive"))))->getCString(),
"fonts/DFPShaoNvW5-GB.ttf",
25);
aliveItem1->setPosition(Point(winSize.width/8, winSize.height-aliveItem1->getContentSize().height));
aliveItem1->setColor(Color3B(255, 0, 0));
this->addChild(aliveItem1);
aliveItem2 = Label::createWithTTF(
"5",
"fonts/DFPShaoNvW5-GB.ttf",
25);
aliveItem2->setPosition(Point(aliveItem1->getPositionX()*2, winSize.height - aliveItem1->getContentSize().height));
aliveItem2->setColor(Color3B(255, 0, 0));
this->addChild(aliveItem2);
// 開啟邊界檢測
this->schedule(schedule_selector(MyPlane::borderCheck));
return true;
}
//邊界檢測
void MyPlane::borderCheck(float dt)
{
//進行邊界判斷,不可超出屏幕
Point location = this->getChildByTag(AIRPLANE)->getPosition();
Size winSize = Director::getInstance()->getWinSize();
// 返回的就是這個矩形的大小
Size planeSize = this->getChildByTag(AIRPLANE)->getContentSize();
if (location.x<planeSize.width / 2)
location.x = planeSize.width / 2;
if (location.x>winSize.width - planeSize.width / 2)
location.x = winSize.width - planeSize.width / 2;
if (location.y<planeSize.height / 2)
location.y = planeSize.height / 2;
if (location.y>winSize.height - planeSize.height / 2)
location.y = winSize.height - planeSize.height / 2;
this->getChildByTag(AIRPLANE)->setPosition(location);
}
//飛機爆炸
void MyPlane::blowUp()
{
this->unscheduleAllSelectors(); // 停止飛機的所有行動
//加載飛機爆炸動畫 音效
if (CocosDenshion::SimpleAudioEngine::getInstance()->isBackgroundMusicPlaying())
{
CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("sound/chinaDown.mp3");
}
Vector<SpriteFrame*> planeBlowUp;
for (int i = 0; i < 4; i++)
{
auto planeName = __String::createWithFormat("china1_down%d.png", i + 1);
auto tempBlowUp = SpriteFrameCache::getInstance()->getSpriteFrameByName(
planeName->getCString());
planeBlowUp.pushBack(tempBlowUp);
}
Animation* animation = Animation::createWithSpriteFrames(planeBlowUp, 0.2f);
Animate* animate = Animate::create(animation);
CallFunc* m_removePlane = CallFunc::create(this, callfunc_selector(MyPlane::removePlane));
Sequence* sequence = Sequence::create(animate, m_removePlane, NULL);
// 停止一切的飛機動作
this->getChildByTag(AIRPLANE)->stopAllActions();
this->getChildByTag(AIRPLANE)->runAction(sequence);
}
//移除飛機
void MyPlane::removePlane()
{
// 移除飛機精靈 true子節點上的所有運行行為和回調將清理
this->removeChildByTag(AIRPLANE, true);
}
//獲取生命值
int MyPlane::getAlive()
{
return m_alive;
}
//設定生命值
void MyPlane::loseAlive()
{
--m_alive;
updateAlive(m_alive);
}
// 更新生命值
void MyPlane::updateAlive(int alive)
{
if (alive >= 0)
{
CCString* strAlive = CCString::createWithFormat("%d", alive);
aliveItem2->setString(strAlive->getCString());
aliveItem2->setColor(Color3B(rand_0_1() * 255, rand_0_1() * 255, rand_0_1() * 255));
}
}
~~~
更新生命值的函數只用在我方飛機生命值減少是調用。
還有就是對于中文字符的處理
~~~
//設置標簽 并 獲取中文文本
auto dictionary = Dictionary::createWithContentsOfFile("fonts/AboutMe.xml");
~~~
可以在項目中添加一個XML文件
~~~
<?xml version="1.0" encoding="UTF-8"?>
<dict>
<key>play</key>
<string>開始游戲</string>
<key>score</key>
<string>得分:</string>
<key>alive</key>
<string>生命:</string>
~~~
通過相應的key來顯示顯示相應的中文。
還有就是,有些字體不支持中文的顯示,比如系統自帶的?arial.ttf就不行,而DFPShaoNvW5-GB.ttf可以。