Equation For Specific Line Length Needed
#1
Hi all,

I'm in the middle of making my Explorer game with scrolling maps. The game uses the mouse to use your sword with. But I'm stuck at what the equation is to make a limited line (sword) from your character toward the area you point your mouse at. I can easily make a line from your character to the mouse coordinates, but I can't make it a limited length. Does anyone out there know how to do this? I think I will keep the sword at 100 pixels long. Let's say the guy is XX by YY coordinates (never mind the scrolling map part, that should be easy to add). And let's say the mouse is using mouseX and mouseY. I just want the sword to reach toward that mouse point but only 100 pixels toward it and no more. Thanks.
Reply
#2
(08-16-2022, 12:53 AM)SierraKen Wrote: Hi all,

I'm in the middle of making my Explorer game with scrolling maps. The game uses the mouse to use your sword with. But I'm stuck at what the equation is to make a limited line (sword) from your character toward the area you point your mouse at. I can easily make a line from your character to the mouse coordinates, but I can't make it a limited length. Does anyone out there know how to do this? I think I will keep the sword at 100 pixels long. Let's say the guy is XX by YY coordinates (never mind the scrolling map part, that should be easy to add). And let's say the mouse is using mouseX and mouseY. I just want the sword to reach toward that mouse point but only 100 pixels toward it and no more. Thanks.

Code: (Select All)
Option _Explicit
Screen _NewImage(800, 600, 32)
Dim heroX, heroY, A, mx, my, sx, sy
Do

    Cls
    ' lets say hero is right in middle of screen and points a 100 pixel sword in direction of mouse
    heroX = 400: heroY = 300
    While _MouseInput: Wend 'poll mouse
    mx = _MouseX: my = _MouseY
    A = _Atan2(my - heroY, mx - heroX)
    sx = heroX + 100 * Cos(A)
    sy = heroY + 100 * Sin(A)
    Line (heroX, heroY)-(sx, sy), &HFFFFFF00
    _Display
    _Limit 60
Loop
b = b + ...
Reply
#3
Thanks tons B+! I figured out how to make that used with scrolling maps. In fact, I made it so he holds onto the sword with his moving right hand. Smile I can't wait to show you all this game. But I want to add as many things as I can think of before I show it to the world, so it might be a few more days, or possibly a little more. We'll see. Smile
Reply
#4
To limit the line, wouldn't you basically do it like you'd draw a hand on a clock (I know you've did that before), but with a smaller radius than one which went all the way to the mouse. If you can draw a large minute hand, and a short hour hand on a clock, then you've basically solved your problem haven't you? Or am I missing something reading this so early in the morning?
Reply
#5
Steve, I thought that would be the case too, but I couldn't get that to work for some reason, maybe I did it wrong. But mostly, I know that equation but I still don't know how it works. B+'s equation works perfectly with the added camera.x and camera.y in the beginning. Here, this is what I have for the sword. lhandx and lhandy keeps the sword in his moving left hand. I brought the length down from 100 to 75 to make it look better.

Code: (Select All)
    'Sword
    swordx = player.x + camera.x + lhandx
    swordy = player.y + camera.y + lhandy

    a = _Atan2(mousey - swordy, mousex - swordx)
    sx = swordx + 75 * Cos(a)
    sy = swordy + 75 * Sin(a)
    Line (swordx, swordy)-(sx, sy), &HFFFFFF00
Reply
#6
Now for choice of swords, consider the Plasma Light Saber: https://staging.qb64phoenix.com/showthre...824#pid824
b = b + ...
Reply
#7
Amazing swords B+. I might look into something like it, if it's possible. I AM getting a little nervous about making the game too big though, right now it's at around 876 lines with no DATA statements. I guess if the code is segmented enough and not all of it being used at once makes it easier to run?
Reply
#8
This is a similar problem to how I did my unit circle visualizer. I had the radius line follow my mouse position, but it had to stop at the circle diameter regardless of where the mouse was at. I used a vector normalization scheme. A mouse position is essentially a 2D position vector in the form (_MOUSEX, _MOUSEY) and in order to get a direction you would:

subtract the hand position (xh%, yh%)  from the mouse position (xm%, ym%) to get the direction vector (dx%, dy%) of the sword

dx% = xm% - xh%
dy% = ym% - yh%

next step is to get the distance (aka magnitude) of the direction vector, and the _HYPOT command does that handily

mag! = _HYPOT(dx%, dy%) ' I'd use a single precision for the magnitude

next you divide dx% and dy% each by the mag! to get a unit vector (ux!, uy!)  <<<notice the unit vector is a single, that's important.

ux! = dx% / mag! ' <<<be sure to trap any mag! value of zero to avoid a division by zero error.
uy! = dy% / mag!           that could happen when your mouse was right on the hand  (if mag!=0 then skip the draw)

The unit vector is simply the direction with a length of one, guaranteed if the above was done correctly. So now multiply each unit element by the length of the sword to get the sword point position (spx!, spy!)

spx! = ux! * 100
spy! = uy! * 100

Then you could just draw the line of the sword with a STEP

LINE (xh%, yh%)-STEP(spx!, spy!) ' the line will round the spx!, spy! to the nearest integer or you could use INT or CINT if desired

It worked like a charm for me. Several steps, but simple equations.


A quickie demo of the process..
Code: (Select All)
SCREEN _NEWIMAGE(1024, 512, 32)
xh% = 512: yh% = 256
swordlength% = 100
DO
    CLS
    WHILE _MOUSEINPUT: WEND
    dx% = _MOUSEX - xh%
    dy% = _MOUSEY - yh%
    mag! = _HYPOT(dx%, dy%)
    IF mag! = 0 THEN
        ux! = 0: uy! = 0
    ELSE
        ux! = dx% / mag! '
        uy! = dy% / mag! '
    END IF
    spx! = ux! * swordlength%
    spy! = uy! * swordlength%
    LINE (xh%, yh%)-STEP(spx!, spy!) '
    _LIMIT 100
    _DISPLAY
LOOP UNTIL _KEYDOWN(27)
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
Reply
#9
Ah yes, when my = heroY then the difference is 0 and will get division by 0 error, unless _ATAN2() can "tolerate" that condition which is possible if _ATAN2() were good because that is likely problem. So test my code and see if throws error when mouse is level with HeroY.

Update: Yeah, seems OK when my = HeroY so _ATAN2() can handle 0 in the 2nd argument. It has no problem drawing horizontal swords.
b = b + ...
Reply
#10
Thanks OldMoses. Even though I did use B+'s sword code already. I did modify your code to make following eyes. I might use this on a monster. Smile 
But this also goes in my tool bucket folder for other stuff in the future.
Here is my "Following Eyes" mod: 

Code: (Select All)
'Following Eyes - Code by OldMoses mod by SierraKen
Screen _NewImage(800, 600, 32)
xh% = 350: yh% = 300
xh2% = 450: yh2% = 300
swordlength% = 5
Do
    Cls
    While _MouseInput: Wend
    dx% = _MouseX - xh%
    dy% = _MouseY - yh%
    mag! = _Hypot(dx%, dy%)
    If mag! = 0 Then
        ux! = 0: uy! = 0
    Else
        ux! = dx% / mag! '
        uy! = dy% / mag! '
    End If
    spx! = ux! * swordlength%
    spy! = uy! * swordlength%
    'Line (xh%, yh%)-Step(spx!, spy!) '
    For sz = .25 To 5 Step .25
        Circle (xh% + spx!, yh% + spy!), sz, _RGB32(255, 255, 255)
    Next sz
    For sz = .25 To 5 Step .25
        Circle (xh2% + spx!, yh2% + spy!), sz, _RGB32(255, 255, 255)
    Next sz
    Circle (xh%, yh%), 15, _RGB32(255, 255, 255)
    Circle (xh2%, yh2%), 15, _RGB32(255, 255, 255)
    Circle (400, 325), 100, _RGB32(255, 255, 255)
    Circle (400, 365), 65, _RGB32(255, 255, 255), , , .3
    _Limit 100
    _Display
Loop Until _KeyDown(27)
Reply




Users browsing this thread: 5 Guest(s)