//
// Created by cuijiahao on 13-9-25.
//
//
#ifndef __Mafia__FanStageLayer__
#define __Mafia__FanStageLayer__
#include "cocos2d.h"
#include "cocos-ext.h"
#include <vector>
USING_NS_CC;
USING_NS_CC_EXT;
using namespace std;
#include "../LayerStage.h"
class FanStageLayer : public LayerStage
{
public:
FanStageLayer();
~FanStageLayer();
virtual bool init();
cocos2d::CCNode* initFanStageLayer();
CREATE_FUNC(FanStageLayer);
void HairUpdate(float fElapsedTime);//头发动画的更新
void update(float fElapsedTime);
void initArmature();
void loadResource();
void StageRun(float fElapsedTime);
bool ccTouchBegan(CCTouch* touch, CCEvent* event);
void ccTouchMoved(CCTouch* touch, CCEvent* event);
void ccTouchEnded(CCTouch* touch, CCEvent* event);
float Distance(CCPoint start, CCPoint end);//求两点间的距离
protected:
private:
CCNode * m_SceneNode;//场景节点
CCNode * m_FanBlade; //扇叶节点
CCNode * m_LastHead; //末尾人物表情
CCNode * m_Head; //人物初始表情
CCSprite * m_PeoHair; //头发精灵
CCSize m_SceneSize;//屏幕大小
CCRect m_rCollideArea; //碰撞区
CCArmature * m_FanArmature; //风扇动画
CCArmature * m_HairArmature; //头发动画
float m_fFanStartSpeed; //风扇初速度
float m_fFanAddSpeed; //风扇加速度
float m_fFanEndSpeed; //风扇末速度
float m_fHairStartSpeed; //头发初速度
float m_fHairAddSpeed; //头发加速度
float m_fHairEndSpeed; //头发末速度
bool m_bFanDir; //风扇转向(true为正转)
bool m_bTouchEnded; //手指抬起
vector<CCPoint> m_vecPoint; //滑动点容器
private:
enum MyFanStageLayerEnum
{
BackGround_UP = 10001, //上边的背景
BackGround_Bottom, //下边的背景
Head, //头部
Hair, //头发
FanBlade, //风扇叶
LastHead
};
};
#endif /* defined(__DotaHero__ShopLayer__) */
----------------------------------------------------------------------------------------------------------------------------
#include "FanStageLayer.h"
#include "../../Common/Toolbox.h"
FanStageLayer::FanStageLayer()
:m_SceneNode(NULL)
,m_FanArmature(NULL)
,m_HairArmature(NULL)
,m_fFanStartSpeed(0.0f)
,m_fFanAddSpeed(0.0f)
,m_fFanEndSpeed(0.0f)
,m_bTouchEnded(false)
,m_PeoHair(NULL)
,m_fHairStartSpeed(0)
,m_fHairAddSpeed(0)
,m_fHairEndSpeed(0)
,m_bFanDir(true)
{
}
FanStageLayer::~FanStageLayer()
{
m_SceneNode->removeFromParentAndCleanup(true);
this->removeFromParentAndCleanup(true);
}
bool FanStageLayer::init()
{
bool bRet = false;
do {
this->initFanStageLayer();
bRet = true;
} while (0);
return bRet;
}
cocos2d::CCNode* FanStageLayer::initFanStageLayer()
{
initLayerStage();//初始父类的参数
//-----------------------------------------------------------------------------
//屏幕区域
m_SceneSize = CCDirector::sharedDirector()->getWinSize();
//开启单点触摸
setTouchEnabled(true);
//开启更新函数
scheduleUpdate();
//设置碰撞区
m_rCollideArea = CCRect(0,0, m_SceneSize.width, m_SceneSize.height*620/960);
//加载场景
m_SceneNode = CCSSceneReader::sharedSceneReader()->createNodeWithSceneFile("CocoStudio/FanStage/Scene/FanStage.json");
this->addChild(m_SceneNode,0);
//Size visibleSize = Director::getInstance()->getVisibleSize();
//获取场景中的风扇叶
m_FanBlade = m_SceneNode->getChildByTag(FanBlade);
//m_FanBlade->setVisible(false);
//获取人物初始表情
m_Head = m_SceneNode->getChildByTag(Head);
//获取场景中的末尾人物表情
m_LastHead = m_SceneNode->getChildByTag(LastHead);
m_LastHead->setVisible(false);
//获取场景中的头发
m_PeoHair = CCSprite::create("Image/Stage/FanStage/hair.png");
m_PeoHair->setPosition(ccp(m_SceneSize.width*220/640 , m_SceneSize.height*795/960));//设置当前图片的位置
m_PeoHair->setScale(0.65f);
m_PeoHair->setAnchorPoint(CCPoint(0,0));
//m_PeoHair->setVisible(false);
this->addChild(m_PeoHair,2);
//加载动画
initArmature();
initedLayerStage();
//m_bIsTimeStage=false;
return NULL;
}
bool FanStageLayer::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
m_vecPoint.clear();//清除滑动点
return true;
}
void FanStageLayer::ccTouchMoved(CCTouch* touch, CCEvent* event)
{
//如果手指滑动是在规定的范围之内,则压栈
if (m_rCollideArea.containsPoint(convertTouchToNodeSpaceAR(touch)))
m_vecPoint.push_back(convertTouchToNodeSpaceAR(touch));//添加滑动点
}
void FanStageLayer::ccTouchEnded(CCTouch* touch, CCEvent* event)
{
m_bTouchEnded = true;
//CCLOG("Paddle::onTouchBegan id = %d, x = %f, y = %f", pTouch->getID(), pTouch->getLocation().x, pTouch->getLocation().y);
}
void FanStageLayer::update( float fElapsedTime )
{
updateStage(fElapsedTime);
}
float FanStageLayer::Distance( CCPoint start, CCPoint end )
{
float length = ccpDistance(start, end);
//float length =sqrt(pow(abs(start.x-end.x),2)+pow(abs(start.y-end.y),2));
return length;
}
void FanStageLayer::initArmature()
{
//加载风扇动画
++m_usRscTotalNum;
CCArmatureDataManager::sharedArmatureDataManager()->addArmatureFileInfoAsync(
"CocoStudio/FanStage/LastFan/LastFan.ExportJson",
this,
schedule_selector(FanStageLayer::loading_callback)
);
//加载头发被吹走的动画
++m_usRscTotalNum;
CCArmatureDataManager::sharedArmatureDataManager()->addArmatureFileInfoAsync(
"CocoStudio/FanStage/LastHair/LastHair.ExportJson",
this,
schedule_selector(FanStageLayer::loading_callback)
);
}
void FanStageLayer::loadResource()
{
m_FanArmature = CCArmature::create("LastFan");
m_FanArmature->getAnimation()->playByIndex(0);
m_FanArmature->setPosition(ccp(m_SceneSize.width*323/640 , m_SceneSize.height*362/960));
m_FanArmature->setVisible(false);
m_FanArmature->setColor( ccc3( 230,172,98));
this->addChild(m_FanArmature,5);
m_HairArmature = CCArmature::create("LastHair");
m_HairArmature->getAnimation()->playByIndex(0);
m_HairArmature->setPosition(ccp(m_SceneSize.width*90/640 , m_SceneSize.height*795/960));
m_HairArmature->setVisible(false);
this->addChild(m_HairArmature,5);
StageStateSet(SSOpen);
}
void FanStageLayer::StageRun(float fElapsedTime)
{
if (m_bTouchEnded && m_vecPoint.size()>=3)//如果手刚刚指抬起,则计算加速度
{
m_bFanDir = CToolbox::IsClockwise(m_FanBlade->getPosition(),m_vecPoint[m_vecPoint.size()-2],m_vecPoint[m_vecPoint.size()-1]);//求方向
求风扇的转向
//FanDirection( m_vecPoint[m_vecPoint.size()-2],m_vecPoint[m_vecPoint.size()-1]);
//风扇点到直线的垂线距离
//float fNearest=GetNearestDistance(m_vecPoint[0],m_vecPoint[m_vecPoint.size()-1],m_FanBlade->getPosition());
float fNearest = CToolbox::GetDistanceForDotToLine(m_FanBlade->getPosition(),m_vecPoint[0],m_vecPoint[m_vecPoint.size()-1]);
//求系数 150是风扇的半径
fNearest /= 150;
if (fNearest > 1)
fNearest = 1;
//求扇叶的加速度
m_fFanAddSpeed += (Distance(m_vecPoint[m_vecPoint.size()-1],m_vecPoint[m_vecPoint.size()-2]) +
Distance(m_vecPoint[m_vecPoint.size()-2],m_vecPoint[m_vecPoint.size()-3]))*4.0f *fNearest;//加速度=距离*系数
//设置手指离开触点为假
m_bTouchEnded = false;
//设置头发的加速度
m_fHairAddSpeed = m_fFanAddSpeed*2.0f;//头发的速度=扇叶的速度*系数
}
else//------------------计算风扇阻力,减少加速度
{
//------------------------扇叶的阻力
if (m_fFanAddSpeed>0)
m_fFanAddSpeed -= m_fFanAddSpeed * fElapsedTime*0.2f;//阻力=加速度 - 速度 * 时间
else
m_fFanAddSpeed = 0;
//----------------头发的阻力
if (m_fHairAddSpeed>0)
m_fHairAddSpeed -= m_fHairAddSpeed * fElapsedTime*0.8/*(1.0f/m_fFanAddSpeed*100)*/;//阻力=加速度 - 速度 * 时间*系数
else
m_fHairAddSpeed = 0;
}
//----------------加速度-------------------
m_fHairEndSpeed = m_fHairStartSpeed + m_fHairAddSpeed;//头发的末速度=初速度+加速度
if (m_bFanDir)//如果风扇转向为正向
{
m_fFanEndSpeed += m_fFanStartSpeed + m_fFanAddSpeed * fElapsedTime;//扇叶的末速度=初速度+加速度*时间
m_fFanEndSpeed++;
}
else//如果是反向
{
m_fFanEndSpeed -= m_fFanStartSpeed + m_fFanAddSpeed * fElapsedTime;//扇叶的末速度=初速度+加速度*时间
m_fFanEndSpeed--;
}
if (m_fHairEndSpeed<1600)
m_fHairEndSpeed = m_fHairEndSpeed/10;//头发的角度=头发的速度/10
else
m_fHairEndSpeed = 160;//如果头发的角度大于180度则让它等于180度
m_PeoHair->setRotation(-m_fHairEndSpeed);//头发的旋转
m_FanBlade->setRotation(m_fFanEndSpeed);//风扇的旋转
//CCLOG("%f,%f",m_fFanAddSpeed,m_fHairEndSpeed);
if (m_fHairEndSpeed>=160)//如果风扇的加速度大于系数则停止更新,并调用头发的更新函数
{
StageStateSet(SSComplete);
m_FanBlade->setVisible(false);
m_FanArmature->setVisible(true);
this->schedule(schedule_selector(FanStageLayer::HairUpdate),0.4f);
}
}
void FanStageLayer::HairUpdate( float fElapsedTime )
{
m_PeoHair->setVisible(false);
m_HairArmature->setVisible(true);
m_LastHead->setVisible(true);
m_Head->setVisible(false);
this->unschedule(schedule_selector(FanStageLayer::HairUpdate));
}