I have been detecting different kinds of input with the different implemented Gesture Detector methods. I do however want to change some of the preferences of the G.D by changing the parameters of the method below:
public GestureDetector(float halfTapSquareSize,
float tapCountInterval,
float longPressDuration,
float maxFlingDelay,
GestureDetector.GestureListener listener)
I got ^ code of http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/input/GestureDetector.html
I am especially interested in changing the value of "halfTapSquareSize"
How would I go about implementing that into my code below?
public class MyGdxGame extends ApplicationAdapter implements GestureDetector.GestureListener {
#Override
public void create() {
super.create();
//Doing stuff at create
}
#Override
public void resize(int width, int height) {
super.resize(width, height);
}
#Override
public void render() {
super.render();
//Rendering stuff
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
//disposing stufff
}
#Override
public boolean touchDown(float x, float y, int pointer, int button) {
return false;
}
#Override
public boolean tap(float x, float y, int count, int button) {
// Doing stuff at tap
return true;
}
#Override
public boolean longPress(float x, float y) {
return false;
}
#Override
public boolean fling(float velocityX, float velocityY, int button) {
return false;
}
#Override
public boolean pan(float x, float y, float deltaX, float deltaY) {
//Doing stuff when paning
}
#Override
public boolean panStop(float x, float y, int pointer, int button) {
return false;
}
#Override
public boolean zoom(float initialDistance, float distance) {
return false;
}
#Override
public boolean pinch(Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2) {
return false;
}
}
Your code only implements the GestureListener. This listener needs to be associated with a GestureDetector, and the GestureDetector then needs to be registered to handle input.
So within your MyGdxGame class, you'll need something like this:-
GestureDetector input = new GestureDetector(this); // 'this' refers to your MyGdxGame instance
Gdx.input.setInputProcessor(input);
Now you can either supply extra arguments to GestureDetector's constructor, as you have mentioned in your post, or use the GestureDetector's relevant methods, like so:
input.setTapSquareSize(someFloatValue);
Related
I recently started programming an app in LibGDX. With this app, one can only now press on boxes which are then filled in blue.
In principle everything works. The problem is only if I move the orthographic camera, or start to zoom, then my input processor still remains in the same place.
In short. Because the camera is moved or zoomed, the input does not work properly.
I have two times here Schreenshots attached so you can see what I mean.
The red dots are always where I pressed.
Regards Timux ;D
Here it works correctly
No more
No problem when I move or zoom my camera, I've tested, you can check this.
May be you're not using unproject() method of camera that translate a point given in screen coordinates to world space.
public class GdxText extends ApplicationAdapter implements InputProcessor {
OrthographicCamera cam;
Texture texture;
Sprite firstSprite,secondSprite;
SpriteBatch spriteBatch;
Vector3 vector3;
#Override
public void create() {
vector3=new Vector3();
cam=new OrthographicCamera();
texture=new Texture("badlogic.jpg");
float w=Gdx.graphics.getWidth();
float h=Gdx.graphics.getHeight();
spriteBatch=new SpriteBatch();
firstSprite=new Sprite(texture);
firstSprite.setSize(100,100);
firstSprite.setPosition(w/2-150,h/2-50);
secondSprite=new Sprite(texture);
secondSprite.setSize(100,100);
secondSprite.setPosition(w/2+50,h/2-50);
Gdx.input.setInputProcessor(this);
}
#Override
public void render() {
Gdx.gl.glClearColor(1,1,1,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
spriteBatch.setProjectionMatrix(cam.combined);
spriteBatch.begin();
firstSprite.draw(spriteBatch);
secondSprite.draw(spriteBatch);
spriteBatch.end();
}
#Override
public void resize(int width, int height) {
cam.setToOrtho(false,width,height);
cam.update();
}
#Override
public boolean keyDown(int keycode) {
if(keycode== Input.Keys.UP) {
cam.zoom -= cam.zoom * .1;
cam.update();
}else if(keycode==Input.Keys.DOWN) {
cam.zoom += cam.zoom * .1;
cam.update();
}
if(keycode== Input.Keys.LEFT) {
cam.position.add(2f,0,0);
cam.update();
}else if(keycode==Input.Keys.RIGHT) {
cam.position.add(-2f,0,0);
cam.update();
}
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 ori=cam.unproject(vector3);
if(firstSprite.getBoundingRectangle().contains(ori.x,ori.y))
System.out.println("Touch on First Sprite");
if(secondSprite.getBoundingRectangle().contains(ori.x,ori.y))
System.out.println("Touch on Second Sprite");
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;
}
#Override
public void dispose() {
spriteBatch.dispose();
texture.dispose();
}
}
I have tried finding an answer to solve the problem, but I think that I don't seem to understand how to use the long press in Libgdx.
I want my character to move right when I long press on the right half of the screen and left when I long press on the left half of the screen.
I have searched and tried.
Here is my InputHandler class :
public class InputHandler implements InputProcessor {
private MainCharacter myMainCharacter;
public InputHandler(MainCharacter mainCharacter) {
myMainCharacter = mainCharacter;
}
#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) {
myMainCharacter.onClick();
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;
}
}
And here is my MainCharacter class :
public class MainCharacter {
private Vector2 position;
private Vector2 velocity;
private Vector2 acceleration;
private float rotation;
private int width;
private int height;
public MainCharacter(float x, float y, int width, int height) {
this.width = width;
this.height = height;
position = new Vector2(x, y);
velocity = new Vector2(0, 0);
acceleration = new Vector2(0, 460);
}
public void update(float delta) {
velocity.add(acceleration.cpy().scl(delta));
if (velocity.y > 200) {
velocity.y = 200;
}
position.add(velocity.cpy().scl(delta));
}
public void onClick() {
if (Gdx.input.getX() <= 135) {
Gdx.app.log("TAG", "LEFT");
position.x--;
} else if (Gdx.input.getX() >= 137) {
Gdx.app.log("TAG", "RIGHT");
position.x++;
}
}
public float getX() {
return position.x;
}
public float getY() {
return position.y;
}
public float getWidth() {
return width;
}
public float getHeight() {
return height;
}
public float getRotation() {
return rotation;
}
}
I used onClick() method as a replacement until I find a solution for the problem. It works fine but it doesn't have the same effect as the long press. My character moves left when I click on the left side of the screen and right when I click on the right side of the screen. But of course it doesn't work when I long press.
So how can I use 'Long Press' ?
I would really appreciate your help.
Gokul gives a nice overview of the GestureListener but I do not believe this is what you are looking for. LongPress indeed only registers after some seconds of pressing and you want to have a touch control the character immediately.
There is no out of the box method in the listeners to keep detecting touched but you can create it yourself.
if (Gdx.input.isTouched())
{
//Finger touching the screen
// You can actually start calling onClick here, if those variables and logic you are using there are correct.
if (Gdx.input.getX() >= screenSize / 2)
{
//Right touched
}
else if (Gdx.input.getX() < screenSize / 2)
{
//Left touched
}
}
Just check for this every frame and do your logic.
You can implement the long press by implementing the GestureListner interface.
GestureDetector will let you detect the following gestures:
touchDown: A user touches the screen.
longPress: A user touches the screen for some time.
tap: A user touches the screen and lifts the finger again. The finger must not move outside a specified square area around the initial touch position for a tap to be registered. Multiple consecutive taps will be detected if the user performs taps within a specified time interval.
pan: A user drags a finger across the screen. The detector will report the current touch coordinates as well as the delta between the current and previous touch positions. Useful to implement camera panning in 2D.
panStop: Called when no longer panning.
fling: A user dragged the finger across the screen, then lifted it. Useful to implement swipe gestures.
zoom: A user places two fingers on the screen and moves them together/apart. The detector will report both the initial and current distance between fingers in pixels. Useful to implement camera zooming.
pinch: Similar to zoom. The detector will report the initial and current finger positions instead of the distance. Useful to implement camera zooming and more sophisticated gestures such as rotation.
A GestureDetector is an event handler. To listen for gestures, one must implement the GestureListener interface and pass it to the constructor of the GestureDetector. The detector is then set as an InputProcessor, either on an InputMultiplexeror as the main InputProcessor:
public class MyGestureListener implements GestureListener{
#Override
public boolean touchDown(float x, float y, int pointer, int button) {
return false;
}
#Override
public boolean tap(float x, float y, int count, int button) {
return false;
}
#Override
public boolean longPress(float x, float y) {
return false;
}
#Override
public boolean fling(float velocityX, float velocityY, int button) {
return false;
}
#Override
public boolean pan(float x, float y, float deltaX, float deltaY) {
return false;
}
#Override
public boolean panStop(float x, float y, int pointer, int button) {
return false;
}
#Override
public boolean zoom (float originalDistance, float currentDistance){
return false;
}
#Override
public boolean pinch (Vector2 initialFirstPointer, Vector2 initialSecondPointer, Vector2 firstPointer, Vector2 secondPointer){
return false;
}
#Override
public void pinchStop () {
}
}
You have to set the GestureDetector that contains your GestureListener as the InputProcessor:
Gdx.input.setInputProcessor(new GestureDetector(new MyGestureListener()));
For more details, check out the link below
https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/input/GestureDetector.GestureListener.html
I defined a mainmenu class where I am Trying to show some images inside a table and make them respond for touches but when I define the call the class (just call it) inside the constructor of the main screen, the controls don't respond although I defined the mainmenu class in the same way of defining the controls class.
(notice when I use mainmenu object inside the main screen it renders the images and the controls but they don't respond for any click).
the main problem is happened when I call the mainmenu, the game is running but controls don't respond for touch. here is the code of the two classes:
public class Controller {
public Viewport viewport;
public Stage stage;
public boolean upPressed;
public boolean leftPressed;
public boolean rightPressed;
public boolean pausePressed;
public static boolean visiblity;
public Image buttonUp;
public Image buttonDown;
public Image buttonLeft;
public Image buttonRight;
public Image buttonpause;
public OrthographicCamera camera;
public Table table;
public Table table1;
public Table table2;
//Constructor.
public Controller(SpriteBatch spriteBatch) {
camera = new OrthographicCamera();
viewport = new FitViewport(Fruits.V_WIDTH, Fruits.V_HIEGT, camera);
stage = new Stage(viewport, spriteBatch);
Gdx.input.setInputProcessor(stage);
visiblity=false;
//Buttons with images.
buttonUp = new Image(new Texture("Pause.png"));
buttonUp.setSize(30, 30);
buttonUp.addListener(new InputListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
upPressed = true;
return true;
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
upPressed = false;
}
});
buttonLeft = new Image(new Texture("buttonleft.png"));
buttonLeft.setSize(65, 65);
buttonLeft.addListener(new InputListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
leftPressed = true;
return true;
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
leftPressed = false;
}
});
buttonRight = new Image(new Texture("buttonright.png"));
buttonRight.setSize(65, 65);
buttonRight.addListener(new InputListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
rightPressed = true;
return true;
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
rightPressed = false;
}
});
buttonpause = new Image(new Texture("pausing.png"));
buttonpause.setSize(30, 30);
buttonpause.addListener(new InputListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
pausePressed = true;
return true;
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
pausePressed = false;
}
});
//Table with buttons.
table = new Table();
table.left().bottom(); //Align to the left bottom.
table.add(buttonLeft).size(buttonLeft.getWidth(), buttonLeft.getHeight()).spaceRight((viewport.getWorldWidth() / 10) * 6.5f);
// table.add(buttonUp).size(buttonUp.getWidth(), buttonUp.getHeight()).spaceRight((viewport.getWorldWidth() / 10) * 6.5f);
table.add(buttonRight).size(buttonRight.getWidth(), buttonRight.getHeight());
stage.addActor(table);
table1=new Table();
table1.right().top();
table1.setFillParent(true);
//table1.add();
table1.row().pad(25, 3, 0, 10);
table1.add(buttonUp).size(buttonUp.getWidth(), buttonUp.getHeight()).spaceRight((viewport.getWorldWidth() / 10) * 6.5f);
stage.addActor(table1);
table2=new Table();
table2.center();
table2.setFillParent(true);
//table1.add();
table2.row().pad(25, 3, 0, 10);
table2.add(buttonpause).size(buttonpause.getWidth(), buttonpause.getHeight()).spaceRight((viewport.getWorldWidth() / 10) * 6.5f);
stage.addActor(table2);
}
public void draw() {
stage.draw();
}
public void resize(int width, int height) {
viewport.update(width, height);
}
public boolean isUpPressed() {
return upPressed;
}
public boolean isLeftPressed() {
return leftPressed;
}
public boolean isRightPressed() {
return rightPressed;
}
public boolean isPausePressed() {
return pausePressed;
}
}
code of mainmenu
public class MainMenu{
/* public Viewport viewport;
public Stage stage;
public boolean pausePressed;
public boolean resumePressed;
public boolean exitPressed;
public Image buttonpause;
public Image buttonDown;
public Image buttonresume;
public Image buttonexit;
public OrthographicCamera camera;
public Table table;
public Table table2;
//Constructor.
public MainMenu(SpriteBatch spriteBatch) {
camera = new OrthographicCamera();
viewport = new FitViewport(Fruits.V_WIDTH, Fruits.V_HIEGT, camera);
stage = new Stage(viewport, spriteBatch);
Gdx.input.setInputProcessor(stage);
//Buttons with images.
buttonpause = new Image(new Texture("pausing.png"));
buttonpause.setSize(30, 30);
buttonpause.addListener(new InputListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
pausePressed = true;
return true;
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
pausePressed = false;
}
});
buttonresume = new Image(new Texture("resume.png"));
buttonresume.setSize(65, 65);
buttonresume.addListener(new InputListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
resumePressed = true;
return true;
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
resumePressed = false;
}
});
buttonexit = new Image(new Texture("exit.png"));
buttonexit.setSize(65, 65);
buttonexit.addListener(new InputListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
exitPressed = true;
return true;
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
exitPressed = false;
}
});
//Table with buttons.
table2=new Table();
table2.center();
table2.setFillParent(true);
//table2.add();
table2.row().pad(25, 3, 0, 10);
table2.add(buttonpause).size(buttonpause.getWidth(), buttonpause.getHeight()).spaceRight((viewport.getWorldWidth() / 10) * 6.5f);
table2.row().pad(25, 3, 0, 10);
table2.add(buttonresume).size(buttonresume.getWidth(), buttonresume.getHeight());
table2.row().pad(25, 3, 0, 10);
table2.add(buttonexit).size(buttonexit.getWidth(), buttonexit.getHeight()).spaceRight((viewport.getWorldWidth() / 10) * 6.5f);
stage.addActor(table2);
}
public void draw() {
stage.draw();
}
public void resize(int width, int height) {
viewport.update(width, height);
}
public boolean isPausePressed() {
return pausePressed;
}
public boolean isResumePressed() {
return resumePressed;
}
public boolean isExitPressed() {
return exitPressed;
}
*/
}
There can only be one input processor set at a time, so only your most recent call to Gdx.input.setInputProcessor has any effect. So move that call to the show() method of your screens (if you're implementing Screen, otherwise do whatever the equivalent is in your structure).
You can also use an InputMultiplexer to combine multiple input processors into one if you want them to be able to work at the same time.
I'm currently following this book to create my libgdx game..
So far, i have these classes to create my game :
AbstractGameScreen.java - that Implements libgdx's Screen
AbstractGameObject.java - that extends libgdx's Actor
GamePlay.java - which is my game screen
GameController.java - where i init my game objects
GameRenderer.java - when i render all my objects
Assets.java - a class that organizes my game assets
Ring.java - an object in my game
And here is my code..
AbstractGameScreen
public abstract class AbstractGameScreen implements Screen {
protected Game game;
public AbstractGameScreen(Game game){
this.game = game;
}
public abstract void render(float deltaTime);
public abstract void resize(int width, int height);
public abstract void show();
public abstract void hide();
public abstract void pause();
public void resume(String bg, String ring){
Assets.instance.init(new AssetManager(), bg, ring); // kosongin, jadinya default
}
public void dispose(){
Assets.instance.dispose();
}
}
AbstractGameObject
public abstract class AbstractGameObject extends Actor{ //implements EventListener{ //extends Sprite{
public Vector2 position;
public Vector2 dimension;
public Vector2 origin;
public Vector2 scale;
public float rotation;
public AbstractGameObject(){
position = new Vector2();
dimension = new Vector2(1, 1);
origin = new Vector2();
scale = new Vector2(1, 1);
rotation = 0;
}
public void update (float deltaTime){
}
public abstract void render(SpriteBatch batch);
}
GamePlay
public class GamePlay extends AbstractGameScreen implements InputProcessor{
private GameController gameController;
private GameRenderer gameRenderer;
private String dummyBg, dummyRing;
private boolean paused;
// for touch purposes
private static final int appWidth = Constants.VIEWPORT_GUI_WIDTH_INT;
private static final int appHeight = Constants.VIEWPORT_GUI_HEIGHT_INT;
public GamePlay(Game game) {
super(game);
// still dummy.. nantinya ngambil dari database nya
this.dummyBg = "bg-default";
this.dummyRing = "ring-default";
Gdx.input.setInputProcessor(this);
}
#Override
public void render(float deltaTime) {
if(!paused){
gameController.update(deltaTime);
}
//Gdx.gl.glClearColor(0x64 / 255.0f, 0x95 / 255.0f,0xed / 255.0f, 0xff / 255.0f);
//Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
// render game nya
gameRenderer.render();
}
#Override
public void resize(int width, int height) {
gameRenderer.resize(width, height);
}
#Override
public void show() {
Assets.instance.init(new AssetManager(), "bg-default", "ring-default");
Gdx.app.log("GamePlay", "After show() method");
gameController = new GameController(game);
gameRenderer = new GameRenderer(gameController);
Gdx.input.setCatchBackKey(true);
}
#Override
public void hide() {
gameRenderer.dispose();
Gdx.input.setCatchBackKey(false);
}
#Override
public void dispose(){
gameRenderer.dispose();
Assets.instance.dispose();
}
#Override
public void pause() {
paused = true;
}
#Override
public void resume() {
super.resume(this.dummyBg, this.dummyRing);
//Assets.instance.init(new AssetManager(), this.dummyBg, this.dummyRing);
paused = false;
}
#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) {
return true;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
return true;
}
// for touch purposes
private float getCursorToModelX(int screenX, int cursorX) {
return (((float)cursorX) * appWidth) / ((float)screenX);
}
private float getCursorToModelY(int screenY, int cursorY) {
return ((float)(screenY - cursorY)) * appHeight / ((float)screenY) ;
}
#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;
}
}
GameController
public class GameController extends InputAdapter{
// game objects
public Array<Tiang> tiangs;
public Array<Ring> rings;
//private Game game;
// game decorations
public Background background; public Sprite[] testSprite;
private Game game;
public GameController(Game game){
this.game = game;
init();
}
private void init(){
// preparing variables
rings = new Array<Ring>();
tiangs = new Array<Tiang>();
initObjects();
initDecorations();
initGui();
}
private void initObjects(){
AbstractGameObject obj = null;
obj = new Ring(1, "default");
obj.addListener(new ClickListener(){
#Override
public void clicked(InputEvent event, float x, float y) {
//super.clicked(event, x, y);
Gdx.app.log("tag", "test clisk");
}
});
rings.add((Ring)obj);
}
private void initDecorations(){
}
private void initGui(){
}
private void handleInput(float deltatime){
}
public void update(float deltaTime){
//if(Gdx.input.isTouched()){
// Gdx.app.log("update", "screen touched");
//}
}
}
GameRenderer
public class GameRenderer implements Disposable{
private OrthographicCamera camera;
private GameController controller;
private SpriteBatch batch;
public GameRenderer(GameController controller){
this.controller = controller;
init();
}
private void init(){
batch = new SpriteBatch();
camera = new OrthographicCamera(Constants.VIEWPORT_WIDTH, Constants.VIEWPORT_HEIGHT); //diambil dari class "Constants" (di package util)
camera.position.set(0, 0, 0);
camera.update();
}
public void resize(int width, int height){
camera.viewportWidth = (Constants.VIEWPORT_HEIGHT / height) * width;
camera.update();
}
public void render(){
renderGui();
renderDecorations();
renderObjects();
}
private void renderGui(){
}
private void renderDecorations(){
}
private void renderObjects(){
batch.setProjectionMatrix(camera.combined);
batch.begin();
for(Ring rings : controller.rings){
rings.render(batch);
}
batch.end();
}
#Override
public void dispose() {
}
}
Assets
public class Assets implements Disposable, AssetErrorListener{
public static final String TAG = Assets.class.getName();
public static final Assets instance = new Assets();
private AssetManager assetManager;
// inner class objects
public AssetTiang tiang;
public AssetBackgroud bg;
public AssetTombol tombol;
public AssetTombolBg tombolBg;
public AssetRing ring;
//singleton pattern, buat mencegah instansiasi dari class yang lain
private Assets(){}
//public void init(AssetManager assetManager){
public void init(AssetManager assetManager, String jenisBg, String jenisRing){
this.assetManager = assetManager;
assetManager.setErrorListener(this);
//load texture atlas yang udah dibikin pake TexturePacker nya (liat ebook page 167)
assetManager.load(Constants.TEXTURE_ATLAS_OBJECTS, TextureAtlas.class);
assetManager.load(Constants.TEXTURE_ATLAS_DECORATION, TextureAtlas.class);
assetManager.load(Constants.TEXTURE_ATLAS_GUI, TextureAtlas.class);
// inner class objects
tiang = new AssetTiang(atlasObject);
bg = new AssetBackgroud(atlasDecoration, jenisBg);
tombol = new AssetTombol(atlasGui);
tombolBg = new AssetTombolBg(atlasDecoration);
ring = new AssetRing(atlasObject, jenisRing);
}
#Override
public void error(AssetDescriptor asset, Throwable throwable) {
// TODO Auto-generated method stub
}
#Override
public void dispose(){
assetManager.dispose();
}
public class AssetRing{
public final AtlasRegion ring;
// jenis ring dimasukin disini, karena jenis ring bisa diganti-ganti sesuai yang dipilih
public AssetRing(TextureAtlas atlas, String jenisRing){
if(!jenisRing.equals("")){
ring = atlas.findRegion(jenisRing);
}
else{
ring = atlas.findRegion("ring-default");
}
}
}
}
And finally, Ring (Object)
public class Ring extends AbstractGameObject{
private TextureRegion ringOverLay;
private float length;
// jenis ring nya
public String jenis;
public Ring(float length, String jenis){
init();
setLength(length);
setJenis(jenis);
}
// getters
public float getLength(){
return this.length;
}
public String getJenis(){
return this.jenis;
}
public Vector2 getPosition(){
return position;
}
// setters
public void setLength(float length){
this.length = length;
dimension.set(5.0f, 1.0f);
}
public void setJenis(String jenis){
this.jenis = jenis;
}
public void setPosition(float x, float y){
position.set(x, y);
}
private void init(){
ringOverLay = Assets.instance.ring.ring; // Assets.instance.namaobjek.atlasregion
origin.x = dimension.x/2; // -dimension.x/2;
origin.y = dimension.y/2;
position.x = -5.0f;
position.y = -2.5f;
}
#Override
public void render(SpriteBatch batch) {
TextureRegion reg = null;
reg = ringOverLay;
batch.draw(reg.getTexture(), position.x, position.y, origin.x, origin.y, dimension.x, dimension.y, scale.x, scale.y, rotation, reg.getRegionX(), reg.getRegionY(), reg.getRegionWidth(), reg.getRegionHeight(), false, false);
}
}
So what's the problem? Okay, the problem is i cannot make the Ring (game object) become clickable.. the Ring is extending AbstractGameObject (which is Actor), and, in the GameController i've add a ClickListener to the Ring object, but the object still unclickable..
Please, anyone tell me what's my mistake?
You're using your Actor (in your case, the Ring) incorrectly: Actors are part of Scene2d, and as such must follow precise rules to work correctly.
To answer your question more specifically, Ring needs to be added to a Stage which itself is an InputProcessor. The Stage is responsible to distribute the input events (such as touch events) to the its Actors. Without defining a Stage your Actors will not respond to any input events.
Read up on Scene2d from the link above. This video tutorial is also helpful.
I am trying to make slingshot type thing(like in angry birds) using LIBGDX(currently learning). So, how do I get the coordinates of the point where user touched the screen and dragged finger to other point n released . I want both co-ordinates initial and released point.
I also want to know how to achieve the above in Android SDK/NDK.
I have not tested this but this should be around about what you need
#Override
Public boolean onTouchEvent (MotionEvent event) {
int downx;
int downy;
int upx;
int upy;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downy = (int)event.gety();
downx = (int)event.getx();
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
upy = (int)event.gety();
upx = (int)event.getx();
}
return false;
}
public class TempScreen extends Screen
{
Game game; // the class which is implementing the InputProcessor
SpriteBatch batcher;
Vector3 touchPoint;
OrthographicCamera cam;
InputMultiplexer multiplexer;
GestureListener listener=new GestureListener()
{
#Override
public boolean zoom(float initialDistance, float distance)
{
// TODO Auto-generated method stub
return false;
}
#Override
public boolean touchDown(float x, float y, int pointer, int button)
{
cam.unproject(touchPoint.set(x, y, 0));
System.out.println(touchPoint);
return false;
}
#Override
public boolean tap(float x, float y, int count, int button)
{
// TODO Auto-generated method stub
return false;
}
#Override
public boolean pinch(Vector2 initialPointer1, Vector2 initialPointer2,
Vector2 pointer1, Vector2 pointer2)
{
// TODO Auto-generated method stub
return false;
}
#Override
public boolean panStop(float x, float y, int pointer, int button)
{
// TODO Auto-generated method stub
return false;
}
#Override
public boolean pan(float x, float y, float deltaX, float deltaY)
{
// TODO Auto-generated method stub
return false;
}
#Override
public boolean longPress(float x, float y)
{
// TODO Auto-generated method stub
return false;
}
#Override
public boolean fling(float velocityX, float velocityY, int button)
{
// TODO Auto-generated method stub
return false;
}
};
GestureDetector detector=new GestureDetector(listener)
{
public boolean touchUp(float x, float y, int pointer, int button)
{
cam.unproject(touchPoint.set(x, y, 0));
System.out.println(touchPoint);
return false;
}
};
public TempScreen(Game game,SpriteBatch batcher)
{
super(game);
this.batcher=batcher;
this.game=game;
touchPoint = new Vector3();
cam = new OrthographicCamera(GameConstants.CAMERA_WIDTH,GameConstants.CAMERA_HEIGHT);
cam.position.set(GameConstants.CAMERA_WIDTH / 2,GameConstants.CAMERA_HEIGHT / 2, 0);
multiplexer = new InputMultiplexer();
multiplexer.addProcessor(game);
multiplexer.addProcessor(detector);
Gdx.input.setInputProcessor(multiplexer);
}
#Override
public void render(float deltaTime)
{
update(deltaTime);
GLCommon gl = Gdx.gl;
gl.glClearColor(0, 0f, 1f, 0.1f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
cam.update();
batcher.setProjectionMatrix(cam.combined);
batcher.enableBlending();
batcher.begin();
draw(deltaTime);
batcher.end();
}
#Override
public void draw(float deltaTime)
{
// TODO Auto-generated method stub
}
#Override
public void update(float deltaTime)
{
// TODO Auto-generated method stub
}
#Override
public void backKeyPressed()
{
// TODO Auto-generated method stub
}
}
Make an InputProcessor and a Vector3:
MyInputprocessor myInputprocessor;
Vector3 touchPoint = new Vector3();
Define the InputProcessor like this:
public class MyInputprocessor implements InputProcessor{
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button){
guicam.unproject(touchPoint.set(screenX, screenY, 0)); //Initial point coordinates
return false;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer){
guicam.unproject(touchPoint.set(screenX, screenY, 0)); //current point coordinates (when you are dragging it)
return false;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button){
guicam.unproject(touchPoint.set(screenX, screenY, 0)); //final/release point coordinates
return false;
}
#Override public boolean keyTyped(char character){return false;}
#Override public boolean mouseMoved(int screenX, int screenY){return false;}
#Override public boolean scrolled(int amount){return false;}
#Override public boolean keyDown(int keycode){return false;}
#Override public boolean keyUp(int keycode){return false;}
}
Create it and set it in your ini code:
myInputprocessor = new MyInputprocessor();
Gdx.input.setInputProcessor(myInputprocessor);