当前位置: 首页 > 面试题库 >

LibGDX-自定义点击监听器?

焦苏燕
2023-03-14
问题内容

我想创建自己的Button类,该类将具有Sprite,并且每当我触摸它时,它将成长或旋转,等等,该类还将具有Draw和Update函数。

要检查我是否触摸它,我可以检查子画面矩形是否包含屏幕类的touchdown和touchup方法中触摸的位置。

我不想这样做,我想做一些类似android button click listener的事情,这可能吗?

就像是

myCoolButton.setOnClickListener(new CoolButtonClassClickListener(

public void OnTouchDown()  {

}

public void OnTouchUp()   {
}
});

有可能吗


问题答案:

当然可以,那正是我所做的。

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

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);
    }
}

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;
    }
}

尽管从技术上讲,这使用Rectangle并使用ShapeRenderer进行渲染,但将它换成Sprite确实不难。之后,您可以仅询问with包含单击是否包含单击,然后从外部调用execute()。

像这样创建:

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

并处理如下事件:

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

这使用我的AbstractMenuScreen类将事件委托给按钮(如果被单击):

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;
    }
    ...

您可以像这样扩展:

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);
 ....


 类似资料:
  • 问题内容: 我想知道是否有人可以帮助我理解如何准确地创建不同的自定义事件侦听器。 我没有事件的具体案例,但我想大致了解它是如何完成的,因此可以将其应用于需要的地方。 我想做的是,以防万一有些人可能需要知道的是: 问题答案: var evt = document.createEvent(“Event”); evt.initEvent(“myEvent”,true,true);

  • 问题内容: 假设我想为自己的班级创建自己的事件监听器,该怎么做?我需要手动维护线程吗? 问题答案: 创建一个将由您的活动实现的接口: 现在,您需要知道事件实际发生的时间。例如,当用户触摸屏幕上的一个点时,重写onTouchEvent方法: 同样,您可以创建所需的特定事件。(示例可能是按下,等待2秒钟然后松开-您需要在touch事件中执行一些逻辑操作)。 在您的活动中,可以使用customView对

  • 2.url点击事件的监听 url点击事件的监听是指将访客和客服发送在聊窗中的链接ur的点击事件暴漏出来,用户可以自定义url打开方式(默认使用SDK内置Webview加载)。监听接口为OnUrlClickListener; 注册监听方法: Ntalker.getInstance().setOnUrlClickListener(OnUrlClickListener onMsgClickListene

  • 本文向大家介绍Spring 实现自定义监听器案例,包括了Spring 实现自定义监听器案例的使用技巧和注意事项,需要的朋友参考一下 应用场景: 在一般的javaWeb项目中经常有一些缓存是需要再项目启动的时候加载到内存中,这样就可以使用自定义的监听器来实现。 1、在web.xml中声明 2、创建类OmsConfigLoader 实现接口 ServletContextListener,项目启动的时候

  • 2.返回按钮的点击监听 在聊窗顶部有一个返回按钮,在返回时可以添加其他事件,使用的接口如下: Ntalker.getInstance().setOnBackBtnListener(new OnBackBtnClickListener() { @Override public void OnBackBtnClick() { Toast.make

  • 当事情发生在课堂上时,事件会被触发。 例如,在单击按钮时或在呈现元素之前/之后。 写事件的方法 使用侦听器的内置事件 Attaching events later 自定义活动 使用监听器的内置事件 Ext JS提供了侦听器属性,用于在Ext JS文件中编写事件和自定义事件。 Writing listener in Ext JS 我们将通过向面板添加listen属性来在前一个程序中添加监听器。 <!