程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++11代碼展示:簡單的手勢識別和響應,上下左右

C++11代碼展示:簡單的手勢識別和響應,上下左右

編輯:關於C++

因為這個是跑酷類游戲的代碼,所以向左向右就按照正常的邏輯,上下滑動本來應該是要執行跳躍操作的,暫時場景屬於靜止狀態,所以先邏輯暫時未拉動攝像機前後移動。

 

C++11的lambda函數實現,用於STL中比較操作。

雖然我明知當前的3D投影視角的攝像機只有一台,對應的pRenderNode查找到的cameraMask的值是camera3D->setCameraFlag(CameraFlag::USER3);設置的,但是以後增加camera做雙攝像機操作就會很方便啦。

 

我打算把這次的跑酷實現為,角色模型和攝像機模型完成跳躍操作,主場景只負責動態加載。

攝像機的操作暫時比較簡單,每秒固定的位移。

主要的問題在於角色移動有點小問題,角色向前移動的過程中增加一個跳躍操作,這個時候需要動畫融合(模型不支持就忽略),物理位移軌跡為雙動作,然後切回普通的步行操作。

 

手勢識別中默認為單點觸控的識別模式,先記錄上一次敲擊點,在觸摸確定為非cancel狀態,即end時候,調用此手勢。取兩點的向量法向,和正右方法向做點乘,正負號可確認偏上下操作。根據左右偏向對比閥值,優先識別為左右滑動操作。

 

 

void PlayerInputController::reveiveTouchBegin(Vec2 pos, Node * pRenderNode)
{
	this->_touchBeginPos = std::move(pos);
}

void PlayerInputController::reveiveTouchEnd(Vec2 pos, Node * pRenderNode)
{
	this->_touchEndPos = std::move(pos);

	Vec2 diff = _touchEndPos - _touchBeginPos;

	diff.normalize();

	auto temp = Vec2(1, 0);//horizontal line

	auto result = Vec2::dot(diff, temp);

	//轉向動作抖動閥值,偏移絕對量大於閥值才認定為有效的左右移動
	const float Threshold = std::sqrt(2) / 2;//假如剛好移動方向和水平方位處於45度角(-135°)時,點乘值為sqrt(2)/2,即平行四邊形的面積

	if (std::abs(result) > Threshold)
	{
		if (result > 0) // right
		{
			//可以移動 且 不是正執行左右移動操作 Gets an action from the running action list by its tag.
			if (_pPlayer->getCurPlayerSprite()->getPositionX() <= MIDDLE_LINE_POS_X
				&& !_pPlayer->getCurPlayerSprite()->getActionByTag(TURN_LEFT)
				&& !_pPlayer->getCurPlayerSprite()->getActionByTag(TURN_RIGHT)
				)
			{
				auto action = MoveBy::create(0.2f, Vec3(10, 0, 0));
				action->setTag(TURN_RIGHT);
				this->_pPlayer->getCurPlayerSprite()->runAction(action);
			}
		}
		else //left
		{
			//可以移動 且 不是正執行左右移動操作 Gets an action from the running action list by its tag.
			if (_pPlayer->getCurPlayerSprite()->getPositionX() >= MIDDLE_LINE_POS_X
				&& !_pPlayer->getCurPlayerSprite()->getActionByTag(TURN_LEFT)
				&& !_pPlayer->getCurPlayerSprite()->getActionByTag(TURN_RIGHT)
				)
			{
				auto action = MoveBy::create(0.2f, Vec3(-10, 0, 0));
				action->setTag(TURN_LEFT);
				this->_pPlayer->getCurPlayerSprite()->runAction(action);
			}
		}
	}
	else //up or down
	{

#define MOVE_FORWARD(POS_X) 
		auto cameraMask = _pPlayer->getCurPlayerSprite()->getCameraMask();
		
		std::vector cameras = pRenderNode->getScene()->getCameras();
		
		auto func = [cameraMask](decltype(*cameras.begin()) targetCamera) ->bool
		{
			return ((unsigned short)targetCamera->getCameraFlag() & cameraMask) != 0;
		};
		
		auto it = std::find_if(cameras.begin(), cameras.end(), func);
		while (it != cameras.end())
		{
			auto temp = (*it)->getPosition3D();
			temp.add(Vec3(0, 0, POS_X));
			(*it)->setPosition3D(temp);
			std::find_if(++it, cameras.end(), func);
		}

		if (diff.y > 0)
		{
			MOVE_FORWARD(-5);
		}
		else
		{
			MOVE_FORWARD(5);
		}
	}
}


 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved