I have an android application consisting of 4 different screens. I am currently creating a new camera for each screen. Each of these screens have the same height and width. Is there a better way to handle this camera, rather than creating a new one for each screen, or is that necessary?
You could make a class like GameObjects and declare there your public static camera.
public static Camera camera;
Now in every screen you got, in the show method you would probably need to reset what you changed to it.
Example, if your camera was moving in a screen, you might want to set the position of the camera again in the show method (same thing about zoom, rotation etc).
You call your camera functions with GameObjects.camera, ex: GameObjects.camera.update();
I create a camera and spritebatch for every screen I have, and it's ok! Don't worry too much about it.
I don't really think that making just one camera is a good ideea anyways.
Related
How can i do a fixed sprite that don't move with my camera (for example: a life bar in the left up corner)?
I have already tried to do this in the hard way and i would like to see if there is a simple way to do this.
Is there a simple way to do that or i need to do this in relative to the player position?
And i am sorry for my broken english, I would be very grateful to those who answer me.
thankyou.
Usually for the task of UI you would use an extra scene2d Stage and implement custom subclasses Actor which you add to the Stage and set their fixed position via Actor.setPosition(). There are already several predefined UI elements in the scene2d.ui package. To simulate a healthbar you could either use a ProgressBar, or you implement your own HealthBar extends Actor, which renders a Sprite of your choice.
The stage is stationary by default and has its own Camera. As long as you do not manipulate that camera anyhow, you can just draw the stage with all elements via stage.draw() and it will always remain at the same place (what you would expect from an ingame HUD).
I have been trying to solve this problem for two days and I have given up trying to find an existing solution.
I have started learning libgdx and finished a couple of tutorials. And now I have tried to use all that I have learned and create a simple side scrolling game. Now, I know that there are libgdx examples of this, but I haven't found a one that incorporates Box2d with scene2d and actors as well as tiled maps.
My main problem is with the cameras.
You need a camera for the Stage (which as far as I know is used for the projection matrix of the SpriteBatch passed to the method draw() at actors, if this is wrong please correct me) and you need a camera for the TileMapRender for calling the render() method. Also, in some of the tutorials there is a OrthographicCamera in the GameScreen, which is used where needed.
I have tried to pass a OrthographicCamera object to methods, I have tried to use the camera from the Stage and the camera from the TileMapRenderer everywhere.
Ex.
OrthographicCamera ocam = new OrthographicCamera(FRUSTUM_WIDTH, FRUSTUM_HEIGHT);
stage.setCamera(ocam); // In the other cases i replace ocam with stage.getCamera() or the one i use for the tileMap Render
tileMapRenderer.render(ocam);
stage.getSpriteBatch().setProjectionMatrix(ocam.combined); // I am not sure if this is needed
I have also tried to use different cameras everywhere.
After trying all of this I haven't noted what happens exactly when but I will list what happens :
There is nothing on the screen ( Probably the camera is away from the stuff that is drawn )
I can see the tiled map and the contours from the debugRenderer (I use debugRender too but I don't think that it interferes with the cameras), but the sprite of the actor is not visible ( probably off screen )
I can see everything that I should but when I try to move the Actor and the Camera, which is supposed to follow him, the sprite goes faster than the body ( the green debug square ).
So my main questions are :
I don't understand what happens when you have multiple cameras. "Through" which one do you actually see on the montior?
Should I use multiple cameras and how ?
Also, I thought that I should mention that I am using OpenGL ES 2.0.
I am sorry for the long question, but I thought that I should describe in detail, since it's a bit complicated for me.
You actually see through all of them at the same time. They might look at a completely different world though, but all of them render their point of view to the screen.
You can use several cameras, or just one. If you use only one you need to make sure that you update the projection matrix correctly, between drawing the TiledMap, your Stage with Actors and maybe for the optional Box2DDebugRenderer.
I'd use an extra Camera for the Box2DDebugRenderer, because you can easily throw it away later. I assume you use a conversion factor to convert meters to pixels and the other way around. Having a 1:1 ratio wouldnt be very good. I always used something between 1m=16px and 1m=128px.
So you initialize it this way, and use that one for your debugging renderer:
OrthographicCamera physicsDebugCam = new OrthographicCamera(Gdx.graphics.getWidth() / Constants.PIXEL_PER_METER, Gdx.graphics.getHeight() / Constants.PIXEL_PER_METER);
For your TiledMapRenderer you may use an extra camera as well, but that one will work in screen-coordinates only, so no conversion:
OrthographicCamera tiledMapCam = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
The TiledMap will always be rendered at (0, 0). So you need to use the camera to move around on the map. It will probably follow a body, so you can update it via:
tiledMapCam.position.set(body.getPosition().x * Constants.PIXELS_PER_METER, body.getPosition().y * Constants.PIXELS_PER_METER)
Or in case it follows an Actor:
tiledMapCam.position.set(actor.getX(), actor.getY())
I actually haven't used scene2d together with Box2D yet, because I didn't need to interact very much with my game objects. You need to implement a custom PhysicsActor here, which extends Actor and builds the bridge from scene2d to Box2D by having a body as a property. It will have to set the Actors position, rotation etc based on the Body at every update-step. But here you have several options. You may re-use the tiledMapCam and work in screen-coordinates. In this case you need to always remember to multiply with Constants.PIXELS_PER_METER when you update your actor. Or you will use another cam with the same viewport like the physicsDebugCam. In this case no conversion is needed, but I'm not sure if this might interfere with some scene2d-specific things.
For a ParallaxBackground you may use another camera as well, for UI you can use another stage and another camera again... or reuse others by resetting them correctly. It's your choice but I think several cameras do not influence performance much. Less resetting and conversions might even improve it.
After everything is setup, you just need to render everything, using the correct cameras and render every "layer"/"view" on top of each other. First a ParallaxBackground, then your Tiledmap, then your Entity-Stage, then your Box2DDebugging view, then your UI-stage.
In general remember to call spriteBatch.setProjectionMatrix(cam.combined); and using cam.update() after you changed anything of your camera.
Here is my problem:
I currently have on Canvas in my main game activity that is constantly being drawn with OnDraw(). This is a board game with two players. When a player's turn begins, there are many options that the player can do, and I would like all of this to be put in a different class.
Also, this new class must draw NEW animations on top of the current canvas. These animations will came from attacks (I haven't even looked into animations yet). So basically I would like another canvas on top of the main one.
Furthermore, the OnDraw function in the main activity must PAUSE and wait for the other class with the canvas on top to complete.
Let me try and summarize this: I have a main game class with one canvas. This class handles the players' turns and setting up the game. It also draws the playing field. I need another class, when it is a player's turn, to draw animations and other things on top of the current canvas.
Can anybody help me with this?
NOTE : I looked into Fragments and FragmentManager, but it seems I can only use XML Views with that and not RenderViews.
Thank you!
You might want to consider using multiple bitmaps as buffers and then just add them on top of each other before rendering to the canvas.
There is a nice example in the "samples" pack that comes with the sdk that shows of how you can merge bitmaps on top of each other.
Let me know if you want to try this out and need some more pointers on how to do it :)
I have used SurfaceView in my game. Right Now, I have created layout considering one device (320 x 480). The game layout looks nice and all functions are working properly. But when I see the same game in another device with different dimension (screen size), the layout does not seem to be proper.
So is there any property, method, formula or helping Tutorial by which I can create game design/layout through canvas which looks same in all screen size devices.
There is one simple hint: don't ever use absolute coordinates on the SurfaceView. Every item's position should be calculated at runtime depending on the actual screen size. This way you'll achieve a layout that will look the same way on every device. Hope this helps.
I'm creating a board game in android. In my absolute layout, I have a board view, and a tile view. Those two views can overlap each other, since you're placing a tile onto the board by click and drag. I am not using a bitmap drawing for this since I want to handle two separate onTouchEvent for the board and for the tile.
Problem: I want my board view to be able to zoom in and pan. At the same time, I want to tile to know to scale itself. Is there anyway to do this on android? My current solution is to scale the two view separately(which is a lot of work) but I think there should be a better solution than this out there. Or my approach on this is completely off?
Any ideas or help would be appreciated. Thanks!