JavaScript制作实体遵循路径

时间:2017-01-16 18:51:44

标签: javascript

我正在制作塔防游戏,除了我需要制作路径系统外,我已经完成了。我不知道我应该使用数组或ctx lineTo还是只使用很多if语句。我希望他们遵循随机生成的路径。

我正在考虑使用:

var path = {
  x: [0,100,100],
  y: [0,10,50],
}

然后使用for循环为路径创建行。但我觉得这样效率很低。我需要一个简单的路径跟踪系统。我不知道如何启动它。

2 个答案:

答案 0 :(得分:0)

下面的工作示例。阅读详细说明。

var startPoint = { x: 0, y : 0 };

// Random colors the mobs could be.
var colors = [ "red", "green", "blue", "purple"];

// Path for the maze
var pathPoints = [
    { x: 0, y: 0 },
    { x: 100, y: 0 },
    { x: 100, y: 50 },
    { x: 150, y: 50 },
    { x: 150, y: 200 },
    { x: 100, y: 200 },
    { x: 100, y: 150 },
    { x: 25,  y: 25 }
];

var getRandomInt = function(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

var drawMap = function() {
    var ctx = document.getElementById("canvas").getContext("2d");

    ctx.beginPath();
    var lastPoint = null;
    for(var i = 0; i < pathPoints.length; i++) {
        var curPoint = pathPoints[i];
        if (lastPoint)
            ctx.lineTo(curPoint.x, curPoint.y);
        ctx.moveTo(curPoint.x, curPoint.y);
        lastPoint = curPoint;
    }
    ctx.stroke();
}

var mobs = [];

var spawnMob = function() {
    mobs.push({
        hp: 100,
        color: colors[getRandomInt(0,colors.length - 1)],
        speed: getRandomInt(2,8),
        position: { x: pathPoints[0].x, y: pathPoints[0].y },
        pathNodeNumber: 0,
        deleteMe: false
    });
};


var drawMob = function(mob) {
      var canvas = document.getElementById('canvas');
      var context = canvas.getContext('2d');

      var radius = 10;

      context.beginPath();
      context.arc(mob.position.x, mob.position.y, radius, 0, 2 * Math.PI, false);
      context.fillStyle = mob.color;
      context.fill();
      context.lineWidth = 3;
      context.strokeStyle = '#003300';
      context.stroke();
}

var moveMobs = function() {
    for(var m = 0; m < mobs.length; m++) {
      
        var curMob = mobs[m];
      
        // If the mob finished the maze, skip it
        if (curMob.deleteMe)
          continue;
        
        var nextPoint = pathPoints[curMob.pathNodeNumber + 1];
        
        // Calculate the vector from the Mob (A) to the next node (B)
        var fromAtoB = { x: nextPoint.x - curMob.position.x, y: nextPoint.y - curMob.position.y};

        // Find the unit vector of this distnace.  The unit vector points in the same direction as fromAtoB, BUT it has a length of 1.
        var magnitude = Math.sqrt(Math.pow(fromAtoB.x,2) + Math.pow(fromAtoB .y,2));
        var unitVector = { x: fromAtoB.x / magnitude, y: fromAtoB.y / magnitude };

        // Use the unit vector to determine direction of movement, use mob.speed to determine magnitude of the movement.
        var mobMovementVector = { x: unitVector.x * curMob.speed, y: unitVector.y * curMob.speed };
        
        var mobMagnitude = Math.sqrt(Math.pow(mobMovementVector.x,2) + Math.pow(mobMovementVector .y,2));
        
        // If the mobMovementVector was longer than the original distance between A and B, we know that the mob will arrive at the point this frame
        if (mobMagnitude >= magnitude) {
            // If the mob has arrived, then set his position to the new point
            curMob.position.x = nextPoint.x;
            curMob.position.y = nextPoint.y; 
            
            // And point the mob to the next point in the path.
            curMob.pathNodeNumber += 1;
          
            if (curMob.pathNodeNumber == pathPoints.length-1) {
                    // If the mob finished the maze, mark it to be skipped
                  curMob.deleteMe = true;
              }
        } else {
            // Move the mob closer
            curMob.position.x += mobMovementVector.x;
            curMob.position.y += mobMovementVector.y;
        }
    }
};

var drawMobs = function() {
    for(var m = 0; m < mobs.length; m++) {
        drawMob(mobs[m]);
    }
}
   
   

var draw = function() {
    var ctx = document.getElementById("canvas").getContext("2d");
    
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    
    drawMap();
    moveMobs();
    drawMobs();
};

setInterval(spawnMob, 1500);

setInterval(draw, 200);
<canvas id="canvas" width="300" height="300"></canvas>

答案 1 :(得分:0)

由于@Autowirepath.x具有相同的长度,您可以像这样循环:

path.y