Cocos2d-X游戏【泰然网《跑酷》】JS到C++移植7:Gesture Recognizer【手势识别】
2013-12-17 20:47
603 查看
尊重开发者的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/17382889
<捕鱼达人>回顾
【cocos2d-x
IOS游戏开发-捕鱼达人1】内容介绍
<城市跑酷>回顾
【cocos2d-x
IOS游戏开发-城市跑酷1】跑酷游戏介绍
上节回顾
Cocos2d-X游戏【泰然网《跑酷》】JS到C++移植6:Running This Way
到目前为止runner可以向前移动。在给runner添加用户控制前,你需要处理玩家的输入。
在游戏中我们用跳上、跳下和转圈这三个手势来控制runner。
$1 Unistroke Recognizer是一个开源库。支持包含花圈在内的16个手势识别,有javaScript版本,可以很容易的导入到Cocos2dx JSB项目里,这也正是泰然网的处理方式。
还有一个C++版的【GeometricRecognizer】,http://depts.washington.edu/aimgroup/proj/dollar/others/cpp.bw.zip
但是它有个缺点:很难区分向上滑动和向下滑动。必须由你自己去识别这两个手势。
Simple Recognizer
Simple Recognizer可以识别简单手势包括swipe up, swipe down, swipe left and swipe right.
创建一个名为“SimpleRecognizer.cpp”的cpp文件。替代内容如下:
然后:Integrated into the PlayLayer
定义新的类成员变量
跳转到函数init()在this->initPhysics()后面添加下面的代码
打开这个层的触摸事件,并设置为一次只反馈一个触摸点的kCCTouchesOneByOne模式。
接着扩展触屏处理,添加下面代码到PlayLayer:
bool PlayScene::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
CCLOG("PlayScene::ccTouchBegan");
CCPoint pos = touch->getLocation();
recognizer->beginPoint(pos.x, pos.y);
return true;
}
void PlayScene::ccTouchMoved(CCTouch* touch, CCEvent* event)
{
//CCLOG("PlayScene::ccTouchMoved");
#if 1
CCPoint pos = touch->getLocation();
recognizer->movePoint(pos.x, pos.y);
#else
CCPoint location = touch->getLocation();
Point2D p_Point2DTemp;
p_Point2DTemp.x = location.x;
p_Point2DTemp.y = location.y;
//记录
p_2dPath.push_back(p_Point2DTemp);
#endif
}
void PlayScene::ccTouchEnded(CCTouch* touch, CCEvent* event)
{
CCLOG("PlayScene::ccTouchEnded");
#if 1
SimpleGestures rtn = recognizer->endPoint();
switch (rtn) {
case SimpleGesturesUp:
CCLOG("Runner::jump");
break;
case SimpleGesturesDown:
CCLOG("Runner::crouch");
break;
case SimpleGesturesNotSupport:
case SimpleGesturesError:
// try dollar Recognizer
// 0:Use Golden Section Search (original)
// 1:Use Protractor (faster)
CCLOG("not support or error touch,use geometricRecognizer!!");
#if 0
//通过GeometricRecognizer校准
//可以选择屏蔽玩家单击操作
if (p_2dPath.size() < 1){
return ;
}
RecognitionResult r = geometricRecognizer->recognize(p_2dPath);
if((r.name != "Unknown") && (r.score > 0.5))
{
if (r.name == "Circle")
//开启runner无敌模式//return;}#endifbreak;}#endif}
void PlayScene::ccTouchCancelled(CCTouch* touch, CCEvent* event)
{CCLOG("onTouchCancelled!!!");}
一些注意事项:
1、在初始化的地方new一个GeometricRecognizer实例recognizer_,调用recognizer_->loadTemplates()方法。注意这个函数只是测试时使用,真正设计时,其手势模板应该是从配置文件中读取。
2、在TouchMove(或者是MouseMove,依平台而定)的时候将坐标push_back到一个集合里(touch_points_)。
3、在TouchEnd的时候调用: RecognitionResult r = recognizer_->recognize(touch_points_);
我们对其返回的结果进行判断,如果(r.name != "Unknown" && r.score > 0.5),那么这就是我们识别出来的一个手势。name是手势模板名称,score是其权重,越高则与模板越匹配。
到现在为止,你就可以支持手势识别了:
简单的识别器 识别 速度超过GeometricRecognizer。由它先识别swipe up 和 swipe down。 如果它不能识别,再使用$1 Unistroke Recognizer。
调试并运行,尝试swipe up, swipe down ,画一个圆。你将看到生成的日志。
<捕鱼达人>回顾
【cocos2d-x
IOS游戏开发-捕鱼达人1】内容介绍
<城市跑酷>回顾
【cocos2d-x
IOS游戏开发-城市跑酷1】跑酷游戏介绍
上节回顾
Cocos2d-X游戏【泰然网《跑酷》】JS到C++移植6:Running This Way
到目前为止runner可以向前移动。在给runner添加用户控制前,你需要处理玩家的输入。
在游戏中我们用跳上、跳下和转圈这三个手势来控制runner。
$1 Unistroke Recognizer是一个开源库。支持包含花圈在内的16个手势识别,有javaScript版本,可以很容易的导入到Cocos2dx JSB项目里,这也正是泰然网的处理方式。
还有一个C++版的【GeometricRecognizer】,http://depts.washington.edu/aimgroup/proj/dollar/others/cpp.bw.zip
但是它有个缺点:很难区分向上滑动和向下滑动。必须由你自己去识别这两个手势。
Simple Recognizer
Simple Recognizer可以识别简单手势包括swipe up, swipe down, swipe left and swipe right.
创建一个名为“SimpleRecognizer.cpp”的cpp文件。替代内容如下:
#include "SimpleRecognizer.h" #define MAX_DOUBLE std::numeric_limits<double>::max(); // class define SimpleRecognizer::SimpleRecognizer() { this->result = SimpleGesturesError; } // be called in onTouchBegan void SimpleRecognizer::beginPoint(double x, double y) { this->result = SimpleGesturesError; points.push_back(Point(x,y)); } // be called in onTouchMoved void SimpleRecognizer::movePoint(double x, double y) { points.push_back(Point(x, y)); if (result == SimpleGesturesNotSupport) { return; } SimpleGestures newRtn = SimpleGesturesError; int len = this->points.size(); //每当触点移动时,在当前触点和之前触点之间计算不同的x坐标和y坐标 double dx = this->points[len - 1].x - this->points[len - 2].x; double dy = this->points[len - 1].y - this->points[len - 2].y; if (abs(dx) > abs(dy)) { //在这种情况下,运动趋势的触点在x轴方向 if (dx > 0) { newRtn = SimpleGesturesRight; } else { newRtn = SimpleGesturesLeft; } } else { //在这种情况下,运动趋势的触点在y轴方向 if (dy > 0) { newRtn = SimpleGesturesUp; } else { newRtn = SimpleGesturesDown; } } // first set result if (result == SimpleGesturesError) { result = newRtn; return; } // if diretcory change, not support Recongnizer if (result != newRtn) { result = SimpleGesturesNotSupport; } } SimpleGestures SimpleRecognizer::endPoint() { if (this->points.size() < 3) { return SimpleGesturesError; } return result; } std::vector<Point>& SimpleRecognizer::getPoints() { return points; }
然后:Integrated into the PlayLayer
定义新的类成员变量
SimpleRecognizer *recognizer; GeometricRecognizer* geometricRecognizer;//使用GeometricRecognizer Path2D p_2dPath;
跳转到函数init()在this->initPhysics()后面添加下面的代码
// enable touch this->setTouchEnabled(true); // set touch mode to kCCTouchesOneByOne this->setTouchMode(kCCTouchesOneByOne); //自己扩展的简单手势识别 recognizer = new SimpleRecognizer(); //加载模板然后记录触摸操作(玩家在手机上所做手势的路径) geometricRecognizer = new GeometricRecognizer; geometricRecognizer->loadTemplates();You enable the touch of the layer, and set touch mode to kCCTouchesOneByOne, which receive touch point one at a time in event callbacks.
打开这个层的触摸事件,并设置为一次只反馈一个触摸点的kCCTouchesOneByOne模式。
接着扩展触屏处理,添加下面代码到PlayLayer:
bool PlayScene::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
CCLOG("PlayScene::ccTouchBegan");
CCPoint pos = touch->getLocation();
recognizer->beginPoint(pos.x, pos.y);
return true;
}
void PlayScene::ccTouchMoved(CCTouch* touch, CCEvent* event)
{
//CCLOG("PlayScene::ccTouchMoved");
#if 1
CCPoint pos = touch->getLocation();
recognizer->movePoint(pos.x, pos.y);
#else
CCPoint location = touch->getLocation();
Point2D p_Point2DTemp;
p_Point2DTemp.x = location.x;
p_Point2DTemp.y = location.y;
//记录
p_2dPath.push_back(p_Point2DTemp);
#endif
}
void PlayScene::ccTouchEnded(CCTouch* touch, CCEvent* event)
{
CCLOG("PlayScene::ccTouchEnded");
#if 1
SimpleGestures rtn = recognizer->endPoint();
switch (rtn) {
case SimpleGesturesUp:
CCLOG("Runner::jump");
break;
case SimpleGesturesDown:
CCLOG("Runner::crouch");
break;
case SimpleGesturesNotSupport:
case SimpleGesturesError:
// try dollar Recognizer
// 0:Use Golden Section Search (original)
// 1:Use Protractor (faster)
CCLOG("not support or error touch,use geometricRecognizer!!");
#if 0
//通过GeometricRecognizer校准
//可以选择屏蔽玩家单击操作
if (p_2dPath.size() < 1){
return ;
}
RecognitionResult r = geometricRecognizer->recognize(p_2dPath);
if((r.name != "Unknown") && (r.score > 0.5))
{
if (r.name == "Circle")
//开启runner无敌模式//return;}#endifbreak;}#endif}
void PlayScene::ccTouchCancelled(CCTouch* touch, CCEvent* event)
{CCLOG("onTouchCancelled!!!");}
一些注意事项:
1、在初始化的地方new一个GeometricRecognizer实例recognizer_,调用recognizer_->loadTemplates()方法。注意这个函数只是测试时使用,真正设计时,其手势模板应该是从配置文件中读取。
2、在TouchMove(或者是MouseMove,依平台而定)的时候将坐标push_back到一个集合里(touch_points_)。
3、在TouchEnd的时候调用: RecognitionResult r = recognizer_->recognize(touch_points_);
我们对其返回的结果进行判断,如果(r.name != "Unknown" && r.score > 0.5),那么这就是我们识别出来的一个手势。name是手势模板名称,score是其权重,越高则与模板越匹配。
到现在为止,你就可以支持手势识别了:
简单的识别器 识别 速度超过GeometricRecognizer。由它先识别swipe up 和 swipe down。 如果它不能识别,再使用$1 Unistroke Recognizer。
调试并运行,尝试swipe up, swipe down ,画一个圆。你将看到生成的日志。
相关文章推荐
- Cocos2d-X游戏【泰然网《跑酷》】JS到C++移植4:游戏主场景的介绍
- Cocos2d-X游戏【泰然网《跑酷》】JS到C++移植1:环境搭建及Parkour介绍
- Cocos2d-X游戏【泰然网《跑酷》】JS到C++移植8: Jumping and Crouching
- Cocos2d-X游戏【泰然网《跑酷》】JS到C++移植2:如何新建一个项目,引擎目录结构介绍
- Cocos2d-X游戏【泰然网《跑酷》】JS到C++移植11:添加金币和障碍物到地图中
- Cocos2d-X游戏【泰然网《跑酷》】JS到C++移植5:初始化物理世界【Chipmunk】
- Cocos2d-X游戏【泰然网《跑酷》】JS到C++移植9:Map Loop【地图循环加载】
- Cocos2d-X游戏【泰然网《跑酷》】JS到C++移植10:Adding Coins and Rocks【添加金币和障碍物】
- Cocos2d-X游戏【泰然网《跑酷》】JS到C++移植6:Running This Way
- Cocos2d-X游戏【泰然网《跑酷》】JS到C++移植3:游戏主菜单界面的实现
- cocos2d-x游戏开发 跑酷(五) 跳起和下蹲动作 手势识别
- cocos2d-x游戏开发 跑酷(五) 跳起和下蹲动作 手势识别
- cocos2d-JS跑酷游戏实战笔记2
- cocos2d-x 3.0游戏实例学习笔记 《跑酷》移植到android手机
- cocos2d-js跑酷游戏实战笔记1
- Cocos2d-JS 贝塞尔曲线根据时间设定即时坐标位置 C++到JS 绑定实现(联网游戏客户端Bezier同步功能实现)
- Cocos2d-x游戏移植到WP8之路 -- c++和c#交互
- Cocos2d-x游戏移植到WP8之路 -- c++和c#交互
- cocos2d-x 3.0游戏实例学习笔记 《跑酷》移植到android手机
- cocos2dx游戏开发之利用多点触摸(实现缩放功能或者简单的手势识别)