topical media & game development 
  
 
 
 
 
  
    
    
  
 sample-collect-hush-js-sketch-files-physicsketch.js / js
  b2Settings.b2_maxPolyVertices = 50;
  
  /* demos/demo_base.js */
  function createWorld() {
          var worldAABB = new b2AABB();
          worldAABB.minVertex.Set(-1000, -1000);
          worldAABB.maxVertex.Set(1000, 1000);
          var gravity = new b2Vec2(0, 300);
          var doSleep = true;
          var world = new b2World(worldAABB, gravity, doSleep);
          createGround(world);
          return world;
  }
  
  function createGround(world) {
          var groundSd = new b2BoxDef();
          groundSd.extents.Set(2000, 50);
          groundSd.restitution = 0.2;
          var groundBd = new b2BodyDef();
          groundBd.AddShape(groundSd);
          groundBd.position.Set(-500, 547);
          return world.CreateBody(groundBd)
  }
  
  function createBall(world, x, y) {
          var ballSd = new b2CircleDef();
          ballSd.density = 1.0;
          ballSd.radius = 20;
          ballSd.restitution = 1.0;
          ballSd.friction = 0;
          var ballBd = new b2BodyDef();
          ballBd.AddShape(ballSd);
          ballBd.position.Set(x,y);
          return world.CreateBody(ballBd);
  }
  
  function createBox(world, x, y, width, height, fixed) {
          if (typeof(fixed) == 'undefined') fixed = true;
          var boxSd = new b2BoxDef();
          if (!fixed) boxSd.density = 1.0;
          boxSd.extents.Set(width, height);
          var boxBd = new b2BodyDef();
          boxBd.AddShape(boxSd);
          boxBd.position.Set(x,y);
          return world.CreateBody(boxBd)
  }
  
  /* physicSketch original part */
  function createBall(world, x, y, rad, fixed) {
          var ballSd = new b2CircleDef();
          if (!fixed) ballSd.density = 1.0;
          ballSd.radius = rad || 10;
          ballSd.restitution = 0.2;
          var ballBd = new b2BodyDef();
          ballBd.AddShape(ballSd);
          ballBd.position.Set(x,y);
          return world.CreateBody(ballBd);
  };
  
  var Stroke = Class.create({
    initialize: function(x, y) {
      this.points = A();
      this.body = null;
      this.bodyType = null;
      this.selected = false;
      this.draggedPoint = null;
      this.cullPoints = null;
      this.fillStyle = '#FFFFFF';
    },
  
    getFillStyle: function() {
      //return this.selected ? '#EEEEFF' : this.fillStyle;
      return this.fillStyle;
    },
  
    getStrokeStyle: function() {
      // not used
      return this.selected ? '#FF0000' : this.strokeStyle;
    },
  
    addPoint: function(x, y) {
      x -= this.baseX;
      y -= this.baseY;
      this.points.push([x, y]);
      if (this.points[this.topIndex][1] < y) {
        this.topIndex = this.points.length - 1;
      }
    },
  
    becomeBodyIn: function(w) {
      if (this.points.length < 3) return;
      var firstPoint = new b2Vec2(this.points.first()[0], this.points.first()[1]);
      var lastPoint = new b2Vec2(this.points.last()[0], this.points.last()[1]);
      firstPoint.Subtract(lastPoint);
      if (firstPoint.Length() < 30.0) {
        this.drawShape();
      }
      else {
        this.drawLines();
      }
    },
  
    drawShape: function() {
      var ps = A();
      var cwAngles = A();
      var ccwAngles = A();
      if (massPoints.length < b2Settings.b2_maxPolyVertices) {
        this.cullPoints = massPoints;
      }
      else {
        for (var i = 0; i < massPoints.length - 1; i++) {
          if (i % Stroke.INTERVAL == 0) {
            this.cullPoints.push(massPoints[i]);
          }
        }
        this.cullPoints.push(massPoints[massPoints.length - 1]);
      }
      if (2 < this.cullPoints.length) {
        this.body = this.createPoly(world, this.baseX, this.baseY, this.cullPoints);
        this.bodyType = 'poly';
      }
    },
  
    addConvexPoint: function(ary, p, angleAry) {
      if (ary.length < 2) {
        ary.push(p);
        return;
      }
      var p1 = ary[ary.length-2];
      var p2 = ary[ary.length-1];
      var p3 = p;
      var v12 = new b2Vec2(p2[0] - p1[0], p2[1] - p1[1]);
      var v13 = new b2Vec2(p3[0] - p1[0], p3[1] - p1[1]);
      if (0 < b2Math.b2CrossVV(v12, v13)) {
        var angle = Math.acos(b2Math.b2CrossVV(v12, v13) / (v13.Length() * v12.Length()));
        angleAry.push(angle);
        ary.push(p);
      }
      else {
        angleAry.pop();
        ary.pop();
        this.addConvexPoint(ary, p, angleAry);
      }
    },
  
    drawLines: function() {
      this.cullPoints = A();
  var trackingStroke = null;
  var selectedStroke = null;
  var draggingStroke = null;
  var draggedMouseXY = null;
  var clocking = true;
  var bodyVisibility = false;
  var usePin = true;
  
  var trackingStrokeStyle = '#FFFF00';
  var jointStrokeStyle = '#8888FF';
  var strokeStyle = '#A9A9A9';
  var selectedStrokeStyle = '#FF0000';
  
  function getStrokeStyle(selected) {
    return selected ? selectedStrokeStyle : strokeStyle;
  }
  function changeStrokeColor(code) {
    strokeStyle = code;
  }
  function changeSelectedStrokeColor(code) {
    selectedStrokeStyle = code;
  }
  
  function toggleTimer(elm) {
    clocking = !clocking;
    if (clocking) {
      elm.innerHTML = 'stop timer';
    }
    else {
      elm.innerHTML = 'start timer';
    }
  }
  function toggleBodyVisibility(elm) {
    bodyVisibility = !bodyVisibility;
    if (bodyVisibility) {
      elm.innerHTML = 'hide physical body';
    }
    else {
      elm.innerHTML = 'show physical body';
    }
  }
  function showInformation(stroke) {
    var body = stroke.body;
    var position = body.GetCenterPosition();
    $('position-x').innerHTML = Math.floor(position.x);
    $('position-y').innerHTML = Math.floor(position.y);
    //$('angle').innerHTML = Math.floor(body.m_rotation * 180.0 % 360);
    $('angle').innerHTML = Math.floor(body.m_rotation * 60.0 % 360); //TODO: what's 60.0?
    $('body-color').value = stroke.fillStyle;
  }
  function deleteSelectedBody() {
    if (!selectedStroke) return;
    var newStrokes = A();
      for (var i = 0; i < strokes.length; i++) {
        if (!strokes[i].body) continue;
        var test = false;
        for (var shape = strokes[i].body.GetShapeList(); shape != null; shape = shape.GetNext()) {
          if (shape.TestPoint(new b2Vec2(xy[0], xy[1]))) {
            test = true;
          }
        }
        if (test) strokesAtThisPoint.push(strokes[i]);
      }
      return strokesAtThisPoint;
    }
    function clearSelectStroke() {
      for (var i = 0; i < strokes.length; i++) {
        if (!strokes[i].body) continue;
        strokes[i].selected = false;
      }
      selectedStroke = null;
    }
    function selectStroke(xy) {
      clearSelectStroke();
      var selectedStrokes = strokesAt(xy);
      if (selectedStrokes.length != 0) {
        selectedStroke = selectedStrokes.last();
        selectedStroke.selected = true;
      }
    }
          Event.observe('canvas', 'mousedown', function(e) {
      var xy = getXY(e);
      var strokesAtThisPoint = strokesAt(xy);
      if (selectedStroke && !clocking && strokesAtThisPoint.length != 0) {
        var clickSelectedStroke = false;
        for (var i = 0; i < strokesAtThisPoint.length; i++) {
          clickSelectedStroke = clickSelectedStroke || (strokesAtThisPoint[i] == selectedStroke);
        }
        if (clickSelectedStroke) {
          draggedMouseXY = xy;
          selectedStroke.draggedPoint = selectedStroke.body.GetCenterPosition().Copy();
        }
        else {
          trackingStroke = new Stroke(xy[0], xy[1]);
        }
      }
      else {
        trackingStroke = new Stroke(xy[0], xy[1]);
      }
          });
          Event.observe('canvas', 'mousemove', function(e) {
      var xy = getXY(e);
      if (selectedStroke && !clocking && draggedMouseXY) {
        if (selectedStroke.draggedPoint) {
          var selectedBody = selectedStroke.body;
          var nextPosition = selectedStroke.draggedPoint.Copy();
          nextPosition.Add(new b2Vec2(xy[0] - draggedMouseXY[0], xy[1] - draggedMouseXY[1]));
          selectedBody.SetCenterPosition(nextPosition, selectedBody.m_rotation);
        }
      }
      else if (trackingStroke) {
        trackingStroke.addPoint(xy[0], xy[1]);
      }
          });
          Event.observe('canvas', 'mouseup', function(e) {
      var xy = getXY(e);
      if (selectedStroke && !clocking && draggedMouseXY) {
        if (draggedMouseXY[0] == xy[0] && draggedMouseXY[1] == xy[1]) {
          if (usePin) {
            var strokesAtThisPoint = strokesAt(xy);
            if (0 < strokesAtThisPoint.length) {
              jointStrokesAt(strokesAtThisPoint[0], strokesAtThisPoint[1], xy[0], xy[1]);
            }
          }
          else {
            selectStroke(xy);
          }
        }
        draggedMouseXY = null;
        selectedStroke.draggedPoint = null;
      }
      else if (trackingStroke) {
        if (trackingStroke.points.length < 2) {
          trackingStroke = null;
          selectStroke(xy);
        }
        else {
          trackingStroke.addPoint(xy[0], xy[1]);
          trackingStroke.becomeBodyIn(world);
          if (trackingStroke.hasBody()) strokes.push(trackingStroke);
          trackingStroke = null;
        }
      }
          });
          step();
  });
  
  
  
(C) Æliens 
04/09/2009
You may not copy or print any of this material without explicit permission of the author or the publisher. 
In case of other copyright issues, contact the author.