From: http://www.cocoachina.com/bbs/read.php?tid-209290.html
基于Cocos2d-x3.0集成物理特性的精确点击测试
原作者:
xhcnb
英文论坛原帖:
http://discuss.cocos2d-x.org/t/cocos3-0-tutorial-accurate-hit-testing-with-cocos2d-x-3-0-integrated-physics-feature/13393
Cocos2d-x 3.0版本有一个基于chipmunk的集成物理特效。这非常容易用来作为Cocos2d-x游戏的精确点击测试。
源代码(需要有github账号)
https://github.com/xhcnb/accurate_hit_testing_cocos2d_x_3_0
如何运行起来?
克隆源代码,android的复制cocos2d文件夹下的cocos2d0-x 3.0版本,文档看起来是这样的:
打开proj.ios_mac/PhysicsDemo.xcodeproj 来创建iOS或Mac
运行proj.android/build_native.py 来建立android项目
我已经把编译好的文件放置在“prebuilt编译好的”文件夹中,请检查并测试。
基本原则
这里是一个开源物体躯干编辑器https://code.google.com/p/box2d-editor/ ,
有了这个开放并强有力的工具我们就能得到一个关于精灵物理躯干的多边形边框。然后我们导入多边形边框的数据到游戏中,
让物理引擎处理剩下的事情。
所有我们该做的事就是写一个解析函数,一个能够读取[box2d-editor]导出的文件并载入到cocos2d-x的物理引擎的解析函数。
我们开始吧!
1. 创建新项目:
cocos new -p com.example.phy -l cpp -d ~/Documents PhysicsDemo
2. 在Xcode里打开新项目(我是用的是Xcode,你可以选择你自己喜欢的编译环境)
open ~/Documents/PhysicsDemo/proj.ios_mac/PhysicsDemo.xcodeproj
3. 制作一张测试用的图像,我是下载了cocos2d-x 的商标,从
http://www.cocos2d-x.org/wiki/Logo_Resources_of_Cocos2d-x
将其命名为 2dx.png,把图像添加在项目里。
4. 下载box2d-editor
https://code.google.com/p/box2d-editor/
找到并打开jar类型文件
注意:请使用JRE 6 来运行它。
5. 获得躯干数据
打开编辑器,创建一个新的项目,命名为bodies.json并将其保存在项目的Resource文件夹里。
别忘了添加把bodies.json添加到项目。
创建一个新的躯干定义,并命名为2dx。
使用Auto-trace按钮获得图像的边缘。
保存bodies.json
接下来,我们应该写一些代码来带入bodies.json。
6. 才修改你的场景
编辑方法HelloWorld::createScene 以此启用物理特效。
1
2
3
|
auto
scene = Scene::createWithPhysics();
//enable debug draw
scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
|
把我们的精灵添加到层里。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
// add "2dx.png"
sp_2dx = Sprite::create(
"2dx.png"
);
// position the sprite on the center of the screen
sp_2dx->setPosition(Point(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
//load
MyBodyParser::getInstance()->parseJsonFile(
"bodies.json"
);
//bind physicsbody to sprite
auto
_body = MyBodyParser::getInstance()->bodyFormJson(sp_2dx,
"2dx"
);
if
(_body !=
nullptr
) {
_body->setDynamic(
false
);
//set it static body.
_body->setCollisionBitmask(0x000000);
//don't collision with anybody.
sp_2dx->setPhysicsBody(_body);
}
// add the sprite as a child to this layer
this
->addChild(sp_2dx, 0);
|
MyBodyParser is the helper class to load bodies.json, use rapid json.
MyBodyParser 就是用来读取bodies.json的类,使用快速json。
你能在源码中查询想要的细节,关键函数是MyBodyParser::bodyFormJson。之后添加touchListener,这个过程较为简单并且没有什么值得多费口舌来讲解。
7. 确认是否我们的精灵已经被点击
在函数HelloWorld::nodeUnderTouch中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
Node* HelloWorld::nodeUnderTouch(cocos2d::Touch *touch)
{
Node* node =
nullptr
;
//translate the touch to layer coordinate.
auto
location =
this
->convertTouchToNodeSpace(touch);
//retrive all physics shapes under the touch location though cocos2d-x.
auto
scene = Director::getInstance()->getRunningScene();
auto
arr = scene->getPhysicsWorld()->getShapes(location);
//iterate the shapes, find our sprite!
for
(
auto
& obj : arr)
{
//find it!!!!
if
( obj->getBody()->getNode() == sp_2dx)
{
node = obj->getBody()->getNode();
break
;
}
}
return
node;
}
|
如果这个函数返回nullptr,这意味着你并没有碰触到精灵物理躯干的内部。
这些就是这篇教程所有的奇妙之处了,确认源代码并阅读更多的信息。