cocos2d之Box2D具体解释 鼠标关节实现

DionysosLai2014-5-7

我们常常要移动物理世界中的某个物体,例如说石头、木块等。假设我们直接改变这些物体的位置,让这些物体尾随我们手指移动,即使这样是可行的,却违反了物理世界的基本规则。这个世界没有“上帝之手”。

换个思路,假设我们要移动物体,那是否说,就是我们要在物体上施加一个某个方向的无穷大的力量。恩,没错。就是这样。

在Box2D中,有一个比較特殊的关节类型:鼠标关节(Mouse Joint),之所以特殊,就是由于它并非物理世界中原生的物体,是来自于用户的操作。鼠标关节,能够试图将物体拖向当前鼠标光标的位置,同一时候在选择方向上没有限制。

使用鼠标关节一般有三个步骤:

1.      创建(在touchBegan中)

2.      改变鼠标关节位置(在touchMove中);

3.      销毁鼠标关节(在touchEnd中)

依照上面步骤:我们一步步创建鼠标关节:

在头文件里创建一个鼠标关节:

b2MouseJoint* m_mouseJoint;

然后在cpp文件里初始鼠标关节为NULL:

m_mouseJoint = NULL;

以下就是创建鼠标关节:

b2Vec2 vec(m_pTouchPoint.x/PTM_RATIO,m_pTouchPoint.y/PTM_RATIO);
// b2Vec2 vec = b2Vec2(touchPoint.x,touchPoint.y); if(m_mouseJoint != NULL)
{
return false;
} // Make a small box.
b2AABB aabb;
b2Vec2 d;
d.Set(0.001f, 0.001f);
aabb.lowerBound = vec - d;
aabb.upperBound = vec + d; b2BodyDef bodyDef;
b2Body *m_groundBody = m_world->CreateBody(&bodyDef); // Query the world for overlapping shapes.
QueryCallback callback(vec);
m_world->QueryAABB(&callback, aabb); if (callback.m_fixture)
{
b2Body* body = callback.m_fixture->GetBody();
b2MouseJointDef md;
md.bodyA = m_groundBody;//一般为世界边界
md.bodyB = body;//须要拖动的物体
md.target = vec;
md.maxForce = 1000.0f * body->GetMass();
m_mouseJoint = (b2MouseJoint*)m_world->CreateJoint(&md);
body->SetAwake(true); CCLog("touch bengin \n"); return true;
}
return false;

在这里。调用了一个回调函数。因此必须在头文件里,新建一个类:

class QueryCallback : public b2QueryCallback
{
public:
QueryCallback(const b2Vec2& point)
{
m_point = point;
m_fixture = NULL;
} bool ReportFixture(b2Fixture* fixture)
{
b2Body* body = fixture->GetBody();
if (body->GetType() == b2_dynamicBody)
{
bool inside = fixture->TestPoint(m_point);
if (inside)
{
m_fixture = fixture; // We are done, terminate the query.
return false;
}
} // Continue the query.
return true;
} b2Vec2 m_point;
b2Fixture* m_fixture;
};

这里要注意一个问题,就是设置鼠标关节边界时:

md.bodyA= m_groundBody;//一般为世界边界

md.bodyB= body;//须要拖动的物体

md.bodyA是我们的世界

以下就是在touchMove中改变鼠标关节的属性,代码例如以下:

m_iTouchType = TOUCH_MOVE;
CCPoint point = pTouch->getLocation();
m_pTouchPoint = point; if(m_mouseJoint == NULL )
return; b2Vec2 vecMouse;
vecMouse.Set((m_pTouchPoint.x)/PTM_RATIO, (m_pTouchPoint.y)/PTM_RATIO);
//改变关节位置.
m_mouseJoint->SetTarget(vecMouse);

最后一个当我们手指离开屏幕时。我们要销毁我们所创建的鼠标关节。在ccTouchEnded增加例如以下代码:

m_iTouchType = TOUCH_END;
CCPoint point = pTouch->getLocation();
m_pTouchPoint = point;
CCLOG("%f, %f", point.x, point.y); //销毁关节.
if(m_mouseJoint != NULL)
{
m_world->DestroyJoint(m_mouseJoint);
m_mouseJoint =NULL;
}

好。到现在为止一切ok该。

版权声明:本文博主原创文章。博客,未经同意不得转载。

cocos2d之Box2D详细说明 鼠标联合实现的更多相关文章

  1. cocos2d中box2d讲解一

    在游戏中我们经常要加入物理碰撞等和物理有关的内容,在游戏中加入物理引擎可以使我们的游戏更加真实,为玩家展示一个更真实的世界,cocos2d-x支持两个物理引擎Box2d和Chipmunk,本文介绍bo ...

  2. Cocos2d学习之路五(Box2d使用CCPhysicsSprite时编译不通过解决方法)

    cocos2d使用box2d引擎,在使用CCPhysicsSprite添加精灵的时候会出现编译不通过错误. 需要注意以下几点: 1.sprite.position=ccp(p.x,p.y);这行代码一 ...

  3. Opencv函数setMouseCallback鼠标事件响应

    用户通过鼠标对图像视窗最常见的操作有: 1. 左键单击按下 2. 左键单击抬起 3. 左键按下拖动 4. 鼠标指针位置移动 单次单击操作响应事件及顺序 Opencv中setMouseCallback( ...

  4. 深入理解DOM事件类型系列第一篇——鼠标事件

    × 目录 [1]类型 [2]顺序 [3]坐标位置[4]修改键[5]相关元素[6]鼠标按键[7]滚轮事件[8]移动设备 前面的话 鼠标事件是web开发中最常用的一类事件,毕竟鼠标是最主要的定位设备.本文 ...

  5. js鼠标滚轮事件

    不多说,直接上代码. //非ie document.body.onmousewheel = function(event) { event = event || window.event; conso ...

  6. opencv2 使用鼠标绘制矩形并截取和保存矩形区域图像

    前言 好长时间没写博文了,今天偷偷懒写篇关于opencv2中鼠标响应操作的文章. 鼠标操作属于用户接口设计,以前一直使用Qt来做,但是如果只需要简单的鼠标,键盘操作,直接调用opencv库的函数也未尝 ...

  7. Visual Studio 2012下Box2D开发环境设置

    Cocos2d-x 3.x默认情况下采用的物理引擎是Chipmunk,如果我们要使用Box2D引擎,需要进行一些设置和调整,而且不同的开发平台下这些设置也有所不同.由于本书在此之前介绍的都是基于微软的 ...

  8. opencv鼠标操作及GUI矩形绘画

    OpenCV的鼠标操作是通过一个中介函数配合回调函数来实现的.指定鼠标操作消息回调函数的函数为SetMouseCallback. void setMouseCallback(const string& ...

  9. opencv——感兴趣区域(ROI)的分析和选取[详细总结]

    引言 在利用OpenCV对图像进行处理时,通常会遇到一个情况,就是只需要对部分感兴趣区域进行处理.因此,如何选取感兴趣区域呢?(其实就是"抠图"). 在学习opencv的掩码运算后 ...

随机推荐

  1. JNI生成C的头文件

    最近再给android封装一个C语言的so,以供安卓程序下使用. 再次记录一下,防止以后忘记了. 首先下载安装JDK,下载地址:http://www.oracle.com/technetwork/ja ...

  2. WM_CLOSE、WM_DESTROY、WM_QUIT学习总结(点击关闭按钮会触发WM_CLOSE消息,DestroyWindow API会触发WM_DESTROY和WM_NCDESTROY消息,MSDN上写的很清楚)

    WM_CLOSE:关闭应用程序窗口 WM_DESTROY:关闭应用程序 WM_QUIT:关闭消息循环 只有关闭了消息循环,应用程序的进程才真正退出(在任务管理器里消失). win32应用程序的完整退出 ...

  3. [Android]Eclipse的使用

    1.取消Eclipse拼写检查 General -> Editors -> Text Editors -> Spelling 取消enable spell checking 前面的勾 ...

  4. Django学习之manage.py使用

    1.django-admin.py startproject mysite 开始一个项目,会初始化一些项目的结构文件 2.python manage.py runserver ip:port 如: p ...

  5. Spring3.0官网文档学习笔记(一)

    Part 1 Spring框架概述 Spring是模块化的,在应用中仅仅须要引入你所须要用到的模块的jar包,其余的jar包不用引入. spring框架支持声明式的事务管理,通过RMI或web ser ...

  6. form表单中的 action=./?> 是什么意思

    ./代表当前目录,?代表查询字符串为空 action="" //一般可以为空的,这里的双引号都要有的,表示提单提交给自己(也就是当前页处理)action="a.php&q ...

  7. poj1087(最大流)

    传送门:A Plug for UNIX 题意:有插座用电器和适配器,用电器有插头,适配器本身有一个插孔和插头,它的作用是可以把别的插头插入到适合该适配器插孔的适配器,然后就可以用适配器的插头接到适合的 ...

  8. fastdfs storage server的设计与实现

     fastdfs是一个针对互联网应用设计的分布式文件系统.具有架构简单.结构清晰.代码量小等特点. 详细的介绍及架构请參考分布式文件系统FastDFS架构剖析(http://www.program ...

  9. hdu4405(概率dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4405 题意:跳棋有0~n个格子,每个格子X可以摇一次色子,色子有六面p(1=<p<=6), ...

  10. LaTeX中表格多行显示的最简单设置方法

    这事实上是一个非常easy的问题,可是这两天发现我之前的解决方式太麻烦了.简介一下这样的最简单的方法: 之前设置多行显示的时候,用类似于以下这样的方法进行多行显示: \begin{table} \ne ...