Creating a Coloring book in AGS?

Started by Dervish, Sun 12/04/2009 07:43:21

Previous topic - Next topic

Dervish

Ok this is a rather broad question seeing as how I haven't even started on the concept but I am think about trying to do a simple coloring book using ags.  So mostly I am looking for people to rack thier brains and come up with some any kind of solutions...

My thought was to basically have a gui of the average paint colors Red Orange Yellow Green Blue and Purple (there would be no paint brushes or anything to complicated just filling areas on the screen)  and then within the "room"  have a bunch of white objects grouped together to create a picture like you would see in any kids coloring book.  So then basically have to do 7 colored versions of that object so if it were 20 objects there would have to be about 160 different spirtes dealing with that room.  Here is just kinda a rough layout to help get the idea...




So I guess my main question would be is there a less space consuming way to achieve what I am trying to do?

Trent R

Well, I don't see how having a paint brush would be too hard.. there's mouse_down code somewhere... and the DrawingSurface/DynamicSprite functions as well.

As for a fill tool... I read a tutorial somwhere for C# on a similar thing, but I believe it required some recursion. Basically, you check the color of the pixel where the mouse is (let's say white) and color it. Then check all adjacent pixels, if they are also white, you color them and check their adjacent pixels.

But I don't exactly know how to do this in AGS.


~Trent
To give back to the AGS community, I can get you free, full versions of commercial software. Recently, Paint Shop Pro X, and eXPert PDF Pro 6. Please PM me for details.


Current Project: The Wanderer
On Hold: Hero of the Rune

EnterTheStory (aka tolworthy)

If you don't have many pictures, it might be easier to make each object a character, then use the tint function to change its color. This would also allow you have shaded images, even photographs. In my game the characters are mostly white, but there's an Easter Egg (how appropriate!) that lets the player color them.

GarageGothic

#3
I wrote a flood-fill script for AGS as part of a bunch of drawing tools for creating light/scale maps for an as-of-yet unpublished module. However, it's quite slow, so I don't know if it would be useful (for instance it makes the music glitch if you fill a large area - however, you could put in some Wait(1) calls which would circumvent this and the user could actually see the area being filled gradually, which would make for a nice effect).

There's a good pseudo-code example of it on wikipedia, which I used as the basis for my script. Here's the basic code from my game. I haven't tested it in a while, so I don't remember if there's any unresolved problems:

Code: ags

function noloopcheck FloodFill(this DrawingSurface*, int x, int y, int color) {
  int beforecolor = this.GetPixel(x, y);
  if (beforecolor == 0) return; //added this so that you won't be able to fill the black outlines with color
  this.DrawingColor = color;
  this.DrawPixel(x, y);
  color = this.GetPixel(x, y);
  if (color == beforecolor) return;
  
  int surfacewidth = this.Width;
  int surfaceheight = this.Height;
  
  int stack[];
  int maxstacksize = surfacewidth*surfaceheight;
  stack = new int[maxstacksize];
  
  int currentstacksize;
  //the following lines are indented wrongly because I removed a conditional before posting
    stack[currentstacksize] = (y*surfacewidth)+x;
    currentstacksize++; //we already decided that beforecolor != fill color
    while ((currentstacksize > 0) && (currentstacksize < maxstacksize-12)) {
      int value = stack[currentstacksize-1]; //because 0 is also an index
      int stacky = value/surfacewidth;
      int stackx = value-(stacky*surfacewidth);
      this.DrawPixel(stackx, stacky);
      currentstacksize--;
      if (this.GetPixel(stackx-1, stacky) == beforecolor) {
        stack[currentstacksize] = (stacky*surfacewidth)+(stackx-1);
        currentstacksize++;
        }
      if (this.GetPixel(stackx+1, stacky) == beforecolor) {
        stack[currentstacksize] = (stacky*surfacewidth)+(stackx+1);
        currentstacksize++;
        }
      if (this.GetPixel(stackx, stacky-1) == beforecolor) {
        stack[currentstacksize] = ((stacky-1)*surfacewidth)+stackx;
        currentstacksize++;
        }
      if (this.GetPixel(stackx, stacky+1) == beforecolor) {
        stack[currentstacksize] = ((stacky+1)*surfacewidth)+stackx;
        currentstacksize++;
        }    
      }
  }



It could be optimized a lot, and when I get time I'll probably rewrite it to use scanline flood fill instead. Also, some of the areas in you example, such as the tree, are a bit too detailed to fill properly using this method. If you need those details, it would be better to make the area to color pure white and add the detail lines as an object on top of the background.

Edit: Tolworthy wrote while I was posting, and his suggestion is good too. You don't need to use characters for that though, you can also use Object.Tint, so that the areas to color and their positions, are set on a room by room basis, which would probably be easier to manage.

Jakerpot

you can make each filling area an object, make the colour pallete inventory objects, and then if player active inventory is purple (this is done in the any click setting) change view to loop x (the loop with the object painted.
It isn't hard, just time wasting.



Trent R

Quote from: Jakerpot on Sun 12/04/2009 16:35:04
you can make each filling area an object, make the colour pallete inventory objects, and then if player active inventory is purple (this is done in the any click setting) change view to loop x (the loop with the object painted.
It isn't hard, just time wasting.
Unlikely Jakerpot, since there's a limit of 40 objects and I count 66 areas on the houses alone.

PS-Characters will be a pain since you can't see them in the editor...

~Trent
To give back to the AGS community, I can get you free, full versions of commercial software. Recently, Paint Shop Pro X, and eXPert PDF Pro 6. Please PM me for details.


Current Project: The Wanderer
On Hold: Hero of the Rune

JpSoft

This looks very interesting. I believe a fill function could be created using AGS, but for sure looks a little painful. I will give a try tonight.

Jp

Ponch

Absolutely nothing to do tonight, so I gave this idea a shot. I used AGS 2.72 (because I'm delightfully old school, you see).

http://www.barnrunner.com/otherstuff/Coloring_Book.rar

The file contains both the EXE and the complete build, so you can take a look at the source code and see if what I did would work for you and your project.

Also, the picture I drew for this coloring book contains boobs (I was bored), so consider that before you open the file in front of anyone who may have an irrational fear of the human body.

Anyhoo, hope this can be of some use to you.

- Ponch

JpSoft

I worked something trying to create a fill function, but i still do not found the way. Maybe CJ could solve this implementing a new function:

DrawingSurface.Fill(int X, int Y)

:)

Jp

Dervish

#9
Hey thanks Guys
I have not really looked at this but I am planning to.  I had to do stuff for Easter Holiday
....

Well Ponch I tried your attempt might be useful if you could paint over the objects with another color after painting with one.

Found a Module done by SHS called ReadBMP might be helpful might not have not messed with it yet.

Also TrentR I could still use objects and just group certain things together like the rocks might be one object and the walls of the house be one object and so forth, but you are right that would quite limit the detail that could be done on a page at a time.  and would be very time consuming unless maybe the object gives decent results.

JpSoft

But could be very usefull to implement a floodfill module or something like that. I will complete it when i finish my crrent project.

Jp

Ponch

Quote from: Dervish on Mon 13/04/2009 17:38:32
Well Ponch I tried your attempt might be useful if you could paint over the objects with another color after painting with one.

You mean like changing the color after you've already applied a color? That could be done easily enough. Just remove the integer check that turns off the area once it's been colored in.

- Ponch

Dervish

Ok this is dealling with the same project but a different question I have decided to go with a object.tint to chage the color now I was wonder as far as a gui goes using the Gui Idea in the original Picture

Is there anyway within the global script to have to assign the different gui buttons to tint the different objects without having to set it up each time in the room editor in other words something to the effect that it would detect what x is as you click ithe object.

object
  • .tint(0,0,250,30,100)  (x being the different object in the different rooms)

    sorry to ask such questions but my scripting is rather shoddy.

GarageGothic

#13
Yeah, totally. You can use Object.GetAtScreenXY. You would have to do it in two stages though, to avoid trying to run the tint function on a null pointer:

Code: ags
Object* tintobject = Object.GetAtScreenXY(mouse.x, mouse.y);
if (tintobject != null) tintobject.Tint(0, 0, 250, 30, 100);


This should be put in the on_mouse_click function. You can set up a global int variable called "color", that is changed by pushing the different gui buttons (in the GUI interaction script). And then do the on_mouse_click function like this:

Code: ags
Object* tintobject = Object.GetAtScreenXY(mouse.x, mouse.y);
if (tintobject != null) {
  if (color == 1) tintobject.Tint(255, 0, 0, 30, 100);
  else if (color == 2) tintobject.Tint(255, 128, 0, 30, 100);
  else if (color == 3) tintobject.Tint(255, 255, 0, 30, 100);
  // ...and so on
  }

Dervish

Ok still in the planing phase of this one and just had a few questions maybe you wizards can answer.

If I am going to use objects and there are multiple pages(ie Rooms) and each room would come close to the object limit.

How much would this affect performance, in other words would I have quite a bit of slowdown?

And if there is a great amount of slowdown is there another way to go about this?

GarageGothic

No, you wouldn't see much slowdown with the object tint method unless you use a whole bunch of animated or transparent objects, which I couldn't really imagine in a coloring book anyway.

Dervish

Would it be possible to handle the colors as Inventory items instead of a gui?

Would it be easier?  Would it be harder?

Could I still have the different inventory items work globally to change the color of the objects?

RickJ

Quote
If I am going to use objects and there are multiple pages(ie Rooms) and each room would come close to the object limit.
How much would this affect performance, in other words would I have quite a bit of slowdown?
1.  Only one room is loaded into memory at a time so the number of rooms would have absolutely no effect.

2.  I wouldn't thing the number of objects would have much effect either.  You would only be tinting one object at a time right?

Quote
Would it be possible to handle the colors as Inventory items instead of a gui?
Not sure how you would do this or waht you may have in mind? 

Dervish

well I am basically think about rotating different colors in and out for different pictures and I don't really want to make multiple guis containing the different colors so I was wondering if a inventory item can be used globally similar to the way one can pass a global action for a gui button press... but what I really want to know is if it would be easier to just do use a gui?

RickJ

OK, something like a palette from which you can select the desired color?   The easiest way is to use a GUI with a bunch of buttons; one for each color.   Then have a collection of solid colored, same sized,  rectangular sprites; one for each possible color.  The Sprite numbers are then associated with specific colors.   Use the "player enters room" event handler to load the colorss intothe buttons (i.e. modify the button graphic to contaon the sprite corresponding to the desired color.   When the button is clicked the sprite/graphic id can be retrieved to determine the color.

In a more sophisticated version of this you could have just one set of sprites and then use the drawing surface functions to fill them with the desired color.  This would allow the uswer to create custom colors.   

SMF spam blocked by CleanTalk