Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: bx83 on Wed 08/03/2017 01:47:23

Title: Drawing circle or rectangle of one background image to another
Post by: bx83 on Wed 08/03/2017 01:47:23
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?

Title: Re: Drawing circle or rectangle of one background image to another
Post by: bx83 on Wed 08/03/2017 05:24:04
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.
Title: Re: Drawing circle or rectangle of one background image to another
Post by: bx83 on Wed 08/03/2017 08:03:14
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...
Title: Re: Drawing circle or rectangle of one background image to another
Post by: bx83 on Wed 08/03/2017 09:40:39
Only one problem:

Can't get a circle shaped window to the 'hidden' room to work, only a square one.
Help?
Title: Re: Drawing circle or rectangle of one background image to another
Post by: Khris on Wed 08/03/2017 10:39:58
Create a circle sprite of the same size, then use
  sprite.CopyTransparencyMask(123); // 123 = slot number of circle sprite
Title: Re: Drawing circle or rectangle of one background image to another
Post by: bx83 on Thu 09/03/2017 11:33:32
Thankyou!

Title: Re: Drawing circle or rectangle of one background image to another
Post by: bx83 on Tue 14/03/2017 01:00:19
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);
Title: Re: Drawing circle or rectangle of one background image to another
Post by: Khris on Tue 14/03/2017 10:45:14
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);