首頁 資料庫 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脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 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)

熱門話題

Java教學
1666
14
CakePHP 教程
1425
52
Laravel 教程
1327
25
PHP教程
1273
29
C# 教程
1252
24
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版本在開始

小紅書如何升級為專業號 小紅書如何升級為專業號 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的作業系統,堪稱是一場史無前例的脫胎換骨。在其眾多新特性中,原生智能無疑是最能帶給用戶直覺感受與體驗升級的新特性

win10系統升級後無法上網的處理教學課程 win10系統升級後無法上網的處理教學課程 Mar 27, 2024 pm 02:26 PM

1.使用win+x快速鍵開啟選單,選擇【指令提示字元(管理員)(A)】,如下圖所示:2、進入到指令提示字元介面後,輸入【ipconfig/flushdns】指令按回車,如下圖所示:3、接著輸入【netshwinsockresetcatalog】指令按回車,如下圖所示:4、最後輸入【netshintipreset】指令按回車,重啟電腦就可以上網了,如下圖所示:

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

小米14Pro是小米公司最新推出的旗艦手機,而澎湃OS則是小米公司自主研發的全新作業系統,致力於提供更流暢、智慧的使用者體驗。而隨著技術的不斷發展,澎湃OS也不斷進行更新與升級。所以很多第一次使用小米手機的用戶在問小米14Pro用戶如何升級澎湃OS呢?小米14Pro怎麼升級澎湃OS不需要更新,原廠自備澎湃OS。其他支援澎湃OS的機型的更新方法:1、開啟手機的設定應用,找到系統更新選項。 2、系統會自動偵測目前的系統版本,在有新版本可供更新時進行提示。 3.只需要點擊&quot;立即更新&quot;,系統就會開始自動下載

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

  wps是許多使用者必備的電腦軟體,定期更新新版本可以讓使用者獲得更好的使用體驗和更多的功能特性。那麼wps要怎麼升級版本呢? wpsoffice升級主要分為三種方法,以下一起來看看吧。  方法一:從官網下載新版  你可以在WPSOffice官網上下載最新版本的安裝包。進入WPSOffice官網(https://www.wps.cn/)後,點選「下載」按鈕,選擇你需要下載的版本,然後依照指示安裝即可。  注意:安裝新版本時,需要卸載舊版本,否則會導致軟體衝突,無法正常使用。  方法二:在WPSOf

如何升級Django版本:步驟與注意事項 如何升級Django版本:步驟與注意事項 Jan 19, 2024 am 10:16 AM

如何升級Django版本:步驟和注意事項,需要具體程式碼範例引言:Django是一個功能強大的PythonWeb框架,它持續地進行更新和升級,以提供更好的效能和更多的功能。然而,對於使用較舊版Django的開發者來說,升級Django可能會面臨一些挑戰。本文將介紹如何升級Django版本的步驟和注意事項,並提供具體的程式碼範例。一、備份項目檔案在升級Djan

See all articles