Omnimaga
Calculator Community => TI Calculators => ASM => Topic started by: chickendude on October 23, 2012, 08:45:26 am
-
I'm trying to put together a routine that will calculate the appropriate X/Y velocity to go towards an object. What i've got now is really buggy, i think the general algorithm/idea is ok though. My biggest hurdle so far has been handling negative numbers, as none of my routines for multiplication/division seem to like negative numbers. What i'm currently doing is really just adjusting the Y velocity and not bothering with the X velocity. The general equation is something like this:
(object Y - bullet Y)/(object X - bullet X)
The X/Y velocities have 5 bits which act as a decimal place, but this doesn't let me use it. I hacked in the ability to handle negative numbers in the division routine (essentially turning all negative numbers positive, then negating the result afterward), but my multiplication routine doesn't like negatives numbers either.
-
Hmm, have you ever created a line drawing routine? Basically, take a point (x1,y1) and (x2,y2), and pretend you are drawing a line between them, but instead of drawing the pixels, use it as a path to draw your bullets. I am sure that finding the velocities would be a lot easier, though. Hopefully somebody comes along that knows more than I do!
-
If the input is negative just multiply it by -1. Then write a script which handles positive numbers only and then multiply the outcome by -1 if the input was smaller than zero.
-
I'm trying to put together a routine that will calculate the appropriate X/Y velocity to go towards an object. What i've got now is really buggy, i think the general algorithm/idea is ok though. My biggest hurdle so far has been handling negative numbers, as none of my routines for multiplication/division seem to like negative numbers. What i'm currently doing is really just adjusting the Y velocity and not bothering with the X velocity. The general equation is something like this:
(object Y - bullet Y)/(object X - bullet X)
The X/Y velocities have 5 bits which act as a decimal place, but this doesn't let me use it. I hacked in the ability to handle negative numbers in the division routine (essentially turning all negative numbers positive, then negating the result afterward), but my multiplication routine doesn't like negatives numbers either.
Ok, so basically, I'm assuming this is what you want to happen:
Angle = atan2(x, y)
xVel = cos(angle)
yVel = sin(angle)
Now, yes, this will work, but it's not going to be very fast. Atan2 is just arcTangent that will give you the angle even if it's in the [90,270] region, but that thing is a little annoying to implement. Cos and Sin aren't that hard, but require lookup tables.
Before I explain this, to make things easier, dX = object X - bullet X and dY = object Y - bullet Y.
What I recommend you do is treat this as a vector problem (sorry, I'm currently in calc 3). Basically, you have your direction vector <dX, dY>. So there is no need to recalculate the direction. All you need to do is scale it to the right speed.
So, the way to do this is to first find the length of the direction vector : length = sqrt(dX^2 + dY^2). And then to scale it to the right speed, divide by the length and multiply by the new speed: <dX, dY>/length*speed.
In the end, here's what you get:
length = sqrt(dX^2 + dY^2)
xVel = (objectX - bulletX)/length*speed
yVel = (objectY - bulletY)/length*speed
The only tricky part of this routine is the square root, but I know I've seen a few around here, so that shouldn't be too difficult.
-
Or the quick and dirty way:
if x < objectX {x++}
if x > objectX {x--}
if y < objectX {y++}
if y > objectX {y--}
It is not pretty, but Δy/Δx will be the same and it will move somewhat diagonally.
-
Or the quick and dirty way:
if x < objectX {x++}
if x > objectX {x--}
if y < objectX {y++}
if y > objectX {y--}
It is not pretty, but Δy/Δx will be the same and it will move somewhat diagonally.
Aside from looking awful, I don't think that would work for this purpose because typically bullets don't change direction after being fired :P
-
Awesome, that's exactly what i needed. I remembered A2 + B2 = C2 but was afraid i'd have to use sine/cosine (and an LUT) which seemed like a lot of work/memory for something that's not that important. I looked at a couple line-drawing routines but they were just way above my head. It's for a boomerang-effect, but only on the way back (the angle should be constant on the way out).
The routine i used is pretty buggy.
Actually, i'm gonna try to implement that right now :)
EDIT: ;)
-
Or the quick and dirty way:
if x < objectX {x++}
if x > objectX {x--}
if y < objectX {y++}
if y > objectX {y--}
It is not pretty, but Δy/Δx will be the same and it will move somewhat diagonally.
Aside from looking awful, I don't think that would work for this purpose because typically bullets don't change direction after being fired :P
True :P
-
Ok, i just tried to write this out but i'm a little confused as to what "speed" is. It seems to me that speed and length are the same? But that can't be right. Right now, bullet x velocity is 96 (%01100000: moving 3 (%011) pixels every frame) when y velocity = 0, so that should mean that length is also 96, right? It seems to me like:
velX = length/(objX-bullX) * speed
velY = length/(objY-bullY) * speed
..would be more accurate, as shouldn't a larger distance between the object and the bullet give a lower velocity?
-
You divide by length because you want the speed to be the same no matter what the distance is.
-
So what is the speed, then? Would speed be "96"? I'm trying to figure out how to calculate the initial velocities.
Let's simplify 96 to 3.
object = 10,10 (x,y)
bullet = 5,2
length = sqrt(32+02)
length = 3
xVel = (10-5)/3*...3? -> 5/1 xVel = 5
yVel = (10-2)/3*3 -> 8/1 yVel = 8
If i change speed to one:
xVel = (10-5)/3*1 -> 5/3 xVel = 1 2/3
yVel = (10-2)/3*1 -> 8/3 yVel = 2 2/3
I don't quite get what values i'm supposed to be using. :/
EDIT: Maybe i've got it now, i'll test it out tomorrow and see.
-
Speed is simply how fast you want your bullets to move. 8 would be 8 pixels per frame, 1 would be 1 pixel per frame, and 96 would be 96 pixels per frame. (Assuming the units on xVel are pixels/frame of course)
You can set it to whatever you want.
-
So what is the speed, then? Would speed be "96"? I'm trying to figure out how to calculate the initial velocities.
Let's simplify 96 to 3.
object = 10,10 (x,y)
bullet = 5,2
length = sqrt(32+02)
length = 3
xVel = (10-5)/3*...3? -> 5/1 xVel = 5
yVel = (10-2)/3*3 -> 8/1 yVel = 8
If i change speed to one:
xVel = (10-5)/3*1 -> 5/3 xVel = 1 2/3
yVel = (10-2)/3*1 -> 8/3 yVel = 2 2/3
I don't quite get what values i'm supposed to be using. :/
EDIT: Maybe i've got it now, i'll test it out tomorrow and see.
No, you calculate length as sqrt((10-5)2+(10-2)2). However, you'll probably want to multiply by speed before you divide by length to prevent integer division roundoff errors (simply dividing by length will give you something between 0 and 1, after all, which would round down to 0).
-
Thanks, i figured that out later. I was confusing dX/Y with velX/Y. :)
-
So i wrote out a little routine to calculate all of that and it worked nicely, i realized later that the problems with my first routine weren't (completely) due to that part of the code but rather an error in the main draw/update coordinates loop where i had reused 'd' to set some other registers to 0 when 'd' wasn't 0. After that i rewrote another routine which ignores X velocity (it's always +/- BULLET_SPEED) but is much faster (no square root, only one multiplication/division call) and i think works fine enough :)
EDIT: ;)
-
Holy balls that looks nice.
-
Holy balls that looks nice.
QFT :D
-
Wow, that is looking excellent!
-
WOW! That looks FULLY sick!
-
That looks great! I reminds me of Super Mario World for the NES when you are on the ship and trying to get the key/wand (I don't remember) from the turtle guy to save the princess.
-
Oh my the epicness :O
-
I was just wondering, is it a static route? Like are are you trying to make it move towards a specific point (like enemy_x + 10 or whatever) or does it try to aim for the player? If its the former you could have hard-coded the offsets.
-
That indeed looks very nice. I would love to see a new Mega Man clone for calcs, preferably one that is almost as good as the original, not one made just to have a Megaman game for calcs like the other one on Ticalc (not that it was bad, but a lot better can be done for calcs). :P
-
Tr1p1ea: It aims towards a set of coordinates. For the boomerang, going out it gets an initial angle/velocity aimed at the player and follows a straight path until it hits the edge of the screen. Then it comes back, this time updating the angle every frame based on the boss's position so that it returns to the boss. This is one of the more boring bosses :P