LibGDX - Custom Click Listener?

前端 未结 2 2062
旧时难觅i
旧时难觅i 2021-01-07 01:07

I want to make my own Button class, that will have a Sprite, and whenever i touch it it will grow or rotate, etc, the class will have also a Draw and Update function.

<
相关标签:
2条回答
  • 2021-01-07 01:44
    buttonUp = new TextButton("", styleUpButton); //** Button text and style **//
       buttonUp.setPosition(84, 40);
       buttonUp.setHeight(64); 
       buttonUp.setWidth(64); 
       buttonUp.addListener(new InputListener() {
       public boolean touchDown (InputEvent event, float x, float y, int pointer, int button)   {
    HereYouHaveToCallMethodYouNeed();
       return true;
    }
       public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
    //  Here may be onemore method.
       }
    });
    
    0 讨论(0)
  • 2021-01-07 01:56

    Of course you can, that's exactly what I did too.

    public interface FFListener
    {
        public void onClick(FFListenerButton flb);
    }
    

    And

    public class FFListenerButton extends FFButton
    {
        private FFListener ffListener;
    
        public FFListenerButton(Rectangle bounds, CharSequence text, FFListener ffListener)
        {
            super(bounds, text);
            this.ffListener = ffListener;
        }
    
        @Override
        protected void action()
        {
            ffListener.onClick(this);
        }
    }
    

    And

    public abstract class FFButton 
    {
        private Rectangle bounds;
        private CharSequence text;
        private boolean selected;
        private boolean hidden;
        private boolean active;
        private boolean disabled;
    
        public FFButton(Rectangle bounds, CharSequence text)
        {
            this.bounds = bounds;
            this.text = text;
            this.hidden = false;
            this.active = false;
            this.disabled = false;
        }
    
        protected abstract void action();
    
        public void execute()
        {
            if(disabled == false)
            {
                action();
            }
        }
    
    
        public boolean contains(float x, float y)
        {
            return bounds.contains(x, y);
        }
    
        public float x()
        {
            return bounds.x;
        }
    
        public float y()
        {
            return bounds.y;
        }
    
        public float width()
        {
            return bounds.width;
        }
    
        public float height()
        {
            return bounds.height;
        }
    
        public void drawBounds(ShapeRenderer shapeRenderer)
        {
            if(hidden != true)
            {
            shapeRenderer.rect(x(), y(), width(), height(), 0, 0, 0);
            }
        }
    
        public CharSequence getText()
        {
            return text;
        }
    
        public FFButton setText(String text)
        {
            this.text = text;
            return this;
        }
    
        public void drawText(SpriteBatch batch)
        {
            if(hidden != true)
            {
                Resources.bitmapFont.draw(batch, getText(), x()+(width()/8), y()+height()*0.75f); //black magic, please adjust
            }
        }
    
        public boolean getSelected()
        {
            return selected;
        }
    
        public FFButton setSelected(boolean selected)
        {
            this.selected = selected;
            return this;
        }
    
        public boolean isActive()
        {
            return active;
        }
    
        public FFButton setActive(boolean active)
        { 
            this.active = active;
            return this;
        }
    
        public boolean isHidden()
        {
            return hidden;
        }
    
        public FFButton setHidden(boolean hidden)
        {
            this.hidden = hidden;
            return this;
        }
    
        public Rectangle getBounds()
        {
            return bounds;
        }
    
        public boolean isDisabled()
        {
            return disabled;
        }
    
        public void setDisabled(boolean disabled)
        {
            this.disabled = disabled;
        }
    }
    

    Although technically this uses a Rectangle and uses ShapeRenderer to render it, it really isn't hard to swap it out for a Sprite. Afterwards, you can just ask with contains whether the click is contains, and call execute() from the outside if it does.

    Create like this:

    backButton = new FFListenerButton(new Rectangle(400, 20, 60, 30), "Back", this);
    

    And handle events like this:

    @Override
    public void onClick(FFListenerButton clb)
    {
        if(clb == backButton)
        {
            backButtonPressed();
        }
        else if(clb == selectButton)
        {
            ...
        }
    }
    

    And this used my AbstractMenuScreen class to delegate the events to the buttons if they were clicked:

    public abstract class AbstractMenuScreen extends BaseScreen
    {
        protected List<FFButton> buttons;
    
        public AbstractMenuScreen(List<FFButton> buttons)
        {
            this.buttons = buttons; 
        }
    
        @Override
        public void render(float delta)
        {
            Gdx.gl.glClearColor(0, 0, 0, 1);
            Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    
            Resources.batch.setProjectionMatrix(Resources.normalProjection);
    
            Resources.batch.begin();
            for(int i = 0; i < buttons.size(); i++)
            {
                FFButton b = buttons.get(i);
                if(b.isHidden() != true)
                {
                    b.drawText(Resources.batch);
                }
            }
    
            Resources.batch.end();
    
            Resources.shapeRenderer.setColor(Color.WHITE);
            Resources.shapeRenderer.begin(ShapeType.Line);
            for(int i = 0; i < buttons.size(); i++)
            {
                FFButton b = buttons.get(i);
                if(b.isHidden() != true)
                {
                    b.drawBounds(Resources.shapeRenderer);
                }
            }
            Resources.shapeRenderer.end();
    
            Resources.shapeRenderer.setColor(Color.RED);
            Resources.shapeRenderer.begin(ShapeType.Line);
            for(int i = 0; i < buttons.size(); i++)
            {
                FFButton b = buttons.get(i);
                if(b.isHidden() != true)
                {
                    if(b.isActive() == true)
                    {
                        b.drawBounds(Resources.shapeRenderer);
                    }
                }
            }
            Resources.shapeRenderer.end();
    
            Resources.shapeRenderer.setColor(Color.MAGENTA);
            Resources.shapeRenderer.begin(ShapeType.Line);
            for(int i = 0; i < buttons.size(); i++)
            {
                FFButton b = buttons.get(i);
                if(b.isHidden() != true)
                {
                    if(b.getSelected() == true)
                    {
                        b.drawBounds(Resources.shapeRenderer);
                    }
                }
            }
            Resources.shapeRenderer.end();
        }
    
        @Override
        public void show()
        {
            Gdx.input.setInputProcessor(this);
        }
    
        @Override
        public boolean touchDown(int screenX, int screenY, int pointer, int button)
        {
            float pointerX = InputTransform.getCursorToModelX(windowWidth, screenX);
            float pointerY = InputTransform.getCursorToModelY(windowHeight, screenY);
            for(int i = 0; i < buttons.size(); i++)
            {
                if(buttons.get(i).contains(pointerX, pointerY))
                {
                    if(buttons.get(i).isHidden() != true)
                    {
                        buttons.get(i).setSelected(true);
                    }
                }
            }
            return true;
        }
    
        @Override
        public boolean touchUp(int screenX, int screenY, int pointer, int button)
        {
            float pointerX = InputTransform.getCursorToModelX(windowWidth, screenX);
            float pointerY = InputTransform.getCursorToModelY(windowHeight, screenY);
            for(int i = 0; i < buttons.size(); i++)
            {
                if(buttons.get(i).contains(pointerX, pointerY) && buttons.get(i).getSelected())
                {
                    buttons.get(i).execute();
                }
                buttons.get(i).setSelected(false);
            }
            return true;
        }
        ...
    

    And you extended from this like this:

    public class ServerClientPickScreen extends AbstractMenuScreen implements FFListener
    {
        private FFButton backButton;
        private FFButton clientButton;
        private FFButton serverButton;
    
        public ServerClientPickScreen()
        {
            super(new ArrayList<FFButton>());
            backButton = new FFListenerButton(new Rectangle(400, 20, 60, 30), "Back", this);
            clientButton = new FFListenerButton(new Rectangle(260, 140, 80, 30), "Client", this);
            serverButton = new FFListenerButton(new Rectangle(140, 140, 80, 30), "Server", this);
            buttons.add(backButton);
            buttons.add(clientButton);
            buttons.add(serverButton);
     ....
    
    0 讨论(0)
提交回复
热议问题