Search code examples
mathluagame-physicstrigonometry

Using trigonometry to calculate angle of movement using mouse position


I'm building a game in Lua for fun (even if you don't know Lua, you can probably help me with this as it applies to any programming language). My problem is I have an x and y variable defined in a table for the player:

player = {}
player.x = 10
player.y = 10
player.velocity = 50

My goal is to have the player move towards the mouses position on the screen. I have it currently set up to increase/decrease the x value and y value for every update depending on the mouse position. My code looks something like this:

function update(delta_time)  -- delta_time is time in milliseconds since last update
  if mouse.x > screen.width and mouse.y < screen.height then
    player.x = player.x + player.velocity * delta_time
    player.y = player.y + player.velocity * delta_time
end

That was just one example of a direction that I would define. My problem is that I don't want to have gigantic blocks of flow controls checking for what quadrant the x and y position of the mouse are in, and adjusting the players x and y position accordingly. I would rather have a fluid 360 degree detection that can move the player towards the angle the mouse is positioned from the center.

Another problem I have is when I move the player to the right of the screen, I will simply increase the x value, but when I move the player to the northeast side of the screen, I increase the x AND y value. This means that the player will go 2 TIMES faster depending on how fine the angle of movement is. When I make north east east angles and north west west, the player now goes 3 TIMES faster because I increase/decrease y by 2 and x by 1. I have no idea how to fix this. I am really good with math and trig, but I am bad at applying it to my game. All I need is someone to switch the lights on for me and I will understand. Thank you for your time if you actually read all this.


Solution

  • Compute a vector from the player position to the mouse position. Normalize this vector (i.e., divide it by its length), then multiply by player.velocity, and then add it to player.x and player.y. This way, the speed is constant, and you get smooth movement in all directions.

    -- define the difference vector
    vec = {}
    vec.x = mouse.x - player.x
    vec.y = mouse.y - player.y
    
    -- compute its length, to normalize
    vec_len = math.pow(math.pow(vec.x, 2) + math.pow(vec.y, 2), 0.5)
    
    -- normalize
    vec.x = vec.x / vec_len
    vec.y = vec.y / vec_len
    
    -- move the player
    player.x = player.x + vec.x * player.velocity * delta_time
    player.y = player.y + vec.y * player.velocity * delta_time