パスに沿って移動

目標はディフェンスゲーム

 ディフェンスゲームを作ってみたいと思ったことがありました。

 遊んでいる時に作れそうな気がしていたのは、気のせいでした。

サンプル

  //パス
  var start = new Point(20, 140);
  var points = [start, new Point(20, 80), new Point(80, 20),
    new Point(270, 20), new Point(300, 50), new Point(270, 80),
    new Point(190, 80), new Point(160, 110), new Point(190, 140),
    new Point(300, 140)];
  var path = new Path(points);
  path.style = {
    strokeColor:"black",
    strokeWidth:0.25,
    dashArray:[2, 1]
  };
  path.smooth();
  //仮想的
  var obj = new Array(30);
  for(i = 0; i < obj.length; i++){
    obj[i] = new Path.Circle(start, 5 + Math.random() * 10);
      obj[i].fillColor = new RgbColor(Math.random(), Math.random(), Math.random());
    obj[i].opacity = 0.5;
    obj[i].speed = Math.random() * 180 + 210;
  }
  //仮設砲台
  var farPoint = new Point(1000, 1000);
  var arm = new Array(2);
  var armCenter = [new Point(100, 80), new Point(240, 50)];
  for(i = 0; i < arm.length; i++){
    arm[i] = new Path.Circle(armCenter[i], 5);
    arm[i].strokeColor = "red";
    arm[i].nearNum;
    arm[i].pathA = new Path.Line(armCenter[i], farPoint);//現在のターゲット
    arm[i].pathB = arm[i].pathA.clone();//距離比較用
  }
  //アニメーション
  var offset, point;
  function onFrame(event){
    if (event.count % 5 == 0){
      //仮想砲台の標的情報の初期化
      for(j = 0; j < arm.length; j++){
        arm[j].nearNum = 0;
        arm[j].pathA.remove();
        arm[j].pathA = new Path.Line(armCenter[j], farPoint);
      }
      //標的の移動と砲台の照準
      for(i = 0; i < obj.length; i++){
        offset = (event.count % obj[i].speed) * path.length / obj[i].speed;
        point = path.getPointAt(offset);
        obj[i].position = point;
        //距離の比較
        for(j = 0; j < arm.length; j++){
          arm[j].pathB.remove();
          arm[j].pathB = new Path.Line(armCenter[j], point);
          if (arm[j].pathA.length > arm[j].pathB.length){
            arm[j].nearNum = i;
            arm[j].pathA.remove();
            arm[j].pathA = new Path.Line(armCenter[j], point);
            arm[j].pathA.strokeColor = "red";
            arm[j].pathA.strokeWidth = 0.25;
          }
        }
      }
    }
  }
 うちのPCのスペックが低いのでオブジェクトが増えるとあっという間に高負荷に悲鳴を上げます。
 フレームレートを下げテストしたところ、なめらかさを犠牲にしても200個程度が限界でした。

覚書

 パス回りの処理で困ることがあったので
  var pathA = new Path();
...
  pathA.remove();
  pathA = new Path.Line(armCenter, point);
 pathA.remove();がない場合、下図のように増殖する。

 パスの長さが決定するタイミングに関して
  var path = new Path.Line(new Point(0, 0), new Point(100, 100));
  console.log(path.length);//->141.42...
  path.segments[1] = new Segment(200, 200);
  console.log(path.length);//->141.42...
 パスの長さは生成時のみ計算。メソッドを呼んだ時は再計算されるが...
  var path = new Path();
  path.add(new Point(0, 0), new Point(100, 100));
  console.log(path.length);//->141.4...
  path.removeSegment(1);
  path.add(new Point(200, 200));
  console.log(path.length);//->424.2...= 300 * sqrt(2)?
 直線の片方の点を移動させた場合の距離計算が不正?

 segmentsは正しく変更されているのでやっていることは間違いないと思うのですが...