问题描述
我想制作我自己的 Button 类,它会有一个 Sprite,当我触摸它时它会增长或旋转等,该类还将具有 Draw 和 Update 功能.
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.
要检查我是否触摸它,我可以检查精灵矩形是否包含屏幕类的 touchdown 和 touchup 方法中的触摸位置.
To check if I touch it i can check if the sprite rectangle contains the position of the touch in the touchdown and touchup method of the screen class.
我不想那样做,我想做类似android按钮点击监听器的东西,这可能吗?
I don't want to do that, i want to make something like android button click listener, is that possible?
类似
myCoolButton.setOnClickListener(new CoolButtonClassClickListener(
public void OnTouchDown() {
}
public void OnTouchUp() {
}
});
有可能吗?
推荐答案
当然可以,我也是这么做的.
Of course you can, that's exactly what I did too.
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 确实并不难.之后,你可以只用 contains 询问点击是否包含,如果是,则从外部调用 execute().
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.
像这样创建:
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 类将事件委托给按钮(如果它们被单击):
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;
}
...
你是这样扩展的:
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);
....
这篇关于LibGDX - 自定义点击监听器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!