#include "LayerMapWalk.h"
#include "Graph\Graph.h"
#include "MapWalkVertex.h"
#include "json\writer.h"
#include "json\reader.h"
#include <iostream>
#include <fstream>
#include "RoleKaito.h"
#include "Graph\Dijkstra.h"
#include "Graph\Spfa.h"
#include "LayerHudControl.h"
#define ZOrderLine -1
#define ZOrderVertex 2
#define ZOrderRole 3
LayerMapWalk::LayerMapWalk( )
{
m_pGraph = 0 ;
}
LayerMapWalk::~LayerMapWalk( )
{
if ( m_pGraph )
{
delete m_pGraph ;
}
}
bool LayerMapWalk::init( )
{
this->setTouchMode( Touch::DispatchMode::ONE_BY_ONE ) ;
this->setTouchEnabled( true ) ;
m_Mode = OperationMode::PutVertex ;
// 背景图
//auto pSpr = Sprite::create( "map_bg.png" ) ;
//this->addChild( pSpr , -2 ) ;
// 初始化编辑数据
auto pSprEdgeEditLine = Sprite::create( "line.png" ) ;
//pSprEdgeEditLine->setColor( Color3B( 0 , 0 , 255 ) ) ;
m_EditData.pSprEdgeLine = pSprEdgeEditLine ;
this->addChild( pSprEdgeEditLine ) ;
pSprEdgeEditLine->setVisible( false ) ;
pSprEdgeEditLine->setAnchorPoint( Point( 0 , 0.5 ) ) ;
// 初始化角色
m_pRole = RoleKaito::create( ) ;
m_pRole->setPosition( 100 , 100 ) ;
m_pRole->setLocalZOrder( ZOrderRole ) ;
this->addChild( m_pRole ) ;
m_pRole->setVisible( false ) ;
// 初始化ID分配表
for ( int i = 0 ; i < 1000 ; ++i )
{
char sz[ 100 ] ;
sprintf( sz , "%d" , i ) ;
m_VertexIdTable[ sz ] = 0 ;
}
m_pGraph = new Graph( ) ;
return true ;
}
bool LayerMapWalk::onTouchBegan( Touch *touch , Event *unused_event )
{
auto pos = touch->getLocation() ;
switch ( m_Mode )
{
case OperationMode::PutVertex:
{
// 坐标变换
pos = this->convertToNodeSpaceAR( pos ) ;
auto pMwv = HitMapWalkVertex( pos ) ;
if ( pMwv )
{
m_Mode = OperationMode::DragEdge ;
auto pSprLine = m_EditData.pSprEdgeLine ;
pSprLine->setPosition( pos ) ;
pSprLine->setVisible( true ) ;
MakeLine( pSprLine , pSprLine->getPosition( ) , pos ) ;
m_EditData.pMwv = pMwv ;
}
else
{
// 创建地图行走的顶点
auto pMwv = MapWalkVertex::create( ) ;
pMwv->setPosition( pos ) ;
AddVertex( pMwv ) ;
}
}
break;
case OperationMode::DragContent:
{
m_EditData.ptDrag = pos - this->getPosition( ) ;
}
break;
case OperationMode::PositionRole:
{
// 坐标变换
pos = this->convertToNodeSpaceAR( pos ) ;
auto pMwv = HitMapWalkVertex( pos ) ;
if ( pMwv )
{
m_pRole->setPosition( pMwv->getPosition( ) ) ;
m_pRole->setVisible( true ) ;
m_pRole->UserData[ "StartVertex" ] = pMwv ;
}
}
break;
case OperationMode::RoleWalk:
{
pos = this->convertToNodeSpaceAR( pos ) ;
auto pMwv = HitMapWalkVertex( pos ) ;
if ( pMwv )
{
auto pVertex = pMwv->GetGraphVertex( ) ;
// 起点
MapWalkVertex* pMwvStart = ( MapWalkVertex*)m_pRole->UserData[ "StartVertex" ] ;
int nTimeStart ;
int Elapsed ;
char sz[ 256 ] ;
string strElapseds ;
// 计算最短路径。用Dijkstra
nTimeStart = ::clock( ) ;
Dijkstra Dijkstra ;
Dijkstra.Execute( *m_pGraph , pMwvStart->GetGraphVertex()->GetId() ) ;
Elapsed = ::clock( ) - nTimeStart ;
sprintf( sz , "Dijkstra : %d ms \n" , Elapsed ) ;
strElapseds += sz ;
// 用 Spfa
nTimeStart = ::clock( ) ;
Spfa spfa ;
spfa.Execute( *m_pGraph , pMwvStart->GetGraphVertex( )->GetId( ) ) ;
Elapsed = ::clock( ) - nTimeStart ;
sprintf( sz , "Spfa : %d ms \n" , Elapsed ) ;
strElapseds += sz ;
m_pLayerHudControl->m_pTxtInfo2->setString( strElapseds ) ;
// 取得路径序列
vector< MapWalkVertex* > MwvSeq ;
//const auto& PathTree = spfa.GetResult( ).PathTree ;
MwvSeq.push_back( pMwv ) ;
//for ( auto it = PathTree.find( pVertex ) , end = PathTree.end( );
// it->second != 0 && it != end ;
// it = PathTree.find( it->second ) )
//{
// MwvSeq.push_back( ( MapWalkVertex* ) it->second->UserData[ "mwv" ] ) ;
//}
for ( Vertex* pParent = pVertex->PathfindingData.pParent ;
pParent != 0 ;
pParent = pParent->PathfindingData.pParent )
{
MwvSeq.push_back( ( MapWalkVertex* ) pParent->UserData[ "mwv" ] ) ;
}
// 开始行走动画
StartWalk( MwvSeq ) ;
}
}
break ;
}
return true ;
}
void LayerMapWalk::onTouchMoved( Touch *touch , Event *unused_event )
{
auto pos = touch->getLocation( ) ;
switch ( m_Mode )
{
case OperationMode::DragEdge:
{
// 坐标变换
pos = this->convertToNodeSpaceAR( pos ) ;
auto pSprLine = m_EditData.pSprEdgeLine ;
MakeLine( pSprLine , pSprLine->getPosition( ) , pos ) ;
}
break;
case OperationMode::DragContent:
{
Point pt = pos - m_EditData.ptDrag ;
this->setPosition( pt ) ;
}
break;
}
}
void LayerMapWalk::onTouchEnded( Touch *touch , Event *unused_event )
{
// 坐标变换
auto pos = this->convertTouchToNodeSpaceAR( touch ) ;
switch ( m_Mode )
{
case OperationMode::DragEdge:
{
auto pMwv = HitMapWalkVertex( pos ) ;
if ( pMwv )
{
AddEdge( m_EditData.pMwv , pMwv ) ;
m_EditData.pSprEdgeLine->setVisible( false ) ;
m_Mode = OperationMode::PutVertex ;
}
else
{
m_EditData.pSprEdgeLine->setVisible( false ) ;
m_Mode = OperationMode::PutVertex ;
}
}
break;
}
}
MapWalkVertex* LayerMapWalk::HitMapWalkVertex( const Point& pos )
{
MapWalkVertex * pRet = 0 ;
// 是否命中节点
for ( auto& it : m_MapWalkVertexes )
{
auto v = pos - it->getPosition( ) ;
if ( v.getLengthSq( ) < 50 * 50 )
{
pRet = it ;
break;
}
}
return pRet ;
}
void LayerMapWalk::MakeLine( Sprite* pSpr , const Point& pt1 , const Point& pt2 )
{
// 设置锚点与位置
pSpr->setAnchorPoint( Point( 0 , 0.5 ) ) ;
pSpr->setPosition( pt1 ) ;
// 缩放
float width = pSpr->getTexture( )->getContentSize( ).width ;
auto v = pt2 - pt1 ;
float len = v.getLength( ) ;
float ScaleX = len / width ;
pSpr->setScaleX( ScaleX ) ;
// 旋转
float rad = v.getAngle( ) ;
float Rotation = CC_RADIANS_TO_DEGREES( -rad ) ;
pSpr->setRotation( Rotation ) ;
}
void LayerMapWalk::StartWalk( const vector< MapWalkVertex* >& MwvSeq )
{
Action *pAct = m_pRole->getActionByTag( 1 ) ;
if ( pAct != 0 && pAct->isDone() == false )
{
return ;
}
Vector< FiniteTimeAction* > Actions ;
for ( int i = MwvSeq.size( ) - 2 ; i >= 0 ; --i )
{
// 计算每一段的距离
Point v = MwvSeq[ i ]->getPosition( ) - MwvSeq[ i + 1 ]->getPosition( ) ;
float len = v.getLength( ) ;
float duration = len / 100 * 1.2 ;
RoleKaito::State Direction ;
float rad = v.getAngle( Point( 1 , 1 ) ) ;
float Degree = CC_RADIANS_TO_DEGREES( rad ) ;
if ( Degree >= 0 && Degree < 90 )
{
Direction = RoleKaito::State::WalkRight ;
}
else if ( Degree >= 90 && Degree <= 180 )
{
Direction = RoleKaito::State::WalkBottom ;
}
else if ( Degree < 0 && Degree >= -90 )
{
Direction = RoleKaito::State::WalkTop ;
}
else if ( Degree < -90 && Degree >= -180 )
{
Direction = RoleKaito::State::WalkLeft ;
}
auto fnSetDirection = [ ]( RoleKaito *pRole , RoleKaito::State Dir )
{
pRole->SetState( Dir ) ;
} ;
Actions.pushBack( CallFunc::create( bind( fnSetDirection , m_pRole , Direction ) ) ) ;
FiniteTimeAction *pAct = MoveTo::create( duration , MwvSeq[ i ]->getPosition( ) ) ;
auto fn = [ ]( RoleKaito *pRole , MapWalkVertex * pGv )
{
pRole->UserData[ "StartVertex" ] = pGv ;
} ;
Actions.pushBack( pAct ) ;
Actions.pushBack( CallFunc::create( bind( fn , m_pRole , MwvSeq[ i ] ) ) ) ;
}
auto fnStopActions = [ ]( RoleKaito *pRole )
{
pRole->SetState( RoleKaito::State::None ) ;
} ;
Actions.pushBack( CallFunc::create( bind( fnStopActions , m_pRole ) ) ) ;
if ( Actions.size( ) == 0 )
{
return ;
}
auto pSeq = Sequence:
Cocos2d-x 地图行走的实现2
5星 · 超过95%的资源 需积分: 16 31 浏览量
2014-08-08
19:08:38
上传
评论 4
收藏 635KB ZIP 举报
Siliphen
- 粉丝: 496
- 资源: 35
最新资源
- 基于java开发操作系统实验,使用首次适应算法和循环首次适应算法,实现存储管理的动态分区分配+源码(毕业设计&课程设计&项目开发
- Royal TSX mac激活版
- 苹果cms海螺主题模板简化版安装教程
- 适合小白理解的消除文法的左递归.doc
- APP-Inventor做的手机TCP通信源程序
- 基于python实现基于决策树进行入侵检测的小模型项目源码.zip
- 最新Jasmine博客模板:简洁美观的自适应Typecho主题
- 照片审核 压缩照片的大小
- 基于Tkinter的百度AI图像识别技术二次开发实践.pdf
- 自定义函数实现delaunayTriangulation 使用Bowyer-Watson 算法
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
- 1
- 2
- 3
前往页