• 【cocos2d-x 3.7 飞机大战】 决战南海I (二) 我方飞机的实现


            在上一篇中。我们实现了游戏的開始界面,接下来要实现游戏的主界面。主界面包括地图、我方飞机、敌机等

            先来实现我方飞机


    我方飞机具有哪些属性呢? 飞机要具有生命值、要有动画效果(尾部喷气),飞机不可以飞出边界。所以要进行边界检測,当飞机生命值为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能够。





  • 相关阅读:
    Linux关机命令详解
    这二个月都在失眠中。
    GMAIL绑定自己的域名MX解析出现错误
    又上火了。
    FTP命令
    怎样做反向域名解析?
    linux 一些常用到的命令。
    LINUX怎么换IP。
    关于 MOD 和 \ 选择
    WIN2000和WIN2003连备份机的疑问
  • 原文地址:https://www.cnblogs.com/cxchanpin/p/6973921.html
Copyright © 2020-2023  润新知