简体   繁体   中英

libgdx making a touch event

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM