Computer Science Canada

2D Side Scrolling Shooting Towards Mouse

Author:  Silinter [ Sat Feb 16, 2008 10:32 pm ]
Post subject:  2D Side Scrolling Shooting Towards Mouse

So, after 2-3 weeks of being on and around the site, I finally came up with a question that I can't seem to find an answer to.
I'm making my final project for my grade 10 Introduction to Programming (TIK20) class. I am, however, ahead of the class by far.
Now, I'm here to ask for somebody to write me a program that will gove me 100% and ace the course Razz
No, My real purpose here is to take over the world! And, while I'm there, I'd wanted to create a character that can shoot. The only problem with that is that I can't for the life of me figure out how to make him shoot towards the mouse. I've tried to check out submitted work to see if any of them had the source for something similar, but only 3 or 4 of them showed up and they were compiled Sad
While I'm on the topic of shooting, how would you figure out the angle of where the mouse is and display it similar to WireHang (http://games.flabber.nl/wire.hang/)?
Collision detection would be no problem, other then the collision detection of sprites, which I haven't really looked into. Althought if anyone can provide me with pointers to some good thread explaining this I would appreciate it.

Also, hello.

Author:  ericfourfour [ Sun Feb 17, 2008 12:45 am ]
Post subject:  RE:2D Side Scrolling Shooting Towards Mouse

Think of it this way: the character wants to shoot in a straigt line between his point (or the gun's) and the mouse's. In otherwords, you're dealing with a line segment (x1, y1, x2, y2). You can get your x and y components from that to make a vector. Then, the only thing the bullet has to do is follow the vector.

Author:  Silinter [ Sun Feb 17, 2008 3:32 pm ]
Post subject:  Re: 2D Side Scrolling Shooting Towards Mouse

And how would I go about doing that now? Embarassed

Author:  Sean [ Sun Feb 17, 2008 4:10 pm ]
Post subject:  Re: 2D Side Scrolling Shooting Towards Mouse

If your shooting a bullet, you want it to track your mouse x and y variables.

Do to this, either increase or decrease until the bullet equals the mouse.

Author:  A.J [ Sun Feb 17, 2008 4:57 pm ]
Post subject:  Re: 2D Side Scrolling Shooting Towards Mouse

You use 'Mouse.Where', which returns the x value of the mouse and the y value of the mouse (and a 'button' which lets you know if it is being pressed).
here is an example I made for you (sry if it doesn't help. It took me 1 min to do it, so it might be bad.)

This program tells you the angle you form (with the mouse) and (0,0):
code:

View.Set ("offscreenonly")
setscreen ("graphics")
type coords :
    record
        x, y, x2, y2 : int
    end record
var x, y, button : int
var points : flexible array 1 .. 0 of coords
var count := 0
loop
    loop
        Mouse.Where (x, y, button)
        var z := sqrt (x ** 2 + y ** 2)
        Draw.FillOval (x, y, 5, 5, yellow)
        Text.Locate (1, 1)
        if button = 0 then
            put x : 4, "  ", y : 4, "  ", arccosd ((y ** 2 - x ** 2 - z ** 2) / (-1 * (2 * z * x))), " degrees."
            Draw.Line (0, 0, x, y, blue)
            Draw.Line (x, 0, x, y, blue)
        else
            Draw.FillOval (x, y, 5, 5, blue)
            put x : 4, "  ", y : 4, "  ", arccosd ((y ** 2 - x ** 2 - z ** 2) / (-1 * (2 * z * x))), " degrees."
            Draw.Line (0, 0, x, y, blue)
            Draw.Line (x, 0, x, y, blue)
            new points, upper (points) + 2
            points (upper (points) - 1).x := 0
            points (upper (points) - 1).y := 0
            points (upper (points) - 1).x2 := x
            points (upper (points) - 1).y2 := y
            points (upper (points)).x := x
            points (upper (points)).y := 0
            points (upper (points)).x2 := x
            points (upper (points)).y2 := y
            exit
        end if
        View.Update
        delay (0)
        Draw.Line (0, 0, x, y, white)
        Draw.Line (x, 0, x, y, white)
        Draw.FillOval (x, y, 5, 5, white)
        for i : 1 .. upper (points)
            Draw.Line (points (i).x, points (i).y, points (i).x2, points (i).y2, blue)
        end for
    end loop
    delay (0)
end loop

Author:  CodeMonkey2000 [ Sun Feb 17, 2008 9:26 pm ]
Post subject:  RE:2D Side Scrolling Shooting Towards Mouse

Your program crashes whe you hit 90 degrees, and I don't think it's very accurate.

Author:  Bored [ Sun Feb 17, 2008 10:30 pm ]
Post subject:  Re: 2D Side Scrolling Shooting Towards Mouse

Since your in grade 10 you propably don't have enough trig knowledge to develop your own forumula to calculate the angle between two points so I have provided you with one here:
Turing:
fcn GETANGLE (x1, y1, x2, y2 : real) : real
    /*Code by Bored - Febuary 17, 2008
    Returns the angle between two points (x1,y1) and (x2,y2)
    0 Degrees is oriented to the right of the screen, 90 is upawrd*/

    var opp := y2 - y1
    var adj := x2 - x1
    if adj = 0 then
        result 0
    elsif opp >= 0 and adj > 0 then
        result arctand (opp/adj)
    elsif adj < 0 then
        result 180 + arctand (opp/adj)
    elsif opp < 0 and adj > 0 then
        result 360 + arctand (opp/adj)
    end if
end GETANGLE


This will return the angle with 0 degrees being to the right and rotating counter clockwise making 90 degrees up. This is the general way in which angles are expressed in two dimension because it is based of of standard position.

Author:  A.J [ Sun Feb 17, 2008 10:33 pm ]
Post subject:  Re: 2D Side Scrolling Shooting Towards Mouse

CodeMonkey2000 @ Sun Feb 17, 2008 9:26 pm wrote:
Your program crashes whe you hit 90 degrees, and I don't think it's very accurate.

It obviously should crash when it hits 90 degrees, since it is impossible for two 90 degree angles to coexist in one triangle.
Maybe you didn't know what angle it measures.

it measures the angle formed at the bottom left side of the screen.
(So the x value of the mouse if one side, the y value is the other, and the hypotenuse is sqrt(x**2-y**2))

Author:  CodeMonkey2000 [ Sun Feb 17, 2008 11:34 pm ]
Post subject:  RE:2D Side Scrolling Shooting Towards Mouse

I know what it measures. Your program only works when you are n the 1st quadrant though. Anything else, its wrong.

Author:  Sean [ Mon Feb 18, 2008 8:38 am ]
Post subject:  Re: 2D Side Scrolling Shooting Towards Mouse

The only reason why it works in the 1st quadrant, is because Turing is only in the first quadrant.

Author:  Mackie [ Mon Feb 18, 2008 12:32 pm ]
Post subject:  Re: 2D Side Scrolling Shooting Towards Mouse

Vilament @ Mon Feb 18, 2008 8:38 am wrote:
The only reason why it works in the 1st quadrant, is because Turing is only in the first quadrant.


Turing has all the quadrants, it only shows the first.

Author:  CodeMonkey2000 [ Mon Feb 18, 2008 1:00 pm ]
Post subject:  RE:2D Side Scrolling Shooting Towards Mouse

No, where the quadrants are vary with your reference point. There are always four, even if they are off screen. I can use the middle of the screen as my reference point and all four quadrants will be on screen.

Author:  McKenzie [ Mon Feb 18, 2008 1:04 pm ]
Post subject:  Re: 2D Side Scrolling Shooting Towards Mouse

You do not need any knowledge of Trigonometric relationships (sin, cos, tan) to solve this problem. Go back to what eric44, and Vilament said. You do want to see the velocity of your shot as a vector. Suppose your shot starts at 100,100 and it is going to spot 500,400. Then this would make sense:
code:
shotX := 100
shotY := 100
shotVx := 4
shot Vy := 3

Where Vx, Vy is the velocity of the shot. If you add Vx, Vy to your X, Y each time around a loop then your X,Y will progress from 100,100 to 500,400.

The key question is how do we compute Vx, Vy, given x1,y1 x2,y2? Use similar triangles. Put your points on a graph and draw a triangle where (x1,y1) -> (x2,y2) is the hypotenuse. Now draw a smaller triangle starting at (x1,y1) with the hypotenuse equal to how far you want the shot to travel every update. In my example I used 5. All I need to do now is use ratios to find how long the other two sides of your triangle is, these will be the x,y components of your velocity vector. In my example I said smallX is to bigX as 5 is to dist(x1,y1,x2,y2), or ... x/400 == 5/500.

Author:  Silinter [ Mon Feb 18, 2008 2:40 pm ]
Post subject:  Re: 2D Side Scrolling Shooting Towards Mouse

McKenzie @ Mon Feb 18, 2008 1:04 pm wrote:
Suppose your shot starts at 100,100 and it is going to spot 500,400. Then this would make sense:
code:
shotX := 100
shotY := 100
shotVx := 4
shot Vy := 3

Where Vx, Vy is the velocity of the shot. If you add Vx, Vy to your X, Y each time around a loop then your X,Y will progress from 100,100 to 500,400.

Wow. You weren't lying. It actually does get there Very Shocked Which is pretty damn good considering that's what I'd want to do and that's a pretty big development right there.
code:
setscreen ("graphics")
View.Set ("offscreenonly")
var shotX, shotY, shotVx, shotVy : int
shotX := 100
shotY := 100
shotVx := 4
shotVy := 3
loop
    drawline (100, 100, shotX, shotY, black)
    shotX += shotVx
    shotY += shotVy
    put shotX, "x ", shotY, "y"
    exit when shotX = 500 and shotY = 400
    View.Update
    delay (50)
    cls
end loop

Quote:
The key question is how do we compute Vx, Vy, given x1,y1 x2,y2? Use similar triangles. Put your points on a graph and draw a triangle where (x1,y1) -> (x2,y2) is the hypotenuse. Now draw a smaller triangle starting at (x1,y1) with the hypotenuse equal to how far you want the shot to travel every update. In my example I used 5.

Now, when you say draw a smaller triangle starting at (x1,y1) with the hypotenuse equal to how far you want the shot to travel, do you mean the length of the hypotenuse being 5 or the hypotenuse end points being (x1,y1) and (4,3). Or would they be the same thing... Question
Quote:
All I need to do now is use ratios to find how long the other two sides of your triangle is, these will be the x,y components of your velocity vector. In my example I said smallX is to bigX as 5 is to dist(x1,y1,x2,y2), or ... x/400 == 5/500.

I'd already finished gr.10 math, in which we do learn briefly about sine, cosine and tangents. However, we didn't start on anything like 'vectors'. What are they? They sound pretty damn important Razz but I'm not very familiar with them... at all. Anybody know a good source that they can link to or explain to me briefly on what they are?
Thx for all the help!

Author:  McKenzie [ Mon Feb 18, 2008 3:05 pm ]
Post subject:  Re: 2D Side Scrolling Shooting Towards Mouse

Vectors are measurements in a direction. 10m is a distance, 10m at a 30 degree angle is a vector. You can always break down a vector into it's horizontal and vertical components. So if I have vector 10m from the origin at an angle of elevation of 30 degrees, I could draw a triangle with 30 as the angle and find the x and y values with trig, like:
sin(30) = y/10
y = 10 * sin(30)
y = 5

The thing is your mouse position is already the x,y components of a vector (and getting the vector from some point to the mouse is straight forward as well). All you need is smaller vector that is proportionate. Consider this simple code:
code:
var mx,my,mb:int
loop
    mousewhere(mx,my,mb)
    cls
    for i: 1..10
        var x := round(mx/10 * i)
        var y := round(my/10 * i)
        drawfilloval(x,y,3,3,red)
    end for
    delay(20)
end loop

Author:  riveryu [ Mon Feb 18, 2008 6:37 pm ]
Post subject:  Re: 2D Side Scrolling Shooting Towards Mouse

Its good to see so many people helping this person in request to help him on a project. However in long terms, I think it is more beneficial in his/her respect that he/her should learn about Trig first, rather than rushing into the programming aspects first. (Aside from this, is'nt basic Trig (tan, cos, sine etc.) covered already in grade 10? It should be, atleast in Ontario which I assume all grade 10 studying Turing are at since its the standard.)

Here's a site for a short Trig intro: http://www.clarku.edu/~djoyce/trig/

Sry if this reply seems irrelevant to topic.

Author:  CodeMonkey2000 [ Mon Feb 18, 2008 6:44 pm ]
Post subject:  RE:2D Side Scrolling Shooting Towards Mouse

Most kids take programming in grade 9, even though it's a grade 10 course.

Author:  Silinter [ Mon Feb 18, 2008 6:44 pm ]
Post subject:  Re: 2D Side Scrolling Shooting Towards Mouse

Silinter @ Mon Feb 18, 2008 2:40 pm wrote:

I'd already finished gr.10 math, in which we do learn briefly about sine, cosine and tangents. However, we didn't start on anything like 'vectors'. What are they? They sound pretty damn important Razz but I'm not very familiar with them... at all. Anybody know a good source that they can link to or explain to me briefly on what they are?
Thx for all the help!

Yes, I already did basic trig last semester, I just didn't know where to start in applying that into programming.

Author:  CodeMonkey2000 [ Mon Feb 18, 2008 6:46 pm ]
Post subject:  RE:2D Side Scrolling Shooting Towards Mouse

That's where you need to think outside the box Very Happy Take a paper and pencil and really think about what's happening.

Author:  Silinter [ Mon Feb 18, 2008 7:21 pm ]
Post subject:  Re: RE:2D Side Scrolling Shooting Towards Mouse

CodeMonkey2000 @ Mon Feb 18, 2008 6:46 pm wrote:
That's where you need to think outside the box Very Happy Take a paper and pencil and really think about what's happening.

Exactly what I'm doing!

EDIT: Alright, hopefully my last question about this topic (no, I'm sure there'll be more) is how would you make turing solve for a variable?
Let's say I have sin*233 degrees = x/10, how could I make turing solve for x? I know it's right under my nose but I can't quite figure it out. It probably is one of the most basic stuff in turing so excuse me if it's stupid, I can't think straight today...

Author:  riveryu [ Mon Feb 18, 2008 7:47 pm ]
Post subject:  Re: 2D Side Scrolling Shooting Towards Mouse

CodeMonkey2000 wrote:

That's where you need to think outside the box..

seems to be Code words for ' figure it out yourself ' . In all my years of programming experience (2 weeks), i dont see anything that requires too much thinking in programming and math relation. I mean programming is not that irrelevant to math that you need hours to visualize the relation, its as easy as imaginary numbers.

when your writing a shooter game, u have a mouse coordinate, a projectile, a target object right? The projectile part; i thought u could juz animate the image of the projectile in relation to the mouse's coordinates and/or the target.
The concept doesnt seem difficult atleast.... However, i have no right to comment on any technical aspects.

Here is a random advice that came up in my mind after looking at recursive functions and forloops... "Think like a computer."

sry if my previous or this comments were unthoughtful.

Author:  Silinter [ Mon Feb 18, 2008 8:17 pm ]
Post subject:  Re: 2D Side Scrolling Shooting Towards Mouse

Oh wow, nvm about that last question, I told you I couldn't think today....

Author:  Clayton [ Mon Feb 18, 2008 8:36 pm ]
Post subject:  RE:2D Side Scrolling Shooting Towards Mouse

What in God's Name is "juz"?

Author:  CodeMonkey2000 [ Mon Feb 18, 2008 8:38 pm ]
Post subject:  RE:2D Side Scrolling Shooting Towards Mouse

It's a type of juice. That or riveryu typing in his foreign accent.

Author:  Silinter [ Mon Feb 18, 2008 8:56 pm ]
Post subject:  Re: 2D Side Scrolling Shooting Towards Mouse

THANK YOU ALL! I had just solved my angle problem! Not my projectile one... I'll have to solve that a bit later. Damn that took a long time... thx to Bored for his angle function, and everyone else who helped...

Author:  CodeMonkey2000 [ Mon Feb 18, 2008 9:47 pm ]
Post subject:  RE:2D Side Scrolling Shooting Towards Mouse

Bored, when the adjecent is zero, you should return 90/270 degrees, not 0. This is what it should be:
Turing:
fcn GETANGLE (x1, y1, x2, y2 : real) : real
    /*Code by Bored - Febuary 17, 2008
     Returns the angle between two points (x1,y1) and (x2,y2)
     0 Degrees is oriented to the right of the screen, 90 is upawrd*/

    var opp := y2 - y1
    var adj := x2 - x1
    if adj = 0 then
        if y2 > y1 then
            result 90
        else
            result 270
        end if
    elsif opp >= 0 and adj > 0 then
        result arctand (opp / adj)
    elsif adj < 0 then
        result 180 + arctand (opp / adj)
    elsif opp < 0 and adj > 0 then
        result 360 + arctand (opp / adj)
    end if
end GETANGLE

Author:  Silinter [ Mon Feb 18, 2008 11:55 pm ]
Post subject:  Re: 2D Side Scrolling Shooting Towards Mouse

Alright, I followed McKenzie's instructions on velocity of a bullet and constructed a program similar to what I'd written up to test McKenzie's instructions before. Take a look;
code:
setscreen ("graphics:600,600,offscreenonly")
%declaring the variables
var initX, initY, targetX, targetY, shotX, shotY, velocity : int
var shotVx, shotVy, ratio : real
%setting the variables
initX := 100
initY := 100
targetX := 500
targetY := 400
velocity := 10
%set he shot's x and y values to start off at the initial position
shotX := initX
shotY := initY
loop
    %using Math.Distance to find the distance then dividing by the velocity to get the ratio
    ratio := Math.Distance (initX, initY, targetX, targetY) / velocity
    shotVx := (targetX - initX) / ratio
    shotVy := (targetY - initY) / ratio
    shotX += round (shotVx)
    shotY += round (shotVy)
    %visual output
    drawfilloval (initX, initY, 2, 2, black)
    drawfilloval (targetX, targetY, 2, 2, black)
    drawline (initX, initY, shotX, shotY, black)
    put shotX, "x ", shotY, "y"
    %should exit when the shot reaches the target
    exit when shotX = targetX and shotY = targetY
    View.Update
    delay (50)
    cls
end loop

Now, this works. But it only seems to work if initX and initY are either (100,100) or (400,400) and anything closer. When you try and set them to something like (600,400) it misses completely. I suspect it's that rounding I need to do in order for the drawline command to work, but as soon as it rounds, the rounded number will be drastically off and therefore will never hit the target. Any ideas on how to make it so that the line will always hit the target?
Also, let's say you made a game where a person would be shooting bullets, how could you make it so that there'd be enough variables to account for the bullets?
Thx again to everyone for all the help!

Author:  riveryu [ Tue Feb 19, 2008 10:19 pm ]
Post subject:  RE:2D Side Scrolling Shooting Towards Mouse

Slinter, do you mind if I store your code in a folder on my pc that one day I might copy and paste stuff from it to another program? Maybe, you should write the concept into a function so you can refer to the projectile calculations and stuff elsewhere in the program, is what ppl usually do to not repeat their code?

How do I have foreign accent? juz means "just" in Warcraft III Battlenet 's standard bad english develpement. I'm Chinese but with no accent.

Author:  McKenzie [ Tue Feb 19, 2008 10:36 pm ]
Post subject:  RE:2D Side Scrolling Shooting Towards Mouse

Silinter, keep all of your variables as real, then round them only when you need to draw.

Author:  Silinter [ Tue Feb 19, 2008 11:11 pm ]
Post subject:  Re: 2D Side Scrolling Shooting Towards Mouse

Ah good, ty McKenzie, I figured it out! And sure riveryu, go right ahead. Here's the working code if you need it for future reference... improve on it as you like, there's probably a lot to improve on anyway =\

code:
setscreen ("graphics:600,600,offscreenonly")
%declaring the variables
var initX, initY, targetX, targetY, velocity : int
var shotVx, shotVy, shotX, shotY, ratio : real
%setting the variables;
%initX and initY are the starting position, targetX and targetY are the target's position
initX := 27
initY := 58
targetX := 400
targetY := 400
velocity := 10
%set the shot's x and y values to start off at the initial position
shotX := initX
shotY := initY
loop
    %using Math.Distance to find the distance then dividing by the velocity to get the ratio
    ratio := Math.Distance (initX, initY, targetX, targetY) / velocity
    shotVx := (targetX - initX) / ratio
    shotVy := (targetY - initY) / ratio
    shotX += shotVx
    shotY += shotVy
    %visual output
    drawfilloval (initX, initY, 2, 2, black)
    drawfilloval (targetX, targetY, 2, 2, black)
    drawline (initX, initY, round (shotX), round (shotY), black)
    drawfilloval (round (shotX), round (shotY), 3, 3, black)
    put shotX, "x ", shotY, "y"
    put round (shotX), "Rx ", round (shotY), "Ry"
    View.Update
    delay (50)
    cls
end loop


Alright, I'm still trying to figure out how to make that code apply to multiple bullets, but I guess I'll finish that tomorrow. I've been trying to figure it out for a while, so if anyone still has enough sympathy left to help me it'd be extremely appreciated. And I don't mean apply that exact code to multiple bullets, just multiple bullets in general are confusing like hell, as well as WALKING while SHOOTING! It's quite a feat!

Author:  Bored [ Mon Feb 25, 2008 1:06 pm ]
Post subject:  Re: RE:2D Side Scrolling Shooting Towards Mouse

CodeMonkey2000 @ Mon Feb 18, 2008 9:47 pm wrote:
Bored, when the adjecent is zero, you should return 90/270 degrees, not 0. This is what it should be:
Turing:
fcn GETANGLE (x1, y1, x2, y2 : real) : real
    /*Code by Bored - Febuary 17, 2008
     Returns the angle between two points (x1,y1) and (x2,y2)
     0 Degrees is oriented to the right of the screen, 90 is upawrd*/

    var opp := y2 - y1
    var adj := x2 - x1
    if adj = 0 then
        if y2 > y1 then
            result 90
        else
            result 270
        end if
    elsif opp >= 0 and adj > 0 then
        result arctand (opp / adj)
    elsif adj < 0 then
        result 180 + arctand (opp / adj)
    elsif opp < 0 and adj > 0 then
        result 360 + arctand (opp / adj)
    end if
end GETANGLE

Thx Code, I didn't even realize I had done that. Musn't have been paying attention Sad


: