I am facing multi resolution issue in box 2d.
First I needed to make bodies multi resolution, I solved it by scaling the vertices by scale factor.
Now I need to make the forces to act same of all different resolution devices,
Is there any way to do it?
I want to make this line of code to work same on all devices
obj.getBody().applyForce( new Vector2(0, -220), obj.getBody().getWorldCenter());
Here 220 is the factor should I make it multi res by this formula
public float getY(float value) {
y = (value / 540) * 100;
return (y / 100) * CAMERA_HEIGHT;
}
Here 540 is the base resolution. I call getY(220) to make it multi resolution.
When I use this code on resolution 540*960 it works fine but when I change the device say of resolution 720*1280 the game acts real slow.
Can any one help me with this issue? I tried to explain my question.
Thanks in ADVANCE.
You scale the graphics by setting your camera to something other than the device's pixel count.
Andengine will do everything else for the scaling.
All you need to get from the device is the ratio of x to y pixels.
In the example I have at this link, I just set one variable and everything is scaled to that.http://pastebin.com/WWGFvTVS
So you just decide what initial scale you want to work on, and do your Box2D stuff without worrying about scale. You just have to scale the Camera that is looking at the scene.
I'm saying the same thing as these other guys, you just don't seem to be understanding them.
Do not scale physics. Scale graphics. You should have physics coordinate system shared between each resolution to make your simulation the same on different devices.
Related
I am developing a game for android using the android NDK Vulkan APIs. The code is, for the most part, in C++14. For most cases things work fine, however, on some devices, I have this problem where the x and y coordinates are switched. I draw on what I think of as the top of the screen, and it draws the objects on the side. Also, when I do anything with the view point (the view matrix), x and y are reversed. If I move the view point in the x direction, it actually moves in the y direction.
Also, the width and height reported by the swap chain are reversed. So that if I plug these values into the perspective matrix like so:
glm::perspective(glm::radians(60.0f), swapchainRetrievedWidth / (float) swapchainRetrievedHeight, 0.1f, 10.0f);
it will draw horribly skewed objects. But if I reverse the width and height, like so:
glm::perspective(glm::radians(60.0f), swapchainRetrievedHeight / (float) swapchainRetrievedWidth, 0.1f, 10.0f);
The objects look fine.
One device where this happens on is using an Adreno 530, API version 1.0.49, driver version: 35.143.1455, OS: android 8.0, phone vendor: HTC. For this device, these symptoms only occur if the device is using the split screen mode with the device held in landscape orientation (the app forces portrait mode). I've seen this happen on other devices too and in the full screen (not split screen) mode. So, I don't think it is the way I reinitialized the swap chain, pipeline, depth buffer, render pass and command buffers when the screen size changes. Since the screen would not change size for the devices where this problem occurs in full screen mode.
Am I doing something wrong? Is there a bug? I am willing to give more information on this problem, but do not know what is needed.
I tried the same thing in OpenGLES 2.0 on the same device in the same circumstances and these symptoms do not occur. Thanks for all your support and help.
(Answer based on discussion in comments)
This happens when you set VkSwapchainCreateInfo::preTransform to something other than VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, but don't actually apply that transform during rendering. The safe thing to do is to always use VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, but if your window is being rotated by the system compositor this is suboptimal from a performance/power point of view.
It's more efficient to look at what transform the system compositor is applying (VkSurfaceCapabilitiesKHR::currentTransform), apply that transform yourself during rendering, and let the compositor know you did so by setting VkSwapchainCreateInfo::preTransform.
I am trying to do something simillar to this, but on Android:
http://docs.opencv.org/doc/tutorials/imgproc/imgtrans/warp_affine/warp_affine.html
I have an image drawn to ImageView and i want to be able to select 6 points (3 source and 3 target)
and use the warpAffine method on OpenCV like the example before.
I'm able to reproduce the example above, but when passing the X,Y coordinates from onTouch event, it doesn't give me what i expect.
I think the problem is how to convert the android touch coordinates to OpenCV Mat column/row.
Maybe i need to display the image on OpenCV surface?
I hope i was clear,
Thanks in advance.
The touch coordinate refer to a point that belongs to your Android's screen resolution (Samsung Galaxy S3 is 720x1280). On the other hand, the OpenCV image could be larger or smaller than that, meaning that a touch coordinate can't be mapped directly into an image coordinate.
What needs to be done to convert from one resolution to the other, is the normalization of the touch coordinate from 720x1280 to the 640x480 range. Therefore, to find the real coordinates on the image you would do:
real_x = (touch_x * 640) / 720;
real_y = (touch_y * 480) / 1280;
I am very beginner to game programming and Libgdx. I am really confused what camera viewport size should I use. In some articles i found that they used 480x800 which is same as target device size. In some articles I found the use meters as 5x5 meter.
So which method is better and how (if you can give some benefits).
If I use meter unites for camera viewport then which is first mapped, width or height.
If i use 5x5 meter for 480x800 pixels device then visible area of world
height = 5 meter = 480px and
width = 800/480 * 5 = 8.33 meter
or
width = 5 meter = 800px and
height = 480/800 * 5 = 3 meter
Is it correct calculation of visible world size and which is used first or second.
I am confused when they start using meter for size everywhere instead of pixels. like actor size is 1x1 meter even it is only 64x64 px. It is really difficult to estimate position and size for me.
Please link any good article about camera and camera units.
Whatever dimensions you specify, they'll be mapped to the entire screen by default. If the aspect ratios don't match, the displayed graphics will be stretched. So if you set your camera to a 5x5 coordinate system on a non-square screen without changing the drawing area, it'll be heavily distorted. If you render it in a square desktop window, it'll be fine.
The advantage of using smaller coordinate systems is that it's easier to calculate with, and possibly more meaningful in the context of a game - e.g. you can think of them as meters, as you said. It's useful in cases where the content matters more than the exact positions on the screen - like drawing the game world.
Using larger coordinates which match the resolution of some devices can be more useful when you're drawing UI. You can see how large you should make each image, for example, if you target that resolution. (Scaling can cause distortions.)
But ultimately, it's a matter of preference. Personally, I like smaller coordinate systems more, so I recently coded my level select menu in a 20*12 system. (I did run into problems when rendering a BitmapFont though - they were not very well made for scaling like this.) Others might prefer to work with resolution-sized coordinates for gameplay rendering as well. What matters is that you should make sure you're not distorting the graphics too much by badly matching aspect ratios.
try 136 for Width and 204 for Height
This is my first post, so I apologise in advance if I have done anything wrong here in asking my question. I've looked all over the net for a specific answer, but can't find one, so here goes.....
I'm writing a game based on Surfaceview and so far, all is going well, however, I want to move my main sprite for example by 1 pixel on a 160DPI screen as a baseline (so basically 1 DIP as 1 pixel = 1 DIP on a 160DPI screen correct?)
I'm using the using the following forumla:
private static final float spritemovestep = 1f;
final float scale = getResources().getDisplayMetrics().density;
MoveX = (int) (spritemovestep * scale + 0.5f);
And then... something like
SpriteX=SpriteX+MoveX
First question - is this correct?
If it is, can someone explain what the +.05f is actually for, I've read that it's to 'round up to the nearest number' but....
if spritemovestep = 1, then on a 120DPI screen (which returns .75 as the scale I think) it would work out as: 1 x .75 + .5? which would be 1.25? So what is the .5 for?
Also what is the result when it's cast to an int value?
On some, the final result seems to be '0' on a low density screen so the sprite isn't moving at all.
Also some sprites which are supposed to be moving at different speed are moving at the same speed at certain densities.
I'm sure I'm being silly and missing something here but I just can't understand how this is supposed to work. If I want to move my sprite by 1 DIP/physical pixel on a MDPI screen how can it move less than 1 pixel on a LDPI screen?
Also, what is this formula I keep seeing:
px = dp * (dpi / 160) - When is this used?
Would really appreciate if someone could answer my questions.
Thanks all
The +0.5f is to round up to the nearest nukber, as you said. Ideally, when the number is scaled down for ldpi, a value of 1 becomes 0.75, which, when cast to an int is expressed as less than 1 or ~=0. By adding the rounding figure, this number is raised to 1.25 which, when cast as an int yields <2 or ~=1. This way, your sprite should be drawn with a minimum movement of 1. The only reason sprites that move at different speeds would move the same speeds is if they are so close that, when rounded, they wind up being the same size using the scale you gave. Altogether, your equation is very similar to others ive seen. Im making a game that uses surfaceview for the company i work for as well, and while i cant go into details on the code, your issue is one that i struggled with for sone time. Im not sure how your physics updates, but perhaps thats something you should check into, specifically, how it counts ticks for your game timer. It may be that your application is reading its ticks as being too close together to reach the point where it would hit the point of moving the 1.25 or 1 after casting to int, and therefore your sprite appears not to move. I briefly experienced that problem and at first was looking at my velocity until i found that the error was in the timer. One other thing i noticed is that your algorithm collects the density. On a mdpi device, does this return 1 or 160? That could make a big difference, but im not sure, as the equation i used was different. The other equation you found is a paraphrase of the equation listed in the development guide at android.developer.com to describe how the os converts pixels into dip. The reson people tend to quote that is to provide a reference to help others build their own algorithm for scaling appropriate for the jeeds of their app. Hopefully that helps, as its really the best answer i can give at this time. Sorry for any typing errors, im sending this from my phone
I've got an image that is 800 by 300, which I know is the width of my test platform's resolution (HTC Desire at 800x480). When I try to draw this image to the screen it scales oddly. It spills over the left hand side of the screen and fills almost all the vertical.
I'm using code like this:
canvas.drawBitmap( screen[1], new Rect(0,0,800,300), new Rect(0,0,800,300), null);
For some reason
width_x = canvas.getWidth();
width_y = canvas.getHeight();
reports my resolution as 533 by 320. Now I assume this is for the expletive-deleted fascinating scaling system Android uses so apps appear the same size on all phones but I want to ignore this. I'm writing a game, so want to handle scaling and positioning myself - for instance using more screen estate if it becomes available. Best Android practice may be suitable for an icon based application, but I would like to draw to absolute pixel positions, and get absolute resolution information for the screen.
Therefore my question is this - is this absolutely impossible? If it is completely contraindicated because Android has a simple and effective system in place to do this then I would be interested to know what it is. Dpi is not relevant to my game design (just like if this was a pc game, it would be irrelevant)
Perhaps my screen actually 533 by 320 unless I specify a resolution somehow? I tried using the scaling values from width and height and the image was the correct size on screen, roughly, but had jagged edges because some sort of scaling had occurred. I therefore did not have access to all the pixels my screen is capable of displaying.
To scale it I used something like
canvas.drawBitmap( screen[1], new Rect(0,0,800,300), new Rect((int)(0.0f),(int)(0.0f),(int)(533.0f),(int)(187.5f)), null); // numbers
Just whacked in for testing - ratio equivalent to reported screen resolution. Looks horrid.
Android is not doing anything to mess with your perceived resolution - you are working with 800x480 pixels on that Desire.
Are you working in a fullscreen, custom View and overriding onDraw? Are you working with a SurfaceView? We need to know these things before we can help you with your problem.
Assuming you are doing the above, you should be able to draw your bitmap to the screen without any scaling using Canvas.drawBitmap(Bitmap bitmap, float left, float top, Paint paint). In your case, that would look something like canvas.drawBitmap( screen[1], 0.0f, 0.0f, null); to put it in the upper left corner of your canvas.
In performance-sensitive apps (like games), you don't want to use the source/destination Rect version of drawBitmap() during your draw loop, since it will do the scaling during every iteration of the loop. Instead, draw a scaled/cropped version of your original bitmap to another member bitmap, and draw that one in the loop, using the x/y offset version of drawBitmap linked above.
If you want to know the amount of screen real estate you're working with (and you definitely should, if you're doing any custom drawing), you'll want to override either onSizeChanged() or surfaceChanged(), depending on implementation.
You should really check out the API demos, there are some great examples of how to do exactly what you're trying to do in there.
Good luck!
I fixed one of my problems - in the manifest file the OS I was targeting was set up incorrectly - switching it to 4 (i.e. 1.6) seemed to fix the values I was getting for height and width, at least for the HTC. Emulator is more problematic, but at least its a major step in the right direction. For your info, I'm working in full screen, landscape mode (fixed), with overridden functions for pretty much everything. (Including onDraw, surfaceChanged, and so forth)
If I can get the absolute width and height I can write my own code for loading the correct assets and using the correct scaling for screen positioning - DPI isn't an issue so hopefully that won't stray too far from suggested guidelines.