public class GameScreen implements Screen {
public void show()
{
buttonsAtlas = new TextureAtlas("Color.pack"); //button atlas image
buttonSkin = new Skin();
buttonSkin.addRegions(buttonsAtlas);
font = new BitmapFont(Gdx.files.internal("CustomFont.fnt"), false); //the font
stage = new Stage(); // window is stage
stage.clear();
TextButton.TextButtonStyle style = new TextButton.TextButtonStyle(); // button properties
style.up = buttonSkin.getDrawable("Red");
style.down = buttonSkin.getDrawable("Blue");
style.font = font;
gameButton = new TextButton("Game Screen", style); //button text and style
gameButton.setPosition(-250, 500); //button location
gameButton.setHeight(600); //button height
gameButton.setWidth(1200); //button width
shopButton = new TextButton("Shop Menuuuu", style); //button text and style
shopButton.setPosition(100, 500); //button location
shopButton.setHeight(600); //button height
shopButton.setWidth(1200); //button width
stage.addActor(shopButton);
stage.addActor(gameButton);
Gdx.input.setInputProcessor(stage);
gameButton.addListener(new InputListener() {
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
gameButton.setBounds(-250, 500, 100, 100);
Gdx.app.log("my app,", "pressed");
game.setScreen(new inGame(game));
return true;
}
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
Gdx.app.log("my app", "released");
}
});
shopButton.addListener(new InputListener() {
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
shopButton.setBounds(100, 500, 100, 100);
Gdx.app.log("my app,", "pressed");
game.setScreen(new Shop(game));
return true;
}
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
Gdx.app.log("my app", "released");
}
});
}
public void render(float x)
{
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act();
game.batch.begin();
stage.draw();
game.batch.end();
}
public void dispose()
{
batch.dispose();
buttonSkin.dispose();
buttonsAtlas.dispose();
stage.dispose();
}
I am trying to make two TextButtons to work at the same time. However there is always one button showing on the screen, which is the last button that was being added to the stage. In this case it is the gameButton because it is the last button that was added to the stage.
How do I make both button work?
There is no point in setting negative Coordinate, may be you need to understand Coordinate systems for game:
o,o is at bottom left corner of screen
so when you give negative value, that part is not being displayed.
so two images are overlapping in your case and stage gives z index to actors and object which is added last will have highest z index, that means last added object will be draws on top of others.
What you need to do:
gameButton.setPosition(0, 0); //x,y --absolute to bottom left corner
gameButton.setSize(200,200); //width, height
shopButton.setPosition(200, 0); //x,y --absolute to bottom left corner
shopButton.setSize(200,200); //width, height
also doing setbound inside actionlistner is not good idea
Related
My first problem is that the textfield is not showing up and the second is that the button is not responding. My idea is when image 'vault1' is touched the textfield should show 5.
This is what I have come up with and I can't figure out what I am doing wrong.
(I have only cut out neseccary code)
public void render(float delta) {
drawSprite("vault1", 600, 450);
}
public void show() {
Gdx.input.setInputProcessor(stage);
skin = new Skin(Gdx.files.internal("ui/menuSkin.json"), new TextureAtlas("ui/atlas.pack"));
vaultInput = new TextField("", skin);
vaultInput.setPosition(300, 250);
vaultInput.setSize(300, 40);
vaultInput.setText(text2);
vault1Button = new Image(vault1);
vault1Button.addListener(new ClickListener() {
public boolean touchDown(InputEvent e, float x, float y, int point, int button) {
System.out.println("133");
vaultInput.setText(score);
return false;
}});
}
private void drawSprite(String name, float x, float y) {
Sprite sprite = textureAtlas.createSprite(name);
sprite.setPosition(x, y);
sprite.draw(batch);
vault1 = sprite;
}
It's hard to tell when you've left out code but you are adding the stage to the input processor:
Gdx.input.setInputProcessor(stage);
The stage and actors added to the stage is now the only things that responds to input. But you are never adding anything to the stage and neither drawing the stage, you are drawing your sprites seperately in the drawSprite method.
If you instead add your button to the stage all you need to do is call stage.draw():
public void render(float delta) {
stage.draw();
stage.act(delta);
}
public void show() {
Gdx.input.setInputProcessor(stage);
skin = new Skin(Gdx.files.internal("ui/menuSkin.json"), new TextureAtlas("ui/atlas.pack"));
vaultInput = new TextField("", skin);
vaultInput.setPosition(300, 250);
vaultInput.setSize(300, 40);
vaultInput.setText(text2);
vault1Button = new Image(vault1);
vault1Button = new Image(vault1);
vault1Button.addListener(new ClickListener() {
public boolean touchDown(InputEvent e, float x, float y, int point, int button) {
System.out.println("133");
vaultInput.setText(score);
return false;
}});
vaultInput.setPosition(x1, y1);
vault1Button.setPosition(x2, y2);
stage.addActor(vaultInput);
stage.addActor(vault1Button);
}
Everything added to the stage will be drawn when calling stage.draw()
The value of the vault1 field is still null when show() is called. So your actual button that you added your listener to has zero size and nothing to draw.
Also, since render() is called continuously in the game loop, you are creating new sprites to draw on every frame and reassigning the vault1 variable every frame.
You need to create your image for the button in show() and add the button to the stage. Then you only need to draw the stage.
I am using Screen-2D to build a button. I want give the button a function when it is click a sprite will be drawn how can i do this. This isn't all all my code but enough to show what am talking about.
public void create () {
buttonStyle = new TextButtonStyle();
buttonStyle.up = skin.getDrawable("button");
buttonStyle.over = skin.getDrawable("buttonpressed");
buttonStyle.down = skin.getDrawable("buttonpressed");
buttonStyle.font = font;
button = new TextButton("START", buttonStyle);
stage.addActor(button);
Gdx.input.setInputProcessor(stage);
button.addListener(new InputListener() {
#Override
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
drawTile(200,50);
return true;
}
});
}
// method used to draw a sprite when passing certain coordinates
public void drawTile(int x , int y) {
spriteBatch.draw(sprite, x , y );
}
public void render () {
Gdx.gl.glClearColor(1f, 0f, 0f, 1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
spriteBatch.begin();
spriteBatch.draw(background, 0, 0);
drawGrid();
spriteBatch.draw(startButton, 0, 0);
stage.draw();
spriteBatch.end()
}
You got the right idea. See this example:
button.addListener(new ChangeListener() {
#Override
public void changed (ChangeEvent event, Actor actor) {
drawTile(200,50);
}
});
https://github.com/libgdx/libgdx/wiki/Scene2d.ui#changeevents
I think you need to read more tutorials about how LibGDX and Scene2D works : Event processing is done before your render method, so any drawing will be erased when you clear screen.
A right approach would be to add a sprite (as Drawable) to a widget group when click firing. Then stage rendering will renderer all your component including your sprites.
Comparaing to MVC pattern : The stage is your model, you modifiy your model when events occurs and the render method is the view of your model (draw your model).
I've got a GameScreen where I have 100 "dots" randomly bounce around the screen. I'm currently adding a UI button in order to rotate the screen; one on the left and one on the right. The button works, however, the button is "linked" to the camera because as the screen rotates (the playing field for the dots spins because the camera rotates), the button rotates with it. I want the button(s) to be fixed to the device screen, and not rotate with the underlying field of dots.
Do I have to unproject the button somehow, or create a separate stage for any UI elements (buttons, statusbar title alone the top, etc)? Many thanks.
Here's my code:
public class GameScreen implements Screen {
final jGdxDots game;
final MyGestureListener myGestureListener;
OrthographicCamera camera;
private Skin skin;
final int NUMBER_OF_DOTS = 100;
int dotTotal;
private Stage stage;
FPSLogger fpsLogger;
float cameraRotate = 0f;
public GameScreen(final jGdxDots gam) {
this.game = gam;
fpsLogger = new FPSLogger();
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480); //boolean = YDOWN or YUP axis.
//create stage
stage = new Stage(Gdx.graphics.getWidth(),Gdx.graphics.getHeight(),true);
//set stage to handle the inputs
//Gdx.input.setInputProcessor(stage);
stage.setCamera(camera);
//stage.setViewport(800, 480, true);
//multiplex the gesture listeners (both for stage and my listener)
myGestureListener = new MyGestureListener();
GestureDetector gd = new GestureDetector(myGestureListener);
InputMultiplexer im = new InputMultiplexer(gd, stage); // Order matters here!
Gdx.input.setInputProcessor(im);
//UI button
skin = new Skin(Gdx.files.internal("data/uiskin.json"));
final TextButton button = new TextButton("Rotate", skin, "default");
button.setWidth(100f); //200f
button.setHeight(100f); //20f
button.setPosition(10f, 10f);
button.addListener(new ClickListener(){
#Override
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button) {
// TODO Auto-generated method stub
cameraRotate = 1f;
return super.touchDown(event, x, y, pointer, button);
}
#Override
public void touchUp(InputEvent event, float x, float y,
int pointer, int button) {
// TODO Auto-generated method stub
super.touchUp(event, x, y, pointer, button);
cameraRotate = 0f;
}
});
stage.addActor(button);
spawnDots(stage);
}
private void spawnDots(Stage theStage) {
//Rectangle raindrop = new Rectangle();
for (int i=0; i < NUMBER_OF_DOTS; i++) {
DotActor dot = new DotActor();
dot.setOrigin(8,8); //(dot.getWidth()/2, dot.getHeight()/2);
dot.vector.set(MathUtils.random(1,4), MathUtils.random(1,4));
dot.actorX = MathUtils.random(0, 800 - dot.getWidth());
dot.actorY = MathUtils.random(0, 480 - dot.getHeight());
stage.addActor(dot);
}
dotTotal = NUMBER_OF_DOTS;
}
#Override
public void dispose() {
stage.dispose();
}
#Override
public void render(float delta) {
//clear screen
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
//logger
fpsLogger.log();
//camera.zoom += 0.005f;
camera.rotate(cameraRotate); //(1.0f);
camera.update();
//run act() method of each actor
stage.act(Gdx.graphics.getDeltaTime());
//run each actor's draw() method who are members of this stage
stage.draw();
}
}
I had this problem too. Create a separate stage, or you might just want to draw directly with a sprite batch in a 'renderer' class
Mine looks something like this:
public OverlayRenderer()
{
this.spriteBatch = new SpriteBatch();
this.loadTextures();
}
public void render(String _message)
{
this.spriteBatch.begin();
this.spriteBatch.draw(TEXTURES.UI, 0, 0);
....
}
and directly after your
stage.draw();
line, I would add
overLayRenderer.render();
Im trying to add drag and drop functionality to several images in Libgdx. I have looked at this example: https://github.com/libgdx/libgdx/blob/master/tests/gdx-tests/src/com/badlogic/gdx/tests/DragAndDropTest.java but Its still not working. The images do not drag and drop. Would anyone be able to give me some pointers in why its not working?
Thanks
private void createButton() {
stage = new Stage();
Gdx.input.setInputProcessor(stage);
skin = new Skin();
skin.add("up", new Texture(Gdx.files.internal("assets/data/up.png")));
skin.add("def", new Texture(Gdx.files.internal("assets/data/Goal.png")));
final Image up = new Image(skin, "up");
up.setBounds(1090, 630, 40, 40);
stage.addActor(up);
Image def = new Image(skin, "def");
def.setBounds(1090, 585, 40, 40);
stage.addActor(def);
DragAndDrop dragAndDrop = new DragAndDrop();
dragAndDrop.addSource(new Source(up) {
public Payload dragStart (InputEvent event, float x, float y, int pointer) {
Payload payload = new Payload();
payload.setObject(payload);
payload.setDragActor(up);
payload.setDragActor(new Label("up", skin));
Label validLabel = new Label("up", skin);
validLabel.setColor(0, 1, 0, 1);
payload.setValidDragActor(validLabel);
return payload;
}
});
dragAndDrop.addTarget(new Target(def) {
public boolean drag (Source source, Payload payload, float x, float y, int pointer) {
getActor().setColor(Color.GREEN);
return true;
}
public void reset (Source source, Payload payload) {
getActor().setColor(Color.WHITE);
}
public void drop (Source source, Payload payload, float x, float y, int pointer) {
System.out.println("Accepted: " + payload.getObject() + " " + x + ", " + y);
}
});
render();
}
public void render () {
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
Table.drawDebug(stage);
}
I implemented your code on a project of mine.
I removed your render and used the one below. Also, you shouldn't need the assets/ prefix to your image import.
skin.add("up", new Texture(Gdx.files.internal("images/coin.png")));
skin.add("def", new Texture(Gdx.files.internal("images/coin.png")));
#Override
public void render(float delta) {
super.render(delta);
stage.draw();
stage.act(Gdx.graphics.getDeltaTime());
}
Another way to do drag in a better way...
public class CaveInterection implements ApplicationListener {
private OrthographicCamera camera;
private SpriteBatch batch;
private Texture bgTexture;
private Sprite sprite;
private Stage stage;
private Texture mirrTexture;
private MyActor mirrorActor;
Sprite img1,img2;
#Override
public void create() {
camera = new OrthographicCamera(1024, 550);
camera.position.set(1024 / 2, 550 / 2, 0);
batch = new SpriteBatch();
stage = new Stage(1024, 550, false);
//bgTexture = new Texture(Gdx.files.internal("data/cave.jpg"));
//bgTexture = new Texture(Gdx.files.internal("data/bg.jpg"));
mirrTexture = new Texture(Gdx.files.internal("data/mirror.png"));
mirrTexture
.setFilter(TextureFilter.Linear, TextureFilter.Linear);
mirrorActor = new MyActor(new TextureRegion(mirrTexture));
mirrorActor.setPosition(700, 400);
mirrorActor.setOrigin(mirrorActor.getWidth()/2, mirrorActor.getHeight()/2);
stage.addActor(mirrorActor);
// finally stage as the input process
Gdx.input.setInputProcessor(stage);
}
#Override
public void dispose() {
batch.dispose();
//bgTexture.dispose();
}
#Override
public void render() {
// clear the screen, update the camera and make the sprite batch
// use its matrices.
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
camera.update();
batch.setProjectionMatrix(camera.combined);
batch.begin();
//batch.draw(bgTexture, 0,0);
// Gdx.app.log("arvind","X :"+mirrorActor.getX()+ " Y :"+mirrorActor.getY());
//batch.draw(bgTexture, 0, 0);
batch.end();
// tell the stage to act and draw itself
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
public class MyActor extends Actor {
TextureRegion region;
float lastX;
float lastY;
public MyActor (TextureRegion region) {
this.region = region;
setWidth(region.getRegionWidth());
setHeight(region.getRegionHeight());
addListener(new InputListener() {
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
Gdx.app.log("arv", "pointer1+"+pointer);
// we only care for the first finger to make things easier
if (pointer != 0) return false;
// record the coordinates the finger went down on. they
// are given relative to the actor's corner (0, 0)
Gdx.app.log("arvind", "touchDown");
Gdx.app.log("arv", "pointer2+"+pointer+""+x+"::::"+y);
lastX = x;
lastY = y;
return true;
}
public void touchDragged (InputEvent event, float x, float y, int pointer) {
// we only care for the first finger to make things easier
if (pointer != 0) return;
Gdx.app.log("arv", "touchDragged");
// adjust the actor's position by (current mouse position - last mouse position)
// in the actor's coordinate system.
translate(x - lastX, y - lastY);
// rotate(2);
// save the current mouse position as the basis for the next drag event.
// we adjust by the same delta so next time drag is called, lastX/lastY
// are in the actor's local coordinate system automatically.
lastX = x - (x - lastX);
lastY = y - (y - lastY);
}
});
}
#Override
public void draw (SpriteBatch batch, float parentAlpha) {
//batch.draw(region, getX(), getY());
batch.draw(region, getX(), getY(), mirrorActor.getOriginX(), mirrorActor.getOriginY(), mirrorActor.getWidth(), mirrorActor.getHeight(), 1, 1,getRotation(), true);
}
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
I have 5 buttons i need to make do different things but they don't and i need to know how to make them do it.
Here is my code;
public class MainMenu implements Screen {
CrazyZombies game;
Stage stage;
TextureAtlas atlas;
Skin skin;
SpriteBatch batch;
Button play, option, quit, custom, store, menu;
public MainMenu(CrazyZombies game) {
this.game = game;
}
public void create () {
stage = new Stage();
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0.09f, 0.28f, 0.2f, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
stage.act(delta);
stage.draw();
batch.begin();
batch.end();
}
#Override
public void resize(int width, int height) {
if (stage == null)
stage = new Stage(width, height, true);
stage.clear();
stage.setViewport(854, 480, true);
stage.getCamera().translate(-stage.getGutterWidth(), -stage.getGutterHeight(), 0);
Gdx.input.setInputProcessor(stage);
/**
* quit Button
*/
TextButtonStyle styleQuit = new TextButtonStyle();
styleQuit.up = skin.getDrawable("8layer");
styleQuit.down = skin.getDrawable("8layer");
quit = new Button(styleQuit);
quit.addListener(new InputListener() {
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button) {
return true;
}
public void touchUp(InputEvent event, float x, float y,
int pointer, int button) {
}
});
/**
* End quit Button
*/
/**
* store Button
*/
TextButtonStyle styleStore = new TextButtonStyle();
styleStore.up = skin.getDrawable("9layer");
styleStore.down = skin.getDrawable("9layer");
store = new Button(styleStore);
store.addListener(new InputListener() {
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button) {
return true;
}
public void touchUp(InputEvent event, float x, float y,
int pointer, int button) {
game.setScreen(new StoreScreen(game));
}
});
/**
* End store Button
*/
/**
* customs Button
*/
TextButtonStyle styleCustom = new TextButtonStyle();
styleCustom.up = skin.getDrawable("10layer");
styleCustom.down = skin.getDrawable("10layer");
custom = new Button(styleCustom);
custom.addListener(new InputListener() {
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button) {
return true;
}
public void touchUp(InputEvent event, float x, float y,
int pointer, int button) {
game.setScreen(new CustomScreen(game));
}
});
/**
* End customs Button
*/
/**
* Options Button
*/
TextButtonStyle styleOptions = new TextButtonStyle();
styleOptions.up = skin.getDrawable("11layer");
styleOptions.down = skin.getDrawable("11layer");
option = new Button(styleOptions);
option.addListener(new InputListener() {
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button) {
return true;
}
public void touchUp(InputEvent event, float x, float y,
int pointer, int button) {
game.setScreen(new OptionScreen(game));
}
});
/**
* End Options Button
*/
/**
* Play Button
*/
TextButtonStyle stylePlay = new TextButtonStyle();
stylePlay.up = skin.getDrawable("7layer");
stylePlay.down = skin.getDrawable("7layer");
play = new Button(stylePlay);
play.addListener(new InputListener() {
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button) {
return true;
}
public void touchUp(InputEvent event, float x, float y,
int pointer, int button) {
Gdx.app.log(CrazyZombies.LOG, "un-touched");
game.setScreen(new GameScreen(game));
}
});
/**
* End Play Button
*/
/**
* start Background
*/
TextButtonStyle styleMenu = new TextButtonStyle();
styleMenu.up = skin.getDrawable("background");
menu = new Button(styleMenu);
/**
* End Background
*/
stage.addActor(menu);
stage.addActor(play);
stage.addActor(option);
stage.addActor(store);
stage.addActor(custom);
stage.addActor(quit);
}
#Override
public void show() {
Audio.playMusic(true);
batch = new SpriteBatch();
atlas = new TextureAtlas("data/mainmenu/mainmenu.pack");
skin = new Skin();
skin.addRegions(atlas);
}
#Override
public void hide() {
dispose();
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
batch.dispose();
skin.dispose();
atlas.dispose();
stage.dispose();
Audio.dispose();
}
public void playButton(Button play) {
}
}
So my 5 buttons are set up and there actions and listeners but now they do not do anything and when i single one button out to test it works but the button can be clicked from any where on the screen so i think it is an issue with button areas but i do not know how to set it up.
I have tryed .getheight(), .getWidth etc. but it is still the same. Although in my texture atlas the height and width for all the images is the same as it all makes one image could this be my issue ?
For your first problem, which is that your buttons doesn't do anything, I think it's because the event is propagated to all of your buttons, probably in the order they have been added to the Stage. The problem is that your touchDown() method returns true. It means that the propagation should stop and then the touchDown() method of your others actors doesn't get called.
You feel like it does nothing but in fact it does something, it's just that your touchDown() method is empty.
For you second problem, it's probably because your didn't set the size of your actors.
Actually it's more simple than that. You need to set the bounds of your buttons. Use the .setBounds(x,y,width,height) method of the button, they do not have a size yet. The click area should be right after setting the bounds.
Take a look at Table layout libgdx and use a table.