Date: Thu, 16 Nov 1995 03:41:32 +0000 From: Matthew Caldwell <sexkittn@BURN.DEMON.CO.UK> Subject: Re: "On MouseOver": an Inspiration > -- In a movie script: > on enterFrame > repeat with x = 48 down to 1 > if the scoreColor of sprite x = 5 and rollover (x) then > set spriteCast = the castNum of sprite x > if the scriptText of cast spriteCast contains "on MouseOver" then mouseOver (script (spriteCast)) > end if > end repeat > endWell yes, but. The trouble is this actually requires 2 checks against each of the 48 sprites rather than only 1 as is the case with a simple rollover scan. So while it provides an additional layer of filtering -- you can set visibly in the score which sprites it'll care about -- it's actually slower (though probably not massively) than the usual brute force method. (As an aside, lazy evaluation would probably be a desirable development for Lingo...)
So, what's the alternative? Here, as everywhere, lists have a part to play. For instance, if you have a setup frame followed by a loop frame (hardly a revolutionary approach, after all), the setup can compile a list of the red-coloured sprites and the loop can then check only those:
-- compile script
on enterFrame
global gActiveSprites
set gActiveSprites = []
repeat with index = 48 down to 1
if the scoreColor of sprite index = 5 then
if the scriptText of cast (the castNum of sprite index)...
contains "on mouseover" then
add gActiveSprites, index
end if
end if
end repeat
end enterFrame
at this stage, gActiveSprites contains only a list of sprites, in front to
back order, that are coloured red in the score and accept a mouseover
message (though remember what JD pointed out re the scriptText check -- a
no go in projectors or dxrs). The actual checking on the next frame can
then be reduced to:
-- looping rollover check
on enterFrame
global gActiveSprites
repeat with spr in gActiveSprites
if rollover(spr) then mouseOver(script (the castNum of sprite spr))
end repeat
end enterFrame
This is still not ideal, of course, because as you loop the sprite will get
repeated mouseOver messages as long as the mouse stays over it. You may
well also only want the topmost rollovered sprite to get a message, rather
than all of them (its not always so, but often). What you really need are
mouseEnter and mouseExit messages, so the sprite only needs to act when its
state changes.
Let's assume, then, that all the active sprites coloured red in the score and containing mouseEnter and mouseExit handlers have been collected in a previous frame just as above. The modified loop frame handler might look something like this:
on enterFrame
global gActiveSprites, gLastWithin
if getOne(gActiveSprites, gLastWithin) then
if rollover(gLastWithin) then return
mouseExit(gLastWithin)
end if
set gLastWithin = 0
repeat with spr in gActiveSprites
if rollover(spr) then
mouseEnter(script (the castNum of sprite spr))
set gLastWithin = spr
return
end if
end repeat
end enterFrame
Obviously, this script's longer than the previous one, but much of the time
it will actually have to do less. When the mouse is over the same sprite as
it was last time, the script looks no further. Only when it changes state
does it bother with the full scan. (Well, ok, this is not actually true:
when the mouse is over an inactive sprite, or no sprite at all, it has to
be checked every loop. To avoid this, place an "active" -- but inert --
sprite in channel 1, covering the whole stage. The script will then always
be able to bail out if the rollover hasn't changed.)
There's loads more, but it's nearly 3am so I guess I'll stop...