I'm creating an Android board game with several differently shaped board spaces (like Risk).
I want to be sure that my board appears correct and that OnTouchListeners stay in place on the GUI regardless of screen size/resolution.
Possible solutions I have thought of and their problems:
Create a single image for the board and assign OnTouchListeners based upon pixel geometry. Problem: If the user's display is a different resolution, my Listener might not be under the same pixels as my image (right?)
Create several ImageButtons and arrange them together. Problem: the ImageButtons might get rearranged based upon the display and I would end up with overlapping spaces or gaps.
Use Android custom drawing. If I do this, how would I link my Listeners to my Canvas and be sure that they are synced?
Basic question:
How to be sure that listeners sync with graphics in a GUI that uses irregular geometry?
I worked on an app with irregular touch areas so I can give you guidance on one way to achieve this.
Start with a single image for your entire board. This image is going to have a certain ("intrinsic") width and height regardless of any device resolutions.
Now here comes the tedious part. You (or maybe your graphic designer) will need to plot out coordinates of an irregular polygon for each touch area. These will be constants to your application.
When you are displaying your board, if you are zooming and panning on the image, you want to keep track of the transform matrix for the display. When the user touches the screen, you will get x,y coordinates from OnTouchListener and for those to be useful, you will have to "de-transform" the x,y to normalize it against the intrinsic dimensions of the board and your polygons.
We rolled our own hit-testing logic using an algorithm from http://alienryderflex.com/polygon/, but you can also try this: Create a Path out of your polygon coordinates (using moveTo(), lineTo(), and close()), then assign the Path to a Region using Region.setPath(). Once you have that, supposedly you should be able to hit-test using Region.contains(x,y), but I've never tried it so I can't guarantee that's going to work.
Related
Let's say for example I have a bitmap image of a tree, and I want to position other images (such as bitmaps of apples) on the tree leaves. Is there a way that I could put markers on the leaves... red dots for instance... and then and then programmatically place apple images centered on those dots?
As a very basic test, I have image with a white background with one red pixel in the center. I'd like to calculate the coordinates of this red point, and then set an ImageView to be placed on those coordinates.
How might I go about this?
It depends, where your 'red point' marker is. If it's in the center or in any specific point (like 2/3 of width, 1/3 of height), you can just divide layout width and height to get right coordinates.
In other cases it would be better to set white background and draw markers manually in overriden dispatchDraw method. In such case you would just know the coordinates of the marker.
You want to position an image over the red dot, right?
I'm thinking of two different ways:
A-> You could make the red dot to be an ImageView itself, and then centering it by using gravity in order to transform it into another kind of image.
Or...
B-> Make a container that uses the white background with red dot as background resource. Then center it by using gravity too, and finally, positioning your image to the center of the container so it will be over the red dot.
No calculation is needed if you thing this could help.
It sounds like you are the one putting the markers onto your bitmaps.
If that is the case, is there a really good reason why you would want to be trying to embed the markers as data in the bitmap itself? That leads you to the problem of having to rediscover the locations. This could be a fuzzy task...what if there is a red barn next to the tree? Are you going to put an apple image on every red pixel making up the barn?
What you might actually want is to define a format which has a bitmap with no markers on it, and then a separate list of coordinates for where you want the apples to go. That doesn't require discovery of any kind...you just ship the image along with the list and you are done.
There are some cases where there is no "place on the side" that you can put information, and you actually need it to go into the bitmap file. If so, consider also that there are some hidden places you can put data in bitmaps... metadata like Exif:
http://en.wikipedia.org/wiki/Exchangeable_image_file_format
So that's a middle-ground, where you can manage to get the list of points to "stow away" into the file containing the image without actually requiring the modification of the pixels.
If you find you are really stuck in a situation where you must put these coordinate specifications into the image data, then something a little bit more unique than a red dot would be easier to detect with certainty. Maybe there's something you know about your images... for instance, that they are PNG files and do not have any transparency. You could make transparent dots indicate substitution points.
The larger and weirder the pattern, the more rare it is...so if you know your objects being pasted are always going to be bigger than 3x3 you could come up with a very unusual 3x3 pixel imprint for your markers that would be unlikely to occur in nature. Uncompressed in 24-bit color, a sufficiently random pattern would only happen 1/(2^24^9) by accident. Small number; although compression would create more gray areas.
But greater point being: if you don't have a good reason to turn a simple problem into a complex image-recognition exercise, don't. Just keep the list of points on the side somewhere so you don't have to hunt for them in the image.
I'd like to create a custom map. It should be or look like one picture, but according to the part of which the user clicks, it should move the user to a different location (i.e. start a different activity). I've seen it done in several games but I don't know how to do it myself.
The part of the picture should have non-geometrical borders (obviously it would be easily done with many square images). Sadly, I don't even know what term describes what I want to do so I wasn't able to find any helpful tutorials or discussed topics.
Example:
Picture: http://i236.photobucket.com/albums/ff40/iathen/mapEx.png
If the user touches the purple slide, (s)he should be leaded to activity_1
If the user touches the blue slide, (s)he should be leaded to activity_2
If the user touches the green slide, (s)he should be leaded to activity_3
In my experience there are 2 main (most used) ways to achieve this.
The first (my favorite):
Get the data from a PNG
You should write multiple layers to a canvas. These layers constitute your "zones" (blue, green, purple in the image). To obtain the data of these areas, you get it from PNGs (with transparencies off course) to write the canvas with whatever you want. You must store the values where there can be a tap from the user (non-transparent areas). Notice that this values can be scaled up/down depending on the map size, screen resolution, map dimensions, etc.
Once you've written the layers to the canvas you should check for a match of the user tap and the stored areas you have. You should take into consideration here the order in which the user tap is processed in your code. For instance, in your image, the purple layer is on top so it must be processed first, the blue as second, and the green as the last one. This way you can have an "island" inside a bigger area.
The second way:
Generate the boundaries programmaticaly
I think this solution is self-explanatory. The only I've faced with this variant is that when the surfaces boundaries get messy, it's really complicated to generate the proper equations.
EDIT:
Using the first approach you can employ multiple PNGs to load data or use a single PNG with data coded into the bytes (i.e. RGB values). It's up to you to decide which one to implement.
Hope it helps!
Since a touchscreen itself isn't very accurate, your collision detection for the buttons doesn't need to be either. It would be a waste of time to try to make a complicated collision detection algorithm to detect a touch within those weird shapes.
Since you are making a game, I assume you know how to handle custom touch events, as well as canvas (at least). There are many ways to do what you want, but in the specific example image you linked is kind of a special case.
You could create a giant bounding circle around the three blobs, and then check if the user touched within the bounds of the circle (ie check if the distance from the touch to the center of the circle is less than or equal to the radius). Once you determine that it is, you could check which section of the circle it falls into by splitting it up into 3 equal sections. Requires some math, but shouldn't be that complicated.
It wouldn't be a perfect solution, but it should be good enough. Although, you might have to change the buttons a little so they aren't so stretched out horizontally, otherwise a bounding circle wouldn't be ideal.
Personally, in my games I always have "nodes" that represent the visual elements of the game, such as buttons. Instead of using a large image like you are doing, I would create separate images for each button, and then check their collisions with touch events independently. That way I could have each button check with their own individual bounding circles, or, if absolutely necessary, I could even have custom algorithms for each individual button.
These aren't perfect solutions. If you do want a pixel-perfect solution, you'll need to implement some polygon collision detection algorithms
One thing to consider is screen size and ratio. The only constants you should use are for percentages.
I have received requirement like this http://www.youtube.com/watch?v=7MYQicokwmY&feature=plcp I am reviewing this requirement.As per requirement we have to build touch detection like in video link for Android enabled Tablets.
In that video toys (toys with circular, star or rectangle shape) uses Conductive Silicone Sensors with that they are detecting touch on screen & deciding shape of external world object like triangle,circle or a star & further processing the shape.
I have to use same touch detection for android tablets.Can anybody help me to find the way to implement this on Android platform ? Is there any API or framework to implement it?
If you see the video around 1:13, they show what I am guessing are some prototypes, the circle has three points, the hexagon too...
My best guess is that the biggest part of the object is non-conductive and only has a few points that are conductive and would actually register as touch points on the screen. The key is that each of them will be different enough that you would be able to recognize them no matter what the orientation is, what the position (and depending on your requirements whether you have several of those objects at the same time on the screen).
You can also play with the area of each conductive points so in your code, you will get the touch information, you can get different pressure values from the MotionEvent
Now how you place the conductive points and how many on each shape is completely up to you and would really depend on what your requirements are (recognizing arbitrary shape is not an option...)
Most touch screens would reject the touch if the area is too large (that's palm rejection), so I don't think there are much other ways to do this...
I am developing a puzzle game, where user has to arrange the images in the grid. The screenshot is given below
I want to able to drag the image of one cell of the grid to another cell. I searched many sites and every where I found examples with Drag and drop API (I.e. by using OnDragListener etc.) which was introduced in Android 3.0, but my application should run in Android 2.2.
So please help me how to implement it using Touching API (I.e. OnTouchListener etc.)
One way of doing it would be take the x & y location of the touch in relation to the grid.
IE. at 10x10 grid on a 100x100 area.
If the touch was at 25,25, it would choose square 2,2(using an array). You could then save that location to a variable (so as to move whatever piece to it that you are changing it with) and on drag update the bitmap x,y in relation to the touch.
Once you lift your finger at say, 75,75, it would set the puzzle piece at 7,7 and move that piece to 2,2.
I used something similar, less the drag, on my Lazer Maze Lite game. Mine was basically moving mirrors and bombs on touch though, but....
http://developer.android.com/guide/topics/ui/drag-drop.html
I've got the following problem:
I display a point on a SurfaceView (e.g. one specific pixel like (x=100,y=100)
on the screen.
Now I want to zoom to this specific point with different zoomlevels.
The zoomlevels are calculated by different scaleFactors. But I don't know
how I can display and scale the specific part of the screen?
Perhaps it would be also possible to move to the known displayed parts by "Scrolling about the screen" (using an OnTouchListener).
Have you tried to Canvas.scale() to the specific point in the drawing loop of the SurfaceView?
http://developer.android.com/reference/android/graphics/Canvas.html#scale%28float,%20float,%20float,%20float%29