2014년 12월 26일 금요일

How to reset the screen after filling it with color?

Hey, would really appreciate if somebody knows how to reset the screen (Canvas box) after it is completely painted with color. I tried to do an if statement with canvas backroundcolor = different color then open another screen but it doesn't seem to work. Is it possible with appinventor? Thanks



Show us some blocks Tanel (a screen capture jpg or png image)  and perhaps we can answer your question.    You can clear a canvas with

That wipes out everything in the canvas but perhaps not what you want to do?



Well there's nothing special to the code just drawing lines to the canvas. What I want to do is that if the user fills the entire screen by drawing lines, the program would recognize it and a message would appear or reset button  or something like this. 
Basically I don't want a button that would let the user to reset the painting before user has filled the entire screen with paint. Hope you understand :)



OK, yes, I understand now.   Ever pixel in the screen must be NOT White.

Yes, there is possibly a way to do that using the  call Canvas1.GetPixelColor .    You will need to check each pixel on the screen to see whether it is White, if any pixel is White, then perhaps allPixelsNotWhite could be true  (using a Boolean value to keep track of the Canvas status).

This means you need to write a routine that will check each and every pixel to determine if there are any white pixels left in the Canvas.  If your canvas is 100 x 100 pixels, this means you need to iterate through 10000 pixels.  When all of the pixels are not White, the allPixelsNotWhite would be false, when that condition exists, the Canvas is filled.     You would have to probably call your routine with a Clock as frequently as you want.    Can you do this successfully?  Depends on how large your canvas is and how long the Android device takes to poll all the pixel locations.

This article shows how the Canvas is arranged  http://www.appinventor.org/Chapter17    


Try some blocks.  Does this work?



Okay thanks for your answer, this is what I came up but it still doesn't do anything. Probably my logic isn't the best and is too simplistic. What blocks should I put to the x and y values? How would the program check 10000 pixels without writing 10000 if else statements? Also my screen setting is  fill parent and I want to fill the whole screen. How would I do it then?
It's my second day using AppInventor so forgive me my brainlessness :)




you would use 2 for each loops: the outer loop to loop through the x coordinates, the inner loop to loop through the y coordinates
be prepared for a long running time, also your app might get unresponsive
it is not the strength of App Inventor to do fast calculations like this



Alright, I messed around with this, and it becomes ridiculous very quickly.  On canvases even under 32x32 on a Samsung Galaxy S5 it can get so bogged down that the canvas can even fail to detect touches.  My best idea would be to try to use "for every number from m to n" blocks or "for each item in list" blocks each time the canvas is drawn on, but like I said that got very slow in all of over 5 ways I tried it, including button trigger.  Perhaps a partial test would be better where only every two or three pixels on each axis is tested would be better.  It would reduce the load by the square of whatever number you pick, and could still be (decently) effective.  However, with your current setup only the very bottom corner pixel would be tested...



The following code polls all the pixels in an image.   I tested it with a 100 x100 pixel image...it took 12 seconds to execute.   If you poll the same size image and post the test results the code crashes, probably because the graphical interface can not keep up.  The testing blocks does not seem to work with an image larger than 60 x 60.



This example shows that my suggestion for using the algorithm to poll every pixel is not practical t to check for 'unpainted' blocks.

Perhaps someone can improve the algorithm I developed?  

How would this work?   If the algorithm was faster, one would put the procedure checkPixels in a Clock timer and poll ever few seconds by calling the procedure.  This is very impractical in practice as AI takes over 12 seconds to poll a 100x100 image on a Samsung Tablet in Live Development.   The app would be faster if the apk was compiled and installed on the device.   I did not test that...perhaps compiled the speed improvement might make it useful for small image polling?



Yep.  12 seconds is way too much.  1 second would be the usual good limit, and 2 seconds is close to extreme for something like this kind of operation as far as users will probably care.  Steve's idea of using a button to trigger it is good, it will save overhead on the device but is still slow.

But I did just notice something.  I think it might be time for a paradigm shift here.  Let's look at this from a user perspective rather than a tech perspective.  I did some tests based on the user perspective asking "What if the drawing does NOT meet the fully drawn condition?".  I found out that in a field of noise (for if you're using a background image) users will probably have trouble detecting any spot 3x3 or smaller they forgot to paint.  On a blank canvas, 2x2 seems to be about the limit.  If the user can't find which pixel they forgot to paint, it's going to really annoy them, particularly if it will require them to draw over anything they spent time on to find it.
Also, since I'm assuming the person will be the one drawing on the canvas, chances are you are using a draw size of 2 or greater, meaning that you are less likely to need to check EVERY pixel to be accurate.
So, because of this, I would suggest you take Steve's example, but for the "each number from..." blocks set the "by..." section to 4.  Using 4 in each section, it can scan a 320x320 canvas in about 5 seconds.  It may do an incomplete scan, but if actually have it do the inverse and draw where it would check, it is actually decently accurate and can save you a HECK of a lot of time and crashing.



 If you poll the same size image and post the test results the code crashes, probably because the graphical interface can not keep up.  
it crashes, because the app is unresponsive then, see also http://josmasflores.blogspot.com/2013/02/a-single-thread-of-execution-in-app.html
you can use a clock component instead, but it still will be slow...



Here's an entirely different approach, using a list
of unpainted rectangles and a slight restriction
on the drawing tool ...

Restrict the drawing tool so that it can only move
up,down, left, or right, so it traces rectangular strokes.

Rectangular stroked on a rectangular background 
leave rectangular unpainted areas. (Though they
may clump into odd shapes and get split into
smaller rectangles by subsequent paint strokes.

Keep track of the unpainted rectangles in a list.
A completely covered rectangle can be dropped
from the list.

Figure the total unpainted area after each brush
stroke, and declare completion if the area drops
below some minimum threshold.



Well I have tried many different ways now but haven't really gotten a satisfying result. But since I still don't want to give up on this idea, could anyone suggest a different platform or game engine that could handle such game? Also would be good if it wasn't too hard to learn. 


댓글 없음:

댓글 쓰기