user1634845
user1634845

Reputation:

HTML5 Canvas: Move directly to point

peoples.

Today I'm writing a game with canvas and I'm having an issue. I've made it so that when you click on the canvas, thew player move to the point you clicked on. The issue is, if the x is greater than y, the player will move all correctly until it gets to the end of the y value, then it turns and goes to the x point. I need it to go directly to the point where I click. Here's my code:

var canvas, ctx, fps;
canvas = $("#canvas")[0];
ctx = canvas.getContext("2d");
fps = 30;

window.onload = function(){init()}

function init(){
    setInterval(function(){
        draw();
    }, 1000 / fps);
}

var backgroundTile = new Image();
backgroundTile.src = "img/background.png";
var lighting = new Image();
lighting.src = "img/lighting.png"
var sprite = new Image();
sprite.src = "img/sprite.png";
var spritePos = {
    posX: 288,
    posY: 208
}
var goX, goY;
goX = spritePos.posX;
goY = spritePos.posY;

function update(){

    if (distance(spritePos.posX, spritePos.posY, goX, goY) <= 5){
        spritePos.posX = goX;
    }

    if (distance(spritePos.posX, spritePos.posY, goX, goY) <= 5){
        spritePos.posY = goY;
    }

    if(spritePos.posX > goX){
        if(spritePos.posX - goX > 5){
            spritePos.posX -= 5;
        } else {
            spritePos.posX = goX;
        }
    } else if(spritePos.posX < goX){
        if(goX - spritePos.posX > 5){
            spritePos.posX += 5;
        } else {
            spritePos.posX = goX;
        }
    }
    if(spritePos.posY > goY){
        if(spritePos.posY - goY > 5){
            spritePos.posY -= 5;    
        } else {
            spritePos.posY = goY;
        }
    } else if(spritePos.posY < goY){
        if(goY - spritePos.posY > 5){
            spritePos.posY += 5;
        } else {
            spritePos.posY = goY;
        }
    }
}

function drawSprite(){
    ctx.drawImage(sprite, spritePos.posX, spritePos.posY);
}

function drawLighting(){
    ctx.drawImage(lighting, (spritePos.posX - spritePos.posX) - 7, (spritePos.posY - spritePos.posY) - 7);
}

function drawBackground(){
    ctx.drawImage(backgroundTile, 0, 0);
}

$("#canvas").click(function(e){
    var x = e.pageX;
    var y = e.pageY;
    goX = x - 32;
    goY = y - 32;
});

function draw(){
    clean();
    drawBackground();
    update();
    drawSprite();
    drawLighting();
}

function clean(){
    ctx.clearRect(0, 0, canvas.width, canvas.height);
}

function distance(pnt1X, pnt1Y, pnt2X, pnt2Y){
    var xs = 0;
    var ys = 0;
    xs = pnt2X - pnt1X;
    xs = xs * xs;
    ys = pnt2Y - pnt1Y;
    ys = ys * ys;
    return Math.ceil(Math.sqrt(xs + ys));
}

I know this question is confusing, so if you need more info let me know.

Upvotes: 1

Views: 4280

Answers (1)

user1693593
user1693593

Reputation:

Here is how you can implement a player moving directly to a point:

ONLINE DEMO HERE

(Updated with constant speed approach)

Example:

When we click somewhere on the canvas our "player" (a black square in this case) moves to the point.

var ctx = demo.getContext('2d'),
    x, y, x1, y1, x2 = 0, y2 = 0, /// positions
    f = 0,                        /// "progress"
    speed,                        /// speed based on dist/steps
    dist,                         /// distance between points
    steps = 3;                    /// steps (constant speed)

demo.onclick = function(e) {

    /// if we are moving, return
    if (f !== 0) return;

    /// set start point
    x1 = x2;
    y1 = y2;

    /// get and adjust mouse position    
    var rect = demo.getBoundingClientRect();
    x2 = e.clientX - rect.left,
    y2 = e.clientY - rect.top;

    /// calc distance
    var dx = x2 - x1,
        dy = y2 - y1;

    dist = Math.abs(Math.sqrt(dx * dx + dy * dy));

    /// speed will be number of steps / distance
    speed = steps / dist;

    /// move player
    loop();
}

Then in the loop the player will be moved from where it stopped last time to the point we click.

function loop() {

    /// clear current drawn player
    ctx.clearRect(x - 6, y - 6, 12, 12);

    /// move a step
    f += speed;

    /// calc current x/y position
    x = x1 + (x2 - x1) * f;
    y = y1 + (y2 - y1) * f;    

    /// at goal? if not, loop
    if (f < 1) {
        /// draw the "player"
        ctx.fillRect(x - 4, y - 4, 8, 8);

        requestAnimationFrame(loop);
    } else {
        /// draw the "player"
        ctx.fillRect(x2 - 4, y2 - 4, 8, 8);

        /// reset f so we can click again
        f = 0;
    }
}

Upvotes: 4

Related Questions