How to change size in libgdx-android-desktop? I am confuse on window sizeing and not sure how to solve this problem.
So for desktop window i want 500x500 but with android i want full screen so i cant hard code it.
For some reason ANDROID_WIDTH is always equal to WINDOW_WIDTH.
int WINDOW_WIDTH = 500;
int WINDOW_WIDTH = 500;
public void create() {
if (Gdx.app.getType() == ApplicationType.Android) {
int ANDROID_WIDTH = Gdx.graphics.getWidth();
int ANDROID_HEIGHT = Gdx.graphics.getHeight();
camera = new OrthographicCamera(ANDROID_WIDTH, ANDROID_HEIGHT);
camera.translate(ANDROID_WIDTH/2, ANDROID_HEIGHT/2);
camera.update();
} else {
camera = new OrthographicCamera(WINDOW_WIDTH, WINDOW_HEIGHT);
camera.translate(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2);
camera.update();
}
Gdx.input.setInputProcessor(new GameInputProcessor());
}
You cannot change the size of the windows by changing the camera. They are two separate concepts.
You set the size on desktop application in your main method through config lwjpg .
Android application is full screen anyway.
LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration();
cfg.title = "Title";
cfg.useGL20 = true;
cfg.height = 640;
cfg.width = 360;
new LwjglApplication(new MyGame(), cfg);
You can give the Window size on Startup:
new LwjglApplication(yourApplicationListener(), "Title", 500, 500, true/false (useGL2));
You can also Change it in your game using:
Gdx.graphics.setDisplayMode(500, 500, true/false (fullscreen));
You can surround this by an if Statement like stuntmania said:
if (Gdx.app.getType().equals(ApplicationType.Android)) {
Gdx.graphics.setDisplayMode(500, 500, false);
} else {
Gdx.graphics.setDisplayMode(Gdx.graphics.getWidth(),Gdx.graphics.getHeight(), true);
}
EDIT:
In LibGDX 1.8 the Method Gdx.graphics.setDisplayMode has been renamed to Gdx.graphics.setWindowedMode:
API Change: Graphics#setDisplayMode(int, int, boolean) has been renamed to
Graphics#setWindowedMode(int, int). This will NOT allow you to switch to fullscreen anymore,
use Graphics#setFullscreenMode() instead. If the window is in fullscreen mode, it will be
switched to windowed mode on the monitor the window was in fullscreen mode on.
(Source)
do this in your desktop project
cfg.width=500;
cfg.height=500;
and in your main class
int ANDROID_WIDTH = Gdx.graphics.getWidth();
int ANDROID_HEIGHT = Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.setToOrtho(false, ANDROID_WIDTH, ANDROID_HEIGHT);
camera.update();
Related
for my app I am creating an image editor which currently works fine but I want to implement un undo button which basically goes back to the previous state of the image. I am trying to do this by using an ArrayList of bitmaps. At first I use this code to open an image from gallery and set canvas:
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(
imageFileUri), null, bmpFactoryOptions);
bmpFactoryOptions.inJustDecodeBounds = false;
bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(
imageFileUri), null, bmpFactoryOptions);
alteredBitmap = Bitmap.createBitmap(bmp.getWidth(), bmp
.getHeight(), bmp.getConfig());
int x = alteredBitmap.getWidth();
int y = alteredBitmap.getHeight();
if (x > y) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
lscape = true;
} else {
lscape = false;
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
width = size.x;
height = size.y;
paint = new Paint();
paint.setColor(Color.GREEN);
paint.setStrokeWidth(5);
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
paint.setStyle(Paint.Style.FILL);
String[] orientationColumn = {MediaStore.Images.Media.ORIENTATION};
Cursor cur = managedQuery(imageFileUri, orientationColumn, null, null, null);
int orientation = -1;
if (cur != null && cur.moveToFirst()) {
orientation = cur.getInt(cur.getColumnIndex(orientationColumn[0]));
}
Matrix matrix = new Matrix();
if (orientation!=90) {
matrix.postRotate(orientation);
scaledBitmap = Bitmap.createScaledBitmap(alteredBitmap, width, height, false);
canvas = new Canvas(scaledBitmap);
canvas.drawBitmap(bmp, matrix, paint);
choosenImage.setImageBitmap(scaledBitmap);
choosenImage.setOnTouchListener(this);
b.add(scaledBitmap);
}
At some point of code I use this to draw a straight line:
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
downx = event.getX();
downy = event.getY();
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
upx = event.getX();
upy = event.getY();
canvas.drawLine(getScaledWidth(downx, width, choosenImage.getWidth()), downy / choosenImage.getHeight() * height, getScaledWidth(upx, width, choosenImage.getWidth()), upy / choosenImage.getHeight() * height, paint);
choosenImage.invalidate();
b.add(scaledBitmap);
break;
case MotionEvent.ACTION_CANCEL:
break;
default:
break;
}
Now what should I write for my onclick on undo button? I've tried everything but dont know how to reset the canvas to display one of the bitmaps saved in the arraylist...dont know if its a problem with my way of setting the canvas to the bitmaps or if im missing something. This was my latest attempt:
scaledBitmap = b.get(b.size()-2);
b.remove(b.size() - 1);
choosenImage.invalidate();
Im new to android development so sorry if I'm not being clear, but really any help would be greatly appreciated I am stuck in this project and it is due in soon.
Thanks in advance!
List of bitmaps --> Out of memory!
Bitmaps are kept in a very limited area of memory and having a whole list of fullscreen bitmaps for und purposes will make your app go out of memory very quickly.
List of paths --> Better
What I did for my (very old) app "Fingercolors", is keeping a list of all paths the user paints. The paths consist of a list of points and some information about color, stroke-width etc.
For undoing a step, I start (offscreen) with an empty bitmap and repaint all paths from the list except for the last one and then show that rebuilt bitmap.
This allows unlimited undo and also redo and it is fast enough even for complex images with lots of paths.
I am trying to scale the texture to fit the screen width. This is what I tried, but it simply repeats the texture. It does not scale it.
In the init method:
TextureLoader.TextureParameter param = new TextureLoader.TextureParameter();
param.minFilter = Texture.TextureFilter.MipMapLinearLinear;
param.genMipMaps = true;
param.wrapU = Texture.TextureWrap.ClampToEdge;
param.wrapV = Texture.TextureWrap.ClampToEdge;
manager.load("textures/texture.png", Texture.class, param);
In the render method:
Texture tex = manager.get("textures/texture.png", Texture.class);
float scale = (float)( (float)Gdx.graphics.getWidth() / (float)(tex.getWidth()));
batch.begin();
Sprite s = new Sprite(tex, 0,0,tex.getWidth(),tex.getHeight());
s.setPosition(0, 0);
s.setOriginCenter();
//s.setScale(scale);
s.setSize(Gdx.graphics.getWidth(), scale * tex.getHeight());
s.setOrigin(0,0);
s.draw(batch);
batch.end();
Does anyone have an idea what I am doing wrong?
Apparently this happened because I was using mipmaps. Without mipmapping, the sprites scale appropriately.
param.minFilter = Texture.TextureFilter.MipMapLinearLinear;
param.genMipMaps = true;
I have quite the annoying problem. I'm building an app where one can share photos. On the SurfaceView where you take the actual photo, the resolution is great. However, when I retrieve that image and display it in a ListView using Picasso, the resolution goes to crap. The pixelation is real. Is there anything that I'm doing horrendously wrong to cause this? The first code snippet below is where I actually save the photo, and the one below that is my getItemView() method in my adapter for the listview. Thanks in advance.
Note that the "photo" variable you see in my code is a Parse subclass I've created to make it easier working with data associated with each photo. I think you can safely ignore it.
EDIT:
SurfaceView of Camera:
Note that I attempt to set the camera parameters to the highest quality allowed. Unfortunately, when I LOG size.width and size.height, I can only get around 176x144. Is there a way to get a higher resolution for supported camera sizes itself?
camera.setDisplayOrientation(90);
Parameters parameters = camera.getParameters();
parameters.set("jpeg-quality", 70);
parameters.setPictureFormat(ImageFormat.JPEG);
List<Camera.Size> sizes = parameters.getSupportedPictureSizes();
Size size = sizes.get(Integer.valueOf((sizes.size()-1)));
parameters.setPictureSize(size.width, size.height);
camera.setParameters(parameters);
camera.setDisplayOrientation(90);
List<Size> sizes2 = parameters.getSupportedPreviewSizes();
Size size2 = sizes.get(0);
parameters.setPreviewSize(size2.width, size2.height);
camera.setPreviewDisplay(holder);
camera.startPreview();
Saving the photo:
// Freeze camera
camera.stopPreview();
// Resize photo
Bitmap mealImage = BitmapFactory.decodeByteArray(data, 0, data.length);
Bitmap mealImageScaled = Bitmap.createScaledBitmap(mealImage, 640, 640, false);
// Override Android default landscape orientation and save portrait
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap rotatedScaledMealImage = Bitmap.createBitmap(mealImageScaled, 0,
0, mealImageScaled.getWidth(), mealImageScaled.getHeight(),
matrix, true);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
rotatedScaledMealImage.compress(Bitmap.CompressFormat.JPEG, 100, bos);
byte[] scaledData = bos.toByteArray();
// Save the scaled image to Parse with the date and time as its file name.
DateTime currentTime = new DateTime();
DateTimeFormatter fmt = DateTimeFormat.forPattern("HH MM SS");
photoFile = new ParseFile(currentTime.toString(fmt), scaledData);
photo.setPhotoFile(photoFile);
Displaying it:
final ParseImageView photoView = holder.photoView;
ParseFile photoFile = photo.getParseFile("photo");
Picasso.with(getContext())
.load(photoFile.getUrl())
.into(photoView, new Callback() {
#Override
public void onError() {
}
#Override
public void onSuccess() {
}
});
The problem is not with the Picasso
It because this line of code
parameters.set("jpeg-quality", 70);
and this
List<Size> sizes2 = parameters.getSupportedPreviewSizes();
Size size2 = sizes.get(0);
When you setup the camera you already turned down the quality to the 70% (because based on the Android Documentation the range of jpeq-quality is between 0-100)
And then you also need to check is the size of the camera is correct or not, because you are making assumption with that code
you can try this code to get the best preview size with your preffered width and height
private Camera.Size getBestPreviewSize(int width, int height, Camera.Parameters parameters){
Camera.Size bestSize = null;
List<Camera.Size> sizeList = parameters.getSupportedPreviewSizes();
bestSize = sizeList.get(0);
for(int i = 1; i < sizeList.size(); i++){
if((sizeList.get(i).width * sizeList.get(i).height) >
(bestSize.width * bestSize.height)){
bestSize = sizeList.get(i);
}
}
return bestSize;
}
I hope this answer will help you, if you have another question about my answer you can try to ask me in the comment :)
I've been working on a simple endless runner android game in 2D. I've opted to go with the canvas route as the learning curve for Open GL seems to be relatively high. I've been following this tutorial so far:
http://www.javacodegeeks.com/tutorials/android-tutorials/android-game-tutorials/
And with the game loop exactly the same:
http://www.javacodegeeks.com/2011/07/android-game-development-game-loop.html
My problem is my game is running at a good 60 FPS on my Galaxy Nexus but when I put the game onto my girlfriend's Nexus 4, the FPS drops to 40 and game performance is very choppy. Same with my cousin's Galaxy S2.
I'm currently using:
MainGamePanel.java
getHolder().setFormat(PixelFormat.RGBA_8888);
I've heard RGB_565 gives better performance, but this actually drops my FPS on my device down to 40 and FPS is same with other devices
Have hardware acceleration enabled, doesn't seem to do much though:
AndroidManifest
android:hardwareAccelerated="true"
In my MainGamePanel, I instantiate all objects that will be drawn onto the canvas before the thread is started:
public MainGamePanel(Context context) {
super(context);
getHolder().addCallback(this);
getHolder().setFormat(PixelFormat.RGBA_8888);
initScreenMetrics(context);
initGameMetrics();
BitmapOptions options = new BitmapOptions();
drillBit = new Drill(getResources(), 0);
drillBit.setX((screenWidth - drillBit.getBitmap().getWidth()) / 2);
drillBackground = new DrillBackground(getResources(), drillBit.getX(), drillBit.getY());
diamond = new Interactable(BitmapFactory.decodeResource(getResources(),R.drawable.diamond, options.getOptions()), screenWidth/2, screenHeight+30);
potion = new Interactable(BitmapFactory.decodeResource(getResources(), R.drawable.potion, options.getOptions()), screenWidth/4, screenHeight+230);
oil = new Interactable(BitmapFactory.decodeResource(getResources(), R.drawable.oil_1, options.getOptions()), 3*screenWidth/4, screenHeight+450);
powerUp = new Interactable(BitmapFactory.decodeResource(getResources(), R.drawable.power_up, options.getOptions()),
3*screenWidth/4, screenHeight+130);
background = new Background(getResources());
thread = new MainThread(getHolder(), this);
setFocusable(true);
}
To animate the drillBit object, I have 4 bitmaps in the constructor and each time the game loops, I switch off the bitmaps (can't think of another way to accomplish this):
drill.java
public Drill(Resources resource, int x) {
BitmapOptions options = new BitmapOptions();
bitmap1 = BitmapFactory.decodeResource(resource, R.drawable.drill_1, options.getOptions());
bitmap2 = BitmapFactory.decodeResource(resource, R.drawable.drill_2, options.getOptions());
bitmap3 = BitmapFactory.decodeResource(resource, R.drawable.drill_3, options.getOptions());
bitmap4 = BitmapFactory.decodeResource(resource, R.drawable.drill_4, options.getOptions());
currentBitmap = bitmap1;
//other stuff
}
draw function in drill:
if (currentBitmap == bitmap1) {
currentBitmap = bitmap2;
}
else if (currentBitmap == bitmap2) {
currentBitmap = bitmap3;
}
else if (currentBitmap == bitmap3) {
currentBitmap = bitmap4;
}
else {
currentBitmap = bitmap1;
}
canvas.draw(currentbitmap, x, y, null);
Any help is appreciated, thanks!
It happens because Canvas draws everything based on pixel.Pixel is different in different resolution devices. So when you execute (screenHeight+30) will draw different in different device. So you can not write directly +30, you need to convert 30 in device dependent pixel.
I use this method to convert static values
public int convertSizeToDeviceDependent(int value,Context mContext) {
DisplayMetrics dm = new DisplayMetrics();
((Activity) mContext).getWindowManager().getDefaultDisplay().getMetrics(dm);
return ((dm.densityDpi * value) / 160);
}
Where to use
diamond = new Interactable(BitmapFactory.decodeResource(getResources(),R.drawable.diamond, options.getOptions()), screenWidth/2, screenHeight+convertSizeToDeviceDependent(30,context));
apply this method to all places where you using hard coded values in this lines
diamond = new Interactable(BitmapFactory.decodeResource(getResources(),R.drawable.diamond, options.getOptions()), screenWidth/2, screenHeight+30);
potion = new Interactable(BitmapFactory.decodeResource(getResources(), R.drawable.potion, options.getOptions()), screenWidth/4, screenHeight+230);
oil = new Interactable(BitmapFactory.decodeResource(getResources(), R.drawable.oil_1, options.getOptions()), 3*screenWidth/4, screenHeight+450);
powerUp = new Interactable(BitmapFactory.decodeResource(getResources(), R.drawable.power_up, options.getOptions()),
3*screenWidth/4, screenHeight+130);
Does anybody know why my image2 does not get scaled in the image2.scaleImage32() method?
Here's my code:
public ZoomScreen setScreen(){
map1.getBitmap().scaleInto(tempBmp, Bitmap.FILTER_BILINEAR);
Graphics g = Graphics.create(tempBmp); //works
g.drawBitmap(100, 100, bitmapImage2.getWidth(), bitmapImage2.getHeight(), bitmapImage2, 0, 0); //works
image2 = PNGEncodedImage.encode(tempBmp); //works
image3 = image2.scaleImage32(Fixed32.toFP(100), Fixed32.toFP(200)); // does not work
ZoomScreen screen = new ZoomScreen(image3);// works
return screen;
}
Perhaps you are passing absolute values of width and height to scaleImage32() method. But it is not a correct way to use this method. You need to pass scale factor instead of absolute value of width and height.
Assuming image is an EncodedImage class instance, and thumbnailSide is a side of scaled image in pixels, here is the code that should work for you:
final int currentWidthFixed32 = Fixed32.toFP(image.getWidth());
final int currentHeightFixed32 = Fixed32.toFP(image.getHeight());
final int thumbnailSideFixed32 = Fixed32.toFP(thumbnailSide);
final int scaleXFixed32 = Fixed32.div(currentWidthFixed32, thumbnailSideFixed32);
final int scaleYFixed32 = Fixed32.div(currentHeightFixed32, thumbnailSideFixed32);
image = image.scaleImage32(scaleXFixed32, scaleYFixed32);