I've been looking at the DrawingSurface functions such as:
DrawingSurface.DrawingColor property
DrawingSurface.DrawCircle
DrawingSurface.DrawImage
DrawingSurface.DrawSurface
etc.
I almost have in my head the solution to my problem, but can't quite bring it together - perhaps somone might know the answer?
Problem:
I want to draw a circle, at position x,y, of one background image; on to the main background image.
example: There are two background images - 1 and 2 - same size, with a 1-to-1 relationship to eachother. I want to take a circle of background 1 (at say, the mouse x,y at that given moment), and copy it to (or 'project it on') background 2. This way, wherever the mouse goes, the user will see a small circle of the 'hidden' image.
(This is similar to the 'tunnel of love' scene in Sam and Max Hit The Road - if anyone knows it - where using the blacklight torch allows you to see through the background to another, hidden background)
(https://cdn2.bigcommerce.com/server5900/00cb3/products/126/images/230/UV-ultraviolet-LED-blacklight-2__21318.1269930061.1280.1280.jpg?c=2)
In the above image, there is a $20 note, with it's main 'background' (of green and white) on it; and another (hidden) 'background' of purple, revealing a hidden object (magnetic stripe).
Solution:
DrawingColor property can be set to 'COLOR_TRANSPARENT', allowing transparency to be drawn on to the surface - but what's behind it? The 2nd frame of background? Or....?
DrawCircle let's me draw a filled circle shape, at position x,y, with the DrawingColour (COLOR_TRANSPARENT), on the background - but how does it relate to the 2nd background?
DrawImage allows me to draw an image sprite on to the background, but only a single sprite;
DrawSurface allows me to set one image, with certain amount of transparancy, on top of another; but a circle of it? A piece of it? Maybe, probably not...
Solution: not found.
What should I do, AGS community?
My room is called 'beach'.
function room_RepExec()
{
DrawingSurface *bg0 = Room.GetDrawingSurfaceForBackground();
bg0.DrawImage(0, 0, 437, 0); //beach, no changes
bg0.DrawingColor = 965; //(colour doesn't matter, just tinges circle with green)
bg0.DrawCircle(mouse.x, mouse.y, 100); //draw a circle
bg0.DrawImage(0, 0, 436, 90); //beach, some changes
bg0.Release(); //release
}
OUTSIDE the circle: 'beach' background (solid), 'beach some changes' background almost totally transparent, still slightly visible.
INSIDE the circle: 'beach' is totally invisible, and 'beach with changes' is totally opaque. The circle makes the difference a lot more obvious.
But how do I make 'beach with changes' completely invisible OUTSIDE the circle? Why can't I have what's inside the circle -- but the opposite?
How does this thing even work?
This has taken me allm day: please help.
Eureka!
Useful for anyone else trying to do the same thing:
function room_RepExec()
{
DynamicSprite *sprite = DynamicSprite.CreateFromExistingSprite(442, true); //dynamic sprite that has the room background + changes (visible to, eg., a blacklight)
sprite.Crop(mouse.x-65, mouse.y-65, 120, 120); //have a small 120x120 square of the background, at mouse x,y (+/- some things to centre in cursor image)
DrawingSurface *surface =Room.GetDrawingSurfaceForBackground(); //get a drawing surface from the current room
surface.DrawImage(mouse.x-65, mouse.y-65, sprite.Graphic, 20); //draw this sprite graphic ('room b/g with changes') at the current mouse x,y
surface.DrawImage(0, 0, 441, 90); //draw an image of the room (without changes) on-top
surface.Release(); //destroy
sprite.Delete();
}
Try it out and tell me if this works for you too...
Only one problem:
Can't get a circle shaped window to the 'hidden' room to work, only a square one.
Help?
Create a circle sprite of the same size, then use
sprite.CopyTransparencyMask(123); // 123 = slot number of circle sprite
Thankyou!
Following on, I'm now having a problem with hidden objects.
I try the code:
if (CandleLit==true) {
oMcguffin.Visible=true;
oMcguffin.Transparency=90;
//100 = invisible
trans=(100 - ((oMcguffin.X) - mouse.x)/(oMcguffin.Y - mouse.y));
if (trans<0) {
trans=0;
}
if (trans>100) {
trans=100;
}
oMcguffin.Transparency=trans;
} else {
oMcguffin.Visible=false;
}
This take an object mcguffin. When the candle is lit, the hidden background is revealed; the object has a level of transparancy so it will only be completely visible when the mouse is over it -- and invisible (or barely) when the mouse cursor moves 100px away.
I'm still having a few problems:
-Is the division of (oMcguffin.X) - mouse.x) by (oMcguffin.Y - mouse.y) the correct way to get this effect? It seems to be, but there might be something simpler. Beacause there are 2 values instead of 1, my brain just stopped, and this was all I could come up with.
-When the mouse is right on centre of the mcguffin, there's a divde by zero error; I've tried adding 1 to mcguffin.x, but it still happens. How do I solve this? Inttofloat also doesn't work.
-How do I make transparancy 'slower'? With this calculation, 1px is 1% transparency, so it seems to dissapear almost instantly. Divide equation by 2, or....???
While I'm at it - is there a function besides Dislplay which I can use for debugging? The function is fine, but since it's blocking, you have to click *every time* to update whatever info it's showing like Display("transparency =",%d);
Distance is calculated by Math.sqrt(dx*dx + dy*dy):
int dx = oMcguffin.X - mouse.x;
int dy = oMcguffin.Y - mouse.y;
int dist = Math.sqrt(dx*dx + dy*dy);
trans = (dist <= 100) * dist + (dist > 100) * 100; // true evaluates to 1, false to 0
oMcguffin.Transparency = trans;
As for non-blocking debugging, add a GUI to your screen (I use a bar on the top) and put a label on it, then use
lblDebug.Text = String.Format("transparency = %d", trans);