#!perl -w # Wanderer v1.1 # by Kevin Reid # # Wanders around and avoids bright spots. # Hold down the command key to stop movement. # # Version History # 1.1 # * Window can be dragged # * Runs faster in background # * Implemented cmd-key freeze # 1.0 # * Initial release use Mac::QuickDraw; use Mac::Windows; use Mac::Events; 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; } elsif ($msg == wHit) { if (PtInRgn($param, $win->contRgn)) { return wInContent; } } return 0; } $BoundRgn = GetGrayRgn(); $Lock = 0; $GWindow = new MacColorWindow ( $wrect = new Rect(0,0,12,12), 'WBouncer', 1, \&CircDef_1, 0, ); $GWindow->sethook(redraw => sub { my $rect = $wrect; RGBForeColor(new RGBColor(32767, 0, 0)); PaintOval($rect); }); $GWindow->sethook(click => sub { my ($self, $pt) = @_; DragWindow $self->window, LocalToGlobal($pt); my $loc = $self->window->contRgn->rgnBBox->topLeft; $pos{'x'} = $loc->h; $pos{'y'} = $loc->v; }); $GWindow->sethook(idle => sub { my ($self) = @_; $Lock = $Mac::Events::CurrentEvent->modifiers & cmdKey; }); WaitNextEvent; WaitNextEvent; WaitNextEvent; $vrect = InsetRect $GWindow->window->portRect, 2, 2; %pos = ('x' => 50, 'y' => 50), %oldpos = ('x' => 0, 'y' => 0), %vel = ('x' => rand 3, 'y' => rand 3), $lim = 65535 * .5; $tick = 0; while ($tick++, $GWindow->window) { unless ($Lock) { foreach (qw(x y)) { my $did = 0; $oldpos{$_} = $pos{$_}; $pos{$_} += $vel{$_}; $p = new Point($pos{'x'}+5+ext($vel{'x'}), $pos{'y'}+5+ext($vel{'y'})); $bright = (map +(($_->red + $_->green + $_->blue) / 3), map $c = GetCPixel($_->h, $_->v), GlobalToLocal $p)[0]; if (!PtInRgn($p, $BoundRgn) or $bright > $lim) { $vel{$_} *= -.78; $pos{$_} = $oldpos{$_}; } SetPort $GWindow->window; RGBForeColor $c; PaintOval $vrect; $vel{$_} += rand(.3) - .15; }} MoveWindow $GWindow->window, $pos{'x'}, $pos{'y'}, 0; WaitNextEvent(1); } sub ext { my ($vel) = @_; ($vel <=> 0) * 6; } END { $GWindow->dispose if $GWindow; } __END__