How to decide width and height for SVG sprite in AndEngine - java

I am using AndEngine to load a svg images as my Sprites.
The problem I am having with this is that i can't figure out how to scale the image to fit the particular device on which it is being run.
sprite= new Sprite(positionX, positionY, WIDTH,HEIGHT,TextureRegion);
The parameters that it takes are the position's on x and y coordinates, and then width, and height.
The problem I am having is that I can't figure out how to scale the sprite to the right width and height for how I want it.
For example I have a title, and I want the title to be bigger on bigger devices, how would I decide if the device is bigger and scale it up for a bigger screen and down for a smaller screen?

If you use a constant camera size, all of the screen is scaled (Hence all of the entities).
Decide on a constant size, for exaple 720x480.
final static int CAMERA_WIDTH = 720;
final static int CAMERA_HEIGHT = 480;
Then, when creating the engine options, use:
... new EngineOptions(... new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), ...);
On each device, the camera will scale itself to fit the resolution as good possible, while keeping the ratio between width & height.
Now, when creating a sprite, just do:
Sprite sprite = new Sprite(x, y, TextureRegion);
Don't give the sprite size! Its size comparing to the camera size will be decided according to the texture region size, and it will be a constant one. Then, it will be scaled by the camera-to-device-screen scaling, which changes from one device to another, but the ratio will remain constant - the game will not look like a bad scaled image on devices with a different resoltuion that the camera width/height ratio.
I think that's a great method that AndEngine provides to deal with different screen resolution; IMHO, it is the best to use.

Related

How to start an Activity in specific coordinates

My Activity has a Canvas with both width and height equal to 6000. When I start the Activity the upper left coordinate of my screen is (0,0) so screen' center is about (30,60). What I want is start the Activity with coordinates (3000,3000) in the center of screen
any solution?
Update 1:
I used this Kotlin code:
var fondo = Lienzo(this) //fondo is the Canvas View (6000,6000)
val scrollV = ScrollView(this)
val hscrollV = HorizontalScrollView(this)
scrollV.addView(fondo)
hscrollV.addView(scrollV)
layaout1.addView(hscrollV) //layaout1 is a RelativeLayout
More code would be nice since I cannot see where you are declaring the position but if you are hard-coding the coordinates, I would suggest instead of using the same variables for width and height and just putting them in the coordinates /2 so if your variables are width and height, it should be kind of like this depending on what you are using:
.setPosition(width/2, height/2);
If this isn't useful then please provide more info or more code to see where your mistake is :)
That's not how Canvases work in Android. You don't declare how big you want it to be and it magically scales to the screen. If you're in the View's onDraw function, the Canvas passed in is the size of the View, in physical pixels. You need to scale your drawing to it. If you're drawing to an offscreen bitmap first and then blitting that to the screen, its your job to scale the bitmap via a matrix when you blit it. Also, in Android the coordinate system is 0,0 as the upper left hand corner. Unless it greatly eases your drawing I suggest you not fight it.
However you could use a matrix transformation on the Canvas to change that. First you'd want to scale the matrix by 6000/view.getHeight() in the y and 6000/view.getWidth() in the x. Then you'd want to translate it by -3000 in the x and -3000 in the y. That should scale it to the view and move origin to center.

Scaling an image and place it in the specific location (coordinates) in Android's LinearLayout

I'm not very skilled in android application developing, and I'm working on a test app. I detected the face and the eyes, now I'm going to draw something like acne or scar on the face (e.g below the eyes on the cheek) based on the coordinates of the eyes. Later, I'm going to put eye-glass or hat on the appropriate locations.
I know the coordinates of the left and the right eye (leftEyePosx... [and so on] in the code). For example 136x168 [left] and 216x168 [right] (mirrored in picture). Now, I'm calculating the scale: glass bitmap should be scaled around 80 pixels (216-136) or bigger for the width, and 80 pixels multiplied with the original image's aspect ratio for the height (e.g. 80 * 0.7). I have the bitmap with the code:
glassBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.glass_01);
Now, how can I re-scale the eye-glass and use the method canvas.drawBitmap() and use eye coordinates and draw the glass on the face? Or should I use another way?
Thanks in advance, and sorry for my bad English :)
First you scale the bitmaps:
Bitmap scaledBitmap = Bitmap.createScaledBitmap(originalBitmap, targetWidth, targetHeight, false);
Then you draw one bitmap on top of the other, at xPos and yPos:
Canvas canvas = new Canvas(baseBitmap);
Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
canvas.drawBitmap(overlayBitmap, xPos, yPos, paint);
xPos and yPos are the upper left corner of the overlay bitmap. For example, if the base image eye is supposed to show in the middle of the overlay bitmap, you have to adjust for this by deducting half the width and height to find the desired xPos and yPos.

Texture Region 2D Array - Why are my sprites drawing so small?

Using the Libgdx Framework, I'm generating an Actor from an Assets.java class and then drawing him depending on the state he is currently in. The problem i'm having is that he's coming out ridiculously small. I'm noticing that when I split the Texture into regions the .Split() function doesn't provide width and height parameters in comparison to a singular declaration of the texture region function here: new TextureRegion(Texture, x, y, width, height);
Note: I've also set the size of the world, the actor size etc they don't need to change how small he is. I'm assuming it's something to do with the sprite size or assets class. But the way i'm slicing the Texture works perfectly for the engine i've created.
I'm wondering is there something I'm missing or something to add to define the width/height of the TextureRegions inside theAssets.java code snippet?
All my sprites are in a 512x512 Texture with a height and width of 85px
Relevant Code:
rubenSprite = loadTexture("data/rubenSprite.png");
rubenFrames = TextureRegion.split(rubenSprite, 85, 85);
WalkF1 = rubenFrames[0][0];
WalkF2 = rubenFrames[0][1];
WalkF3 = rubenFrames[0][2];
WalkF4 = rubenFrames[0][3];
WalkF5 = rubenFrames[0][4];
... More TextureRegions
If more code is needed, or anything elaborated let me know. Thanks.
The size of actor is not size of texture inside. Actor has boundaries. When this boundaries are too low image cannot fit inside. On to the contrary, it is analogously.
You should set your actor as:
setWidth(width);
setHeight(height);
setBounds(left, right, width, height);
And make sure, that texture is also set to width and height.
btw.
I recommend, use drawables with Actors. It is more clearer. You create skin, where you define all your moves and then you call your textures from the skin.

libgdx optimal Height and Width

Does it matter what height and width I use for my game? In my game I have a few polygons, they all are connected to images that I have painted, but when I have width and height as 800x480 I have to paint the images very small, this causes them to get blurry. Also, I don't really understand how this behaves on different sized phone screens.., does the images I have painted get streched, or do they stay small, even on big tablets? So my question is basically what is the optimal width and height to have on a libgdx game?
This is a part of my code, to maybe help you understand what I mean
WIDTH = Gdx.graphics.getWidth();
HEIGHT = Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480 );
What will happen if I change these values? What would it be best to change them to?
I was reading on a tutorial of sorts, but they didn't really talk about this part.
Do I have to do something complicated to get my painted images to look decent on all devices?
EDIT:
This is how I currently implement a cloud into my game:
public class AnotherScreen implements Screen{
Polygon cloudPoly;
Texture cloud;
#Override
public void render(float delta) {
batch.setProjectionMatrix(camera.combined);
batch.begin();
renderBackground();
batch.draw(cloud,cloudPoly.getX(),cloudPoly.getY());
batch.end();
}
#Override
public void show() {
cloud = new Texture(Gdx.files.internal("assets/textures/cloud.png"));
cloudPoly = new Polygon();
cloudPoly.setPosition(MathUtils.random(350,600),MathUtils.random(380,440));
// theses vertices are just a little square atm
float[] cloudVertices = new float[] {
0,0,
0,20,
20,20,
20,0
};
cloudPoly.setVertices(cloudVertices);
}
}
The cloud image has width 256p and height 128p, when I set 'camera.setToOrtho(false, 800, 480 );' won't this cloud always stay in proportion?
I am sorry if I am unclear, I am a new programmer and my english could be better, love you doh for staying with me!
does the images I have painted get streched, or do they stay small, even on big tablets?
One of the greatest features of libgdx is that it lets you do things exactly as you want them. So, it is really your choice. With this snippet
WIDTH = Gdx.graphics.getWidth();
HEIGHT = Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.setToOrtho(false, WIDTH, HEIGHT);
You would have a different viewport size in every different screen size. So your images would stay small.
In the other hand, if you use predefined values for the viewport like:
WIDTH = 800;
HEIGHT = 480;
camera = new OrthographicCamera();
camera.setToOrtho(false, WIDTH, HEIGHT);
You would get the same viewport for every screen and the images would stretch to occupy the same space in each axis. This won't necessarily be the same for each axis. So a perfect square image in one screen may look like a rectangle in another screen with a different x-y ratio.
There is a third option, you can fix one side and let the other be calculated, so you keep the ratio of your images (a square stays as square). You must decide what will be the fixed side. For a game like Super Mario Bros I would recommend you to fix the height and calculate the width:
HEIGHT = 480;
WIDTH = (Gdx.graphics.getWidth()/Gdx.graphics.getHeight())*HEIGHT;
camera = new OrthographicCamera();
camera.setToOrtho(false, WIDTH, HEIGHT);
Every screen would see the same height in the game world. But some screens would see more in the width than others. If thats a problem for you (you want them to see the same ammount of the world but keep the ratio too), than adding black bars to each side is an option.
So my question is basically what is the optimal width and height to have on a libgdx game?
The optimal solution is having a different set of images for several resolutions. And choosing whats the most appropiate at runtime. But that increases the game size a lot.
Another dirty way is having only one big set and let the images shrink in lower resolutions. It looks better than the inverse. But some people think this is just too dirty :p (not me, so I recommend it).

What is a right way to render repeated-background in libgdx?

public render(){
...
while (y < Height){
while(x < Width){
batch.draw(bg,x,y,bg.getWidth()/ratio,bg.getHeight()/ratio);
x += bg.getWidth()/ratio;
}
y += bg.getHeight()/ratio;
x = 0;
}
...
}
I have a pattern texture(bg) which will repeat to make a repeated background, so i make it repeated in render function (code above). At first it works very well, but when the ratio get bigger (so the sprite get smaller to fit the background), it become very laggy. Can you tell me a right way to make repeated background like above code without affect performance.
I'm guessing it gets laggy because you are drawing hundreds of quads to the screen, and if there are too many, it will become a CPU bottleneck and reduce frame rate. But the other answer might actually be the reason: if you are shrinking a texture significantly without using mip mapping, it will really eat up GPU time.
Since this is just a repeating texture, you only need to draw one quad for the whole screen. First, when you load the texture, make sure it repeats:
bg.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);
//call this only one time, after you instantiate the Texture
Then you can draw a single quad to the screen and set the UV's of the vertices big enough for the number of times you want it to tile.
// bottom left corner...wherever you want to put it.
float bottomY = 0;
float leftX = 0;
//width and height of background. This is just an example. By the way, Java
//convention is for all variable names to start with a lower-case letter,
//to avoid confusion.
float width = screenWidth;
float height= screenHeight;
//I'm using RATIO like you are, which I think is the reciprocal of how much
//you want to scale the texture up. By the way, it is convention to make
//constant variable (static final primitives in Java) names be in all caps.
float uRight = width * RATIO / bg.getWidth();
float vTop= height * RATIO / bg.getHeight();
batch.draw(bg, leftX, bottomY, width, height, 0, 0, uRight, vTop);
There are a few things that could be causing the lag. The biggest one is the fact that your background image is probably a large resolution that you are drawing many times just at a smaller width and height. I would say look into mipmaps and take a look at this tutorial http://www.badlogicgames.com/wordpress/?p=1403

Categories

Resources