Hello,
A quick bandage for this is to switch the x and y positions in atanfull. Since this is cartesian coordinates( screen x and y) you want to make sure the slope is being calculated as (y2-y1)/(x2-x1). If you use
atanful(x,y) it will have the wrong slope - using (x2-x1)/(y2-y1).
The other thing, I just used trig. I couldn't get it to work with newxvalue and newyvalue so I used sin and cosine. Here is you version with those minor changes I just mentioned. It's still buggy, but it's closer to what I think you were going for:
set display mode 1152,864,16
sync on: sync rate 30
radius#=25
X#=rnd(screen width()-radius#*2)+radius#
Y#=rnd(screen height()-radius#*2)+radius#
ink 0,0
do
cls 9868950
print rgb(150,150,150)
timer=timer-1
if sqrt((((mouseX()-X#)/2)^2)+(((mouseY()-Y#)/2)^2))<13.5 and timer<0
angle#=atanfull(y#-mousey(),x#-Mousex())
speed#=abs(mousemoveX()+mousemoveY())/2
timer=6
endif
`X#=newXvalue(X#,angle#,speed#)
`Y#=newZvalue(Y#,angle#,speed#)
x#=speed#*cos(angle#)+x#
y#=speed#*sin(angle#)+y#
Xold#=X#
Yold#=Y#
if X#>screen width()-radius#/2 and timer<0 then angle#=atanfull(Oldy#-y#,x#-Oldx#):timer=6
if X#<radius#/2 and timer<0 then angle#=atanfull(Oldy#-y#,x#-Oldx#):timer=6
if Y#>screen height()-radius#/2 and timer<0 then angle#=atanfull(y#-Oldy#,Oldx#-x#):timer=6
if Y#<radius#/2 and timer<0 then angle#=atanfull(y#-Oldy#,Oldx#-x#):timer=6
circle X#,Y#,Radius#
sync
loop
I whipped up another version similar to yours. My original intent was to get rid of all of the floats because there are no fractions when it comes to screen positions - but I changed my mind because of rounding and things like that.
Anyway, in an attempt to get over the mouse position problem in regards to speed, I created my own mouse pointer and a function to control it's speed.
mousemove(speed#) - where speed controls the pointer speed. Put a fraction in there to use only a percent of the actual mouse speed and slow it down. Put a whole number in there to multiply the speed by that amount. This isn't the same speed that get's transferred to the circle, that is still the
mousemovex() and
mousemovey() average.
I use
curvevalue to interpolate the circle's movement over time. I was guessing that is why you had the timer variable. This version is quite buggy also, but I was trying for a few optimizations including getting rid of your distance calculation.
If you move the mouse to fast, it draws two circles. I don't know why.
rem swat cicrle
rem latch 05/26/2007
set display mode 800,600,16
sync on
sync rate 60
hide mouse
rem seed the random generator
randomize timer()
grey=rgb(150,150,150)
rem create mouse pointer
cls 0
ink RGB(0,255,255),0
box 0,0,8,8
line 8,8,16,16
get image 1,0,0,17,17
sprite 1,screen width()/2,screen height()/2,1
cls 0
ink grey,0
circle 25,25,25
get image 2,0,0,26,26
rem intialize
radius=25
x#=rnd(screen width()-(4*radius))+radius*2
y#=rnd(screen height()-(4*radius))+radius*2
newx#=x#
newy#=y#
cls grey
ink 0,0
circle x,y,radius
rem main loop
do
cls grey
movemouse(.5)
text 0,0,str$(angle)
rem check if the pointer is hitting the circle
x1=x#-radius
x2=x#+radius
y1=y#-radius
y2=y#+radius
if mouse_within(x1,y1,x2,y2)
rem calculate angle
angle=wrapvalue((atanfull(y#-oldy,x#-oldx))*-1)
rem how fast is the mosue moving?
speed#=(abs(mousemovex())+abs(mousemovey()))/2.0
speed#=speed#*20
rem new postions of the circle
newx#=speed#*cos(angle)+x#
newy#=-1*speed#*sin(angle)+y#
`x=newx
`y=newy
endif
rem possible collision with screen border?
if newx# <= radius*2 or newx# >= screen width()-radius*2 then newx#=newx#*-1.0
if newy# <= radius*2 or newy# >= screen height()-radius*2 then newy#=newy#*-1.0
rem interpolate position over time
x#=curvevalue(newx#,x#,20)
y#=curvevalue(newy#,y#,20)
circle x#,y#,radius
oldx=sprite x(1)
oldy=sprite y(1)
sync
loop
end
function movemouse(speed#)
x=sprite x(1)+(mousemovex()*speed#)
y=sprite y(1)+(mousemovey()*speed#)
if x > screen width() then x=screen width()-1
if x < 0 then x=0
if y > screen height() then y=screen height()-1
if y < 0 then y=0
sprite 1,x,y,1
endfunction
function mouse_within(x1,y1,x2,y2)
result=0
sx=sprite x(1)
sy=sprite y(1)
if sx>=x1 and sx<=x2 and sy>=y1 and sy <=y2
result=1
endif
endfunction result
Enjoy your day.