Actionscript 3 number drawing recognition - actionscript-3

I am working on a game to compare a kid drawing (with mouse or gesture) to numbers from 1 to 9, is converting the drawing to bitmap and compare it with number converted to bitmap a good idea?
and how to handle the difference in size (width-height) between the 2 images?
Thanks

You can do it with image comparison, but it's pretty tricky to get it right.What I would suggest is:
Pre-generate small (10x10 pixels or even smaller) grayscale images of the numbers and blur them a little
Convert drawing to grayscale
Blur drawing a bit
Crop borders from drawing
Resize drawing down to the size of your number images;
Compare the small drawing image with the generated number images, pixel by pixel and be lenient to what you accept as a match.

You can try Mouse Gesture Recognition
var gesture:MouseGesture = new MouseGesture(stage);
gesture.addGesture('B','260123401234');
gesture.addEventListener(GestureEvent.MATCH,matchHandler);
function matchHandler(event:GestureEvent):void
{
trace (event.datas + ' matched !')
}

Related

AS3 - How to calculate intersection between drawing and bitmap

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

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

I converted scrolling background to a bitmap, which now uses more memory, but scrolls much faster, how/why?

So I'm in the process of making an as3 game with a scrolling cave background. I have it set up to randomly generate a 30x30 cave (900 tiles). I would generate the cave then add all of the tiles as children to a "Background" movieclip. I was having some issues with it lagging so I decided to convert the background to a bitmap. Before I did this trace(System.totalMemory); output a value of around 20,000,000. Afterwards it's around 28,000,000, however the lagging/background-scrolling issues I had seem to have stopped. Why would it use more memory, and why would it alleviate my scrolling issues despite this? Here's the important part of the code.
//My cave is 1800 x 1800 pixels
var bitMapData:BitmapData = new BitmapData(1800, 1800);
//Drawing the cave to a bitmapdata
bitMapData.draw(background1);
var bitMap:Bitmap = new Bitmap(bitMapData);
//Removing all of the tiles from the background
while(background1.numChildren > 0) {
background1.removeChildAt(0);
}
//adding the bitmap to my background
background1.addChild(bitMap);
Any insight is greatly appreciated.
See, drawing a MovieClip is always done through vector renderer, this involves querying its structure, querying display list and more, also in case those MCs of yours have uneven scale (unequal and not in the line of powers of 2) even bitmap rendering is slowed. Having one Bitmap instead of 900 MCs lowers display list traversal time by a great margin (900 vs 1 - isn't it a decent improvement?). Of course, bitmaps occupy more memory than MCs, but this is same old memory vs performance issue that every programmer hits sooner or later. Don't worry about this 8M bitmap, just don't make too many bitmaps this big for mobile platform.

Why would I want to use unit scale? (Libgdx)

I have looked into the SuperKaolio example on Libgdx github repo. It is basically a test for integrating Tiled maps with Libgdx. They are using the unit scale 1/16 and if I have understood it correctly it means that the world no longer is based on a grid of pixels but on a grid of units (each 16 pixels wide). This is the code and comment in the example:
// load the map, set the unit scale to 1/16 (1 unit == 16 pixels)
map = new TmxMapLoader().load("data/maps/tiled/super-koalio/level1.tmx");
renderer = new OrthogonalTiledMapRenderer(map, 1 / 16f);
I am basically wondering why you would want to do that. I only got problems doing it and can't see any obvious advantages.
For example, one problem I had was adding a BitMap font. It didn't scale at all with the background and one pixel in the font occupied an entire unit. Image here.
I'm using this code for drawing the font. It's a standard 14 points arial font included in libgdx
BitmapFont font = new BitmapFont();
font.setColor(Color.YELLOW);
public void draw(){
spriteBatch.begin();
font.draw(batch, "Score: " + thescore, camera.position.x, 10f);
spriteBatch.end();
}
I assume there is a handy reason to have a 1/16th scale for tiled maps (perhaps for doing computations on which tile is being hit or changing tiles (they're at handy whole-number indices).
Anyway, regardless of what transformation (and thus what "camera" and thus what projection matrix) is used for rendering your tiles, you can use a different camera for your UI.
Look at the Superjumper demo, and see it uses a separate "guiCam" to render the "GUI" elements (pause button, game over text, etc). The WorldRenderer has its own camera that uses world-space coordinates to update and display the world.
This way you can use the appropriate coordinates for each aspect of your display.

Drawing the exact region of the Bitmap in as3

I am working on a Action Script 3.0 application , in which i ill be allowed to load the image and make them draggable. Consider i am loading the deer image and making it as draggable.
Problem with this is , if i click on the translucent area ( white space around the bitmap ), i dont want the bitmap to draggable.is there any way to draw the deer boundary region exactly without the white space around it.
You can use BitmapData methods to get each pixel color, and then, you can either :
On creation, for each pixel if it's not fully transparent (!= 0) you can draw a point of a Shape, which will be transparent, and make it dragable in place of your bitmap (as noticed in comment, it will be quite CPU consuming, so use the second method)
On click, get the click coordinate relative to the bitmap, check if the pixel is transparent and make it drag only if it's not.
In either way, that will be quite CPU consuming. You may also consider convert your bitmap to a vector image (Sprite). This will allow flash to detect real images boundaries.