首页 数据库 mysql教程 cocos2dx A* + tiledMap(改良升级)

cocos2dx A* + tiledMap(改良升级)

Jun 07, 2016 pm 03:43 PM
升级

此次在之前那篇cocos2dx A* tiledMap文章中新加了些功能并且调整了结构 拥有的功能: 能避开障碍物,搜寻最优路径 优化了行走的路径,使之平滑行走(之前的是瓦片级的, 现在是像素级的, #define PRECISE_SEARCH_PATH 开启精确的路径行走) 添加了人物根据位置会被

此次在之前那篇cocos2dx A* + tiledMap文章中新加了些功能并且调整了结构

拥有的功能:

能避开障碍物,搜寻最优路径

优化了行走的路径,使之平滑行走(之前的是瓦片级的, 现在是像素级的, #define PRECISE_SEARCH_PATH 开启精确的路径行走)

添加了人物根据位置会被物体遮住或遮住物体的功能

添加了点击路面, 到达该点.   点击物体, 可以到达该物体的功能

添加了捡拾物体功能

添加了坐椅子功能

添加了人物的骨骼动画(行走和站立)

PathSearchInfo 搜索路径引擎

Player 玩家类

PathSprite 瓦片精灵类

Paddle物体类(桌子,椅子等)

MathLogic 数学逻辑类

cocos2dx A* + tiledMap(改良升级)


#pragma once
#include "StaticValue.h"
#include "PathSprite.h"
#include "MathLogic.h"
#include "cocos2d.h"
#include <functional>
#include "paddle.h"
USING_NS_CC;
class PathSearchInfo:public CCNode//寻路类(主要负责寻路的参数和逻辑)
{
public:
	PathSearchInfo(CCTMXTiledMap* tiledMap);

private:
	int m_playerMoveStep;//人物当前的行程的索引
	std::function<void> m_moveDone;//移动结束回调
	bool m_isSetMoveDoneCallback;

	std::function<void>)> m_drawPath;//画线回调  调试用
	bool m_isSetDrawPathCallback;

	std::function<void point paddle selectobj> m_selectObj;//选中物体回调
	bool m_isSetSelectObjCallback;

	CCTMXTiledMap* m_map;//地图
	CCTMXLayer* m_road;//道路
	CCSize m_mapSize;//地图大小
	CCSize m_tileSize;//地图的块大小
	vector<pathsprite> m_openList;//开放列表(里面存放相邻节点)
	PathSprite* m_inspectArray[MAP_WIDTH][MAP_HEIGHT];//全部需要检测的点
	vector<pathsprite> m_pathList;//路径列表
	vector<pathsprite> m_haveInspectList;//检测过的列表
	PathSprite* m_moveObj;//移动的物体
	bool m_enableMove;//是否能移动
	bool m_isMoving;//是否正在移动
public:
	CCTMXTiledMap* getMap()
	{
		return m_map;
	}
	void setEnableMove(bool isEnable)
	{
		m_enableMove = isEnable;
	}

	bool getEnableMove()
	{
		return m_enableMove;
	}

	bool getIsMoving()
	{
		return m_isMoving;
	}
 	void setMoveDoneCallback(function<void>& pFunc);//设置回调

	void setDrawPathCallback(function<void>)>& pFunc);//设置回调
	
	void setSelectCallback(function<void point paddle selectobj> &pFunc);//设置回调

	void initMapObject(const char* layerName, const char* objName);////初始化地图里的物体(设置深度,设置物体回调函数)

	CCPoint getMapPositionByWorldPosition(CCPoint point);//根据世界坐标得到地图坐标

	CCPoint getWorldPositionByMapPosition(CCPoint point);//根据地图坐标得到世界坐标

	void pathFunction( CCPoint point, PathSprite* obj );//计算路径函数

private:
	void calculatePath();//计算路径
	
	float calculateTwoObjDistance(PathSprite* obj1, PathSprite* obj2);//计算两个物体间的距离

	void inspectTheAdjacentNodes(PathSprite* node, PathSprite* adjacent, PathSprite* endNode);//把相邻的节点放入开放节点中
	
	PathSprite* getMinPathFormOpenList();//从开放节点中获取F值最小值的点
	
	PathSprite* getObjFromInspectArray(int x, int y);//根据横纵坐标从检测数组中获取点
	
	bool removeObjFromOpenList( PathSprite* sprite);//从开放列表中移除对象
	
	void resetInspectArray();//重置检测列表
	
	bool detectWhetherCanPassBetweenTwoPoints(CCPoint p1, CCPoint p2);//检测2个位置中是否有障碍物
	
	void resetObjPosition();//重置玩家位置
	
	void clearPath();//清除路径

	void moveObj();//移动实现函数
};
</void></void></void></pathsprite></pathsprite></pathsprite></void></void></void></functional>
登录后复制

#include "PathSearchInfo.h"


PathSearchInfo::PathSearchInfo( CCTMXTiledMap* tiledMap )
{
	memset(m_inspectArray, NULL, MAP_WIDTH*MAP_HEIGHT*sizeof(PathSprite*));
	m_isSetMoveDoneCallback = false;
	m_isSetDrawPathCallback = false;
	m_isSetSelectObjCallback = false;
	m_enableMove = true;

	m_map = tiledMap;
	m_mapSize = m_map->getMapSize();//获取地图的尺寸 地图单位
	m_tileSize = m_map->getTileSize();//获取瓦片的尺寸  世界单位
	m_road = m_map->layerNamed("road");//行走路径的地图

	for (int j = 0;  j tileAt(CCPoint(i, j));
			if (_sp) {
				PathSprite* _pathSprite = new PathSprite(_sp);
				_pathSprite->m_x = i;
				_pathSprite->m_y = j;

				m_inspectArray[i][j] = _pathSprite;//把地图中所有的点一一对应放入检测列表中
			}
		}
	}	
}

void PathSearchInfo::setMoveDoneCallback( function<void>& pFunc )
{
	m_moveDone = pFunc;
	m_isSetMoveDoneCallback = true;
}

void PathSearchInfo::setDrawPathCallback( function<void>)>& pFunc )
{
	m_drawPath = pFunc;
	m_isSetDrawPathCallback = true;
}

void PathSearchInfo::setSelectCallback( function<void point paddle selectobj> &pFunc )
{
	m_selectObj = pFunc;
	m_isSetSelectObjCallback = true;
}

void PathSearchInfo::initMapObject( const char* layerName, const char* objName )
{
	//图片层
	CCTMXLayer* _layer = m_map->layerNamed(layerName);
	if (!_layer)
	{
		return;
	}
	//对象层
	CCTMXObjectGroup* pipeGroup = m_map->objectGroupNamed(objName);
	if (!pipeGroup)
	{
		return;
	}
	//得到所有的对象
	CCArray* _array = pipeGroup->getObjects();
	CCObject *_obj;
	CCARRAY_FOREACH(_array, _obj )
	{
		//得一个
		CCDictionary* _dictionary  = (CCDictionary*)_obj;

		//得到属性
		float _x = ((CCString*)_dictionary->objectForKey("x"))->floatValue();//世界单位
		float _y= ((CCString*)_dictionary->objectForKey("y"))->floatValue();
		float _widht = ((CCString*)_dictionary->objectForKey("width"))->floatValue();//世界单位
		float _height = ((CCString*)_dictionary->objectForKey("height"))->floatValue();

		CCString* _terminalX = ((CCString*)_dictionary->objectForKey("terminalX"));//终点x坐标
		CCString* _terminalY = ((CCString*)_dictionary->objectForKey("terminalY"));//终点y坐标
		CCString* _type = ((CCString*)_dictionary->objectForKey("type"));//物体类型
		CCString* _enableSit = ((CCString*)_dictionary->objectForKey("enableSit"));//是否能坐下
		CCString* _enableTouch =(( CCString*)_dictionary->objectForKey("enableTouch"));//是否能触摸
		CCString* _enablePickUp =(( CCString*)_dictionary->objectForKey("enablePickUp"));//是否能触摸

		Paddle* _parent = Paddle::paddleWithContentSize(CCSize(_widht, _height));//创建一个物体类

		//设置物体属性
		if (_terminalX && _terminalY)
		{
			_parent->m_terminal = CCPoint( _terminalX->floatValue(), _terminalY->floatValue());
			if (m_isSetSelectObjCallback)
			{
				_parent->m_selectCallback =m_selectObj;
			}

		}
		else
		{
			_parent->m_terminal = CCPoint(-1, -1);
		}
		_parent->m_type = _type?  (OBJTYPE)_type->intValue():NONE_TYPE;
		_parent->m_enableSit = _enableSit? _enableSit->boolValue():false;
		_parent->m_enableTouch = _enableTouch?_enableTouch->boolValue():false;
		if (_enablePickUp)
		{
			_parent->m_enablePickUp = _enablePickUp->boolValue();
			_parent->m_selectCallback =m_selectObj;
		}
		else
		{
			_parent->m_enablePickUp =false;
		}
		//设置物体位置
		CCPoint _offset = CCPoint(_x, _y  );//偏移量
		_parent->setPosition(_offset);
		_parent->setAnchorPoint(CCPoint(0,0));

		for (int i = 0; i tileAt(CCPoint(_x/m_tileSize.width+i,m_mapSize.height-1-_y/m_tileSize.height-j));
				if (_Sprite)
				{

					_Sprite->retain();
					_Sprite->removeFromParent();
					_Sprite->setPosition(_Sprite->getPosition()-_offset);
					_parent->addChild(_Sprite);
					_Sprite->release();

#if 0//测试该物体
					CCMoveBy* action = CCMoveBy::create(1,CCPoint(0,50));
					CCMoveBy* actionR = CCMoveBy::create(1,CCPoint(0,-50));
					CCSequence* seq = CCSequence::create(action, actionR, NULL);
					_Sprite->runAction(CCRepeatForever::create(seq));
#endif

				}

			}
		}

		//设置对象深度
		if (_parent->m_enablePickUp)
		{
			m_map->addChild(_parent, BASE_ZODER - getWorldPositionByMapPosition(m_mapSize).y  );
		}
		else
		{
			m_map->addChild(_parent, BASE_ZODER - _y );
		}
		

	}
} 

void PathSearchInfo::pathFunction( CCPoint point, PathSprite* obj )
{
	if (!m_enableMove)
	{
		return;
	}
	if (point.x m_endX = _sp->m_x;
		obj->m_endY = _sp->m_y;
		//计算路径
		calculatePath();

		resetInspectArray();
		//移动物体
		moveObj();

		//绘制路径
		if (m_isSetDrawPathCallback)
		{
			m_drawPath(m_pathList);
		}
	}

}

void PathSearchInfo::calculatePath()
{
#ifdef PRECISE_SEARCH_PATH
	//得到开始点的节点
	PathSprite*    _endNode= m_inspectArray[m_moveObj->m_startX][m_moveObj->m_startY];
	//得到结束点的节点
	PathSprite*   _startNode = m_inspectArray[m_moveObj->m_endX][m_moveObj->m_endY];

	//因为是开始点 把到起始点的距离设为0, F值也为0
	_startNode->m_costToSource = 0;
	_startNode->m_FValue = 0;

	//把已经检测过的点从检测列表中删除
	m_inspectArray[m_moveObj->m_endX][m_moveObj->m_endY] = NULL;
	//把该点放入已经检测过点的列表中
	m_haveInspectList.push_back(_startNode);
	//然后加入开放列表
	m_openList.push_back(_startNode);

	PathSprite* _node = NULL;
	while (true)
	{
		//得到离起始点最近的点(如果是第一次执行, 得到的是起点)
		_node = getMinPathFormOpenList();
		if (!_node)
		{
			//找不到路径
			break;
		}
		//把计算过的点从开放列表中删除
		removeObjFromOpenList( _node);
		int _x = _node->m_x;
		int _y = _node->m_y;

		//
		if (_x ==m_moveObj->m_startX && _y == m_moveObj->m_startY)
		{
			break;
		}

		//检测8个方向的相邻节点是否可以放入开放列表中


		PathSprite* _adjacent = NULL;




		_adjacent = getObjFromInspectArray(  _x +1, _y);
		inspectTheAdjacentNodes(_node, _adjacent, _endNode);

		_adjacent = getObjFromInspectArray(  _x , _y -1);
		inspectTheAdjacentNodes(_node, _adjacent, _endNode);

		_adjacent = getObjFromInspectArray(  _x -1, _y);
		inspectTheAdjacentNodes(_node, _adjacent, _endNode);

		_adjacent = getObjFromInspectArray(  _x , _y+1);
		inspectTheAdjacentNodes(_node, _adjacent, _endNode);


		_adjacent = getObjFromInspectArray( _x + 1, _y + 1);
		inspectTheAdjacentNodes(_node, _adjacent, _endNode);

		_adjacent = getObjFromInspectArray(  _x +1, _y-1);
		inspectTheAdjacentNodes(_node, _adjacent, _endNode);

		_adjacent = getObjFromInspectArray(  _x -1, _y - 1);
		inspectTheAdjacentNodes(_node, _adjacent, _endNode);

		_adjacent = getObjFromInspectArray(  _x -1, _y+1);
		inspectTheAdjacentNodes(_node, _adjacent, _endNode);


	}

	while (_node)
	{
		//把路径点加入到路径列表中
		//m_pathList.insert(m_pathList.begin(), _node);
		m_pathList.push_back(_node);
		_node = _node->m_parent;
	}
#else

	//得到开始点的节点
	PathSprite*   _startNode = m_inspectArray[m_moveObj->m_startX][m_moveObj->m_startY];
	//得到结束点的节点
	PathSprite*  _endNode = m_inspectArray[m_moveObj->m_endX][m_moveObj->m_endY];

	//因为是开始点 把到起始点的距离设为0, F值也为0
	_startNode->m_costToSource = 0;
	_startNode->m_FValue = 0;

	//把已经检测过的点从检测列表中删除
	m_inspectArray[m_moveObj->m_startX][m_moveObj->m_startY] = NULL;
	//把该点放入已经检测过点的列表中
	m_haveInspectList.push_back(_startNode);
	//然后加入开放列表
	m_openList.push_back(_startNode);

	PathSprite* _node = NULL;
	while (true)
	{
		//得到离起始点最近的点(如果是第一次执行, 得到的是起点)
		_node = getMinPathFormOpenList();
		if (!_node)
		{
			//找不到路径
			break;
		}
		//把计算过的点从开放列表中删除
		removeObjFromOpenList( _node);
		int _x = _node->m_x;
		int _y = _node->m_y;

		//
		if (_x ==m_moveObj->m_endX && _y == m_moveObj->m_endY)
		{
			break;
		}

		//检测8个方向的相邻节点是否可以放入开放列表中


		PathSprite* _adjacent = NULL;




		_adjacent = getObjFromInspectArray(  _x +1, _y);
		inspectTheAdjacentNodes(_node, _adjacent, _endNode);

		_adjacent = getObjFromInspectArray(  _x , _y -1);
		inspectTheAdjacentNodes(_node, _adjacent, _endNode);

		_adjacent = getObjFromInspectArray(  _x -1, _y);
		inspectTheAdjacentNodes(_node, _adjacent, _endNode);

		_adjacent = getObjFromInspectArray(  _x , _y+1);
		inspectTheAdjacentNodes(_node, _adjacent, _endNode);


		_adjacent = getObjFromInspectArray( _x + 1, _y + 1);
		inspectTheAdjacentNodes(_node, _adjacent, _endNode);

		_adjacent = getObjFromInspectArray(  _x +1, _y-1);
		inspectTheAdjacentNodes(_node, _adjacent, _endNode);

		_adjacent = getObjFromInspectArray(  _x -1, _y - 1);
		inspectTheAdjacentNodes(_node, _adjacent, _endNode);

		_adjacent = getObjFromInspectArray(  _x -1, _y+1);
		inspectTheAdjacentNodes(_node, _adjacent, _endNode);


	}

	while (_node)
	{
		//把路径点加入到路径列表中
		m_pathList.insert(m_pathList.begin(), _node);
		//m_pathList.push_back(_node);
		_node = _node->m_parent;
	}
#endif // PRECISE_SEARCH_PATH


}

float PathSearchInfo::calculateTwoObjDistance( PathSprite* obj1, PathSprite* obj2 )
{

	float _x = abs(obj2->m_x - obj1->m_x);
	float _y = abs(obj2->m_y - obj1->m_y);

	return _x + _y;
}

void PathSearchInfo::inspectTheAdjacentNodes( PathSprite* node, PathSprite* adjacent, PathSprite* endNode )
{
	if (adjacent)
	{
		float _x = abs(endNode->m_x - adjacent->m_x);
		float _y = abs(endNode->m_y - adjacent->m_y);

		float F , G, H1, H2, H3;
		adjacent->m_costToSource = node->m_costToSource + calculateTwoObjDistance(node, adjacent);//获得累计的路程
		G = adjacent->m_costToSource;

		//三种算法, 感觉H2不错
		H1 = _x + _y;
		H2 = hypot(_x, _y);
		H3 = max(_x, _y);

#if 1 //A*算法 = Dijkstra算法 + 最佳优先搜索
		F = G + H1;
#endif
#if 0//Dijkstra算法
		F = G;
#endif
#if 0//最佳优先搜索
		F = H2;
#endif
		adjacent->m_FValue = F;

		adjacent->m_parent = node;//设置父节点
		adjacent->m_sprite->setColor(ccORANGE);//搜寻过的节点设为橘色(测试用)
		m_haveInspectList.push_back(adjacent);
		node->m_child = adjacent;//设置子节点

		PathSearchInfo::m_inspectArray[adjacent->m_x][adjacent->m_y] = NULL;//把检测过的点从检测列表中删除
		PathSearchInfo::m_openList.push_back(adjacent);//加入开放列表
	}
}

PathSprite* PathSearchInfo::getMinPathFormOpenList()
{
	if (m_openList.size()>0) {
		PathSprite* _sp =* m_openList.begin();
		for (vector<pathsprite>::iterator iter = m_openList.begin(); iter !=  m_openList.end(); iter++)
		{
			if ((*iter)->m_FValue m_FValue)
			{
				_sp = *iter;
			}
		}
		return _sp;
	}
	else
	{
		return NULL;
	}

}

PathSprite* PathSearchInfo::getObjFromInspectArray( int x, int y )
{
	if (x >=0 && y >=0 && x ::iterator iter = m_openList.begin(); iter !=  m_openList.end(); iter++)
	{
		if (*iter == sprite)
		{
			m_openList.erase(iter);
			return true;
		}
	}
	return false;

}  

cocos2d::CCPoint PathSearchInfo::getMapPositionByWorldPosition( CCPoint point )
{
	return CCPoint((int)(point.x/PathSearchInfo::m_tileSize.width),(int)(PathSearchInfo::m_mapSize.height - point.y/PathSearchInfo::m_tileSize.height) );
}

cocos2d::CCPoint PathSearchInfo::getWorldPositionByMapPosition( CCPoint point )
{
	return CCPoint(PathSearchInfo::m_tileSize.width * point.x, (PathSearchInfo::m_mapSize.height + point.y)*PathSearchInfo::m_tileSize.height);
}

void PathSearchInfo::resetInspectArray()
{
	for (vector<pathsprite>::iterator iter = m_haveInspectList.begin(); iter != m_haveInspectList.end(); iter++)
	{
		//(*iter)->m_sprite->setColor(ccWHITE);
		(*iter)->m_costToSource = 0;
		(*iter)->m_FValue = 0;
		(*iter)->m_parent = NULL;
		(*iter)->m_child = NULL;

		m_inspectArray[(*iter)->m_x][(*iter)->m_y] = (*iter);
	}
}

bool PathSearchInfo::detectWhetherCanPassBetweenTwoPoints( CCPoint p1, CCPoint p2 )
{ 
	float _maxX = p1.x>p2.x?p1.x:p2.x;
	float _maxY = p1.y>p2.y?p1.y:p2.y;
	float _minX = p1.x<p2.x float _miny="p1.y<p2.y?p1.y:p2.y;" if p2.x>1)
		{
			return false;
		}
		float _x = p1.x;
		for (int _y = _minY; _y  1)
		{
			return false;
		}
		float _y = p1.y;
		for (int _x = _minX; _x m_sprite->getPosition());
	CCSprite* _sp = m_road->tileAt(_point);

	if (_sp)
	{
		m_moveObj->m_x = _point.x;
		m_moveObj->m_y = _point.y;
	} 
	else
	{
		CCSprite* _up = m_road->tileAt(_point + CCPoint(0, -1));
		if (_up)
		{
			m_moveObj->m_x = _point.x;
			m_moveObj->m_y = _point.y - 1;
			return;
		}
		CCSprite* _down = m_road->tileAt(_point + CCPoint(0, 1));
		if (_down)
		{
			m_moveObj->m_x = _point.x;
			m_moveObj->m_y = _point.y +1;
			return;
		}
		CCSprite* _left = m_road->tileAt(_point + CCPoint(-1, 0));
		if (_left)
		{
			m_moveObj->m_x = _point.x -1;
			m_moveObj->m_y = _point.y ;
			return;
		}
		CCSprite* _right = m_road->tileAt(_point + CCPoint(1, 0));
		if (_right)
		{
			m_moveObj->m_x = _point.x + 1;
			m_moveObj->m_y = _point.y ;
			return;
		}

	}
#endif // PRECISE
}

void PathSearchInfo::clearPath(  )
{
	
	for (vector<pathsprite>::iterator iter = m_haveInspectList.begin(); iter !=  m_haveInspectList.end(); iter++)
	{
		(*iter)->m_sprite->setColor(ccWHITE);
	}
	resetInspectArray();

	//把移除了障碍物的地图放入检测列表中
	//m_inspectList = m_mapList;
	m_openList.clear();
	m_pathList.clear();
	m_haveInspectList.clear();
	m_moveObj->m_startX = m_moveObj->m_x;
	m_moveObj->m_startY = m_moveObj->m_y;
	m_moveObj->m_sprite->stopAllActions();

	m_playerMoveStep = 0;
}



void PathSearchInfo::moveObj()
{
#ifndef PRECISE_SEARCH_PATH
	m_playerMoveStep++;
	m_isMoving = true;
	//如果运动完毕
	if (m_playerMoveStep >= m_pathList.size())
	{
		if (m_isSetMoveDoneCallback)
		{
			m_isMoving = false;
			m_moveDone(CCPoint((*(m_pathList.end()-1))->m_x, (*(m_pathList.end()-1))->m_y));
		}
		return;
	}
	//存储当前的移动进程
	m_moveObj->m_x = m_pathList[m_playerMoveStep]->m_x;
	m_moveObj->m_y = m_pathList[m_playerMoveStep]->m_y;

	//设置深度
	m_moveObj->m_sprite->setZOrder(BASE_ZODER - m_pathList[m_playerMoveStep]->m_sprite->getPositionY());

	//根据路径列表移动人物
	CCPoint _terminalPosition =  m_pathList[m_playerMoveStep]->m_sprite->getPosition()+m_tileSize/2;
	float _length =  MathLogic::calculateLengthRequiredTwoPoint(_terminalPosition,m_moveObj->m_sprite->getPosition());
	m_moveObj->m_sprite->runAction(CCSequence::create(CCMoveTo::create(MOVE_SPEED * _length,_terminalPosition), CCCallFunc::create(this, SEL_CallFunc(&PathSearchInfo::moveObj)), NULL));
#else
	m_isMoving = true;
	
	if (m_playerMoveStep == m_pathList.size()-1)
	{
		//sitChairJudge();
		if (m_isSetMoveDoneCallback)
		{
			m_isMoving = false;
			m_moveDone(CCPoint((*(m_pathList.end()-1))->m_x, (*(m_pathList.end()-1))->m_y));
		}
		return ;
	}

	for (int i = 1;i m_x, m_moveObj->m_y), CCPoint(m_pathList[m_playerMoveStep]->m_x,m_pathList[m_playerMoveStep]->m_y)))
		{
			CCPoint _terminalPosition = m_pathList[m_playerMoveStep]->m_sprite->getPosition()+m_tileSize/2;
			float _length = MathLogic::calculateLengthRequiredTwoPoint(_terminalPosition,m_moveObj->m_sprite->getPosition());
			m_moveObj->m_sprite->runAction(CCSequence::create(CCMoveTo::create(MOVE_SPEED * _length,_terminalPosition), CCCallFunc::create(this, SEL_CallFunc(&PathSearchInfo::moveObj)), NULL));
			//存储当前的移动进程
			m_moveObj->m_x = m_pathList[m_playerMoveStep]->m_x;
			m_moveObj->m_y = m_pathList[m_playerMoveStep]->m_y;

			m_moveObj->m_sprite->setZOrder(BASE_ZODER - m_pathList[m_playerMoveStep]->m_sprite->getPositionY());

			break;
		}
	}


#endif
}


</pathsprite></p2.x></pathsprite></pathsprite></void></void></void>
登录后复制

#pragma once

#include "cocos2d.h"
#include "vector"
#include "cocos-ext.h"
using namespace std;
USING_NS_CC;
USING_NS_CC_EXT;
class PathSprite 
{
public:
	PathSprite(CCSprite* sprite):m_parent(NULL),
												m_child(NULL),
												m_costToSource(0),
												m_FValue(0),
												m_sprite(sprite),
												m_startX(0),
												m_startY(0),
												m_endX(0),
												m_endY(0)
	{

	};
public:
	CCSprite* m_sprite;//包含的瓦片精灵
	PathSprite* m_parent;//父节点
	PathSprite* m_child;//子节点
	float m_costToSource;//到起始点的距离
	int m_x;//地图坐标
	int m_y;
	float m_FValue;

	int m_startX;//开始点
	int m_startY;

	int m_endX;//结束点
	int m_endY;

};
登录后复制

#pragma once
#include "PathSprite.h"
enum WalkState
{
	WALK_LEFT,
	WALK_RIGHT,
	WALK_STAND
};

class Player:public PathSprite
{
public:
	CCArmature *armature;
	WalkState m_walkState;
public:
	Player(CCSprite* sprite);
public:
	void walkLeft();
	
	void walkRight();

	void stand();
	
	void walking();
};
登录后复制

#include "Player.h"

Player::Player(CCSprite* sprite):PathSprite(sprite)
{
	//创建一个人物
	CCArmatureDataManager::sharedArmatureDataManager()->addArmatureFileInfo("DemoPlayer/DemoPlayer.ExportJson");
	armature = NULL;
	armature = CCArmature::create("DemoPlayer");//0走路,1开枪,2开枪,3开空枪,4
	armature->setAnchorPoint(CCPoint(0.7, 0));

	sprite->addChild(armature);
}

void Player::walkLeft()
{
	if (m_walkState == WALK_LEFT)
	{
		return;
	}
	armature->getAnimation()->playWithIndex(1);
	armature->setScaleX(1);
	m_walkState = WALK_LEFT;
}

void Player::walkRight()
{
	if (m_walkState == WALK_RIGHT)
	{
		return;
	}
	armature->getAnimation()->playWithIndex(1);
	armature->setScaleX(-1);
	m_walkState = WALK_RIGHT;
}

void Player::stand()
{
	if (m_walkState == WALK_STAND)
	{
		return;
	}
	if (m_walkState == WALK_LEFT)
	{
		armature->getAnimation()->playWithIndex(2);
		armature->setScaleX(1);
	}
	if (m_walkState == WALK_RIGHT)
	{
		armature->getAnimation()->playWithIndex(2);
		armature->setScaleX(-1);
	}
	m_walkState = WALK_STAND;
}

void Player::walking()
{
	if (m_endX - m_startX  >=0)
	{
		walkRight();
	}
	else
	{
		walkLeft();
	}
}
登录后复制

#ifndef _PADDLE_H_
#define _PADDLE_H_

#include "cocos2d.h"
#include <functional>
//#include "stdafx.h"
//using namespace std;

USING_NS_CC;

typedef enum tagPaddleState 
{
	kPaddleStateGrabbed,
	kPaddleStateUngrabbed
} PaddleState; 
enum OBJTYPE
{
	NONE_TYPE = 0,
	CHAIR_LEFT = 1,
	CHAIR_FRON = 2 ,
	CHAIR_RIGHT = 3,
	CHAIR_BACK = 4
};
class Paddle : public CCSprite, public CCTargetedTouchDelegate
{
public:
	PaddleState        m_state;
	bool m_isSelect;
	bool m_enableSit;
	bool m_enableTouch;
	bool m_enablePickUp;
	CCPoint m_terminal;
	std::function<void paddle> m_selectCallback;
	OBJTYPE m_type;
	CCSprite* m_playerSprite;
	CCSprite* m_chairPartSprite;
public:
	Paddle(void);
	virtual ~Paddle(void);

	CCRect rect();
	bool initWithTexture();
	virtual void onEnter();
	virtual void onExit();
	bool containsTouchLocation(CCPoint point);
	virtual bool ccTouchBegan(CCTouch* touch, CCEvent* event);
	virtual void ccTouchMoved(CCTouch* touch, CCEvent* event);
	virtual void ccTouchEnded(CCTouch* touch, CCEvent* event);
	virtual CCObject* copyWithZone(CCZone *pZone);

	virtual void touchDelegateRetain();
	virtual void touchDelegateRelease();

	static Paddle* paddleWithContentSize(CCSize);//创建物体

	void setSelect(bool isSelect);//选中时
	void setOpacity(GLubyte opacity);
	void sitChair();//坐下
	void standUp();//站起
	
};

#endif</void></functional>
登录后复制

#include "Paddle.h"
#include "FilePath.h"
using namespace std;
Paddle::Paddle(void):m_chairPartSprite(NULL), m_playerSprite(NULL),m_enableSit(false)
{
}

Paddle::~Paddle(void)
{
}

CCRect Paddle::rect()
{
	CCSize s = this->getContentSize();
	return CCRectMake(this->getPositionX(),  this->getPositionY(), s.width, s.height);
}

Paddle* Paddle::paddleWithContentSize(CCSize size)
{
	Paddle* pPaddle = new Paddle();
	pPaddle->initWithTexture();
	pPaddle->setContentSize(size);

	pPaddle->autorelease();

	return pPaddle;
}

bool Paddle::initWithTexture()
{
	if( CCSprite::init() )
	{
		m_state = kPaddleStateUngrabbed;
	}

	return true;
}

void Paddle::onEnter()
{
	CCDirector* pDirector = CCDirector::sharedDirector();
	pDirector->getTouchDispatcher()->addTargetedDelegate(this, 0, false);
	CCSprite::onEnter();
}

void Paddle::onExit()
{
	CCDirector* pDirector = CCDirector::sharedDirector();
	pDirector->getTouchDispatcher()->removeDelegate(this);
	CCSprite::onExit();
}    

bool Paddle::containsTouchLocation(CCPoint point)
{
	//CCLog("%f, %f", convertToNodeSpaceAR(point).x, convertToNodeSpaceAR(point).y);
	return rect().containsPoint((point));

}

bool Paddle::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
	if (m_isSelect) {
		setSelect(false);

	}
	auto nodePosition = this->getParent()->convertToNodeSpace( touch->getLocation() );
	CCLog("%f, %f", nodePosition.x, nodePosition.y);
	if (m_state != kPaddleStateUngrabbed) return false;
	if ( !containsTouchLocation(nodePosition) ) return false;
	CCLog("touchSuccess")  ;
	m_state = kPaddleStateGrabbed;

	setSelect(true);

	if (m_selectCallback)
	{
		m_selectCallback(m_terminal, this);
	}
	
	//sitChair();
	

	return true;
}

void Paddle::ccTouchMoved(CCTouch* touch, CCEvent* event)
{
	// If it weren't for the TouchDispatcher, you would need to keep a reference
	// to the touch from touchBegan and check that the current touch is the same
	// as that one.
	// Actually, it would be even more complicated since in the Cocos dispatcher
	// you get CCSets instead of 1 UITouch, so you'd need to loop through the set
	// in each touchXXX method.

	CCAssert(m_state == kPaddleStateGrabbed, "Paddle - Unexpected state!");    

	// CCPoint touchPoint = touch->getLocation();

	//setPosition( ccp(touchPoint.x, getPosition().y) );
}

CCObject* Paddle::copyWithZone(CCZone *pZone)
{
	this->retain();
	return this;
}

void Paddle::ccTouchEnded(CCTouch* touch, CCEvent* event)
{
	CCAssert(m_state == kPaddleStateGrabbed, "Paddle - Unexpected state!");    

	m_state = kPaddleStateUngrabbed;
} 

void Paddle::touchDelegateRetain()
{
	this->retain();
}

void Paddle::touchDelegateRelease()
{
	this->release();
}

void Paddle::setSelect(bool isSelect)
{
	CCArray* _array = this->getChildren();
	CCObject *_obj;
	m_isSelect = isSelect;
	CCARRAY_FOREACH(_array, _obj )
	{
		CCSprite* _sp = (CCSprite *)_obj;
		if (isSelect)
		{
			_sp->setColor(ccRED);
		}
		else
		{
			_sp->setColor(ccWHITE);

		}

	}


}

void Paddle::setOpacity( GLubyte opacity )
{
	CCArray* _array = this->getChildren();
	CCObject *_obj;
	CCARRAY_FOREACH(_array, _obj )
	{
		CCSprite* _sp = (CCSprite *)_obj;
		_sp->setOpacity(opacity);
	}
}

void Paddle::sitChair()
{
	switch (m_type)
	{
	case NONE_TYPE:
		break;
	case CHAIR_LEFT:
		{
			m_playerSprite = CCSprite::create(g_chair_left_player);
			m_playerSprite->setAnchorPoint(CCPoint());
			m_playerSprite->setPosition(CCPoint(-8,-15));
			this->addChild(m_playerSprite, 100);

			m_chairPartSprite= CCSprite::create(g_chair_left_part);
			m_chairPartSprite->setAnchorPoint(CCPoint());
			m_chairPartSprite->setPosition(CCPoint(-15,-5));
			this->addChild(m_chairPartSprite, 100);
			break;
		}
	case CHAIR_FRON:
		break;
	case CHAIR_RIGHT:
		break;
	case CHAIR_BACK:
		{

			m_playerSprite = CCSprite::create(g_chair_back_player);
			m_playerSprite->setAnchorPoint(CCPoint());
			m_playerSprite->setPosition(CCPoint(-15,-5));
			this->addChild(m_playerSprite);
			break;
		}
	default:
		break;
	}
}

void Paddle::standUp()
{
	if (m_playerSprite)
	{
		m_playerSprite->removeFromParentAndCleanup(true);
		m_playerSprite = NULL;
	}
	if (m_chairPartSprite)
	{
		m_chairPartSprite->removeFromParentAndCleanup(true);
		m_chairPartSprite = NULL;
	}
}
登录后复制

//
//  MathLogic.h
//  MapGame
//
//  Created by TinyUlt on 14/10/11.
//
//

#ifndef __MapGame__MathLogic__
#define __MapGame__MathLogic__

#include <stdio.h>
#include "cocos2d.h"
USING_NS_CC;
class MathLogic
{
public:
	//线性方程 一元二次方法 求y
	static float linearEquationWithOneUnknown_solveYRequiredX(CCPoint knownPoint1, CCPoint knownPoint2, float x)
	{
		float _x1 = knownPoint1.x;
		float _y1 = knownPoint1.y;
		float _x2 = knownPoint2.x;
		float _y2 = knownPoint2.y;
		float m_p1 = (_y1 -_y2)/(_x1-_x2);
		float m_p2 = _y1 - m_p1 * _x1;
		//         float m_p1 = (knownPoint1.y -knownPoint2.y)/(knownPoint1.x-knownPoint2.x);
		//         float m_p2 = knownPoint1.y - m_p1 * knownPoint1.x;

		return m_p1* x + m_p2;
	}

	//线性方程 一元二次方法 求x
	static float linearEquationWithOneUnknown_solveXRequiredY(CCPoint knownPoint1, CCPoint knownPoint2, float y)
	{
		float _x1 = knownPoint1.x;
		float _y1 = knownPoint1.y;
		float _x2 = knownPoint2.x;
		float _y2 = knownPoint2.y;
		float m_p1 = (_y1 -_y2)/(_x1-_x2);
		float m_p2 = _y1 - m_p1 * _x1;
		//         float m_p1 = (knownPoint1.y -knownPoint2.y)/(knownPoint1.x-knownPoint2.x);
		//         float m_p2 = knownPoint1.y - m_p1 * knownPoint1.x;

		return (y - m_p2)/m_p1;
	}

	//求点到直线最短路径长度
	static float linearEquationWithOneUnknown_solveShortLenghtRequiredPoint(CCPoint knownPoint1, CCPoint knownPoint2, CCPoint point)
	{
		if ((point.x == knownPoint1.x && point.y == knownPoint1.y) || (point.x == knownPoint2.x && point.y == knownPoint2.y))
		{
			return 0;
		}

		float _x1 = knownPoint1.x;
		float _y1 = knownPoint1.y;
		float _x2 = knownPoint2.x;
		float _y2 = knownPoint2.y;
		float m_p1 = (_y1 -_y2)/(_x1-_x2);
		float m_p2 = _y1 - m_p1 * _x1;

		CCPoint p1((point.y - m_p2)/m_p1, point.y);
		CCPoint p2(point.x, m_p1* point.x + m_p2);
		float offsetY = abs( p2.y - point.y);
		float offsetX = abs(p1.x - point.x);

		if (offsetX == 0 && offsetY == 0)
		{
			return 0;
		}


		return offsetX * offsetY / calculateLengthRequiredTwoPoint(p1, p2);
	}

	//计算2点距离
	static float calculateLengthRequiredTwoPoint(CCPoint p1, CCPoint p2)
	{
		float _offsetX = abs( p1.x - p2.x);
		float _offsetY =abs(  p1.y - p2.y);
		return sqrt(_offsetX * _offsetX + _offsetY * _offsetY);
	}

	//绝对值
	static float abs(float value)
	{
		return value>0?value:-value;
	}
};
#endif /* defined(__MapGame__MathLogic__) */
</stdio.h>
登录后复制

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "PathSearchInfo.h"
#include "Player.h"
class Paddle;
class HelloWorld : public cocos2d::CCLayer
{
public:
	// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
	virtual bool init();  

	// there's no 'id' in cpp, so we recommend returning the class instance pointer
	static cocos2d::CCScene* scene();

	// a selector callback
	void menuCloseCallback(CCObject* pSender);

	// implement the "static node()" method manually
	CREATE_FUNC(HelloWorld);
	void onEnter();
	virtual bool ccTouchBegan(CCTouch* touch, CCEvent* event);
	virtual void ccTouchMoved(CCTouch* touch, CCEvent* event);
	virtual void ccTouchEnded(CCTouch* touch, CCEvent* event);

	void drawPath(vector<pathsprite>& vec);//绘制路径(测试用)

	void update(float dt);//跟新大地图(行走时, 人不动, 地图跟着人动);

	void selectObjCallback(CCPoint point, Paddle* selectObj);//选择物体回调

	void moveDone(CCPoint point);//移动结束回调

public:
	PathSearchInfo* m_pathSearch;//寻路引擎类

	CCPoint m_orignPoint;//人物的起始点

	Player* m_player;//人物

	Paddle* m_currentSelect;//当前选中的物品
};
#endif // __HELLOWORLD_SCENE_H__</pathsprite>
登录后复制

#include "HelloWorldScene.h"
#include "Paddle.h"
#include "MathLogic.h"
#include <functional>
USING_NS_CC;


CCScene* HelloWorld::scene()
{
	// 'scene' is an autorelease object
	CCScene *scene = CCScene::create();

	// 'layer' is an autorelease object
	HelloWorld *layer = HelloWorld::create();

	// add layer as a child to scene
	scene->addChild(layer);

	// return the scene
	return scene;
}

// on "init" you need to initialize your instance
void HelloWorld::onEnter()
{
	CCDirector* pDirector = CCDirector::sharedDirector();
	pDirector->getTouchDispatcher()->addTargetedDelegate(this, -1, false);
	CCLayer::onEnter();

}

bool HelloWorld::init()
{
	//////////////////////////////
	// 1. super init first
	if ( !CCLayer::init() )
	{
		return false;
	}
	
	CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
	CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();

	CCTMXTiledMap* _map = CCTMXTiledMap::create("gameMap.tmx");
	_map->setPosition(CCPoint());
	this->addChild(_map);

	m_pathSearch = new PathSearchInfo(_map);

	std::function<void point> _fun = std::bind(&HelloWorld::moveDone,this,std::placeholders::_1);
	m_pathSearch->setMoveDoneCallback(_fun);

	std::function<void>)> _funDrawPath = std::bind(&HelloWorld::drawPath,this,std::placeholders::_1);
	m_pathSearch->setDrawPathCallback(_funDrawPath);

	std::function<void point paddle selectobj> _funcSelect = std::bind(&HelloWorld::selectObjCallback,this,std::placeholders::_1,std::placeholders::_2);  
	m_pathSearch->setSelectCallback(_funcSelect);
	/////////////////////////////
	 
	CCMenuItemSprite* _menuItemSprite = CCMenuItemSprite::create(CCSprite::create("CloseNormal.png"),CCSprite::create("CloseSelected.png"),NULL,this,SEL_MenuHandler(&HelloWorld::menuCloseCallback));
	CCMenu* _menu = CCMenu::create(_menuItemSprite,NULL);
	this->addChild(_menu, 1000);

	m_currentSelect = NULL;

	//m_isMoving = false;
	CCLabelTTF* pLabel = CCLabelTTF::create("A* + tiledMap", "Arial", 24);

	// position the label on the center of the screen
	pLabel->setPosition(ccp(origin.x + visibleSize.width/2, origin.y + visibleSize.height - pLabel->getContentSize().height));

	// add the label as a child to this layer
	this->addChild(pLabel, 1);

	this->scheduleUpdate();

	//设置起始和终点
	m_orignPoint = CCDirector::sharedDirector()->getWinSize()/2 ;//+ CCSize(0, 100);
	
	//创建一个人物
	CCSprite* _sp = CCSprite::create();
	_sp->setScale(0.08);

	m_player = new Player(_sp);
	m_player->m_sprite->setOpacity(100);
	m_pathSearch->getMap()->addChild(m_player->m_sprite, BASE_ZODER);
	m_player->m_sprite->setPosition(m_orignPoint);//设置人物的起始的世界坐标
	m_player->m_startX =m_pathSearch->getMapPositionByWorldPosition(m_orignPoint).x;
	m_player->m_startY =m_pathSearch->getMapPositionByWorldPosition(m_orignPoint).y;
	m_player->m_x = m_player->m_startX;
	m_player->m_y = m_player->m_startY;

	m_pathSearch->initMapObject("desk", "desk");
	m_pathSearch->initMapObject("chairLeft", "chairLeft");
	m_pathSearch->initMapObject("chairFront", "chairFront");
	m_pathSearch->initMapObject("chairBack", "chairBack");
	m_pathSearch->initMapObject("zhuzi", "zhuzi");
	m_pathSearch->initMapObject("goods", "goods");
	return true;
}

void HelloWorld::drawPath( vector<pathsprite>& vec )
{
	for (vector<pathsprite>::iterator iter = vec.begin(); iter !=  vec.end(); iter++)
	{
		(*iter)->m_sprite->setColor(ccGREEN);
	}
}

CCRect getBoundingBox(float x, float y, float width, float height)
{
	return CCRect(x - width/2, y - height/2, width, height);
}

bool HelloWorld::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
	if (m_pathSearch->getEnableMove())
	{
		m_currentSelect = NULL;
		auto nodePosition = convertToNodeSpace( touch->getLocation() );
		m_pathSearch ->pathFunction(m_pathSearch->getMapPositionByWorldPosition(nodePosition),m_player);
	}
	return true;
}

void HelloWorld::ccTouchMoved(CCTouch* touch, CCEvent* event)
{

}

void HelloWorld::ccTouchEnded(CCTouch* touch, CCEvent* event)
{

}

void HelloWorld::menuCloseCallback(CCObject* pSender)
{
	if (!m_pathSearch->getEnableMove())
	{
		m_pathSearch->setEnableMove(true);
		m_currentSelect->standUp();
		m_player->m_sprite->setVisible(true);
	}
}
void HelloWorld::update(float dt)
{
	//移动层
	this->setPosition(m_orignPoint - m_player->m_sprite->getPosition());

	if(m_pathSearch->getIsMoving())
	{
		m_player->walking();
	}
	else
	{
		m_player->stand();
	}
}

void HelloWorld::selectObjCallback( CCPoint point, Paddle* selectObj )
{
	//如果不能移动物体的话, 不能点击其他物体
	if (m_pathSearch->getEnableMove())
	{
		m_currentSelect = selectObj;

		m_pathSearch ->pathFunction( point ,m_player);
	}
}

void HelloWorld::moveDone(CCPoint point)
{
	//判断是有选择的物体
	if (m_currentSelect)
	{
		//判断是否能坐下
		if (m_currentSelect->m_enableSit/* && point.x == m_currentSelect->m_terminal.x&& point.y ==  m_currentSelect->m_terminal.y*/)
		{
			m_currentSelect->sitChair();
			m_pathSearch->setEnableMove(false);
			m_player->m_sprite->setVisible(false);
		}
		//判断是否能捡起
		if (m_currentSelect->m_enablePickUp)
		{
			m_currentSelect->m_enablePickUp = false;
			m_currentSelect->runAction(CCSequence::create(CCFadeOut::create(0.5), CCRemoveSelf::create(true), NULL));
			m_currentSelect = NULL;
		}
	}
}





</pathsprite></pathsprite></void></void></void></functional>
登录后复制

static char* g_chair_left_player = "player_1/chair_left_player.png";
static char* g_chair_back_player = "player_1/chair_back_player.png";
static char* g_chair_left_part = "player_1/chair_left_part.png";
登录后复制

#define MAP_WIDTH 600//要比tmx中的map大1
#define MAP_HEIGHT 600
#define BASE_ZODER 100000
#define MOVE_SPEED 1/200.0

#define PRECISE_SEARCH_PATH//精确的寻 路系统, 需要消耗额外的运算(魔兽争霸级的!)
登录后复制



本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

Conda升级Python版本的几种方法 Conda升级Python版本的几种方法 Feb 18, 2024 pm 08:56 PM

Conda升级Python版本的几种方法,需要具体代码示例概述:Conda是一个开源的包管理器和环境管理系统,用于管理Python包和环境。在使用Python开发过程中,为了使用新版本的Python,我们可能需要从较旧的Python版本升级。本文将介绍使用Conda升级Python版本的几种方法,并提供具体的代码示例。方法一:使用condainstall命

升级numpy版本:详细易学的指南 升级numpy版本:详细易学的指南 Feb 25, 2024 pm 11:39 PM

如何升级numpy版本:简单易懂的教程,需要具体代码示例引言:NumPy是一个重要的Python库,用于科学计算。它提供了一个强大的多维数组对象和一系列与之相关的函数,可用于进行高效的数值运算。随着新版本的发布,不断有更新的特性和Bug修复可供我们使用。本文将介绍如何升级已安装的NumPy库,以获取最新特性并解决已知问题。步骤1:检查当前NumPy版本在开始

win10系统升级后不能上网的处理教程 win10系统升级后不能上网的处理教程 Mar 27, 2024 pm 02:26 PM

1、使用win+x快捷键打开菜单,选择【命令提示符(管理员)(A)】,如下图所示:2、进入到命令提示符界面后,输入【ipconfig/flushdns】命令按回车,如下图所示:3、接着输入【netshwinsockresetcatalog】命令按回车,如下图所示:4、最后输入【netshintipreset】命令按回车,重启电脑就可以上网了,如下图所示:

小红书如何升级为专业号 小红书如何升级为专业号 Mar 01, 2024 pm 04:00 PM

很多朋友表示想知道在小红书里怎样去升级成为专业号,下面为大家介绍一下操作方法,感兴趣的朋友和我一起来看看吧。打开手机上的“小红书”APP,进入后点击右下方的“我的”选项,接着在我的页面中找到左上角的“三条横线”图标并点击打开。2.这时会弹出一个菜单页,在其中点击选择“创作中心”这一项进入。3.接下来在进入的页面里“创作服务”下的选项中找到“更多服务”,并在上面点击进入。4.页面跳转后,在“作者能力”下方的选项里点击“开通专业号“这一项。5.最后在进入的页面里会对小红书专业号进行介绍,在底部点击“

小艺升级为智能体!HarmonyOS NEXT鸿蒙原生智能开启全新AI时代 小艺升级为智能体!HarmonyOS NEXT鸿蒙原生智能开启全新AI时代 Jun 22, 2024 am 01:56 AM

6月21日,华为开发者大会2024(HDC2024)再聚东莞松山湖。本届大会上,最令人关注的莫过于HarmonyOSNEXT正式面向开发者和先锋用户启动Beta,并全方位展示了HarmonyOSNEXT全场景、原生智能和原生安全三大“王炸”级创新特性。HarmonyOSNEXT原生智能:开启全新AI时代放弃安卓框架之后,HarmonyOSNEXT成为真正独立于安卓、iOS的操作系统,堪称是一场史无前例的脱胎换骨。在其众多新特性中,原生智能无疑是最能带给用户直观感受和体验升级的新特性

小米14Pro怎么升级澎湃OS? 小米14Pro怎么升级澎湃OS? Mar 18, 2024 pm 07:34 PM

小米14Pro是小米公司最新推出的旗舰手机,而澎湃OS是小米公司自主研发的全新操作系统,致力于提供更加流畅、智能的用户体验。而随着技术的不断发展,澎湃OS也在不断进行更新和升级。所以很多第一次使用小米手机的用户在问小米14Pro用户如何升级澎湃OS呢?小米14Pro怎么升级澎湃OS不需要更新,原厂自带澎湃OS。其他支持澎湃OS的机型的更新方法:1、打开手机的设置应用,找到系统更新选项。2、系统会自动检测当前的系统版本,在有新版本可供更新时进行提示。3、只需要点击"立即更新",系统就会开始自动下载

怎么升级wps版本?wps office怎么更新版本? 怎么升级wps版本?wps office怎么更新版本? Mar 14, 2024 am 08:43 AM

  wps是很多用户必备的电脑软件,定期更新新版本可以让用户获取更好的使用体验和更多的功能特性。那么wps要怎么升级版本呢?wpsoffice升级主要分为三种方法,下面一起来看看吧。  方法一:从官网下载新版本  你可以在WPSOffice官网上下载最新版本的安装包。进入WPSOffice官网(https://www.wps.cn/)后,点击「下载」按钮,选择你需要下载的版本,然后按照提示安装即可。  注意:安装新版本时,需要卸载旧版本,否则会导致软件冲突,无法正常使用。  方法二:在WPSOf

详解荣耀手机升级到鸿蒙系统的方法 详解荣耀手机升级到鸿蒙系统的方法 Mar 25, 2024 am 11:51 AM

在一片新的科技领域中,新的操作系统总是备受关注。近日,荣耀手机宣布将会升级到华为开发的全新操作系统——鸿蒙系统。对于许多荣耀手机用户来说,这无疑是一大利好消息。但是,很多用户或许对如何升级到鸿蒙系统还存在疑惑。本文将详细解释荣耀手机升级到鸿蒙系统的方法,帮助用户更好地了解并操作。首先,要升级荣耀手机到鸿蒙系统,用户需要保证手机已经连接到网络,并且电量充足。此

See all articles