InputListener for the Actor - java

I have a problem that keyDown event is never fired in the Actor when I press any key. Though, the touchDown (for mouse clicks) works.
Actor code:
public class MapActor extends Actor {
private TiledMap map;
private OrthogonalTiledMapRenderer renderer;
private int directions = 0;
private OrthographicCamera camera;
public MapActor(String pathToMap, OrthographicCamera camera) {
TmxMapLoader loader = new TmxMapLoader();
map = loader.load(pathToMap);
renderer = new OrthogonalTiledMapRenderer(map);
this.camera = camera;
this.setBounds(0, 0, 500, 500);
this.addListener(new InputListener() {
// a - 29, w - 51, d - 32, s - 47
#Override
public boolean keyDown(InputEvent event, int keycode) {
System.out.println("Test");
return true;
}
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
Gdx.app.log("Touch", "touch down");
return true;
}
});
}
#Override
public void act(float delta) {
}
#Override
public void draw(Batch batch, float parentAlpha) {
super.draw(batch, parentAlpha);
batch.end();
renderer.setView(camera);
renderer.render();
batch.begin();
}
public void dispose() {
renderer.dispose();
map.dispose();
}
}
Here is how I add the Actor to the Stage:
#Override
public void create () {
stage = new Stage(new ScreenViewport());
Gdx.input.setInputProcessor(stage);
MapActor mapActor = new MapActor("maps/testmap.tmx", (OrthographicCamera) stage.getCamera());
stage.addActor(mapActor);
}
Any suggestions are welcomed.

Only the actor that has keyboard focus will receive keyboard events.
To set which actor has keyboard focus, you can use the following...
`Stage.setKeyboardFocus(Actor actor);`
From then on, keyboard events will be passed to the specified actor.

Related

Add multiple InputListener to Actor libgdx

I have a problem with InputListener.
I have create class who extend TextButton to make TextButtons with borders and one default Inputlistener. And in my main code i want to add one more Inputlistener to set a new screen when it is pressed (in my code it's just a print to watch if that works) but only the touchDown works...
My TextButtonWithBorder class :
public class TextButtonWithBorder extends TextButton {
ShapeRenderer shapeRenderer = new ShapeRenderer();
public TextButtonWithBorder(String text, Skin skin) {
super(text, skin);
this.setTransform(true);
this.addReduceClickListener();
}
public TextButtonWithBorder(String text, Skin skin, String styleName) {
super(text, skin, styleName);
this.setTransform(true);
this.addReduceClickListener();
}
public TextButtonWithBorder(String text, TextButtonStyle style) {
super(text, style);
this.setTransform(true);
this.addReduceClickListener();
}
#Override
public void draw(Batch batch, float parentAlpha) {
batch.end();
shapeRenderer.setProjectionMatrix(batch.getProjectionMatrix());
shapeRenderer.begin(ShapeRenderer.ShapeType.Line);
shapeRenderer.setColor(Color.WHITE);
shapeRenderer.rect(getX(),getY(),getWidth()*getScaleX(),getHeight()*getScaleY());
shapeRenderer.end();
batch.begin();
super.draw(batch, parentAlpha);
}
public void setCenter(float x,float y)
{
setPosition(x-getWidth()/2*getScaleX(),y-getHeight()/2*getScaleY());
}
public void setCenter(Vector2 center)
{
setPosition(center.x-getWidth()/2*getScaleX(),center.y-getHeight()/2*getScaleY());
}
public Vector2 getCenter()
{
return new Vector2(getX()+getWidth()/2*getScaleX(),getY()+getHeight()/2*getScaleY());
}
public void addReduceClickListener()
{
addListener((new InputListener(){
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
Vector2 center = getCenter();
setScale(0.9F);
setCenter(center);
return true;
}
public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
Vector2 center = getCenter();
setScale(1F);
setCenter(center);
}
}));
}
public void dispose()
{
shapeRenderer.dispose();
}
}
And My main code :
public class MainMenuScreen implements Screen {
final PongAndroid game;
Stage stage;
BitmapFont font;
TextButtonWithBorder buttonOnePlayer;
TextButtonWithBorder buttonTwoPlayers;
TextButtonWithBorder buttonAbout;
TextButtonWithBorder buttonExit;
Label title;
ImageButton options;
public MainMenuScreen(final PongAndroid game) {
this.game=game;
stage = new Stage(game.viewport,game.batch);
Gdx.input.setInputProcessor(stage);
// Styles
font = new BitmapFont(Gdx.files.internal("MVboli50.fnt"));
TextButton.TextButtonStyle textButtonStyle = new TextButton.TextButtonStyle();
textButtonStyle.font = font;
Label.LabelStyle labelStyle = new Label.LabelStyle();
labelStyle.font = font;
ImageButton.ImageButtonStyle imageButtonStyle = new ImageButton.ImageButtonStyle();
// Configure Actors
// title
title = new Label("Pong Android",labelStyle);
title.setFontScale(2f);
title.setPosition(game.WIDTH/2-title.getWidth()/2*title.getFontScaleX(),game.HEIGHT-title.getHeight()-(game.HEIGHT*0.15f));
// buttonOnePlayer
buttonOnePlayer = new TextButtonWithBorder("1 Player",textButtonStyle);
buttonOnePlayer.setWidth(game.WIDTH*0.70f);
buttonOnePlayer.setHeight(buttonOnePlayer.getHeight()*1.2f);
buttonOnePlayer.setPosition(game.WIDTH/2-buttonOnePlayer.getWidth()/2,title.getY()-title.getHeight()/2-buttonOnePlayer.getHeight()-game.HEIGHT*0.05f);
//buttonTwoPlayer
buttonTwoPlayers = new TextButtonWithBorder("2 Players",textButtonStyle);
buttonOnePlayer.setTransform(true);
buttonTwoPlayers.setWidth(buttonOnePlayer.getWidth());
buttonTwoPlayers.setHeight(buttonTwoPlayers.getHeight()*1.2f);
buttonTwoPlayers.setPosition(buttonOnePlayer.getX(),buttonOnePlayer.getY()-buttonOnePlayer.getHeight()-game.HEIGHT*0.05f);
//buttonAbout
buttonAbout = new TextButtonWithBorder("About",textButtonStyle);
buttonOnePlayer.setTransform(true);
buttonAbout.setWidth(buttonTwoPlayers.getWidth()/2-game.WIDTH*0.05f);
buttonAbout.setHeight(buttonAbout.getHeight()*1.2f);
buttonAbout.setPosition(buttonTwoPlayers.getX(),buttonTwoPlayers.getY()-buttonAbout.getHeight()-game.HEIGHT*0.05f);
//buttonExit
buttonExit = new TextButtonWithBorder("Exit",textButtonStyle);
buttonOnePlayer.setTransform(true);
buttonExit.setWidth(buttonAbout.getWidth());
buttonExit.setHeight(buttonExit.getHeight()*1.2f);
buttonExit.setPosition(buttonAbout.getX()+buttonAbout.getWidth()+game.WIDTH*0.1f, buttonAbout.getY());
// Add listeners to Actors
buttonExit.addListener(new InputListener(){
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
System.out.println("down");
return super.touchDown(event, x, y, pointer, button);
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
System.out.println("up");
super.touchUp(event, x, y, pointer, button);
System.out.println("up");
}
});
// Add Actors to stage
stage.addActor(title);
stage.addActor(buttonOnePlayer);
stage.addActor(buttonTwoPlayers);
stage.addActor(buttonAbout);
stage.addActor(buttonExit);
//stage.addActor();
}
#Override
public void show() {
}
#Override
public void render(float delta) {
stage.act(delta);
stage.draw();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
stage.dispose();
buttonOnePlayer.dispose();
buttonTwoPlayers.dispose();
buttonAbout.dispose();
buttonExit.dispose();
}
}
My question is how to add multiple InputListener to an Actor ?
Return true for both InputListeners to handle the touchUp event. This is my output when clicking once:
listener A: touchDown
listener B: touchDown
listener A: touchUp
listener B: touchUp
The code:
private SpriteBatch batch;
private Viewport viewport;
private Stage stage;
private Texture texture;
private BitmapFont font;
#Override
public void create() {
batch = new SpriteBatch();
viewport = new StretchViewport( Gdx.graphics.getWidth(), Gdx.graphics.getHeight() );
stage = new Stage( viewport, batch );
texture = new Texture( "badlogic.jpg" );
font = new BitmapFont();
Gdx.input.setInputProcessor( stage );
TextButton.TextButtonStyle textButtonStyle = new TextButton.TextButtonStyle(
new TextureRegionDrawable( new TextureRegion( texture ) ), null, null, font );
TextButton textButton = new TextButton( "text", textButtonStyle );
textButton.setPosition(
0.5f * Gdx.graphics.getWidth() - 0.5f * textButton.getWidth(),
0.5f * Gdx.graphics.getHeight() - 0.5f * textButton.getHeight()
);
textButton.addListener( new InputListener(){
#Override
public boolean touchDown( InputEvent e, float x, float y, int pointer, int button ) {
Gdx.app.log( "listener A", "touchDown" );
return true;
}
#Override
public void touchUp( InputEvent e, float x, float y, int pointer, int button ) {
Gdx.app.log( "listener A", "touchUp" );
}
} );
textButton.addListener( new InputListener(){
#Override
public boolean touchDown( InputEvent e, float x, float y, int pointer, int button ) {
Gdx.app.log( "listener B", "touchDown" );
return true;
}
#Override
public void touchUp( InputEvent e, float x, float y, int pointer, int button ) {
Gdx.app.log( "listener B", "touchUp" );
}
} );
stage.addActor( textButton );
}
#Override
public void dispose() {
batch.dispose();
stage.dispose();
texture.dispose();
font.dispose();
}
#Override
public void resize( int width, int height ) {
viewport.update( width, height, true );
}
#Override
public void render() {
Gdx.gl.glClearColor( 0, 0, 0, 1 );
Gdx.gl.glClear( GL20.GL_COLOR_BUFFER_BIT );
stage.act( Gdx.graphics.getDeltaTime() );
stage.draw();
}
Buttons in LibGDX already have built-in InputListeners that robustly handle different button and hover states. Instead of adding your own InputListener, you should add a ChangeListener to respond to button presses.

libgdx inputListener doesn't work with actor

I tried use InputListener with Actor, but it doesn't work. I really don't know why. I found many information about it and saw official documentation but not one of all didn't help me.
My log messages are not shown when I touch the sprite. But if I use the global input processor (for whole screen) it works fine, but I want to add only one listener only for actor.
What am I doing wrong?
public class GameScreen implements Screen {
final Launch launch;
Texture texture;
Stage stage;
public GameScreen(Launch launch) {
Gdx.app.setLogLevel(Application.LOG_DEBUG);
this.launch = launch;
texture = new Texture("hero.png");
stage = new Stage();
Hero hero = new Hero();
hero.addListener(new HeroListener());
stage.addActor(hero);
Gdx.input.setInputProcessor(stage);
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.draw();
stage.act(Gdx.graphics.getDeltaTime());
}
#Override
public void resize(int width, int height) {
}
#Override
public void show() {
}
#Override
public void hide() {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
stage.dispose();
texture.dispose();
}
private class Hero extends Actor {
#Override
public boolean addListener(EventListener listener) {
Gdx.app.debug("MyTag", "my debug message");
return super.addListener(listener);
}
#Override
public void draw(Batch batch, float parentAlpha) {
batch.draw(texture, 0, 0, 500, 500);
}
}
private class HeroListener extends InputListener {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
Gdx.app.debug("MyTag", "touch down");
return super.touchDown(event, x, y, pointer, button);
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
Gdx.app.debug("MyTag", "touch up");
super.touchUp(event, x, y, pointer, button);
}
}
}
The problem is that you are not giving any size or position to your actor. InputListener work for events whitin the bounds of the Actor. If you do not define any size to your Actor, it won't ever receive an event.
Hero hero = new Hero();
hero.addListener(new HeroListener());
hero.setBounds(0, 0, 500, 500);
stage.addActor(hero);
That should make your InputListener listen to touchDown/Up events in the (0, 0), (500, 500) bounds.
Also, it's conveninent because you can use those bounds when drawing after:
#Override
public void draw(Batch batch, float parentAlpha) {
batch.draw(texture, getX(), getY(), getWidth(), getHeight());
}

libgdx world to screen pos and factors

I want to draw a texture on a body, which is a box.
How do I convert the coordinates of the body to screen coordinates?
I know that the other way around is with camera.unproject(pos), is it similar to this?
I see a lot of people using constants such as WORLD_TO_SCREEN = 32, but I currently don't have that in my game. Is that a problem, and how can I implement it now? Because it seems like people that are using these factors can convert world to screen positions easily. I currently have a camera and an ExtendViewport
camera = new OrthographicCamera(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
viewport = new ExtendViewport(VIEWPORT_WIDTH, VIEWPORT_HEIGHT, camera);
camera.position.set(VIEWPORT_WIDTH/2, VIEWPORT_HEIGHT/2, 0f);
Viewport width and height are set to this
public static final int VIEWPORT_WIDTH = 20;
public static final int VIEWPORT_HEIGHT = 22;
I don't really know what I'm doing, I read documentation and read some tutorials, but if someone could give some explanation about these variables and the world_to_screen factor that would really help me out.
I also set APP_WIDTH=1280, APP_HEIGHT = 720
Do viewport width and height mean that for box2d my screen is 20 meters wide and 22 meters high?
(asking it again because I added a lot the question and I would really like to know these things)
[EDIT]
So I'm trying to draw a ground picture on the ground body
float x = stage.getGround().getX();
float y = stage.getGround().getY();
float w = stage.getGround().getWidth();
float h = stage.getGround().getHeight();
stage.act(delta);
stage.draw();
stage.updateCamera();
Texture texture = new Texture(Gdx.files.internal("ground.png"));
Sprite sprite = new Sprite(texture);
sprite.setSize(w, h);
sprite.setPosition(x-sprite.getWidth()/2, y-sprite.getHeight()/2);
But I don't see it anywhere
[EDIT 2]
Stage Class
public class Mission1Stage extends Stage{
public static final int VIEWPORT_WIDTH = 20;
public static final int VIEWPORT_HEIGHT = 22;
private World world;
private Ground ground;
private LeftWall leftWall;
private Rocket rocket;
private static final float TIME_STEP = 1 / 300f;
private float accumulator = 0f;
private OrthographicCamera camera;
private Box2DDebugRenderer renderer;
private Viewport viewport;
private SpriteBatch spriteBatch = new SpriteBatch();
private Vector3 touchPoint;
private ShapeRenderer shapeRenderer;
private Button boostButton;
private Skin boostSkin;
private Button boostLeftButton;
private Skin boostLeftSkin;
private Button boostRightButton;
private Skin boostRightSkin;
private Button resetButton;
private Skin resetSkin;
private Game game;
private boolean isTouched = false;
public Mission1Stage(Game game) {
setUpWorld();
renderer = new Box2DDebugRenderer();
shapeRenderer = new ShapeRenderer();
setupCamera();
setUpButtons();
addActor(new Background(ground));
}
private void setUpWorld() {
world = WorldUtils.createWorld();
setUpGround();
setUpRocket();
}
private void setUpGround() {
ground = new Ground(WorldUtils.createGround(world));
addActor(ground);
}
private void setUpLeftWall() {
leftWall = new LeftWall(WorldUtils.createLeftWall(world));
}
private void setUpRocket() {
rocket = new Rocket(WorldUtils.createRocket(world));
addActor(rocket);
}
private void setupCamera() {
camera = new OrthographicCamera(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
viewport = new ExtendViewport(VIEWPORT_WIDTH, VIEWPORT_HEIGHT, camera);
camera.position.set(VIEWPORT_WIDTH/2, VIEWPORT_HEIGHT/2, 0f);
camera.update();
}
private void setUpButtons() {
boostSkin = new Skin(Gdx.files.internal("skin/flat-earth-ui.json"));
boostButton = new Button(boostSkin);
boostButton.setSize(80,80);
boostButton.setPosition(Gdx.graphics.getWidth()-boostButton.getWidth()*2,0);
boostButton.setTransform(true);
boostButton.scaleBy(0.5f);
Gdx.input.setInputProcessor(this);
addActor(boostButton);
boostLeftSkin = new Skin(Gdx.files.internal("skin/flat-earth-ui.json"));
boostLeftButton = new Button(boostLeftSkin);
boostLeftButton.setSize(100, 100);
boostLeftButton.setPosition(0, 0);
addActor(boostLeftButton);
boostRightSkin = new Skin(Gdx.files.internal("skin/flat-earth-ui.json"));
boostRightButton = new Button(boostRightSkin);
boostRightButton.setSize(100, 100);
boostRightButton.setPosition(boostLeftButton.getWidth(), 0);
addActor(boostRightButton);
resetSkin = new Skin(Gdx.files.internal("skin/flat-earth-ui.json"));
resetButton = new Button(resetSkin);
resetButton.setSize(100, 100);
resetButton.setPosition(Gdx.graphics.getWidth()-100, Gdx.graphics.getHeight()-100);
addActor(resetButton);
}
#Override
public void act(float delta) {
super.act(delta);
handleInput();
accumulator += delta;
while(accumulator >= delta) {
world.step(TIME_STEP, 6, 2);
accumulator -= TIME_STEP;
}
}
#Override
public void draw() {
super.draw();
renderer.render(world, camera.combined);
float x = getGround().getBody().getPosition().x;
float y = getGround().getBody().getPosition().y;
float w = getGround().getWidth() * 2;
float h = getGround().getHeight() * 2;
spriteBatch.setProjectionMatrix(getCamera().combined);
Texture texture = new Texture(Gdx.files.internal("ground.png"));
Sprite sprite = new Sprite(texture);
sprite.setSize(w, h);
sprite.setPosition(x-sprite.getWidth()/2, y-sprite.getHeight()/2);
spriteBatch.begin();
sprite.draw(spriteBatch);
spriteBatch.end();
}
public void handleInput() {
if(boostButton.isPressed()) {
rocket.boost();
}
if(boostLeftButton.isPressed()) {
rocket.turnLeft();
}
if(boostRightButton.isPressed()) {
rocket.turnRight();
}
if(resetButton.isPressed()) {
}
}
public boolean resetScreen() {
if(resetButton.isPressed()) return true;
return false;
}
public void updateCamera() {
}
public Ground getGround() {
return ground;
}
public void resize(int width, int height) {
viewport.update(width, height);
camera.position.x = VIEWPORT_WIDTH / 2;
camera.position.y = VIEWPORT_HEIGHT /2;
}
private void translateScreenToWorldCoordinates(int x, int y) {
getCamera().unproject(touchPoint.set(x, y, 0));getCamera();
}
}
Screen class
public class Mission1Screen implements Screen{
private Game game;
private Mission1Stage stage;
private SpriteBatch spriteBatch = new SpriteBatch();
private Skin boostSkin;
private Button boostButton;
public Mission1Screen(Game game) {
this.game = game;
stage = new Mission1Stage(game);
}
#Override
public void show() {
}
#Override
public void render(float delta) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if(stage.resetScreen()) {
game.setScreen(new Mission1Screen(game));
}
stage.act(delta);
stage.draw();
stage.updateCamera();
}
#Override
public void resize(int width, int height) {
stage.resize(width, height);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
}
}
[EDIT 3]
public class Main extends Game {
#Override
public void create () {
this.setScreen(new Mission1Screen(this));
}
#Override
public void render () {
super.render();
}
#Override
public void dispose () {
}
}
We mostly use Pixel to meter conversion because box2d best works in meters (0-10) but you can avoid this conversion by using small worldwidth and height of your viewport. I mostly prefer 48 and 80 as viewport width and height.
You can use unproject(vector3) method of camera that translate a point given in screen coordinates to world space. I am using this method in touchdown because I get screen coordinate as parameter then I need to convert it into camera world space so that I can generate object at a particular position in world.
public class MyGdxTest extends Game implements InputProcessor {
private SpriteBatch batch;
private ExtendViewport extendViewport;
private OrthographicCamera cam;
private float w=20;
private float h=22;
private World world;
private Box2DDebugRenderer debugRenderer;
private Array<Body> array;
private Vector3 vector3;
#Override
public void create() {
cam=new OrthographicCamera();
extendViewport=new ExtendViewport(w,h,cam);
batch =new SpriteBatch();
Gdx.input.setInputProcessor(this);
world=new World(new Vector2(0,-9.8f),true);
array=new Array<Body>();
debugRenderer=new Box2DDebugRenderer();
vector3=new Vector3();
BodyDef bodyDef=new BodyDef();
bodyDef.type= BodyDef.BodyType.StaticBody;
bodyDef.position.set(0,0);
Body body=world.createBody(bodyDef);
ChainShape chainShape=new ChainShape();
chainShape.createChain(new float[]{1,1,55,1});
FixtureDef fixtureDef=new FixtureDef();
fixtureDef.shape=chainShape;
fixtureDef.restitution=.5f;
body.createFixture(fixtureDef);
chainShape.dispose();
}
#Override
public void render() {
super.render();
Gdx.gl.glClearColor(0,1,1,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
world.step(1/60f,6,2);
batch.setProjectionMatrix(cam.combined);
batch.begin();
world.getBodies(array);
for (Body body:array){
if(body.getUserData()!=null) {
Sprite sprite = (Sprite) body.getUserData();
sprite.setPosition(body.getPosition().x-sprite.getWidth()/2, body.getPosition().y-sprite.getHeight()/2);
sprite.setRotation(body.getAngle()*MathUtils.radDeg);
sprite.draw(batch);
}
}
batch.end();
debugRenderer.render(world,cam.combined);
}
#Override
public void resize(int width, int height) {
super.resize(width,height);
extendViewport.update(width,height);
cam.position.x = w /2;
cam.position.y = h/2;
cam.update();
}
private void createPhysicsObject(float x,float y){
float sizeX=2,sizeY=2;
BodyDef bodyDef=new BodyDef();
bodyDef.position.set(x,y);
bodyDef.type= BodyDef.BodyType.DynamicBody;
Body body=world.createBody(bodyDef);
PolygonShape polygonShape=new PolygonShape();
polygonShape.setAsBox(sizeX,sizeY);
FixtureDef fixtureDef=new FixtureDef();
fixtureDef.shape=polygonShape;
fixtureDef.restitution=.2f;
fixtureDef.density=2;
body.createFixture(fixtureDef);
body.setFixedRotation(false);
polygonShape.dispose();
Sprite sprite=new Sprite(new Texture("badlogic.jpg"));
sprite.setSize(2*sizeX,2*sizeY);
sprite.setPosition(x-sprite.getWidth()/2,y-sprite.getHeight()/2);
sprite.setOrigin(sizeX,sizeY);
body.setUserData(sprite);
}
#Override
public void dispose() {
batch.dispose();
debugRenderer.dispose();
world.dispose();
}
#Override
public boolean keyDown(int keycode) {
return false;
}
#Override
public boolean keyUp(int keycode) {
return false;
}
#Override
public boolean keyTyped(char character) {
return false;
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
vector3.set(screenX,screenY,0);
Vector3 position=cam.unproject(vector3);
createPhysicsObject(vector3.x,vector3.y);
return false;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
return false;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
return false;
}
#Override
public boolean mouseMoved(int screenX, int screenY) {
return false;
}
#Override
public boolean scrolled(int amount) {
return false;
}
}

Libgdx can I add Actions to Image?

I am Trying to add action to the image but it's not working.
is it allowed to add action to images?
I tried to rotate it this way and it works:
mainButtons.center.rotateBy(5);
center is Image.
but when I try this way it is not working :
mainButtons.center.addAction(Actions.rotateBy(5));
I defined the image here:
public class MainButtons {
public Viewport viewport;
public Stage stage;
public GameImages gameImages;
public boolean centerPressed;
public Image center;
public OrthographicCamera camera;
public static Table table;
//Constructor.
public MainButtons(SpriteBatch spriteBatch) {
camera = new OrthographicCamera();
viewport = new StretchViewport(KidTele.V_WIDTH,KidTele.V_HIEGH,camera);
stage = new Stage(viewport, spriteBatch);
defineCenter();
}
public void defineCenter()
{
center=gameImages.centerImage();
center.setBounds(viewport.getWorldWidth()/5f,viewport.getWorldHeight()/3f,viewport.getWorldWidth()/1.5f,viewport.getWorldHeight()/3f);
center.addListener(new InputListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
centerPressed = true;
return true;
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
centerPressed = false;
}
});
//center.setVisible(false);
stage.addActor(center);
}
}
And call it here:
public class PlayScreen implements Screen {
#Override
public void render(float delta) {
update(delta);
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
b2dr.render(world, gamecam.combined);
game.batch.setProjectionMatrix(gamecam.combined);
game.batch.begin();
if(mainButtons.centerPressed) {
mainButtons.center.addAction(Actions.rotateBy(5));
// mainButtons.center.rotateBy(5);
}
game.batch.draw(background, 0, 0, gameport.getWorldWidth(), gameport.getWorldHeight());
game.batch.end();
mainButtons.draw();
}
}

InputListener doesn't work with OrthographicCamera and Actors

I have a Stage with OrthographicCamera and also I have a Actor with InputListener setter by addListener (from actor class). The problem is that the actor doesn't proccess input, but if in my screen I delete OrthographicCamera the Actor proccess the input, so, with OrthographicCamera Actor doesn't proccess input but it works if I remove OrthographicCamera.
Any advice?
I have the following code
public class Test implements Screen {
private Game game;
private Stage stage;
private MemoryActor actor;
private AssetManager manager;
private boolean loaded = false;
float width, height;
private OrthographicCamera camera;
public Test(Game game){
this.game = game;
stage = new Stage();
manager = new AssetManager();
manager.load("img.png",Texture.class);
manager.load("img1.png",Texture.class);
InputMultiplexer im = new InputMultiplexer();
im.addProcessor(stage);
Gdx.input.setInputProcessor(im);
height = Gdx.graphics.getHeight();
width = Gdx.graphics.getWidth();
camera = new OrthographicCamera(width, height);
camera.position.set(((width / 2)), ((height / 2)), 0);
camera.update();
stage.setViewport(new ExtendViewport(300,300, camera));
}
public void createActor(){
Texture back = manager.get("img.png", Texture.class);
actor = new MemoryActor(manager.get("img1.png", Texture.class), back,0,0,50,50);
actor.setInputListener(new InputListener(){
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
System.out.println("down");
return true;
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
System.out.println("up");
}
});
stage.addActor(actor);
}
#Override
public void render(float delta) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if (manager.update()){
if (!loaded){
createActor();
loaded = true;
}
}
stage.draw();
}
#Override
public void resize(int width, int height) {
}
#Override
public void show() {
}
#Override
public void hide() {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
}
}
and MemoryActor:
public class MemoryActor extends Actor {
...
public MemoryActor(){}
public MemoryActor(Texture texture, Texture texBack, float x, float y, float width, float height){
...
}
public void setInputListener(InputListener il){
addListener(il);
}
#Override
public void draw(Batch batch, float alpha){
...
}
}
Just registering the stage as an InputProcessor isn't enough. You also need to trigger the event processing of Stage via stage.act() in every frame.
Furthermore you need to properly update the stage's Viewport when a resize event occurs. This can be done via stage.getViewport().update(width, height, true). Otherwise the stage will process the events based on incorrect assumptions about the screen size and might also render your stage not the way you want it. The true is important because it will also center the camera on the new screen size, which is necessary in case of UIs.

Categories

Resources