实现Kinect摄影机前的玩家的移动同步控制游戏人物的移动。玩家向左移动,游戏人物向左移动。
Kinect获取数据流接口为:Sensor→Source→Reader→Frame→Data
1.打开Kinect传感器:
hResult = GetDefaultKinectSensor(&pSensor);//获取一个设备
hResult = pSensor->Open();//打开一个设备
2.获取彩色图像帧
hResult = pSensor->get_ColorFrameSource(&pColorSource);
hResult = pColorSource->OpenReader(&pColorReader);
hResult = pColorSource->get_FrameDescription(&pColorDescription);
在使用阅读器时需要判断ID是否追踪,用到了骨骼数据,需要打卡骨骼帧源
3.打开骨骼帧源
IBodyFrameSource* pBodyFrameSource = nullptr;
if (SUCCEEDED(hResult))
{
hr = pSensor->get_BodyFrameSource(&pBodyFrameSource);//得到骨骼帧源
}
if (SUCCEEDED(hr))
{
hr = pBodyFrameSource->OpenReader(&m_pBodyFrameReader);//骨骼帧源打开骨骼帧源读取器
}
在Kienct里所获取的每一个对象都需主动释放,否则无法获取其他变量。
template
inline void SafeRelease(Interface *& pInterfaceToRelease)
{
if (pInterfaceToRelease != NULL){
pInterfaceToRelease->Release();
pInterfaceToRelease = NULL;
}
}
微软提供人脸加框函数,可以利用其获取坐标,每次移动都需要记录其坐标,计算前后坐标数据变化,将参数传给游戏中的人物。
hr = pFaceFrameResult->get_FaceBoundingBoxInColorSpace(&faceBox);//Kinect对人脸进行加框的函数
pt1 = Point(faceBox.Left, faceBox.Top);
pt2 = Point(faceBox.Right, faceBox.Bottom);
参数计算(这里只用到顶点,也可以选择矩形中心)
move_change =(pt1.x - move_f)*0.5;
move_f = pt1.x;
manage.bear.BearPos.x+= move_change;
跳跃实现,只需要用到坐标的Y轴
high_change =(pt1.y - move_h);
move_h = pt1.y;
if(high_change > 10 )
manage.bear.BearPos.y+= move_h;
手势识别
描述:玩家挥3次手开始游戏。
在更新骨骼数据时,确定手腕和手肘的位置,并判断其位置变化。
//骨骼信息更新代码
if(m_pBodyFrameReader != nullptr)
{
IBodyFrame* pBodyFrame = nullptr;
hr =m_pBodyFrameReader->AcquireLatestFrame(&pBodyFrame);
if (SUCCEEDED(hr))
{
hr =pBodyFrame->GetAndRefreshBodyData(BODY_COUNT, ppBodies);
}
SafeRelease(pBodyFrame);
}
记录玩家右手手部和手肘位置的两块骨骼坐标,Kinect捕捉到的动作使用的是3D空间坐标,需要将其转化为2D的深度图。利用转换函数MapCameraPointToDepthSpace()
for (int j = 0;j < _countof(joints); ++j)
{
bodyPoint =joints[j].Position;
pCoordinateMapper->MapCameraPointToDepthSpace(bodyPoint,&depthPoint);
jointPoints[j].Y= static_cast
}
r_wr_y =jointPoints[JointType_WristRight].Y;
r_el_y =jointPoints[JointType_ElbowRight].Y;
比较前后两次的位置变化,判断挥手动作,用count变量来统计玩家的挥手次数,当玩家挥手次数大于3次就开始游戏。
if (r_wr_y <=r_el_y) r_hand_s = 1;
if (r_hand_s ==1 && r_wr_y>r_el_y)
{
r_hand_s = 0;
count++;
}
if (count>3)
{
Level = 1;
cvDestroyWindow("关卡选择");
}