Search code examples
randomluadirection

Random direction en 2D lua


I want to create a random direction for my sprite, in Lua 2D.

So, i've tried that :

Sprite.x = Sprite.x + vx
Sprite.y = Sprite.y + vy

Sprite.vx = math.random(-1,1)
Sprite.vy = math.random(-1,1)

So, i managed to create a random direction, but my problem is the speed of the sprite, is directly linked to the number of direction. For example if i want the speed to be 1, it can only have 4 direction. I made a sprite with a lot more, by setting the random speed between -3 and 3, but then it's faster than what i want.

What should i do?

I've seen a few posts talking about random direction, but the description wasn't about lua and i couldn't really understand it..

Thanks!


Solution

  • If I am understanding the problem correctly, you want to choose random directions for the velocity, but you don't want the speed to change. To do this you can choose random velocity components for the x- and y-directions, and then normalize this to a unit vector by dividing each component by the magnitude of the vector.

    Also, math.random(-1, 1) will only give value of -1, 0, or 1. If you want more variety in the directions, use math.random() to get floating point values in the range [0, 1). You can randomly choose to make the components negative to get a full spectrum of directions.

    Here is a little function that returns a pair of vx and vy velocity components:

    function rand_v_dir ()
    
       vx = math.random()
       vy = math.random()
    
       norm = math.sqrt(vx * vx + vy * vy)
       vx = vx / norm
       vy = vy / norm
    
       if math.random(0, 1) == 0 then
          vx = -vx
       end
    
       if math.random(0, 1) == 0 then
          vy = -vy
       end
    
       return vx, vy
    end
    

    Here are ten random velocity vectors generated by the above function:

    > for i = 1, 10 do
    vx, vy = rand_v_dir()
    print("Velocity: ", vx, vy)
    print("Speed: ", math.sqrt(vx * vx + vy * vy))
    end
    
    Velocity:   -0.70784982398251   0.70636295676368
    Speed:  1.0
    Velocity:   -0.28169296961382   -0.95950459658625
    Speed:  1.0
    Velocity:   0.71839382297246    -0.69563662577168
    Speed:  1.0
    Velocity:   0.29007205509751    0.9570048081653
    Speed:  1.0
    Velocity:   -0.40540707321421   0.91413626171807
    Speed:  1.0
    Velocity:   -0.7236198731718    0.69019872439091
    Speed:  1.0
    Velocity:   0.31888322750977    0.94779401096069
    Speed:  1.0
    Velocity:   -0.64427423170525   0.76479455696325
    Speed:  1.0
    Velocity:   -0.66481241135881   0.74701034644996
    Speed:  1.0
    Velocity:   -0.65843036923729   0.75264164704463
    Speed:  1.0
    

    We can do better than this, though. This approach gives directions that are biased towards the corners, as pointed out by @JoelCornett and @nobody in the comments. One improvement would be to select a random angle between 0 and , and to take the velocity vector to be a unit vector. Then the cosine of the angle will be the velocity component in the x-direction, and the sine of the angle will be the component in the y-direction (measuring the angle with respect to the positive x-axis).

    This approach also has the benefit of being simpler to code:

    function rand_polar_dir ()
    
       dir = 2 * math.pi * (math.random())
    
       vx = math.cos(dir)
       vy = math.sin(dir)
    
       return vx, vy
    end
    

    Here are ten random velocity vectors generated with the second approach:

    > for i = 1, 10 do
    vx, vy = rand_polar_dir()
    print("Velocity: ", vx, vy)
    print("Speed: ", math.sqrt(vx * vx + vy * vy))
    end
    Velocity:   0.093304068605003   -0.99563766038743
    Speed:  1.0
    Velocity:   -0.31453683190827   -0.9492452693446
    Speed:  1.0
    Velocity:   0.72403297094833    0.68976536371416
    Speed:  1.0
    Velocity:   -0.39261186353618   -0.91970425931962
    Speed:  1.0
    Velocity:   -0.74523744965918   0.66679917788303
    Speed:  1.0
    Velocity:   0.15192428057379    -0.98839213522374
    Speed:  1.0
    Velocity:   0.93666276755405    -0.35023257969239
    Speed:  1.0
    Velocity:   0.86478573695856    -0.50214104507902
    Speed:  1.0
    Velocity:   0.64665884247741    -0.7627793530542
    Speed:  1.0
    Velocity:   0.2877390096936 0.95770886092828
    Speed:  1.0
    

    For both of the above approaches, the magnitude of the velocity vector is 1. If you want to double the speed, just multiply the random vector by 2.