2016-05-31 16 views
0

Ich frage mich heute, wie man ein Canvas-Element nahtlos einem anderen Canvas-Element folgen lässt. Zum Beispiel versuche ich ein Spiel zu machen, in dem ein Canvas-Element dem Spieler (der mit W, A, S, & D) bewegt werden kann, kontinuierlich folgt. Ich hatte eine Idee, den Satz des Pythagoras zu verwenden, um nach dem nächsten schnellsten Weg zu suchen, um von Punkt A (dem Canvas-Element) zu Punkt B (dem Spieler) zu gelangen. Ich habe jedoch keinen physischen Weg, dies zu tun. Hat jemand irgendwelche Ideen oder Antworten, wie ich ein Canvas-Element so konstant wie möglich einem Spieler folgen lassen kann, damit es den Spieler am schnellsten erreicht? HierTarget Smooth Following

Ich habe ein Beispiel für eine sehr schlechte Art und Weise zu folgen:

<!DOCTYPE html> 

<html> 

<head> 
    <title>Target Following Test</title> 
</head> 

<body> 
    <script src="https://code.jquery.com/jquery-2.1.0.js"></script> 
    <center> 
    <canvas id="canvas" width="800" height="500"></canvas> 
    </center> 
    <script> 
    var canvas = document.getElementById("canvas"); 
    var ctx = canvas.getContext("2d"); 
    var width = canvas.width; 
    var height = canvas.height; 
    var circle = function(x, y, radius, fillCircle, color) { 
    ctx.beginPath(); 
    ctx.fillStyle = color; 
    ctx.arc(x, y, radius, 0, Math.PI * 2, false); 
    if (fillCircle) { 
     ctx.fill(); 
    } else { 
     ctx.stroke(); 
    } 
    }; 
    var drawRect = function(x, y, color) { 
    ctx.fillStyle = color; 
    ctx.fillRect(x, y, 20, 20) 
    } 
    //Moving Obstacle 
    var Obstacle = function(x, y) { 
    this.x = x; 
    this.y = y; 
    this.vSpeed = 0; 
    this.hSpeed = 0; 
    } 
    Obstacle.prototype.drawOb = function(color) { 
    drawRect(this.x, this.y, "Red") 
    } 
    Obstacle.prototype.follow = function() { 
    this.y += this.vSpeed 
    this.x += this.hSpeed 
    if (this.x < ball.x - 9) { 
     this.hSpeed = 1; 
    } 
    if (this.x > ball.x - 10) { 
     this.hSpeed = -1; 
    } 
    if (this.y > ball.y - 10) { 
     this.vSpeed = -1; 
    } 
    if (this.y < ball.y - 9) { 
     this.vSpeed = 1; 
    } 
    } 
    Obstacle.prototype.checkCollision = function(direction) { 
    return (ball.x - ball.radius < this.x + 20) && 
     (ball.x + ball.radius > this.x) && 
     (ball.y - ball.radius < this.y + 20) && 
     (ball.y + ball.radius > this.y); 
    } 
    // The Ball constructor 
    var Ball = function() { 
    this.x = 20 
    this.y = 20 
    this.xSpeed = 0; 
    this.ySpeed = 0; 
    this.radius = 10; 
    }; 
    // Draw the ball at its current position 
    Ball.prototype.draw = function() { 
    circle(this.x, this.y, 10, true, "Black"); 
    }; 
    Ball.prototype.reposition = function(reX, reY) { 
    this.x = reX; 
    this.y = reY; 
    } 
    // Update the ball's position based on its speed 
    Ball.prototype.move = function() { 
    this.x += this.xSpeed; 
    this.y += this.ySpeed; 
    if (this.x < 11) { 
     this.x = 11; 
    } else if (this.x > width - 11) { 
     this.x = width - 11; 
    } else if (this.y < 11) { 
     this.y = 11; 
    } else if (this.y > height - 11) { 
     this.y = height - 11; 
    } 
    }; 
    // Set the ball's direction based on a string 
    Ball.prototype.setDirection = function(direction) { 
    if (direction === "up") { 
     this.xSpeed = 0; 
     this.ySpeed = -2; 
    } else if (direction === "down") { 
     this.xSpeed = 0; 
     this.ySpeed = 2; 
    } else if (direction === "left") { 
     this.xSpeed = -2; 
     this.ySpeed = 0; 
    } else if (direction === "right") { 
     this.xSpeed = 2; 
     this.ySpeed = 0; 
    } else if (direction === "stop") { 
     this.xSpeed = 0; 
     this.ySpeed = 0; 
    } 
    }; 

    function simulate() { 
    var prev_ball_x = ball.x; 
    var prev_ball_y = ball.y; 
    var prev_fol_x = follower.x; 
    var prev_fol_y = follower.y; 
    ball.move(); 
    follower.follow() 
    if (follower.checkCollision()) { 
     ball.setDirection('stop'); 
     follower.vSpeed = 0; 
     follower.hSpeed = 0; 
     follower.x = prev_fol_x; 
     follower.y = prev_fol_y; 
     ball.x = prev_ball_x; 
     ball.y = prev_ball_y; 
    } 
    } 

    function draw() { 
    ctx.clearRect(0, 0, width, height); 
    ball.draw(); 
    follower.drawOb(); 
    ctx.strokeRect(0, 0, width, height); 
    } 
    // An object to convert keycodes into action names 
    var keyActions = { 
    37: "left", 
    38: "up", 
    39: "right", 
    40: "down" 
    }; 
    // The keydown handler that will be called for every keypress 
    $("body").keydown(function(event) { 
    var direction = keyActions[event.keyCode]; 
    ball.setDirection(direction); 
    }); 
    $("body").keyup(function(event) { 
    ball.setDirection('stop'); 
    }) 
    setInterval(function() { 
    // separate drawing and simulating phases 
    simulate(); 
    draw(); 
    }, 10); 
    // Create all the Objects! 
    var ball = new Ball(); 
    var follower = new Obstacle(400, 100); 
    </script> 
</body> 

</html> 
+1

Die geringste Entfernung zwischen A & B ist eine Linie. Weitere Informationen zur Verwendung der linearen Interpolation finden Sie im Duplikat [Fragen und Antworten] (http://stackoverflow.com/questions/27561041/comparing-x-y-of-two-positions-on-a-canvas/27561396#27561396). – markE

+0

@markE: Eines der beiden duple Ziele für diese Frage scheint gelöscht worden zu sein. Könnten Sie als Gold-Plaketten-Halter bitte die Duplikat-Liste bearbeiten, um das zu beheben? Oder noch besser, schließen Sie dies z.B. als ein Betrüger von https://stackoverflow.com/questions/13849185/moving-an-object-along-a-straight-line-at-a-constant-speed-from-point-a-to-b stattdessen. –

Antwort

1

Anmerkung: Ich habe nicht wirklich Code geprüft ... Aber hoffentlich verstehe ich Ihre Frage richtig. Und wenn ich das tue, könnte die Lösung ziemlich einfach sein.

Der einfachste und schnellste Weg ist, das Canvas-Element in einer geraden Linie zum Spieler zu bewegen, ohne die Hilfe von Herrn Pythagoras. Dafür musst du die Position des Spielers (x, y) kennen, was du tust.

Ich nahm eine Beschleunigungsfunktion von einer AS3 Frage, aber es ist das gleiche für JS: AS 3 simple ease

Bei jedem Update der Folge auf die Position des Spielers erleichtern:

follower.x += (player.x - follower.x)/delay; 
follower.y += (player.y - follower.y)/delay; 

Beispiel: Fiddle

es ist nicht eine Drop-in-Lösung für Ihr Skript, aber es ist hoffentlich hilfreich

+0

Sorry, aber ich möchte eine konstante Geschwindigkeit, wenn es folgt – Cool123

+0

@ Cool123 So entfernen Sie die Verzögerung. Sie könnten sogar ['Math.sign'] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign) verwenden, um die Richtung zu ermitteln, in die sich der Follower bewegen kann multipliziere es mit einer Konstanten. Spielen Sie mit diesem Code ein bisschen herum und Sie werden es herausfinden. –

+0

Ok, ich weiß nicht, wie das funktionieren wird. Bitte geben Sie ein Beispiel – Cool123