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.
Related
I'm creating a 2d game using the Java version of Box2d.
I know that the engine is generally paired with a separate library to handle animation, but I'm looking for something simple, with a more rustic feel, so I'm considering handling the animation from scratch.
The animation I am trying to create is something for the collision of two objects.
I'm using openGl to handle the graphics, and I pretty much have everything set up with the fps and rendering, it's just a matter of tweaking the frames to make it look smooth.
I tried bliting images of some things that I drew myself and it looked atrocious. I think the main problem is that the animation frame images are not linked to the physics forces and so they don't blend well.
What I want to try next is a sort 'spark effect' using a small number of pixels that sort of resemble 'dust' exploding off of the colliding images. If you've ever played dxball, you may recall a similar effect when the ball collided with the paddle at high speed.
As you can see in the above image, the principles are fairly simple. I figure by creating a set of small bodies with fixtures, I can use the box2d engine to produce this effect. I already have code that grabs the point of collision for all bodies, and am familiar enough with parabolic functions that I pretty sure I can create the force direction.
I'm just not sure if there is a better way of doing this, or how to apply a polynomial function to a body like in the image.
Does anybody know how to achieve this functionality with box2d? Any built in methods or documentation that would be helpful?
As a point of reference, the following snippet of code demonstrates the drawing of a small, red box on all of the collision points.
for(Vec2 point : listener.worldmanifold.points){
glPushMatrix();
newpos = point.mul(30);
glTranslatef(newpos.x, newpos.y, 0);
glColor3f(1,0,0);
glRectf(-2, -2, 2, 2);
glPopMatrix();
}
I'm having quite a bit of difficulty wrapping my head around the actual display side of things with libgdx. That is, it just seems fairly jumbled in terms of what needs to be done in order to actually put something up onto the screen. I guess my confusion can sort of be separated into two parts:
What exactly needs to be done in terms of creating an image? There's
Texture, TextureRegion, TextureAtlas, Sprite, Batch, and probably a
few other art related assets that I'm missing. How do these all
relate and tie into each other? What's the "production chain" among
these I guess would be a way of putting it.
In terms of putting
whatever is created from the stuff above onto the monitor or
display, how do the different coordinate and sizing measures relate
and translate to and from each other? Say there's some image X that
I want to put on the screen. IT's got it's own set of dimensions and
coordinates, but then there's also a viewport size (is there a
viewport position?) and a camera position (is there a camera size?).
On top of all that, there's also the overall dispaly size that's
from Gdx.graphics. A few examples of things I might want to do could
be as follow:
X is my "global map" that is bigger than my screen
size. I want to be able to scroll/pan across it. What are the
coordinates/positions I should use when displaying it?
Y is bigger
than my screen size. I want to scale it down and have it always be
in the center of the screen/display. What scaling factor do I use
here, and which coordinates/positions?
Z is smaller than my screen
size. I want to stick it in the upper left corner of my screen and
have it "stick" to the global map I mentioned earlier. Which
positioning system do I use?
Sorry if that was a bunch of stuff... I guess the tl;dr of that second part is just which set of positions/coordinates, sizes, and scales am I supposed to do everything in terms of?
I know this might be a lot to ask at once, and I also know that most of this stuff can be found online, but after sifting through tutorial after tutorial, I can't seem to get a straight answer as to how these things all relate to each other. Any help would be appreciated.
Texture is essentially the raw image data.
TextureRegion allows you to grab smaller areas from a larger texture. For example, it is common practice to pack all of the images for your game/app into a single large texture (the LibGDX “TexturePacker” is a separate program that does this) and then use regions of the larger texture for your individual graphics. This is done because switching textures is a heavy and slow operation and you want to minimize this process.
When you pack your images into a single large image with the TexturePacker it creates a “.atlas” file which stores the names and locations of your individual images. TextureAtlas allows you to load the .atlas file and then extract your original images to use in your program.
Sprite adds position and color capabilities to the texture. Notice that the Texture API has no methods for setting/getting position or color. Sprites will be your characters and other objects that you can actually move around and position on the screen.
Batch/SpriteBatch is an efficient way of drawing multiple sprites to the screen. Instead of making drawing calls for each sprite one at a time the Batch does multiple drawing calls at once.
And hopefully I’m not adding to the confusion, but another I option I really like is using the “Actor” and “Stage” classes over the “Sprite” and “SpriteBatch” classes. Actor is similar to Sprite but adds additional functionality for moving/animating, via the act method. The Stage replaces the SpriteBatch as it uses its own internal SpriteBatch so you do not need to use the SpriteBatch explicitly.
There is also an entire set of UI components (table, button, textfield, slider, progress bar, etc) which are all based off of Actor and work with the Stage.
I can’t really help with question 2. I stick to UI-based apps, so I don’t know the best practices for working with large game worlds. But hopefully someone more knowledgeable in that area can help you with that.
This was to long to reply as a comment so I’m responding as another answer...
I think both Sprite/SpriteBatch and Actor/Stage are equally powerful as you can still animate and move with Sprite/SpriteBatch, but Actor/Stage is easier to work with. The stage has two methods called “act” and “draw” which allows the stage to update and draw every actor it contains very easily. You override the act method for each of your actors to specify what kind of action you want it to do. Look up a few different tutorials for Stage/Actor with sample code and it should become clear how to use it.
Also, I was slightly incorrect before that “Actor” is equivalent to Sprite, because Sprite includes a texture, but Actor by itself does not have any kind of graphical component. There is an extension of Actor called “Image” that includes a Drawable, so the Image class is actually the equivalent to Sprite. Actor is the base class that provides the methods for acting (or “updating”), but it doesn’t have to be graphical. I've used Actors for other purposes such as triggering audio sounds at specific times.
Atlas creates the large Texture containing all of your png files and then allows you to get regions from it for individual png's. So the pipeline for getting a specific png graphic would be Atlas > Region > Sprite/Image. Both Image and Sprite classes have constructors that take a region.
I'm working on a simple game with libGDX and want to make the main character to be fixed in the center of the screen and the world move when I press a button. I was wondering how to do... I was thinking to add a physicsBody to the world that contains other bodies and apply impulses to it when the button is pressed, is this possible in libGDX? And if it is, can i apply other impulses or forces to the bodies contained in the world's physicsBody? I think this way would be the best for me if it is possible, because i have to work a lot with physics, but if you have other ideas tell me please
There's no need to think about applying forces to all the non-character objects, that's just going to get messy very quickly.
The simple solution is to move your camera so that it always looks at your character. So your game loop may look something like:-
Process input
Update physics, character and other entity positions.
Move camera to point at character's new position.
Render
This way, you can update your game world without having to think about the camera at all. Then, when it comes to rendering, you can position your camera and render your graphics without needing to know anything about the game physics. It keeps the physics and rendering relatively independent, and makes it much easier to change things in the future.
For example, you may later decide that you want the camera to follow your character for the most part, but then follow a baddy whilst it is their turn. This is now easy to do, you just specify the character / entity to look at in your game logic, and then position the camera to look at whatever target that is, before you render.
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'm currently developing a 2D RPG with LWJGL, and am still in the engine stage of development. I've got a lot of the tech I want created, but one of my big problems is fixing the camera on the player. All the solutions I've seen involve moving the world and keeping the player still, which can work, but it seems apparent that this can cause some calculation issues if not closely monitored. Normally, I'd write a system where I wouldn't have to worry about it, but I refuse, because I eventually intend on adding multiplayer capability, where a moving world would be unplayable.
Is there a way to affix the camera to an object or point that can move WITHOUT using translate to move the world around? Also, I'd like to avoid Slick if possible. That would require me to rework much of my game engine as it currently stands.
Whenever you are going to project the 3d viewport onto a 2d screen you need to move everything according to the point of view of the observer (the so called camera or view).
I guess you can't escape from this. What you usually do is having a Camera object which holds position and rotation that is used to build the view matrix which is passed to the vertices of your scene through a uniform to the shaders. Passing transformation matrices to shaders is the normality so you shouldn't feel burdened by it. You can always premultiply it with the perspective matrix.
You must move the whole world to match the position of your camera just because you need to transform everything in your scene as it is seen from that point of view, otherwise how could you then project it on your screen? There is no "move the camera, keep the world still" concept.
Move the world visually, it's how every other RPG does it. Don't move the actual world's location though.
Draw everything but the ui normally, than translate it all according to the players position (i.e. glTranslate2f(-player.x,-player.y)). This is all done in the render method. On networked multiplayer, the viewport is done to that specific player (i.e. Bob's screen is translated based off Bob's position, Jane's is translated based off Jane's position). Should you instead want single-screen multiplayer, you will probably have to use mutliple framebuffers (one per player), and use them as viewports.