lufy's legend
标题:
实现Box2D刚体跟随鼠标移动
[打印本页]
作者:
yorhomwang
时间:
2014-7-30 18:12
标题:
实现Box2D刚体跟随鼠标移动
今天有位朋友问我如何实现刚体跟随鼠标移动,先开始我理解错了,就说用LSprite的setBodyMouseJoint函数,可是他说他要的效果不是拖动,而是直接跟随,也就是说当鼠标没有按下,只在界面上移动时,刚体也跟着移动。我首先想到了用b2Body的SetPosition来实现,具体的代码如下:
<!DOCTYPE html>
<html>
<head>
<title>刚体跟随鼠标</title>
<meta charset="utf-8">
<script type="text/javascript" src="./lufylegend-1.9.0.js"></script>
<script type="text/javascript" src="./Box2dWeb-2.1.a.3.min.js"></script>
<script type="text/javascript">
LInit(30, "mylegend", 800, 480, main);
var loopIndex = 0, loopFrame = 5;
var mainBodyLayer = null;
function main () {
LGlobal.setDebug(true);
LGlobal.box2d = new LBox2d();
var backLayer = new LSprite();
backLayer.graphics.drawRect(3, "black", [0, 0, LGlobal.width, LGlobal.height]);
addChild(backLayer);
var w = 150, h = 50;
mainBodyLayer = new LSprite();
mainBodyLayer.x = (LGlobal.width - w) * 0.5;
mainBodyLayer.y = (LGlobal.height - h) * 0.5;
mainBodyLayer.addBodyPolygon(w, h);
backLayer.addChild(mainBodyLayer);
backLayer.addEventListener(LMouseEvent.MOUSE_MOVE, onMouseMove);
backLayer.addEventListener(LEvent.ENTER_FRAME, loop);
}
function onMouseMove (event) {
var backLayer = event.currentTarget,
b = mainBodyLayer.box2dBody,
lb = LGlobal.box2d,
scale = lb.drawScale,
vec = new lb.b2Vec2(event.offsetX / scale, event.offsetY / scale);
b.SetPosition(vec);
}
function loop (event) {
var backLayer = event.currentTarget;
for (var i = 0; i < backLayer.childList.length; i++) {
var o = backLayer.childList[i];
if ((o.y > LGlobal.height || o.y < 0 || o.x < 0 || o.x > LGlobal.width) && o.objectIndex != mainBodyLayer.objectIndex) {
o.remove();
}
}
if (loopIndex++ < loopFrame) {
return;
}
loopIndex = 0;
var r = Math.random() * 15 + 5;
var bodyLayer = new LSprite();
bodyLayer.x = Math.random() * LGlobal.width;
bodyLayer.y = 50;
bodyLayer.addBodyCircle(r, r, r, 1);
backLayer.addChild(bodyLayer);
}
</script>
</head>
<body>
<div id="mylegend">Loading……</div>
</body>
</html>
复制代码
写完代码一运行,虽然实现了效果,但是感觉效果很不自然,因为如果鼠标移动过快,刚体碰撞就会失灵,因为这里的原理相当于瞬移。所以这种方法不算太好,可是我是一个完美主义的人,就这样去给问问题的朋友交差似乎不大厚道,于是我又继续研究了一下。后来灵机一动,我想到了鼠标关节。关于鼠标关节,其实lufylegend里有封装,也就是调用setBodyMouseJoint这个函数,可是我说过了,这个只能实现拖动刚体,所以实现刚体跟随鼠标移动就只能自己写了。鼠标关节的用法还是交给拉登大叔去讲吧:
http://www.ladeng6666.com/blog/2012/08/18/drag-b2body-with-mousejointdef/
最后奉上终解决方案的代码吧:
<!DOCTYPE html>
<html>
<head>
<title>刚体跟随鼠标</title>
<meta charset="utf-8">
<script type="text/javascript" src="./lufylegend-1.9.0.js"></script>
<script type="text/javascript" src="./Box2dWeb-2.1.a.3.js"></script>
<script type="text/javascript">
LInit(30, "mylegend", 800, 480, main);
var mouseJoint = null;
var mainBodyLayer;
var loopIndex = 0, loopFrame = 5;
function main () {
LGlobal.setDebug(true);
LGlobal.box2d = new LBox2d();
var backLayer = new LSprite();
backLayer.graphics.drawRect(3, "black", [0, 0, LGlobal.width, LGlobal.height]);
addChild(backLayer);
var w = 150, h = 50;
mainBodyLayer = new LSprite();
mainBodyLayer.x = (LGlobal.width - w) * 0.5;
mainBodyLayer.y = (LGlobal.height - h) * 0.5;
mainBodyLayer.addBodyPolygon(w, h, 1);
backLayer.addChild(mainBodyLayer);
createMouseJoint(mainBodyLayer.x, mainBodyLayer.y);
backLayer.addEventListener(LMouseEvent.MOUSE_MOVE, onMouseMove);
backLayer.addEventListener(LEvent.ENTER_FRAME, loop);
}
function createMouseJoint (x, y) {
var b = mainBodyLayer.box2dBody, scale = LGlobal.box2d.drawScale;
var jointDef = new LGlobal.box2d.b2MouseJointDef();
jointDef.bodyA = LGlobal.box2d.world.GetGroundBody();
jointDef.bodyB = b;
jointDef.collideConnected = true;
jointDef.maxForce = 300000.0 * b.GetMass();
jointDef.target.Set(x / scale, y / scale);
mouseJoint = LGlobal.box2d.world.CreateJoint(jointDef);
b.SetAwake(true);
}
function onMouseMove (event) {
var mX = event.offsetX / LGlobal.box2d.drawScale,
mY = event.offsetY / LGlobal.box2d.drawScale;
mouseJoint.SetTarget(new LGlobal.box2d.b2Vec2(mX, mY));
}
function loop (event) {
var backLayer = event.currentTarget;
for (var i = 0; i < backLayer.childList.length; i++) {
var o = backLayer.childList[i];
if ((o.y > LGlobal.height || o.y < 0 || o.x < 0 || o.x > LGlobal.width) && o.objectIndex != mainBodyLayer.objectIndex) {
o.remove();
}
}
if (loopIndex++ < loopFrame) {
return;
}
loopIndex = 0;
var r = Math.random() * 15 + 5;
var bodyLayer = new LSprite();
bodyLayer.x = Math.random() * LGlobal.width;
bodyLayer.y = 50;
bodyLayer.addBodyCircle(r, r, r, 1);
backLayer.addChild(bodyLayer);
}
</script>
</head>
<body>
<div id="mylegend">Loading……</div>
</body>
</html>
复制代码
bodyFollowMouse.rar
2014-7-30 18:11 上传
点击文件名下载附件
130.5 KB, 下载次数: 11720
欢迎光临 lufy's legend (http://lufylegend.com/forum/)
Powered by Discuz! X2.5