box2d&帆布,这就是全部

时间:2016-09-07 14:03:20

标签: canvas box2d

我的目标是绘制没有createjs的物理实体,换句话说我只想用canvas API绘制。 这里有一个优秀的链接与box2dweb和createjs。

我想在没有createjs文件的情况下这样做。 我可以绘制一条蓝线,用物理红线转换它,删除蓝线。

如果我绘制另一条蓝线,我的代码不起作用。为了使它工作,我必须摧毁物理体。

我只能绘制一条线(形状),但我希望能够绘制无限数量的形状。

我确信这很简单。

createjs代码: http://jsdo.it/masasgames/OzhB

var b2Vec2 = Box2D.Common.Math.b2Vec2;
var b2BodyDef = Box2D.Dynamics.b2BodyDef;
var b2Body = Box2D.Dynamics.b2Body;
var b2FixtureDef = Box2D.Dynamics.b2FixtureDef;
var b2Fixture = Box2D.Dynamics.b2Fixture;
var b2World = Box2D.Dynamics.b2World;
var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape;
var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape;
var b2DebugDraw = Box2D.Dynamics.b2DebugDraw;

var stage = new createjs.Stage("canvas");
var world = new b2World(new b2Vec2(0, 5), true);

var shape;
var drawing = false;

var previousMouseX = 0;
var previousMouseY = 0;
var u = new b2Vec2(0, 0);
var anchor = [];
var bodies = [];
var d = 1.0;

function init() {
  if (createjs.Touch.isSupported()) {
    createjs.Touch.enable(stage);
  }

  var back = new createjs.Shape();
  back.graphics.beginFill("#FFFFFF");
  back.graphics.drawRect(0, 0, 450, 450);

  stage.addChild(back);

  stage.addEventListener("mousedown", onMouseDown);
  stage.addEventListener("pressup", onMouseUp);

  createjs.Ticker.timingMode = createjs.Ticker.RAF;
  createjs.Ticker.addEventListener("tick", tick);


  //Box2D
  var groundFixDef = new b2FixtureDef();
  groundFixDef.density = 1.0;
  groundFixDef.friction = 0.5;
  groundFixDef.restitution = 0.2;
  groundFixDef.shape = new b2PolygonShape();
  groundFixDef.shape.SetAsBox(2.325, 0.1);

  var groundDef = new b2BodyDef();
  groundDef.type = b2Body.b2_staticBody;

  groundDef.position.Set(2.25, 4.6);
  world.CreateBody(groundDef).CreateFixture(groundFixDef);

  groundDef.position.Set(2.25, -0.1);
  world.CreateBody(groundDef).CreateFixture(groundFixDef);

  groundFixDef.shape.SetAsBox(0.1, 2.25);
  groundDef.position.Set(-0.1, 2.25);
  world.CreateBody(groundDef).CreateFixture(groundFixDef);

  groundDef.position.Set(4.6, 2.25);
  world.CreateBody(groundDef).CreateFixture(groundFixDef);

  var debugDraw = new b2DebugDraw();
  debugDraw.SetSprite(document.getElementById("canvas").getContext("2d"));
  debugDraw.SetDrawScale(100);
  debugDraw.SetFillAlpha(0.3);
  debugDraw.SetLineThickness(1.0);
  debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
  world.SetDebugDraw(debugDraw);

}

function tick() {
  if (drawing) {
    shape.graphics.setStrokeStyle(5, 1, 1);
    shape.graphics.beginStroke("#000000");
    shape.graphics.moveTo(previousMouseX, previousMouseY);
    shape.graphics.lineTo(stage.mouseX, stage.mouseY);

    var p = new b2Vec2(0, 0);
    p.x = stage.mouseX - previousMouseX;
    p.y = stage.mouseY - previousMouseY;

    if (vecMagnitude(p) !== 0) {

      if (Math.cos(10 / 180 * Math.PI) > vecAngle(p, u)) {
        setAnchor(previousMouseX, previousMouseY);
      }

      u.x = p.x;
      u.y = p.y;
    }

    previousMouseX = stage.mouseX;
    previousMouseY = stage.mouseY;
  }

  for (var i = 0; i < bodies.length; i++) {
    var body = bodies[i];
    var line = body.GetUserData();
    var position = body.GetPosition();

    line.x = position.x * 100;
    line.y = position.y * 100;
    line.rotation = body.GetAngle() * 180 / Math.PI;
  }


  world.Step(1 / 60, 10, 10);
  //world.DrawDebugData();
  world.ClearForces();
  stage.update();
}

function vecMagnitude(v) {
  return Math.sqrt(Math.pow(v.x, 2) + Math.pow(v.y, 2));
}

function vecAngle(v1, v2) {
  return (v1.x * v2.x + v1.y * v2.y) / (vecMagnitude(v1) * vecMagnitude(v2));
}

function onMouseDown(e) {
  if (!drawing) {
    shape = new createjs.Shape();
    shape.regX = 0;
    shape.regY = 0;
    stage.addChild(shape);

    previousMouseX = stage.mouseX;
    previousMouseY = stage.mouseY;

    anchor = [];
    setAnchor(stage.mouseX, stage.mouseY);

    drawing = true;
  }
}

function onMouseUp() {
  drawing = false;
  setAnchor(stage.mouseX, stage.mouseY);
  createBody();
}

function setAnchor(x, y) {
  anchor.push(new b2Vec2(x, y));
}

function createBody() {
  var boxDef = new b2BodyDef();
  boxDef.type = b2Body.b2_dynamicBody;
  boxDef.position.Set(0, 0);

  var body = world.CreateBody(boxDef);

  for (var i = 0; i < anchor.length - 1; i++) {
    var position = new b2Vec2((anchor[i].x + anchor[i + 1].x) / 200, (anchor[i]
      .y + anchor[i + 1].y) / 200);
    var angle = Math.atan2(anchor[i].y - anchor[i + 1].y, anchor[i].x - anchor[
      i + 1].x);

    var l = vecMagnitude(new b2Vec2(anchor[i].x - anchor[i + 1].x, anchor[i].y -
      anchor[i + 1].y)) / 100;

    if (anchor.length == 2 && l < 0.05) {
      l = 0.05;
    }

    var boxFixDef = new b2FixtureDef();
    boxFixDef.density = d * l * 0.05;
    boxFixDef.friction = 0.5;
    boxFixDef.restitution = 0.1;
    boxFixDef.shape = new b2PolygonShape();
    boxFixDef.shape.SetAsOrientedBox(l / 2, 0.025, position, angle);
    body.CreateFixture(boxFixDef);
  }

  body.SetUserData(shape);
  bodies.push(body);
}

init();

这是我的工作代码仅适用于一个形状: http://jsdo.it/licart/QOmS

var b2Vec2 = Box2D.Common.Math.b2Vec2;
var b2BodyDef = Box2D.Dynamics.b2BodyDef;
var b2Body = Box2D.Dynamics.b2Body;
var b2FixtureDef = Box2D.Dynamics.b2FixtureDef;
var b2Fixture = Box2D.Dynamics.b2Fixture;
var b2World = Box2D.Dynamics.b2World;
var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape;
var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape;
var b2DebugDraw = Box2D.Dynamics.b2DebugDraw;

var shape;
var dessin = false;
var drawing = false;
var SCALE = 100;
var PTM = 100;
var previousMouseX = 0;
var previousMouseY = 0;
var u = new b2Vec2(0, 0);
var anchor = [];
var bodies = [];
var d = 1.0;

var world = new b2World(new b2Vec2(0, 9.8), true);
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
canvasWidth = 800,
  canvasHeight = 400;
var mouseX = 0;
var mouseY = 0;

var mousedown;

var debugDraw = new b2DebugDraw();
debugDraw.SetSprite(document.getElementById("canvas").getContext("2d"));
debugDraw.SetDrawScale(100);
debugDraw.SetFillAlpha(0);
debugDraw.SetLineThickness(0);
debugDraw.SetFlags(b2DebugDraw.e_shapeBit);
world.SetDebugDraw(debugDraw);

//Box2D
var groundFixDef = new b2FixtureDef();
groundFixDef.shape = new b2PolygonShape();
groundFixDef.shape.SetAsBox(2.325, 0.1);

var groundDef = new b2BodyDef();
groundDef.type = b2Body.b2_staticBody;

groundDef.position.Set(2.25, 3.6);
var sol = world.CreateBody(groundDef);
sol.CreateFixture(groundFixDef);
sol.SetUserData("rectangle");


canvas.addEventListener('mousemove', function(e) {
  mouseX = e.pageX - this.offsetLeft;
  mouseY = e.pageY - this.offsetTop;
  if (mousedown) {
    context.beginPath();
    context.moveTo(previousMouseX, previousMouseY);
    context.lineWidth = 5;
    context.lineJoin = 'round';
    context.strokeStyle = 'blue';
    context.lineTo(mouseX, mouseY);
    context.stroke();
  }
}, false);

function tick() {

  world.Step(1 / 30, 8, 2);


  if (drawing) {
    var p = new b2Vec2(0, 0);
    p.x = mouseX - previousMouseX;
    p.y = mouseY - previousMouseY;
    if (vecMagnitude(p) !== 0) {
      if (Math.cos(10 / 180 * Math.PI) > vecAngle(p, u)) {
        setAnchor(previousMouseX, previousMouseY);
      }
      u.x = p.x;
      u.y = p.y;
    }
    previousMouseX = mouseX,
      previousMouseY = mouseY;

  }
  for (body = world.GetBodyList(); body; body = body.GetNext()) {
    var x = body.GetPosition().x;
    var y = body.GetPosition().y;
    var angle = body.GetAngle();


    switch (body.GetUserData()) {
      case "rectangle":

        var X = body.GetFixtureList().GetShape().GetVertices()[1].x - body.GetFixtureList()
          .GetShape().GetVertices()[0].x;
        var Y = body.GetFixtureList().GetShape().GetVertices()[2].y - body.GetFixtureList()
          .GetShape().GetVertices()[1].y;

        context.save();

        context.translate(x * PTM, y * PTM);
        context.rotate(angle);
        context.translate(-x * PTM, -y * PTM);

        context.lineWidth = 5;
        context.strokeStyle = "pink";
        context.strokeRect(((x * PTM) - (X * PTM / 2)), ((y * PTM) - (Y *
          PTM / 2)), X * PTM, Y * PTM);

        context.restore();
        break;
      case shape:

        context.save();
        context.clearRect(0, 0, canvas.width, canvas.height);
        context.beginPath();
        context.translate(x * 100, y * 100);
        context.rotate(angle);
        context.strokeStyle = "red";
        context.lineWidth = 5;
        for (var i = 0; i < anchor.length - 1; i++) {
          var p1 = anchor[i];
          var p2 = anchor[i + 1];
          context.moveTo(p1.x, p1.y);
          context.lineTo(p2.x, p2.y);
        }
        context.stroke();

        context.restore();
        break;

    }
  }
  world.ClearForces();
}

window.setInterval(tick, 1000 / 30);


canvas.addEventListener('mousedown', function(e) {
  dog_eraseline();
  mousedown = true
  if (!drawing) {
    previousMouseX = mouseX;
    previousMouseY = mouseY;
    anchor = [];
    setAnchor(mouseX, mouseY);

    drawing = true;
  }
}, false);

canvas.addEventListener('mouseup', function() {
  mousedown = false;
  drawing = false;
  setAnchor(mouseX, mouseY);
  createBody();

}, false);


function dog_eraseline() {
  for (body = world.GetBodyList(); body; body = body.GetNext()) {
    if (body.GetUserData() == shape) world.DestroyBody(body);
  };
}

function setAnchor(x, y) {
  anchor.push(new b2Vec2(x, y));
}

function vecMagnitude(v) {
  return Math.sqrt(Math.pow(v.x, 2) + Math.pow(v.y, 2));
}

function vecAngle(v1, v2) {
  return (v1.x * v2.x + v1.y * v2.y) / (vecMagnitude(v1) * vecMagnitude(v2));
}

function createBody() {
  var boxDef = new b2BodyDef();
  boxDef.type = b2Body.b2_dynamicBody;
  boxDef.position.Set(0, 0);

  var body = world.CreateBody(boxDef);

  for (var i = 0; i < anchor.length - 1; i++) {
    var position = new b2Vec2((anchor[i].x + anchor[i + 1].x) / 200, (anchor[
      i].y + anchor[i + 1].y) / 200);
    var angle = Math.atan2(anchor[i].y - anchor[i + 1].y, anchor[i].x -
      anchor[i + 1].x);
    var l = vecMagnitude(new b2Vec2(anchor[i].x - anchor[i + 1].x, anchor[i]
      .y - anchor[i + 1].y)) / 100;

    if (anchor.length == 2 && l < 0.05) {
      l = 0.05;
    }

    var boxFixDef = new b2FixtureDef();
    boxFixDef.density = d * l * 0.05;
    boxFixDef.friction = 0.5;
    boxFixDef.restitution = 0.1;
    boxFixDef.shape = new b2PolygonShape();
    boxFixDef.shape.SetAsOrientedBox(l / 2, 0.025, position, angle);
    body.CreateFixture(boxFixDef);
  }
  body.SetUserData(shape);
  bodies.push(body);
}

1 个答案:

答案 0 :(得分:0)

没有人给我答案。 我自己找到了解决方案。 我分享了它!

在tick中包含draw_world()及其完成:

这里的作者是@author J Barker&amp; P Kirven

查看http://jsdo.it/licart/2Y7S