Drawing circle or rectangle of one background image to another

Started by bx83, Wed 08/03/2017 01:47:23

Previous topic - Next topic

bx83

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)



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?


bx83

My room is called 'beach'.

Code: ags

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.

bx83

Eureka!

Useful for anyone else trying to do the same thing:

Code: ags

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

bx83

Only one problem:

Can't get a circle shaped window to the 'hidden' room to work, only a square one.
Help?

Khris

Create a circle sprite of the same size, then use
Code: ags
  sprite.CopyTransparencyMask(123); // 123 = slot number of circle sprite

bx83


bx83

Following on, I'm now having a problem with hidden objects.

I try the code:

Code: ags


  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);

Khris

Distance is calculated by Math.sqrt(dx*dx + dy*dy):

Code: ags
    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
Code: ags
  lblDebug.Text = String.Format("transparency = %d", trans);

SMF spam blocked by CleanTalk