AS3 - How to calculate intersection between drawing and bitmap - actionscript-3

I'm trying to create a handwriting game with AS3 on Adobe Animate. I've created my board, functions(drawing, erasing, saving, printing and color pannel) so far. But i need to show a score. To do it i thought if i can calculate the percentege of intersection between drawing and a bitmap image(which is my background for now).
Is there any way to do it? Or can you at least tell me with which function should i try that? Thanks a lot.
Note: Here is 2 images from my game. You can easily understand what am i trying to explain and do.
players will try to draw correctly(drawn board)
Empty Board

just a suggestion,
lets assuming that you are recording draw data, a set of points according the frame rate that records mouse positions inside an array.
i used 8 points in my own example, the result would be like this: (6 of 8 = 75% passed)
► black line is correct path(trace btimap) ► red is client draw
we need to search whole of the points array and validate them, so a percentage will be gain easily
how to validate
each point contain x and y, to check if its placed on a black pixel (bitmap trace) we just do
if (bitmapData.getPixel(point.x, point.y) == 0x0) // 0x0 is black
getPixel returns an integer that represents an RGB pixel value from a
BitmapData object at a specific point (x, y). The getPixel() method
returns an unmultiplied pixel value. No alpha information is returned.
Improvment
this practice would be more accurate when there is really more captured points during draw, also the Trace-Bitmap must be like this (above image), not a Dashed (smoothed, styled, ...) Line, however you can use this trace bitmap in background (invisible) and only present a dashed copy of that with a colorful background (like grass and rock textures or any graphical improves) to players.
Note
also define a maximum search size if you need more speed for validating draw. this maximum will be used to ignoring some points, for example if max=5 and we have 10 points, 0,2,4,6,8 can be ignored

Related

Is there a way to have smooth/subpixel motion without turning on smoothing on graphics?

I'm creating this 2D, pixel art game. When the camera follows the player (it uses easing), on the final approach, the position gets several subpixel adjustments.
If I have smoothing ON (on my graphic assets), the graphics look good (sharp. it's pixel art) but the subpixel motion is jerky/jumpy.
If I have smoothing OFF, the subpixel motion is smooth, but the pixel art graphics look blurry.
I'm using Flash player v21. I've tried this with Starling and with Flash's display list.
You have a pixelated object that is moving in increments of less than the pixel size, but you don't want to restrict your mathematical easing to integers, or even worse, factors of 8 or what have you. The solution I am using in my project for this exact issue is posted below (I just got it working last week!)
Concept
create a driver that is controlled by the easing using floating point numbers.
Allow this driver to then control where the actual display object is rendered. We can use a constraint to only allow the display object to render on your chosen resolution.
Code Example
// you'll put these lines or equivalent in the correct spots for your particular needs.
// SCALE_UP will be your resolution control. If your pixels are 4 pixels wide, use 4.
const SCALE_UP: int = 4;
var d:CharacterDriver = new CharacterDriver();
var c:Character = new Character();
c._driver = d; // I've found it useful to be able to reference the driver
d._drives = c; // or the thing the driver drives via the linked object.
// you don't have to do this.
then when you are ready to do your easing of the driver:
function yourEase(c:Character, d:CharacterDriver):void{
c.x = Math.ceil(d.x - Math.ceil(d.x)%SCALE_UP);//this converts a floating point number into a factor of SCALE_UP
c.y = Math.ceil(d.y - Math.ceil(d.y)%SCALE_UP);
Now this will make your character move around 4 pixels at a time, but still be able to experience easing!
The bit with the modulo (%) operator is the key. For instance, 102-102%4 = 100. 103-103%4 = 100. 104-104%4 = 104.
In case anyone is confused by that, look at what 102%4 does: 4 goes into 102 25 times with a remainder of 2. so 102%4 = 2. Then 102 - 2 = 100.
In your case, since the "camera" is following the player (i.e. the background is moving, right?) then you really need to apply drivers to everything in the background instead, but it is basically the same idea.
Hope this helps.
since you specifically mentioned the "final approach" i think your problem comes from the fact that the easing equations puts your graphics at fractional coordinates, especially while getting closer to the target, but you should also notice it during the rest of the animation.
depending on the easing "engine" that you're using you should be able to set a "round values" flag, so all the coordinates set will be integer values and not fractional
if that's not possible, find a way in your display objects to round the x and y values every time they change

AS3 Bitmap black and white - for compression reasons

I have a field made up of BitmapData, which I use for pixel-precise hit detection.
However, BitmapData naturally stores 2^32 (or 2^24 with no alpha?) possibilities for each pixel. I only need 2 - black or white.
But I still need to use .draw to make other objects being drawn onto that BitmapData. It doesn't need to be visible.
Extracting a pixel for hit-detection does not seem too difficult - but drawing without cycling through each pixel seems hard. Is it possible?
What would the right approach for this problem be?
If you depend on having your bitmap data to be black or white only, you can employ BitmapData.threshold() after drawing a new mask over that bitmap. To turn your existing BitmapData to black and white with a threshold of half red channel do the following:
bd.threshold(bd,bd.rect,new Point(),"<",0x00800000,0x0,0x00ff0000,true);
bd.threshold(bd,bd.rect,new Point(),">=",0x00800000,0x00ffffff,0x00ff0000,true);
The first call with turn all points that have red below 0x80 black, the second will turn all the remaining points white. Change the mask and threshold value to use green or blue channels if you want. Consider applying a properly channeled ColorTransform object to your draw calls to make the mask correctly applied to a newly drawn object.

Smoothest way to render large matrices to canvas element

I have created a dot matrix slider on a canvas element (much like the sort you get in the stock exchange). Currently I have each letter laid out as an individual matrix and then, through a succession of loops I have these letter converted into one large matrix.
I then go through and draw this matrix column by column up to a maximum amount of columns. The matrix then gets redrawn every X milliseconds, offsetting the viewable area of the matrix by one each iteration until it eventually loops. The large matrix doesn't get redrawn every time.
My issue is that the animation doesn't seem smooth at lower redraw intervals - it jumps about. I've checked the frame rate and it seems fine but occasionally it jumps and I can't work out why!
The function with the settings is right at the bottom of the JSFiddle.
dotMatrix({
animationDelay: 1000,
canvasSelector: '#dot-matrix',
dotRadius: 2,
loop: true
});
Here are some steps you could do:
Prerender each char to an off-screen canvas in a solid color on transparent background. This canvas will be used as a sprite-sheet later. Drawing a rounded rectangle is a relative expensive operation especially when you need x number of it per char.
Set up a gradient for the colors and store that too in an off-screen canvas (by now we can see memory-caching is coming to the rescue..).
Every time you update use requestAnimationFrame instead of setInterval. The latter is not able to synchronize to monitor update. Scroll delay can be calculated using the number of frames elapsed as well as the time since last update (see rAF doc for details).
For each update clear, then "blit" the letter from the sprite-sheet canvas to main canvas. When all are blitted change composite mode to source-atop and blit the gradient canvas on top, and reset composite mode to source-over (don't use save/restore - they are expensive).
In the last step you could also use composite mode copy instead of clearing canvas and using source-over, as that will remove any previous existing pixels for the area you draw to.
Hope this gives you some inputs to improve the performance.

Output values in Pixel Blender (trace)

I'm absolutely new to Pixel Blender (started a couple of hours ago).
My client wants a classic folding effect for his app, I've shown him some example of folding effect via masks and he didn't like them, so I decide to dive in Pixel Blender to try to write him a custom shader.
Thx God I've found this one and I'm modyfing it by playing with values. But how can I trace / print / echo values from Pixel Blender ToolKit? This would speed up a lot all the tests I'm doing.
Here i've found in the comments that it's not possible, is it true?
Thx a lot
Well, you cannot directly trace values in Pixel Bender, but you can, for example, make a certain bitmap, then apply that filter with requested values and trace reultant bitmap's pixel values to find out what point corresponded the one selected.
For example, you make a 256x256 bitmap, with each point (x,y) having "x" red and "y" green component value. Then you apply that filter with selected values, and either display the result, or respond to clicks and trace underlying color's red and green values, which will give you the exact point on the source bitmap.

Creating a reusable shape in AS3 based on a user's selections

I'm currently working on an educational Flash application on the Adobe CS5 Flash Professional platform, using the ActionScript 3 programming language.
In my program the user is required to plot a shape onto a 4x4 squared grid, which I’ve generated using a For Loop that runs through sixteen times.
As the For Loop constructs the grid, it adds 16 child instances of the same 23x23 pixel squared MovieClip, laid out equally in four rows and four columns and each of these MovieClip is assigned a unique ID number ranging from 1-16 and a Mouse Down listener event, ready for user interaction.
Should the user click on a square in the grid, during the course of plotting and selecting their shape, the MovieClip’s colour will firstly change to signify to the user it has been selected for inclusion.
Secondly I’ve also set-up a Boolean based Array [0-15], which links to the corresponding ID numbers of the grid, so for example if I selected the top left square in my 4x4 grid, the [0] property of my Boolean array would change from false to true and likewise if I selected the third square along on the second row of my grid the [6] property of my array would do the same and so on.
Now using this technique and referencing the array, I can always know which blocks have been chosen by my user and by running another For Loop on a subsequent slide in my program, I’ve managed to output, based on my ‘selection’ Boolean array, the same shape that my user has designed, in the confines of another 4x4 grid, with the selected blocks colour changed from grey to black, if any array value is set to True.
Now my problem is that my user will subsequently need to plot their designed shape, produced on the first grid, onto a larger second grid in large volumes (up to 8-9 times on some occasions). This grid is considerably larger than 4x4 one, being 24 x 12 to be exact (288 blocks).
Now what I need is when my user clicks on this second larger grid I want an output of their designed shape to be added to the stage as a brand new MovieClip.
But importantly the shape needs to be cropped down. For example if the user made a square shape on the first grid by selecting blocks 2,3,6,7; I don’t want a 16 block MovieClip (92x92 pixels, based on my 23x23 pixel blocks) being added to the bigger grid with four blocks shaded a different colour, I want a 4 block, squared shape (46 x 46 pixels, based on my 23x23 blocks) to be added, from the top-left grid square you select on the second grid.
Ideally I’d like to create my user’s plotted shape programmatically using the Shape Drawing tool and do this within a function, so I can then run the function each time the user enters the second grid area and update the user’s shape, should the user had gone back and amended it in the first grid. This would also give me the scope to also change the shape colour prior to adding the child of it to my stage, which is another area of functionality I need and another reason why I’d like to do this shape programmatically.
I imagine capturing the x/y co-ordinates of the blocks from the first grid in a further array and subsequently searching through that array to find the first block instance and then draw the shape from this point, could be the way forward but that is as far as my thinking has taken me.
Any ideas or suggested reading on how to do this would be very welcome. Many Thanks.
My suggestion is that you use bitmaps as your base class for such a shape, initialize it with full transparence, then draw() your MCs on that bitmap.bitmapData with adjusted X&Y values, then you place that bitmap over your "larger grid" using supplied X&Y.
var bd:BitmapData=new BitmapData(23*4,23*4,true,0x0);
var mat:Matrix=new Matrix();
mat.tx=-1*LeftCornerX;
mat.ty=-1*LeftCornerY;
for (i=0;i<16;i++) if (BlockMCsSelected[i]) bd.draw(BlockMCs[i],mat);
var bm:Bitmap=new Bitmap(bd);
bm.x=SuppliedX;
bm.y=SuppliedY;
LargerGrid.addChild(bm);
Basically, this should do if you specify your input data correctly. But if you need it to receive events, encapsulate this bitmap into a Sprite object, that one can process events, and give coordinates to sprite, not bitmap.