lufy's legend

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 9088|回复: 0

实现Box2D刚体跟随鼠标移动

[复制链接]

46

主题

3

好友

1866

积分

偏将军

Rank: 4

发表于 2014-7-30 18:12:49 |显示全部楼层
今天有位朋友问我如何实现刚体跟随鼠标移动,先开始我理解错了,就说用LSprite的setBodyMouseJoint函数,可是他说他要的效果不是拖动,而是直接跟随,也就是说当鼠标没有按下,只在界面上移动时,刚体也跟着移动。我首先想到了用b2Body的SetPosition来实现,具体的代码如下:
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.         <title>刚体跟随鼠标</title>
  5.         <meta charset="utf-8">
  6.         <script type="text/javascript" src="./lufylegend-1.9.0.js"></script>
  7.         <script type="text/javascript" src="./Box2dWeb-2.1.a.3.min.js"></script>
  8.         <script type="text/javascript">
  9.                 LInit(30, "mylegend", 800, 480, main);
  10.                 var loopIndex = 0, loopFrame = 5;
  11.                 var mainBodyLayer = null;
  12.                 function main () {
  13.                         LGlobal.setDebug(true);
  14.                         LGlobal.box2d = new LBox2d();

  15.                         var backLayer = new LSprite();
  16.                         backLayer.graphics.drawRect(3, "black", [0, 0, LGlobal.width, LGlobal.height]);
  17.                         addChild(backLayer);

  18.                         var w = 150, h = 50;
  19.                         mainBodyLayer = new LSprite();
  20.                         mainBodyLayer.x = (LGlobal.width - w) * 0.5;
  21.                         mainBodyLayer.y = (LGlobal.height - h) * 0.5;
  22.                         mainBodyLayer.addBodyPolygon(w, h);
  23.                         backLayer.addChild(mainBodyLayer);

  24.                         backLayer.addEventListener(LMouseEvent.MOUSE_MOVE, onMouseMove);
  25.                         backLayer.addEventListener(LEvent.ENTER_FRAME, loop);
  26.                 }
  27.                 function onMouseMove (event) {
  28.                         var backLayer = event.currentTarget,
  29.                         b = mainBodyLayer.box2dBody,
  30.                         lb = LGlobal.box2d,
  31.                         scale = lb.drawScale,
  32.                         vec = new lb.b2Vec2(event.offsetX / scale, event.offsetY / scale);
  33.                         b.SetPosition(vec);
  34.                 }
  35.                 function loop (event) {
  36.                         var backLayer = event.currentTarget;
  37.                         for (var i = 0; i < backLayer.childList.length; i++) {
  38.                                 var o = backLayer.childList[i];
  39.                                 if ((o.y > LGlobal.height || o.y < 0 || o.x < 0 || o.x > LGlobal.width) && o.objectIndex != mainBodyLayer.objectIndex) {
  40.                                         o.remove();
  41.                                 }
  42.                         }
  43.                         if (loopIndex++ < loopFrame) {
  44.                                 return;
  45.                         }
  46.                         loopIndex = 0;
  47.                         var r = Math.random() * 15 + 5;
  48.                         var bodyLayer = new LSprite();
  49.                         bodyLayer.x = Math.random() * LGlobal.width;
  50.                         bodyLayer.y = 50;
  51.                         bodyLayer.addBodyCircle(r, r, r, 1);
  52.                         backLayer.addChild(bodyLayer);
  53.                 }
  54.         </script>
  55. </head>
  56. <body>
  57.         <div id="mylegend">Loading……</div>
  58. </body>
  59. </html>
复制代码
写完代码一运行,虽然实现了效果,但是感觉效果很不自然,因为如果鼠标移动过快,刚体碰撞就会失灵,因为这里的原理相当于瞬移。所以这种方法不算太好,可是我是一个完美主义的人,就这样去给问问题的朋友交差似乎不大厚道,于是我又继续研究了一下。后来灵机一动,我想到了鼠标关节。关于鼠标关节,其实lufylegend里有封装,也就是调用setBodyMouseJoint这个函数,可是我说过了,这个只能实现拖动刚体,所以实现刚体跟随鼠标移动就只能自己写了。鼠标关节的用法还是交给拉登大叔去讲吧:
http://www.ladeng6666.com/blog/2012/08/18/drag-b2body-with-mousejointdef/
最后奉上终解决方案的代码吧:
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.         <title>刚体跟随鼠标</title>
  5.         <meta charset="utf-8">
  6.         <script type="text/javascript" src="./lufylegend-1.9.0.js"></script>
  7.         <script type="text/javascript" src="./Box2dWeb-2.1.a.3.js"></script>
  8.         <script type="text/javascript">
  9.                 LInit(30, "mylegend", 800, 480, main);
  10.                 var mouseJoint = null;
  11.                 var mainBodyLayer;
  12.                 var loopIndex = 0, loopFrame = 5;
  13.                 function main () {
  14.                         LGlobal.setDebug(true);
  15.                         LGlobal.box2d = new LBox2d();

  16.                         var backLayer = new LSprite();
  17.                         backLayer.graphics.drawRect(3, "black", [0, 0, LGlobal.width, LGlobal.height]);
  18.                         addChild(backLayer);

  19.                         var w = 150, h = 50;
  20.                         mainBodyLayer = new LSprite();
  21.                         mainBodyLayer.x = (LGlobal.width - w) * 0.5;
  22.                         mainBodyLayer.y = (LGlobal.height - h) * 0.5;
  23.                         mainBodyLayer.addBodyPolygon(w, h, 1);
  24.                         backLayer.addChild(mainBodyLayer);

  25.                         createMouseJoint(mainBodyLayer.x, mainBodyLayer.y);

  26.                         backLayer.addEventListener(LMouseEvent.MOUSE_MOVE, onMouseMove);
  27.                         backLayer.addEventListener(LEvent.ENTER_FRAME, loop);
  28.                 }
  29.                 function createMouseJoint (x, y) {
  30.                         var b = mainBodyLayer.box2dBody, scale = LGlobal.box2d.drawScale;
  31.                         var jointDef = new LGlobal.box2d.b2MouseJointDef();
  32.                         jointDef.bodyA = LGlobal.box2d.world.GetGroundBody();
  33.                         jointDef.bodyB = b;
  34.                         jointDef.collideConnected = true;
  35.                         jointDef.maxForce = 300000.0 * b.GetMass();
  36.                         jointDef.target.Set(x / scale, y / scale);
  37.                         mouseJoint = LGlobal.box2d.world.CreateJoint(jointDef);
  38.                         b.SetAwake(true);
  39.                 }
  40.                 function onMouseMove (event) {
  41.                         var mX = event.offsetX / LGlobal.box2d.drawScale,
  42.                         mY = event.offsetY / LGlobal.box2d.drawScale;
  43.                         mouseJoint.SetTarget(new LGlobal.box2d.b2Vec2(mX, mY));
  44.                 }
  45.                 function loop (event) {
  46.                         var backLayer = event.currentTarget;
  47.                         for (var i = 0; i < backLayer.childList.length; i++) {
  48.                                 var o = backLayer.childList[i];
  49.                                 if ((o.y > LGlobal.height || o.y < 0 || o.x < 0 || o.x > LGlobal.width) && o.objectIndex != mainBodyLayer.objectIndex) {
  50.                                         o.remove();
  51.                                 }
  52.                         }
  53.                         if (loopIndex++ < loopFrame) {
  54.                                 return;
  55.                         }
  56.                         loopIndex = 0;
  57.                         var r = Math.random() * 15 + 5;
  58.                         var bodyLayer = new LSprite();
  59.                         bodyLayer.x = Math.random() * LGlobal.width;
  60.                         bodyLayer.y = 50;
  61.                         bodyLayer.addBodyCircle(r, r, r, 1);
  62.                         backLayer.addChild(bodyLayer);
  63.                 }
  64.         </script>
  65. </head>
  66. <body>
  67.         <div id="mylegend">Loading……</div>
  68. </body>
  69. </html>
复制代码

bodyFollowMouse.rar

130.5 KB, 下载次数: 11645

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

防止垃圾广告,请填写任意字符

Archiver|lufy's legend

GMT+8, 2024-3-29 18:48 , Processed in 0.054404 second(s), 27 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部