Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: Héctor Bometón on Sun 26/07/2020 16:37:13

Title: Can you store and/or recover a drawing made with DrawingSurface? [SOLVED]
Post by: Héctor Bometón on Sun 26/07/2020 16:37:13
I managed to get the "freehand paint" (https://www.adventuregamestudio.co.uk/forums/index.php?topic=58278.0 (https://www.adventuregamestudio.co.uk/forums/index.php?topic=58278.0)) working pretty well, as you can see in the following video. Now, the question is, can it be permanently visible or stored somewhere somehow? When I leave the room and come back, it's all gone.

I fear the answer is simpler than I think but I've been working so many hours... my brain just wont work properly...

Title: Re: Can you store and/or recover a drawing made with DrawingSurface?
Post by: Cassiebsg on Sun 26/07/2020 21:22:06
Just don't delete the drawing surface?  ???

Draw it on an object, or permanently on the BG? All depends on exactly what you want to achieve. If it's suppose to be erasable, then adding it to the BG is a bad solution, but if you want whatever graffiti to stay there til the end of the game, then use the BG as canvas. 
Otherwise, save it in an object or don't delete the drawing the surface (I think that if you don't delete it, it'll stay there, AGS will though throw an error file complaining about not deleting it, which you might not want in the final release).
Title: Re: Can you store and/or recover a drawing made with DrawingSurface?
Post by: Crimson Wizard on Sun 26/07/2020 21:41:08
Cassiebsg, you probably confuse "drawing surface" and "dynamic sprite".

DrawingSurface can be deleted (by calling Release) freely as it's merely an interface to access some object. When you release Drawing Surface, the object stays changed. In fact, Releasing a surface is a must because with Direct3D and OpenGL renderers it signals to update the video texture.

Drawing on room background does not stay and gets lost when you leave the room. This is probably made intentionally, to not increase size of saved games.

The solution is to create a global DynamicSprite, draw on that sprite instead, and either assign that sprite to the room object, or paint that sprite to room background whenever player enters the room.
In your case things are little more complicated as, it seems, you can draw anywhere, so object will be inconvenient. Perhaps do this:
* create a global DynamicSprite.
* when entering a room, if that sprite already exists, then paste it on room background.
* when drawing, draw both on that sprite AND room background. Dynamic sprite will work as a reserved image for restoring room background later.
Title: Re: Can you store and/or recover a drawing made with DrawingSurface?
Post by: javixblack on Sun 26/07/2020 23:23:04
I can't help you with nothing, but tiene pinturria el jueguito, guachín
Title: Re: Can you store and/or recover a drawing made with DrawingSurface?
Post by: Héctor Bometón on Mon 27/07/2020 08:14:03

Well, you can't draw "anywhere", only onto certain regions or hotspots, but I get it.

Never used Dynamic Sprites before, but I think I understood your explanation. I'll give it a try! Thank you very much!

Title: Re: Can you store and/or recover a drawing made with DrawingSurface?
Post by: Héctor Bometón on Sat 17/04/2021 23:45:41
Quote from: Crimson Wizard on Sun 26/07/2020 21:41:08
Cassiebsg, you probably confuse "drawing surface" and "dynamic sprite".

DrawingSurface can be deleted (by calling Release) freely as it's merely an interface to access some object. When you release Drawing Surface, the object stays changed. In fact, Releasing a surface is a must because with Direct3D and OpenGL renderers it signals to update the video texture.

Drawing on room background does not stay and gets lost when you leave the room. This is probably made intentionally, to not increase size of saved games.

The solution is to create a global DynamicSprite, draw on that sprite instead, and either assign that sprite to the room object, or paint that sprite to room background whenever player enters the room.
In your case things are little more complicated as, it seems, you can draw anywhere, so object will be inconvenient. Perhaps do this:
* create a global DynamicSprite.
* when entering a room, if that sprite already exists, then paste it on room background.
* when drawing, draw both on that sprite AND room background. Dynamic sprite will work as a reserved image for restoring room background later.

So... It's been a while, but I still haven't managed to make it work. I'm struggling understanding how to store and load/paste the previously drawn surface onto the Room when I enter. I understand the solution, but I'm currently not able to code it propoerly. could anyone be so kind to help me out with this? Thanks!
Title: Re: Can you store and/or recover a drawing made with DrawingSurface?
Post by: Snarky on Sun 18/04/2021 08:50:42
I'm going to assume that there is only one room in the game where you want to be able to graffiti. If there are multiple rooms, we might want to use a slightly different solution.

1. You need a persistent DynamicSprite (one that doesn't stop existing when you leave the room). You do this by declaring a DynamicSprite* variable in the global script. Then we need to export it to make it available to other scripts, and import it so it's actually accessible to them:

Code (ags) Select
// GlobalScript.asc

// A sprite to store our graffiti painting
DynamicSprite* sprGraffiti;
export sprGraffiti;

Code (ags) Select
// GlobalScript.ash
import DynamicSprite* sprGraffiti;


Note that this variable is declared but not assigned: it is null until we actually create a DynamicSprite.

2. Now in the room itself, you're either drawing directly on the room background, or on an object overlaid on the room. From the other thread you linked, it looks like you're drawing directly on the background. (There are pros and cons to this, but let's go with it for now.)

So when we enter the room (the room event "Player enters room (before fadein)"; make sure you properly link the function to this event), we need to make sure we update the background to include any graffiti already painted.

Code (ags) Select
// Room script

function room_Load()
{
  if(sprGraffiti != null)
  {
    // There is a sprite, so let's draw it onto the background
    DrawingSurface* surf = Room.GetDrawingSurfaceForBackground();
    surf.DrawImage(0,0,sprGraffiti.Graphic);
    surf.Release();
  } 
}


3. Now we just need to make sure that we update the DynamicSprite whenever the player leaves the room. (An alternative is to update the DynamicSprite every time we paint onto the background, but this should be easier.) We do this using the room event "Player leaves room"â€"again making sure we link the event to the function:

Code (ags) Select
// Room script

function room_Leave()
{
    sprGrafitti = DynamicSprite.CreateFromBackground();
}


As you see, this is where we actually create the DynamicSprite.

(For robustness, we should test that this event is triggered not just when the player leaves the room, but also if you change to a different player character in a different room, e.g. for a cutscene.)
Title: Re: Can you store and/or recover a drawing made with DrawingSurface?
Post by: Snarky on Sun 18/04/2021 08:56:23
Oh, one more thing: I'm not sure that if you draw onto the background, save before leaving the room, and restore that save, the graffiti will have been stored. If not, we do need to update the DynamicSprite as soon as you draw onto the background.
Title: Re: Can you store and/or recover a drawing made with DrawingSurface?
Post by: Héctor Bometón on Sun 25/07/2021 10:52:44
Quote from: Snarky on Sun 18/04/2021 08:56:23
Oh, one more thing: I'm not sure that if you draw onto the background, save before leaving the room, and restore that save, the graffiti will have been stored. If not, we do need to update the DynamicSprite as soon as you draw onto the background.

Wow... I'm really sorry I never answered. I  really thought I did...

Your solution worked perfectly, as usual. Thank you VERY MUCH!