MouseChaser2

Contest: Mouse Chaser
For Contest Description, see Mouse Chaser

code format="vbnet" 'mouse chaser by tsh73 'for the Just Basic contest, November 2008 'variant 0 - starting point for the contest 'v 0.1 - with constant speed 'v 0.2 - move only on timer (so it not speed up then mouse moves) 'just a point on screen, chasing mouse 'quits on ESC 'v 0.3 variable speed (if far far avay), removed flicker (by "if too close, skip") and added refresh by F5 'v 0.4 working with drawing speed vector 'v 0.5 + wings. Kind of. 'v 0.6 mass rename of working vars 'v 0.7 + trail (needs arrays and stuff) 'v 0.8 make refresh on F5 work again
 * Entry #2: tsh73**

nomainwin

nPoints = 20 dim x(nPoints), y(nPoints), a(nPoints)

'open "mouse chaser - press ESC to quit" for graphics_nsb as #gr open "mouse chaser - press ESC to quit, F5 to refresh" for graphics_nsb_fs as #gr #gr, "down" #gr, "trapclose [trapcloseLabel]" #gr, "when characterInput [checkEsc]" #gr, "setfocus"    'for characterInput to work #gr, "when mouseMove [MouseMove]"

'global x, y   #gr, "rule XOR" #gr "color red" for i = 1 to nPoints x(i) = -100 y(i) = -100    'set it offscreen gosub [draw]   'draw first time next

timerFired=0 timerDelay = 1                 'you may need to increase this. Try 40 or 60. timer timerDelay, [timerUp]   'indeed I need the chaser run even if mouse won't move 'btw I KNOW that I wil not get less then 16 ms on XP. That's OK for me   wait

[timerUp] timer 0 timerFired=1 'fall through to mouseMove [MouseMove] if timerFired=1 then for i = 1 to nPoints 'update coords 'x = MouseX 'y = MouseY 'now, that's wrong. It's glued on a cursor. We want chase 'So we move it to MouseX, MouseY a bit ' "a bit" could be that you wish (...) if i = 1 then  'first sees mouse dx=MouseX-x(i) dy=MouseY-y(i) v=3 else           'others see previous dx=x(i-1)-x(i) dy=y(i-1)-y(i) v=0.8*v+0.2*3*(2-i/nPoints) 'use 0.8 v of previous, to pick up speed end if           r=sqr(dx^2+dy^2)

if r<2*v and clsRequest<>1 then goto [skip1]   'means we just stay atop mouse dxN=dx/r 'normalised dyN=dy/r if v<0.02*r then v=0.02*r  'speed up on large distance (like, then maximised) if clsRequest<>1 then gosub [draw] 'clear previous end if

x(i) = x(i)+v*dxN y(i) = y(i)+v*dyN 'print MouseX, MouseY 'get angle by dxN, dyN a(i)=atan2(dxN, dyN)+90 gosub [draw] 'draw in new position

[skip1] next i       #gr, "discard" if clsRequest=1 then clsRequest=0 end if       if clsRequest=2 then #gr,"cls" clsRequest=1 end if       timerFired=0 timer timerDelay, [timerUp]   'set next timer end if   wait

[checkEsc] key$ = left$(Inkey$, 2) if key$ = chr$(27) then goto [trapcloseLabel] if len(key$) =2 then if right$(key$, 1) = chr$(_VK_F5) then clsRequest=2 '2: asked, 1: cleared, 0: idle end if   wait

[trapcloseLabel] timer 0 'you have to use it - If you will use timer, that is   close #gr end

'-- 'returnable subs [draw] 'segLen=int(50*(1-i/nPoints)+3) segLen=int(50/i) #gr, "north ;set ";x(i) ;" ";y(i) #gr, "turn ";a(i) #gr, "turn 110; go ";segLen #gr, "turn 30; go ";segLen 'somehow draw mirror part #gr, "north ;set ";x(i) ;" ";y(i) #gr, "turn ";a(i) #gr, "turn -110; go ";segLen #gr, "turn -30; go ";segLen return

'-- 'functions function atan2(x,y) 'returns 0..360 degrees if abs(x)<0.001 then atan2 = 90+(y<0)*180 : exit function pi = 3.1415925 tan = y/x atn = atn(tan) select case case x>0 and y>0 atan2 = atn/pi*180 case x<=0 atn = atn + pi       atan2 = atn/pi*180 case else atn = atn + 2*pi atan2 = atn/pi*180 end select end function code