[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

Re: [MacPerl-Toolbox] Re: WindowBounce



Alan Fry <ajf@afco.demon.co.uk>  wrote:

> 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.

Thank you.

>         $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().

I have fixed this. A new version is at the end of this message.

> 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.

This will not work correctly on multiple-monitor systems.

-- 
 Kevin Reid: |    Macintosh:      
  "I'm me."  | Think different.

--------------------------------------------------------------------

#!perl -w

# WindowBounce v1.1
# by Kevin Reid
#
# Version History
# 1.1
#   * Now correctly handles lack of a front window.
# 1.0
#   * Initial release

use Mac::QuickDraw;
use Mac::Windows;
use Mac::Events;

use constant LOSS => 0.98;
use constant GRAV => 0.8;
use constant BOOSTVEL => 35;

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 = FrontWindow() ?
  XorRgn(GetGrayRgn(), FrontWindow()->strucRgn)
  : CopyRgn(GetGrayRgn());

$GWindow = new MacColorWindow (
  $wrect = new Rect(0,0,10,10),
  'WBouncer',
  1,
  \&CircDef_1,
  0, 0, (FrontWindow || ())
);
$GWindow->sethook(redraw => sub {
  my $rect = $wrect;

  for (my $shade = 65535; $shade >= 0; $shade -= 15000) {
    RGBForeColor(new RGBColor($shade, 0, 0));
    PaintOval($rect);
    $rect = InsetRect($rect, 1, 1);
  }
});
WaitNextEvent;
WaitNextEvent;
WaitNextEvent;
SetPort $GWindow->window;
InvertRgn($BoundRgn);

%pos    = ('x' => -50, 'y' => -50),
%oldpos = ('x' => 0, 'y' => 0),
%vel    = ('x' => rand 10, 'y' => rand 10),

$tick = 0;
while ($tick++, $GWindow->window) {


  foreach (qw(x y)) {
    my $did = 0;

    $oldpos{$_} = $pos{$_};
    $pos{$_} += $vel{$_};
    if (!PtInRgn(new Point($pos{'x'}+5, $pos{'y'}+5), $BoundRgn)) {
      $vel{$_} *= - LOSS;
      $pos{$_} = $oldpos{$_};
      $did = 1;
    }
    if ($did and abs($vel{$_}) < 1.5) {
      $vel{$_} = BOOSTVEL;
    } 
  }

  MoveWindow $GWindow->window, $pos{'x'}, $pos{'y'}, 0;

  $vel{'y'} += GRAV;

  unless ($tick % 20) {
    SendBehind($GWindow->window, FrontWindow());
    DisposeRgn $BoundRgn;

    if (${FrontWindow()} == ${$GWindow->window}) {
      $BoundRgn = CopyRgn(GetGrayRgn());
    } else {
      $BoundRgn = XorRgn(GetGrayRgn(), FrontWindow()->strucRgn);
      until (PtInRgn(new Point($pos{'x'}+5, $pos{'y'}+5), $BoundRgn)) {
        $pos{'x'} = rand $BoundRgn->rgnBBox->right;
        $pos{'y'} = rand $BoundRgn->rgnBBox->bottom;
      }
    }
  }
  WaitNextEvent;
}

END {
  $GWindow->dispose if $GWindow;
}    

__END__

==== Want to unsubscribe from this list?
==== Send mail with body "unsubscribe" to macperl-toolbox-request@macperl.org