Community
SCI Programming => SCI Syntax Help => Topic started by: gumby on October 10, 2021, 12:48:55 PM
-
Is there any way to detect what the color of a pixel is (or the index # of the palette) when clicking on a view? I have several views that are very large and irregularly shaped and I'd like it so that the view only responds to a click when that click isn't on a transparent portion of it.
If not, I was thinking about solving this need with creating polygons on-the-fly that match the placement of the view on the screen. Anyone see any gotchas this this approach? One potential one that comes to mind is that I don't think I want to use any of the existing polygon types, unless maybe PTotalAccess would be appropriate?
-
Is there any way to detect what the color of a pixel is (or the index # of the palette) when clicking on a view? I have several views that are very large and irregularly shaped and I'd like it so that the view only responds to a click when that click isn't on a transparent portion of it.
IsItSkip kernel function detects whether a pixel in a cel is transparent. Usage something like:
(if (IsItSkip (view loop cel (- (event x?) (candidate nsLeft?)) (- (event y?) (candidate nsTop?))) ...then...)
(more code/checks are needed to avoid garbage results)
This code gets the x and y of the event being processed from an event variable, and the top/left corner of the view you're testing against. IsItSkip returns a simple TRUE if the pixel is transparent, FALSE otherwise.
This unfortunately will only work on the skip (transparent) color and not other colors.
Requires the LSL6 interpreter.
-
Thank you Lars, greatly appreciate the guidance. From an implementation perspective, the template game already handled it in Actor.sc. All I had to do in my code was set the signal for the views to $1000.
-
Follow up: The template game code doesn't work out-of-the-box with scaled views however.
In Actor.sc, I changed the onMe method of the View class to first check to see if the view is scaled and if it is compute the scale factor for x and y and use that in the IsItSkip check:
(method (onMe param1 param2 &tmp temp0 temp1 xScaleFactor yScaleFactor a b)
(if (IsObject param1)
(= temp0 (param1 x?))
(= temp1 (param1 y?))
else
(= temp0 param1)
(= temp1 param2)
)
(cond
((& signal $0080) 0)
(
(and (not (IsObject onMeCheck)) (& signal skipCheck))
(if (!= scaleX maxScale)
(= a (CelWide view loop cel))
(= b (- nsRight nsLeft))
(= xScaleFactor (+ (/ (- a (/ (+ b 1) 2)) b) 1))
else
(= xScaleFactor 1)
)
(if (!= scaleY maxScale)
(= a (CelHigh view loop cel))
(= b (- nsBottom nsTop))
(= yScaleFactor (+ (/ (- a (/ (+ b 1) 2)) b) 1))
else
(= yScaleFactor 1)
)
(if
(or
(not (if (or nsLeft nsRight nsTop) else nsBottom))
(and
(<= nsLeft temp0)
(<= temp0 nsRight)
(<= nsTop temp1)
(<= temp1 nsBottom)
)
)
(not
(IsItSkip
view
loop
cel
(* (- temp1 nsTop) xScaleFactor)
(* (- temp0 nsLeft) yScaleFactor)
)
)
)
)
(else (super onMe: temp0 temp1))
)
)
EDIT: Modified to include rounding
-
Makes sense that it wouldn't, IsItSkip works on arbitrary view cels, not on View instances.
-
It does, yeah. Just wanted to document it here just in case it helps someone else out in the future.