Making an object follow another object - FAIL!

First of all, I’m new to the forum (and to ruby) so hi everyone!

I’ve started playing around with Ruby, and I decided to see if I could
do anything fun with the sdl extension library. I started by just
putting a spinning object on the screen, and then worked out from there.
I’ve built this program mainly by trial and error, and I haven’t
bothered with using classes or defs yet, so it’s a bit messy.

Anyway, I’ve gotten so far as to have an object moving randomly around
the screen, and now I’m trying to make another object follow the first
one.

My code so far (messy):

require ‘sdl’
include Math

SDL.init( SDL::INIT_VIDEO )
screen = SDL::setVideoMode(640,480,16,SDL::SWSURFACE)

image = SDL::Surface.loadBMP(“icon.bmp”)
image.setColorKey( SDL::SRCCOLORKEY , image[0,0])
image = image.displayFormat

angle = 0 #Angle for object 1
angle2 = 0 #Angle for object 2
xpos = 100.000000000000000000000 #X-coord for object 1
ypos = 100.000000000000000000000 #Y-coord for object 1
x2pos = 100.000000000000000000000 - image.w #X-coord for object 2
y2pos = 100.000000000000000000000 #Y-coord for object 2
xspeed = 1 #Speed in X
yspeed = 1 #Speed in Y
a_count = 0 #Counter for determining
angle
a_dur = 100 #sets how long object
shold spin before changing direction
a_change = 0 #determines change in
angle
a_slow = 1 #Determines how slow
object turns
a_update = 0 #same as above

while true

event = SDL::Event2.poll
case event
when SDL::Event2::Quit
exit
when SDL::Event2::KeyDown
exit if event.sym == SDL::key::ESCAPE
end

#Determines if the angle should incline or decline,
#and sets how long before the next change
a_count += 1
if a_count == a_dur

a_count = 0
a_dur = rand(250) + 50
a_change = rand(3) -1

end

#Sets the angle and how slow the object should turn. The higher
#a_slow is, the slower it will turn.
#Also sets the angle for object 2.
a_update += 1
if a_update == a_slow

angle += a_change
angle2 = (atan((y2pos-ypos) / (x2pos-xpos)))/(PI/180)
a_update = 0

end

#Makes sure the angles are always between 1 and 360.
if angle > 360
angle = angle - 360
end

if angle < 1
angle = angle + 360
end

if angle2 > 360
angle2 = angle2 - 360
end

if angle2 < 1
angle2 = angle2 + 360
end

puts angle2

#Determines the new X an Y positions for the objects.

xpos = xpos + (cos(angle*(PI/180))xspeed )
ypos = ypos + (sin(angle
(PI/180))*yspeed )

x2pos = x2pos + (cos(angle2*(PI/180))xspeed )
y2pos = y2pos + (sin(angle2
(PI/180))*yspeed )

#Makes object 1 bounce

if xpos >= 640 - image.w/2
xpos = 638 - image.w/2
angle = 180 - angle
end

if xpos <= 0 + image.w/2
xpos = 2 + image.w/2
angle = 540 - angle
end

if ypos >= 480 - image.h/2
ypos =478 - image.h/2
angle = 360 - angle
end

if ypos <= 0 + image.h/2
ypos = 2 + image.h/2
angle = 360 - angle
end

if x2pos >= 640 - image.w/2

x2pos = 638 - image.w/2

angle2 = 180 - angle2

end

if x2pos <= 0 + image.w/2

x2pos = 2 + image.w/2

angle2 = 540 - angle2

end

if y2pos >= 480 - image.h/2

y2pos =478 - image.h/2

angle2 = 360 - angle2

end

if y2pos <= 0 + image.h/2

y2pos = 2 + image.h/2

angle2 = 360 - angle2

end

screen.fillRect(0,0,640,480,[100,100,100])

SDL.transformBlit(image,screen,angle,1,1,image.w/2,image.h/2,xpos,ypos,0
)
SDL.transformBlit(image,screen,angle2,1,1,image.w/2,image.h/2,x2pos,y2pos,0
)

screen.updateRect(0,0,0,0)

end

My question is a mathematical one, here we go:

As you can see here " angle2 = (atan((y2pos-ypos) /
(x2pos-xpos)))/(PI/180)" I determined the angle of the second object by
calculating the angle between the two objects. It works as long as
angle2 is less than 90 or more than 270, but if it gets between there it
breaks away.

Is there any problems with my math, or is there some other problem
somewhere in the code that makes it behave like that?

On Thu, Feb 14, 2008 at 8:48 PM, Lasse S. [email protected]
wrote:

My question is a mathematical one, here we go:

As you can see here " angle2 = (atan((y2pos-ypos) /
(x2pos-xpos)))/(PI/180)" I determined the angle of the second object by
calculating the angle between the two objects. It works as long as
angle2 is less than 90 or more than 270, but if it gets between there it
breaks away.

Is there any problems with my math, or is there some other problem
somewhere in the code that makes it behave like that?

I’m not going to help with the math, but is there some reason why you
don’t just keep a position buffer, the length of which (the length of
the array) determines the distance between the two sprites? That way,
it just follows a path instead of an angle.

Todd

My trig class was a long time ago, but from what I recall certain
trigonometric functions are only positive in certain quadrants (angle
ranges). This seems to touch on that:

Lasse S. wrote:

My question is a mathematical one, here we go:

As you can see here " angle2 = (atan((y2pos-ypos) /
(x2pos-xpos)))/(PI/180)" I determined the angle of the second object by
calculating the angle between the two objects. It works as long as
angle2 is less than 90 or more than 270, but if it gets between there it
breaks away.

Compare Math.atan and Math.atan2. Math.atan2 relieves you from doing a
manual branching depending on the angle.

Regards
Stefan

Todd B. wrote:

I’m not going to help with the math, but is there some reason why you
don’t just keep a position buffer, the length of which (the length of
the array) determines the distance between the two sprites? That way,
it just follows a path instead of an angle.

Todd

Yeah I had that idea too, but I’d already started trying to figure how
to use the angle. And I could feel I was close, so I didn’t really want
to start over with another idea.

Now I’ve done that anyway, and it works, so thanks for the advices.