Kevin Reid posted his script "WindowBounce" on the 5th May 1999. As with previous postings, Kevin's script is a joy of originality and ingenuity. I admire enormously the economy of code (for instance the reflection routine) where so much is accomplished in so few words. The strategy underlying the script, as I understand it, is to confine the bouncing ball to the region of the screen which is not already occupied by the script's window. The region is defined by: $BoundRgn = XorRgn(GetGrayRgn(), FrontWindow()->strucRgn); This has the drawback that the script can only be run if the script window is first opened. Otherwise XorRgn() fails for the lack of a FrontWindow(). That means the script cannot be run from "Script-Run" or BBedit for example. An alternative strategy is to look for edges around the confining region, using FindWindow() to detect a window border and PtInRect() to detect a screen border. A version of the script using this approach is appended and I hope Kevin will forgive me for bowdlerising his work in this way. It can be run from BBedit, and recognises any (reasonable) number of MacPerl open windows. Two issues came to mind. Firstly FindWindow() returns a GrafPtr for any MacPerl window which is open, which is expected and, as it happens, useful in this context. However FndWindow() returns 0 for any other open window (for instance a BBEdit window) and I wonder if this behaviour is correct? I feel it's probably wrong. Secondly the script, both Kevin's original and this slightly modified version, call Point->new() repeatedly. It would seem beter practice to modify an existing 'point' using the construction $pt->h(N) rather than to keep creating new points? However this eats memory. So it seems that perhaps the problem Kevin unearthed in which $col->red(N) eats memory is more widespread than just a problem with RGBColor(). If so, it seems to me quite important, for there are many occasions (for instance resizing rectangles and regions) where it is nigh impossible to _avoid_ the construction. Does anyone have any thoughts on these two issues? Alan Fry =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #!perl -w use Mac::QuickDraw; use Mac::Windows; use Mac::Events; use strict; my(%pos, %oldpos, %vel, $GWindow, $wrect, $scrn); use constant LOSS => 0.98; use constant GRAV => 0.8; use constant BOOSTVEL => 32; %pos = ('x' => 10, 'y' => 30); %oldpos = ('x' => 0, 'y' => 0 ); %vel = ('x' => rand 10, 'y' => rand 10); $wrect = new Rect(0,0,10,10); $scrn = GetMainDevice()->gdRect; $scrn->top($scrn->top + 20); $GWindow = new MacColorWindow ($wrect, '', 1, \&CircDef_1, 0); $GWindow->sethook('redraw', \&shade); sub CircDef_1 { my ($variant, $win, $msg, $param) = @_; if ($msg == wCalcRgns) { my $r = OffsetRect( $win->portRect, -$win->portBits->bounds->left, -$win->portBits->bounds->top ); my $circ = NewRgn(); OpenRgn; FrameOval $r; CloseRgn $circ; CopyRgn $circ, $win->contRgn; CopyRgn $circ, $win->strucRgn; } return 0; } sub shade{ my $r = $wrect; for (my $shade = 65535; $shade >= 0; $shade -= 15000) { RGBForeColor(new RGBColor($shade, 0, 0)); PaintOval($r); $r = InsetRect($r, 1, 1); } } while ($GWindow->window) { if (FindWindow($GWindow->window->strucRgn->rgnBBox->topLeft)) { $pos{'x'} = rand $scrn->right; $pos{'y'} = (rand ($scrn->bottom - $scrn->top)) + $scrn->top; MoveWindow $GWindow->window, $pos{'x'}, $pos{'y'}, 0; next; } foreach my $j (qw(x y)) { $oldpos{$j} = $pos{$j}; $pos{$j} += $vel{$j}; if (test()) { $vel{$j} *= - LOSS; $pos{$j} = $oldpos{$j}; if ( abs($vel{$j}) < 1.5 ) { $vel{$j} = BOOSTVEL } } } MoveWindow $GWindow->window, $pos{'x'}, $pos{'y'}, 0; $vel{'y'} += GRAV; WaitNextEvent; } sub test { my($code, $ptr, $tl); my $found = 0; $tl = Point->new(($pos{'x'}), ($pos{'y'})); ($code, $ptr) = FindWindow($tl); if ($ptr and $$ptr != ${$GWindow->window}) { $found = 1 } if ($found or !PtInRect($tl, $scrn)) { return 1 } else { return 0 } } END { $GWindow->dispose if defined $GWindow } =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= ==== Want to unsubscribe from this list? ==== Send mail with body "unsubscribe" to macperl-toolbox-request@macperl.org