简体   繁体   中英

HTML5 + JavaScript - Move Character Towards Mouse Location?

I have a character in the middle of my canvas, and he rotates to always face my mouse position - wherever it is on the canvas.

What I want to do now, is when I press W, or Up arrow, my character will walk towards the mouse. I'm not sure about the math behind this, so I'm asking for a little bit of help.

Right now, I have this function that listens out for the WASD/Arrow keys:

Player.prototype.playerAnimation = function (){

    //UP
    if(this.isUpKey){

        //Character movement [drawX/Y is the position of character]
        this.drawY = mouseY;
}

Of course though, this only moves the character to the Y location of my mouse - not what I'm looking for at all. I just don't know what kind of formula is required?

Thanks

If you're already successfully rotating towards the mouse, you must be calculating the angle between the character and the cursor, so now instead of moving in absolute terms ( =mouseY ) you should just increment this.drawY and this.drawX by some value that will effectively be the speed of your character.

But, you want the diagonal of the X and Y moves to be that value, so something like this will break it into the component X and Y:

this.drawX=this.drawX+this.speed*Math.cos(d2r(angle));
this.drawY=this.drawY+this.speed*Math.sin(d2r(angle));

and in case you're working in degrees instead of radians:

function d2r(d){
    var r=d*(Math.PI/180);
    return r;   
}

you may have to play with the signs in the formula depending on how your angle is being determined. Oh, and if you want it to keep moving if the key stays pressed, you'll want to add some setTimeout to refire the playerAnimation function after some time

You shouldn't use sin and cos because these functions are slow, therefore you can't use angle in computing data (you will need it only to rotate sprites or something like that).

In first place you should make object with x, y, xspeed, yspeed, speed (px per second) and direction properties.

Lets assume your character is at position (10,10) with speed = 5. Now you click (or just hover) with mouse on position (50,40). First you have to get dx and dy (deltas).

dx = mouse.x - character.x // 50 - 10 = 40
dy = mouse.y - character.y // 40 - 10 = 30

Next get distance from character position to mouse position.

distance = sqrt(dx*dx + dy*dy) // sqrt(40*40 + 30*30) = sqrt(1600 + 900) = 
                               // = sqrt(2500) = 50 (Pythagorean theorem)

Now we can compute xspeed and yspeed of character.

factor = distance / character.speed // 50 / 5 = 10
character.xspeed = dx / factor // 40 / 10 = 4
character.yspeed = dy / factor // 30 / 10 = 3

Now lets assume you have 60 ticks of your physics loop per second (probably your physics loop isn't separated from your main loop so it's just your fps count). Every tick your character x is incremented by xspeed, and y by yspeed (if your are pressing key of course). So one second later (which takes 60 ticks) you character will be at position (10 + 60*4, 10 + 60*3) = (250, 190) . It's quite fast, so you can lower your character speed or lower your fps (I don't recommend it).

If you want your character to stop at mouse position (like in cRPG) then use timer or counter. Ticks count that is necessary for your character to get to mouse position is a computed earlier factor , which equals to 10 . After 10 ticks of your loop, character position will be (50,40). So you can create var ticks in character object and every loop tick decrement it by 1, and when it gets to 0 then reset xspeed and yspeed of character to 0, so it won't move anymore. Another way is to use timeout, but it's worse. Just after 10/60s = 1/6s ~= 0.18s timeout callback function resets xspeed and yspeed of character to 0.

If you need angle, you can compute it using dx/dy and tan.

This way of doing movement is much faster than using sin and cos.

Of course you render movement by drawing character at (character.x, character.y) position.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM