L
Lasse Svensson
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?
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?