I'm attempting to put together a slick animation in which a view that takes up most of the screen space rotates to reveal another view on the rear side:
rotatingView.animate().rotationY(90)
.setDuration(250)
.setInterpolator(new AccelerateInterpolator())
.withEndAction( /* Runnable that sets up the rear side of the view,
then rotates Y another 90 degrees */);
Problem is, about 80% of the way through this animation, the view disappears. The view doesn't reappear until about 20% of the way into the second half. Put another way, it disappears at 11 o'clock and reappears at 1 o'clock. Why is this?
I finally stumbled on the answer to this type of problem. UsesetCameraDistance(), but note that:
The distance is expressed in "depth pixels." The default distance depends on the screen density. For instance, on a medium density display, the default distance is 1280. On a high density display, the default distance is 1920.
So, to "raise" the camera to the point where the near edge of a view doesn't clip it, set the distance to several times the "default" distance. In my case with several tablet screens, a value of 4000f was needed. See the link for more onsetCameraDistance()parameter calculation.
You may want to combinesetCameraDistance()with clipToPadding="false" and clipChildren="false" in your XML file; these control masking of one view by another.
Also, I suspect YMMV across different Android releases and vendors.
Related
I am using the formula to calculate speed and am using the screen width as distance and fps as time. The speed of the sprite is still different when moving across the screen. How should I change the formula in order to make the speed feel the same on all screen sizes?
public static float distanceX = Screen.width;
public static float time = 60f ;
public static float speed = Player.distanceX / Player.time;
To answer the question, you have to define what the "feel" needs to be. For example, suppose the device is held in landscape orientation. A 4:3 device is much narrower than a 16:9 device, so if you have a bunch of squares arranged horizontally on the screen, you'll have more of them on the 16:9 device than on the 4:3 device.
If your goal is to move from one side of the screen to the other in a constant amount of time, then the formula you show in your question is correct.
If your goal is to move past N squares in a constant amount of time, then you need a different formula. It sounds like this is what you want.
One approach is to define a device-independent "arena" in which everything moves, and then fit it to the device. For example, you could define the world to be 1000x1000, and that things move at 100 units per second. You then fit the arena to the screen by either cutting off the top and bottom, or letter-boxing the sides. A side-scrolling platformer would usually match the arena to the device height, and then show a wider or narrower field of view horizontally. (For an example of this approach, see Android Breakout.)
On a related note, it's unwise to assume that a device has a certain fixed frame rate. Some advice can be found in this appendix.
I've been writing a 2D Surfaceview game for what seems an eternity now and I simply cannot get my head around screen independence for Android.
Basically, my sprite jumps like so: Y value is decreased by an amount (I call it the 'step amount'), then the step amount is reduced by say, 1 and that goes on until the step amount is a negative number which then in effect gets added to the sprite's Y value and it 'falls' back down - works perfectly (This is the way I've always made sprites 'jump').
The problem comes when I run this on a different DPI screen - it still works, but the sprite jumps to a completely different height relative to the screen size.
I understand why this is happening, but I just can't work out a way to fix it!
How do I get it 'jumping' to the correct height on all screen res? (I'm working mainly with 160 and 240 DPI at the moment)
Thanks, would really appreciate any comments.
Regards
I'm having difficulties understanding about the OpenGL perspective view. I've read tons of information however it didn't help me trying to achieve what I'm after. Which is making sure my 3d scene is filling the entire screen on every Android device.
To test this, I will be drawing a quad in 3d space which in the end should touch every corner, filling up the whole device's screen. I could then use this quad, or actually its coordinates to specify a bounding box at a certain Z distance which I could use to put my geometry and making sure those fill up my screen. When the screen resizes, or I am to run it on another screen resolution, I would recalculate this bounding box and geometry. I'm not talking about static geometry, but for instance say I want to fill the screen with balls and it doesn't matter how big or how many balls there are, the only important thing is the screen is filled and there are no redundant balls outside the visible frustum.
As far as I understand when specifying the viewport you actually bind pixel values to the frustum's boundaries. I know that you can actually set an orthographic view in a way your window pixels match 3d geometry position but I'm not sure how this works in perspective view.
Here I'm assuming the viewport width and height to be mapped to the nearZ. So when a ball is at Z=1f it has it's original size
When moving the ball into the screen so into the direction of farZ, the ball would be scaled down in order for the perspective to work. So a ball at Z=51f for instance, would appear smaller on my screen and I would need more balls to fill up the entire screen.
Now in order to do so, I'm looking for the purple boundaries
Actually I need these boundaries to fill the entire screen on different frustum sizes (width x height) while the frustum angle and Z distance for the balls is always the same
I guess I could use trig to calculate these purple boundaries (see blue triangle note)
Am I correctly marking the frustum angle, it being the vertical angle of the frustum?
Could someone elaborate on the green 1f and -1f values as I seem to have read something about it? Seems like some scalar that is used to resize the geometry within the frustum?
I actually want to be able to programmaticaly position geometry against the viewport borders within 3d space at any resolution/window for any arbitrary Android device.
Note: I have a flash background which uses a stage (visual area) with a known width x height at any resolution which makes it easy to position/scale assets either using absolute measurements or percentual measurements. I guess I'm trying to figure out how this system applies to OpenGL's perspective view.
I guess this post using gluUnproject answers the question.
I'm looking for an Algorithm or Pattern to calculate where objects can be placed on multiple resolutions. So far, I have got the X and Y screen size, but im not sure how to turn it into a calculation that would place something such as a drawText() at a location on the screen no matter the screen size.
I was thinking perhaps using percentages might be easier to work with. I have a program that draws text to the screen at the top left corner indicating what position the screen has been touched.
when i run this on the emulator, with the
drawText(info, 10,10, paint);
it displays great, but when i run it on my phone (Droid 2 Global) the top of the text is cut off.
In short:
Is there any way to draw something to the screen (using SurfaceView) that will remain in the same spot over multiple screen dimensions / dpi?
Thanks for your time.
It's no perfect solution that i've seen so far.
I came across this issue by specifying the position for the particular item for the specific screen ratio(native screen resolution in an emulator), then recalculate its position and scale it up/down when running it in the different screen size.
displayXpos = constDevelopmentScreenXpos (targetDeviceScreenHeight/constDevelopmentScreenHeight) etc..
displayXScale = similarAlgorithm
This is not the best, but it give you some idea.
Also, i fill some 'limbo' area with a background and choose to not care it when the target device X:Y screen ratio is different from development device.
HTH
ya, it is better to use calculation in percentage
first get the total size avail of the screen, then calculate percentage on it and the place the control based on calculation
to get avail size
Display mDisplay= activity.getWindowManager().getDefaultDisplay();
int width= mDisplay.getWidth();
int height= mDisplay.getHeight();
I am trying to make an app whereby a picture will be shown, there're a few objects that user needs to identify (i.e. a cup), by touching the cup in the picture on the screen, a circle will be drawn if it's valid.
So far, I have a surfaceview with a bitmap as drawable to be displayed full screen, and upon touching the screen, a circle will be drawn to the view.
I could only think of getting the coordinate of the cup manually in the picture(hardcoded), and check it against the coordinate from touch event.getX() and event.getY(). But this would not work as screen resolution changes.
What is a better way in doing so? It's like I'm trying to find a way to precisely allow touch on certain areas which I've defined in my app.
You can store the coords as you were suggesting but adjust them based on the size of the SurfaceView vs. the size of the BitmapDrawable. For example, if you know a given area is 100px from the left, you could take your scale as surfaceView.getWidth() / bitmapDrawable.getIntrinsicWidth(). Multiply your scale times your value (100px) to get the final position. If you're keeping the same aspect ratio on the image, you need to get your scale from the larger of the two (width vs. height) and use that same scale for height and width.
In a given resolution, is the location of cup fixed or it varies there as well.
Also, what about the orientation (landscape, portrait)? does the location change accordingly as well?
There are standard resolutions, so you can always think of mapping the location with resolution.
Also, you can get X, Y coordinate and check if it falls within a range based on height and width of cup image.
First of all find out the size of screen (screen dimensions).
Now place objects relatively corresponding to your screen area.
eg. keep cup on SCREENWIDTH - 60 and check coordinates of touch similarly.