I'm trying to display in a vertical and centered way an Image, and a button for my Screen Menu.
I've almost accomplished that only using actors but I decided that maybe a layout would be the best practice here.
So I've done:
public MenuScreen(final MyGame myGame) {
this.myGame = myGame;
font = new BitmapFont();
camera = new OrthographicCamera();
camera.setToOrtho(false, 480, 800);
stage = new Stage();
batch = new SpriteBatch();
stage.getViewport() .setCamera(camera);
skin = new Skin(Gdx.files.internal("menu/glassy-ui.json"));
button = new TextButton("NEW GAME", skin);
button.setTransform(true);
button.setScale(0.5f);
button.addListener(new ClickListener(){
#Override
public void clicked(InputEvent event, float x, float y) {
myGame.setScreen(new GameScreen( myGame));
}
});
Image imageLogo = new Image( new Texture(Gdx.files.internal("titleLogo.png")));
// imageLogo.setScaling(Scaling.fit);
Table myTable = new Table();
myTable.setFillParent(true);
myTable .add(imageLogo);// .width(imageLogo.getWidth()).height(imageLogo.getHeight()).row() ;
myTable.row() ;
myTable.add(button);
stage.addActor(myTable);
Gdx.input.setInputProcessor(stage);
batch.setProjectionMatrix(camera.combined);
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
batch.begin();
stage.act(delta);
stage.draw();
batch.end();
}
But it seems that the viewport of the stage isn't affecting the table area which goes offscreen and I'm not even sure that the image is displayed...
This is what I see :
Tried to read wiki and approaches of other developers.
For what I've read everyone has different system to accomplish that goal, nobody used a camera, and I suspect that's my real problem.
Thanks!
stage.setDebugAll(true); //enable debug mode and check what's going on
camera.setToOrtho(false, 480, 800);
By this you're setting viewport of camera by a fix value. You are not resizing/scaling any Actor so make sure all your actor should have size in the context of 480, 800.
camera.position.set(Gdx.graphics.getWidth()/2,Gdx.graphics.getHeight()/2,1);
This will move your camera in center.
I'm trying to make an isometric map on Android using libgdx. I'm basicaly drawing shapes with a ShapeRenderer and handling gestures by moving/zooming the camera. Here is my code.
public class MyGdxGame extends ApplicationAdapter{
private OrthographicCamera cam;
private ShapeRenderer mShapeRenderer;
private InputHandler mInputHandler;
#Override
public void create() {
mShapeRenderer = new ShapeRenderer();
mInputHandler = new AndroidInputHandler();
Gdx.input.setInputProcessor(mInputHandler);
Gdx.graphics.setContinuousRendering(false);
}
#Override
public void render() {
System.out.println("render()");
mInputHandler.handleInput(cam);
cam.update();
// clearing scene
Gdx.graphics.getGL20().glClearColor(1, 1, 1, 1);
Gdx.graphics.getGL20().glClear( GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT );
//drawing updated scene
mShapeRenderer.setProjectionMatrix(cam.combined);
mShapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
mShapeRenderer.setColor( 0.95f, 0.95f, 0.95f,1);
mShapeRenderer.rect(0, 0, 5.1f, 4.8f);
mShapeRenderer.rect( 6.890f,24.014f,2.201f, 6f);
mShapeRenderer.end();
}
#Override
public void resize(int width, int height) {
cam = new OrthographicCamera( 10f,10f * height / width);
cam.position.set(5, 5, 7);
cam.lookAt(0, 0, 0);
Vector3 up =cam.position.cpy();
up.nor();
up.crs((new Vector3(-1, 1, 0)).nor());
cam.up.set(up);
cam.zoom=1f;
cam.far=100000;
cam.near=0;
}
...
}
InputHandler is a custom class that handle gestures like pinch to zoom and camera translation. It only calls camera.translate(Vector3) and camera.zoom = new zoom.
My problem is that whenever i pinch to zoom, some of my shape are cut.
expected drawing
cutted shapes
I don't realy know where this comes from. I think there is something happening with my viewport. I tried modifying the base zoom and camera viewport sizes but I dont realy understand the concept of viewport width and height.
Any help would be apreciated.
Thanks
I am having 3 different screens which contains splash screen, after menu screen and game screen. Splash > Menu > Gamestarts.
How can i add an image button ??
I want to implement 3 buttons inside Menu screen, Not getting any idea where to start.
public class MenuScreen implements Screen {
private Spacegame game;
private SpriteBatch batch;
private Sprite sprite;
private Texture texture;
TextureRegion bg,play,spacegamelogo,button;
OrthographicCamera camera;
Vector3 touchPoint;
private Skin buttonskin;
public MenuScreen(Spacegame game)
{
touchPoint = new Vector3();
this.game=game;
batch=new SpriteBatch();
bg=AssetLoader.bg;
spacedebrislogo=AssetLoader.spacedebrislogo;
button=AssetLoader.button;
}
#Override
public void show() {
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
camera = new OrthographicCamera(1, h / w);
sprite = new Sprite(bg);
sprite.flip(false, true);
sprite.setSize(1.0f,
1.0f * sprite.getHeight() / sprite.getWidth() );
sprite.setOrigin(sprite.getWidth() / 2,
sprite.getHeight() / 2);
sprite.setPosition(-sprite.getWidth() / 2,
-sprite.getHeight() / 2);
}
#Override
public void render(float delta) {
batch.setProjectionMatrix(camera.combined);
batch.begin();
sprite.draw(batch);
batch.draw(spacedebrislogo, 33, 54, 50, 40);
batch.end();
if (Gdx.input.isTouched()) {
game.setScreen(new GameScreen());
dispose();
}
}
THere are a lot of methods to do it..
I will tell you the way I do.
First I create my button image, add it to the assets folder and load the texture region.
Now I make a sprite out of it.
Sprite button1=new Sprite(myTextureRegion);
To check if the button is touched I can use the rectangle from the sprite to check if you touched the image.
In your touchUp method you will do something like
if(button1.getBoundingRectangle.contains(screenX,screenY))
// do your thing
To make my game more interesting i like to add some rotation or scaling of my sprite when is clicked, so it looks better, you can play with it, or you can make 2 textures, one for touched down and one for touched up.
I have a sprite that is supposed to act like a loadbar. I have tried this by using an example image that has been created like a 9patch-type (http://cdn.dibbus.com/wp-content/uploads/2011/03/btn_black.9.png). It seems okay in the start, but as the width of the sprite increases the sprite starts to look pixeled. Anyone know what the problem could be, or have any solution? The code is shown below.
public Sprite loaded;
public void init()
{
atlas = new TextureAtlas(Gdx.files.
internal("data/misc/menu_button.pack"));
loaded = atlas.createSprite("loadbar");
loaded.setPosition((Misc.WIDTH/2) - unloaded.getWidth()/2,
Misc.HEIGTH - unloaded.getHeight());
}
public void draw_load_bar() //render function
{
if(loaded.getWidth() < 600)
{
loaded.setSize(loaded.getWidth()+ 0.5f, loaded.getHeight());
}
loaded.draw(batch);
}
Dont use a Sprite to stretch it. I'd recommend a real Ninepatch from libgdx for it.
public NinePatch loaded;
private float posX, posY, width, height;
public void init()
{
loaded = new NinePatch(the Texture here,10, 10, 10, 10); //bounds outside
//set right pos here...
}
public void draw_load_bar(SpriteBatch batch) //render function
{
if(loaded.getWidth() < 600)
{
//update the size of it here (guess pos is static)
width++;
}
//need to parse the batch and the right sizes.
loaded.draw(batch, posx, posy, width, height);
}
after that you can handle it like a Sprite or Texture but it does stratch right without issues. If you want to the full Picture to be Stretched simply do net set any bounds at the creation new NinePatch(texture, 0,0,0,0)
Using AndEngine for Android, I would like to have my scene look like this:
The red box is the world which must be limited to a given size, say 2000px*450px.
The blue box is the Camera, which is limited as well (as usual), for example to 750px*450px.
For the whole scene, I have a background image that is exactly 450px high. So my Camera can be scaled to whatever size is appropriate, but the background must exactly fit to the height. The width of the Camera may be variable.
The player (circle) must always be in the center (horizontally) but may not leave the world's boundaries.
To achieve this, I've tried adding two types of sizes:
camera size (CAMERA_WIDTH, CAMERA_HEIGHT)
world size (WORLD_WIDTH, WORLD_HEIGHT)
And this function was to add boundaries to the world so that the physics engine prevents the player from leaving those boundaries:
private void createWorldBoundaries() {
Body body;
final Rectangle wall_top = new Rectangle(0, WORLD_HEIGHT-5, WORLD_WIDTH, 10, mVertexManager);
final Rectangle wall_bottom = new Rectangle(0, 5, WORLD_WIDTH, 10, mVertexManager);
final Rectangle wall_left = new Rectangle(5, 0, 10, WORLD_HEIGHT, mVertexManager);
final Rectangle wall_right = new Rectangle(WORLD_WIDTH-5, 0, 10, WORLD_HEIGHT, mVertexManager);
body = PhysicsFactory.createBoxBody(mPhysicsWorld, wall_top, BodyType.StaticBody, new PhysicsFactory.createFixtureDef(0.0f, 0.5f, 0.5f));
wall_top.setUserData(body);
body = PhysicsFactory.createBoxBody(mPhysicsWorld, wall_bottom, BodyType.StaticBody, new PhysicsFactory.createFixtureDef(0.0f, 0.5f, 0.5f));
wall_bottom.setUserData(body);
body = PhysicsFactory.createBoxBody(mPhysicsWorld, wall_left, BodyType.StaticBody, new PhysicsFactory.createFixtureDef(0.0f, 0.5f, 0.5f));
wall_left.setUserData(body);
body = PhysicsFactory.createBoxBody(mPhysicsWorld, wall_right, BodyType.StaticBody, new PhysicsFactory.createFixtureDef(0.0f, 0.5f, 0.5f));
wall_right.setUserData(body);
attachChild(wall_top);
attachChild(wall_bottom);
attachChild(wall_left);
attachChild(wall_right);
}
But this is not working, unfortunately. (see edit)
Setting the camera to chase the player has the wrong result for me: The player does really stay in the center of the screen all time, but I want the player only to stay in the center horizontally, not vertically.
What am I doing wrong and what can I change? And the basic question is: How can I make the world wider than the camera view, while the height is equal to the camera view. The result should be that you can horizontally walk through your world (moving camera) and you can always see the full height.
Edit:
As you define the coordinates of the Rectangle's center and not its top-left corner, you have to do it like this, it seems:
final Rectangle wall_top = new Rectangle(WORLD_WIDTH/2, WORLD_HEIGHT-1, WORLD_WIDTH, 2, mVertexManager);
final Rectangle wall_bottom = new Rectangle(WORLD_WIDTH/2, FIELD_BASELINE_Y+1, WORLD_WIDTH, 2, mVertexManager);
final Rectangle wall_left = new Rectangle(1, WORLD_HEIGHT/2, 2, WORLD_HEIGHT, mVertexManager);
final Rectangle wall_right = new Rectangle(WORLD_WIDTH-1, WORLD_HEIGHT/2, 2, WORLD_HEIGHT, mVertexManager);
However, I had found the other solution in several tutorials. Are these authors not testing their code before writing the tutorials or did the behaviour change from GLES1 to GLES2 or with any recent version?
i think your question about the world boundaries is self answered, isn't it?
PhysicsWorld Boundaries
for further research you can download nicolas' AndEngine Examples App from the Play Store and look up the different examples here (GLES_2, didn't look for AnchorCenter yet): https://github.com/nicolasgramlich/AndEngineExamples/tree/GLES2/src/org/andengine/examples
Taken from the PhysicsExample, the code for the rectangles should look like this, if the bounds are set to the camera bounds. in your case, you can extend width like you want (3 times CAMERA_WIDTH?)
final Rectangle ground = new Rectangle(0, CAMERA_HEIGHT - 2, WORLD_WIDTH, 2, vertexBufferObjectManager);
final Rectangle roof = new Rectangle(0, 0, WORLD_WIDTH, 2, vertexBufferObjectManager);
final Rectangle left = new Rectangle(0, 0, 2, CAMERA_HEIGHT, vertexBufferObjectManager);
final Rectangle right = new Rectangle(WORLD_WIDTH - 2, 0, 2, CAMERA_HEIGHT, vertexBufferObjectManager);
Camera following player
for the Camera to follow your player, you can lookup the code of the BoundCameraExample https://github.com/nicolasgramlich/AndEngineExamples/blob/GLES2/src/org/andengine/examples/BoundCameraExample.java
the interesting part for you should be the addFace method at the bottom
private void addFace(final float pX, final float pY) {
final FixtureDef objectFixtureDef = PhysicsFactory.createFixtureDef(1, 0.5f, 0.5f);
final AnimatedSprite face = new AnimatedSprite(pX, pY, this.mBoxFaceTextureRegion, this.getVertexBufferObjectManager()).animate(100);
final Body body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef);
this.mScene.attachChild(face);
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(face, body, true, true));
this.mBoundChaseCamera.setChaseEntity(face);
}
this method creates a physics body + sprite for "your player" (in this case, a boxed face) and sets the sprite as a chaseEntity for the camera to follow. Since the camera has bounds, that it can't exceed and your camera will have the height of your PhysicWorld boundaries, you can use this to let your camera follow the player in x, but not in y direction.
if you (i don't know why) don't want to use these boundaries, you can overwrite the onUpdate method of your Sprite and re-locate your camera only in x-direction, instead of xy coords
face.registerUpdateHandler(new IUpdateHandler() {
#Override
public void onUpdate(final float pSecondsElapsed) {
float[] coord = face.getSceneCenterCoordinates();
this.mBoundChaseCamera.setCenter(sceneCenterCoordinates[0], CAMERA_Y_POSITION);
}
}
where the CAMERA_Y_POSITION is a static final field with the y-position.
I hope this answers your question(s). :-)
edit: oops, i forgot to mention, how to achieve the camera to be bound and i will edit the world width above:
this.mBoundChaseCamera.setBounds(0, 0,
WORLD_WIDTH, CAMERA_HEIGHT);
all settings are like your image given (except the exact position of the face, that has to be given to the addFace(px, py))
Edit: Difference between scene boundaries in Andengine GLES2 vs GLES2-AnchorCenter
As far as i understood the question, i thought you would use GLES2, i thought of the (older) default GLES2 branch of AndEngine and posted the boundaries. As you found out yourself before and stated in the comments, you use another approach to set the rectangles - where you need to set the rectangles center as pX and pY. The reason for this is in fact, that with the AnchorCenter branch, you won't set the upper left position of an entity anymore and instead use it's center position.