I'm new at Libgdx and one aspect that blocks me to continue with my Libgdx learning is the fact that a I don't know how to use the GestureListener. It's seems there's a user with the same doubt if you see in this link LibGdx: Utilizing a Gesture Listener, but it didn't help me much. So my question is: how do I use my own GestureListener class to process my player moviments? I wanna use the pan function to make it jump, but I don't know how to put my player object inside the method. If you see my gesture detector class:
public class GestureHandler implements GestureListener {
// Main Game class
private ClimbUp mainGame;
public GestureHandler(ClimbUp game) {
this.mainGame = game;
}
#Override
public boolean touchDown(float x, float y, int pointer, int button) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean tap(float x, float y, int count, int button) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean longPress(float x, float y) {
// TODO Auto-generated method stub
return false;
}
...
Then I followed what they told the user what to do: in the main class I passed the fallowing instruction:
Gdx.input.setInputProcessor(new GestureDetector(new GestureHandler(this)));
Now in my splash screen, I don't know how to use. How to make my GestureHandler object works for all project? I'll be very grateful with an answer!
So, you have some you class which need GestureListener "services" - you want to be informed when some gesture event happens and you want to have information of gesture properties.
Then, as you did, make your class implement GestureListener interface.
After that your IDE (Eclipse or Android Studio or something else) will complain that you didn't implemented all GestureListener methods, but it can also do that for you. If you (in eclipse) hover the error in the code IDE will offer you to create missing methods.
I would say you are at about that step. But now your methods have to do something useful. Like, if you want to do something when player taps the screen add your code inside that method. Do something there. Inside GestureListener methods you have some info available, as method parameters like x & y coordinates, button (left, middle, right) and something like that.
So, when you call that setInputProcessor with object created in you class that implemented G.L. interface libGDX will know to call your methods when some event occurs.
Every method IDE generated has that "todo" mark - that's where you have to put your code instead. The code that will handle that event, move your space ship, fire the bullet or what ever. You don't have to do something for every event, but only for those you are interested in. You can leave other empty, but your class must have them.
Here is some example:
// importing interface
import com.badlogic.gdx.input.GestureDetector.GestureListener;
// defining my class that implements that interface
public class TouchController implements GestureListener{
// constructor - just storing objects passed to it.
public TouchController(Playground pg, Army army, Hud hud){
super();
this.pg = pg;
this.army = army;
this.hud = hud;
initialZoom = pg.zoom;
}
// Adding some action to touchDown method - I'm just calling my hud object's method and passing coords I get
#Override
public boolean touchDown(float x, float y, int pointer, int button) {
hud.pressedAt(x, pg.camera.viewportHeight-y); // opposite Y axis
// TODO Auto-generated method stub
return false;
}
// Similar thing. I unproject coords I get.
#Override
public boolean tap(float x, float y, int count, int button) {
if (!hud.buttonPressed){
Vector3 touchPos = new Vector3();
touchPos.set(x, y, 0);
pg.camera.unproject(touchPos);
army.add(touchPos.x, touchPos.y, SoldierSide.RED);
}else hud.released();
return false;
}
// Again similar stuff, but this pan methods is getting also delta value (difference from last reading x and y values) which can be useful
#Override
public boolean pan(float x, float y, float deltaX, float deltaY) {
if (hud.aimDrag) hud.aimDragged((int)deltaX, (int)deltaY);
else if (hud.sliderDrag) hud.sliderDragged((int)deltaX, (int)deltaY);
else if (!hud.buttonPressed) pg.panned((int)deltaX, (int)deltaY);
return false;
}
...
Related
I am analizing a game code.
A method which name is act() is running despite it is not called.
Its like, there is a secret method somwere but i cant see it.
i follow source of method.i find so code.The some part of codes are as below.
I think parent class send method to child class when a new object execuded.
Is there a name of this approach.
This is LevelScreen class.It does not have act() method but act() method is working.I can see the changes when i change the parametres in act() method in Plane class.
class LevelScreen : BaseScreen(){
plane = Plane(100f, 500f, mainStage)}
This is Plane class which has act() method.
class Plane(x: Float, y: Float, s: Stage) : BaseActor(x, y, s){
override fun act(dt: Float) {
super.act(dt)
// simulate force of gravity
setAcceleration(800f)
accelerateAtAngle(270f)
applyPhysics(dt)
................
.............
}
This is parent class of Plane class
open class BaseActor(x: Float, y: Float, s: Stage) : Group(){
override fun act(dt: Float) {
super.act(dt)
if (!animationPaused)
elapsedTime += dt
}
}
This is a class which is in framework of libGDX
public class Group extends Actor implements Cullable{
public void act (float delta) {
super.act(delta);
Actor[] actors = children.begin();
for (int i = 0, n = children.size; i < n; i++)
actors[i].act(delta);
children.end();
}
}
Look at the main project file where the Stage is created. The main file will have a method called render and this is where the act method is called for the first time. All Actors are added to the Stage and then inside of the render method the act method is called on the Stage, which then calls the act method on all of the Actors that it contains.
This is the section you are looking for (taken from one of my projects):
#Override
public void render (){
Gdx.gl.glClearColor(0.6f, 0.64f, 0.7f, 1.0f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act(Gdx.graphics.getRawDeltaTime()); // START OF ACT METHODS
stage.draw();
}
I am trying to implement a map of the universe. When mouse on a pic of the planet simply hovering on the picture, I want to see some information. How to handle this in libgdx?
In the following example, I am trying to give mouseClick sound while hovering, still does not work.
ImageButton imageButton = new ImageButton(drawable);
imageButton.setSize(100,100);
imageButton.setPosition(100,100);
imageButton.addListener(new FocusListener() {
#Override
public boolean handle(Event event) {
mouseClick.play();
return true;
}
});
Here how my override methods #enter and #exit looks`, I created HoverListener and override both methods.
#Override
public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) {
super.enter(event, x, y, pointer, fromActor);
fromActor.setName("Hello");
}
#Override
public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) {
super.exit(event, x, y, pointer, toActor);
toActor.setName("Bye");
}
Then btn_station.addListener(new HoverListener());
Still no interaction :/
Check the following:
You stage is the input processor: Gdx.input.setInputProcessor(stage)
Your Actor is on the stage: stage.addActor(actor)
The size of your actor is set: actor.setSize(100f, 100f)
You handle input events correctly (implement and override relevant interfaces)
As per your response to my comments, it sounds like in this case you did not set the stage as the input processor.
Is it possible to allow the user to touch an actor only one time.
I've tried using boolean but the problem is I write addListener in the class constructor and I want it to be here not in a separate method
I believe you can remove the listener like this, I have not tested it though and no time for it right now.
final Table t = new Table();
t.addListener(ClickListener listener = new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
super.clicked(event, x, y);
//Do stuff
//...
//remove this listener
t.removeListener(this);
}
});
I'm using a number of input controllers. One to control the camera and one to control buttons that have been placed on a scene.
Ive been trying to work out how to create my own custom controller but so far have been unsuccessful in finding any tutorials on how to do it.
Also i would like to deactivate the camera controller if the touch or gesture is bellow a certain height.
Many thanks in any help
Just create a class CamController implements InputProcessor (or extends InputAdapter).
Then override all the methods you need (i use touchDown here as an example) and do the following (Pseudocode!!! Do not copy and paste!!!):
protected boolean touchDown(int screenX, int screenY, int pointer, int button) {
boolean handled = false;
if (screenX <= maxX && screenX >= minX && screenY <= maxY && screenY >= minY) {
// The touch is inside the limits of the camera controller, the controller is activated
// Move camera to the touchpoint:
camera.position.set(screenX, screenY);
camra.update();
handled = true;
}
return handled;
}
Create the controller for the button, again the controller implements InputProcessor an override the methods.
Next in your ApplicationListener or in your Screens create() or show() method you create an InputMultiplexer:
InputMultiplexer m = new InputMultiplexer(new CamController(camera, limitX, limitY), new ButtonController);
And the you just need to set the InputMultiplexer as the active InputProcessor.
It's important to use CamController as the first one, because it then calls touchDown-method for this and only if the touchDown returns false it calls touchDown for the ButtonController.
Hope it helps.
I have a class Bubble that extends Actor.
public Bubble(MyGdxGame game,Texture texture){
this.game=game;
setPosition(0,0);
setSize(32,32);
gameObject=new GameObject("","bubble");
direction=new MovementDirection();
sprite=new Sprite(texture);
setTouchable(Touchable.enabled);
setWidth(sprite.getWidth());
setHeight(sprite.getHeight());
setBounds(0,0,sprite.getWidth(),sprite.getHeight());
addListener(new InputListener() {
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
Gdx.app.log("BUBBLE", "touchdown");
return true; // must return true for touchUp event to occur
}
public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
Gdx.app.log("BUBBLE", "touchup");
}
});
}
This is in a class that implements Screen
public void show() {
// TODO Auto-generated method stub
super.show();
//2 bubbles test
gameStage=new Stage(MyGdxGame.WIDTH,MyGdxGame.HEIGHT,true);
Gdx.input.setInputProcessor(gameStage);
for (int i=0; i<10; i++){
Bubble b=new Bubble(game,Assets.bubbleTexture);
b.randomize();
gameStage.addActor(b);
}
//if (bubbleList==null)
// createBubbles();
}
Am I going about this the wrong way by adding the listener # the bubble level? (It seems creating an InputListener for every bubble I spawn is a little crazy).
According to : http://libgdx.l33tlabs.org/docs/api/com/badlogic/gdx/scenes/scene2d/Actor.html
Actor has a touchUp() and touchDown event - but complains when i try to override them (which lead me to believe they dont exist). Overriding these I feel would be a better approach
The docs you linked to are outdated.
Those methods were deprecated and removed in favor of using InputListeners.
In your example if you want to use the same InputListener instance for all instances of your Actor class (Bubble) then you can just implement the InputListener to refer to the Actor class instance using inputEvent.getRelatedActor() and then instantiate one such InputListener as a static member of Bubble and pass it in the constructor to addListener.
class Bubble extends Actor{
private static InputListener bubbleListener= new InputListener() {
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
Bubble b = (Bubble) event.getRelatedActor();
b.doSomething();
...
return true; //or false
}
}
public Bubble(){
addListener(bubbleListener);
...
}
...
}