- 注册时间
- 2013-2-20
- 最后登录
- 2020-1-26
- 阅读权限
- 45
- 积分
- 1866
- 精华
- 1
- 帖子
- 181
|
今天有位朋友问我如何实现刚体跟随鼠标移动,先开始我理解错了,就说用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>
复制代码 |
|