其实自定义button很简单,AndEngine不是开源的吗? 对,既然是开源的,当然看源码才是王道,理解了作者的实现原理,写自己的自然就容易多了。
我属于比较菜,又兼比较懒得类型,所以就直接打开源码copy了,下面是直接贴出的源码。
public class ButtonSprite extends TiledSprite {
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Fields
// ===========================================================
private final int mStateCount;
private OnClickListener mOnClickListener;
private boolean mEnabled = true;
private State mState;
// ===========================================================
// Constructors
// ===========================================================
public ButtonSprite(final float pX, final float pY, final ITextureRegion pNormalTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager) {
this(pX, pY, pNormalTextureRegion, pVertexBufferObjectManager, (OnClickListener) null);
}
public ButtonSprite(final float pX, final float pY, final ITextureRegion pNormalTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager, final OnClickListener pOnClickListener) {
this(pX, pY, new TiledTextureRegion(pNormalTextureRegion.getTexture(), pNormalTextureRegion), pVertexBufferObjectManager, pOnClickListener);
}
public ButtonSprite(final float pX, final float pY, final ITextureRegion pNormalTextureRegion, final ITextureRegion pPressedTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager) {
this(pX, pY, pNormalTextureRegion, pPressedTextureRegion, pVertexBufferObjectManager, (OnClickListener) null);
}
public ButtonSprite(final float pX, final float pY, final ITextureRegion pNormalTextureRegion, final ITextureRegion pPressedTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager, final OnClickListener pOnClickListener) {
this(pX, pY, new TiledTextureRegion(pNormalTextureRegion.getTexture(), pNormalTextureRegion, pPressedTextureRegion), pVertexBufferObjectManager, pOnClickListener);
}
public ButtonSprite(final float pX, final float pY, final ITextureRegion pNormalTextureRegion, final ITextureRegion pPressedTextureRegion, final ITextureRegion pDisabledTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager) {
this(pX, pY, pNormalTextureRegion, pPressedTextureRegion, pDisabledTextureRegion, pVertexBufferObjectManager, (OnClickListener) null);
}
public ButtonSprite(final float pX, final float pY, final ITextureRegion pNormalTextureRegion, final ITextureRegion pPressedTextureRegion, final ITextureRegion pDisabledTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager, final OnClickListener pOnClickListener) {
this(pX, pY, new TiledTextureRegion(pNormalTextureRegion.getTexture(), pNormalTextureRegion, pPressedTextureRegion, pDisabledTextureRegion), pVertexBufferObjectManager, pOnClickListener);
}
public ButtonSprite(final float pX, final float pY, final ITiledTextureRegion pTiledTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager) {
this(pX, pY, pTiledTextureRegion, pVertexBufferObjectManager, (OnClickListener) null);
}
public ButtonSprite(final float pX, final float pY, final ITiledTextureRegion pTiledTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager, final OnClickListener pOnClickListener) {
super(pX, pY, pTiledTextureRegion, pVertexBufferObjectManager);
this.mOnClickListener = pOnClickListener;
this.mStateCount = pTiledTextureRegion.getTileCount();
switch(this.mStateCount) {
case 1:
Debug.w("No " + ITextureRegion.class.getSimpleName() + " supplied for " + State.class.getSimpleName() + "." + State.PRESSED + ".");
case 2:
Debug.w("No " + ITextureRegion.class.getSimpleName() + " supplied for " + State.class.getSimpleName() + "." + State.DISABLED + ".");
break;
case 3:
break;
default:
throw new IllegalArgumentException("The supplied " + ITiledTextureRegion.class.getSimpleName() + " has an unexpected amount of states: '" + this.mStateCount + "'.");
}
this.changeState(State.NORMAL);
}
// ===========================================================
// Getter & Setter
// ===========================================================
public boolean isEnabled() {
return this.mEnabled;
}
public void setEnabled(final boolean pEnabled) {
this.mEnabled = pEnabled;
if(this.mEnabled && this.mState == State.DISABLED) {
this.changeState(State.NORMAL);
} else if(!this.mEnabled) {
this.changeState(State.DISABLED);
}
}
public boolean isPressed() {
return this.mState == State.PRESSED;
}
public State getState() {
return this.mState;
}
public void setOnClickListener(final OnClickListener pOnClickListener) {
this.mOnClickListener = pOnClickListener;
}
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
@Override
public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
if(!this.isEnabled()) {
this.changeState(State.DISABLED);
} else if(pSceneTouchEvent.isActionDown()) {
this.changeState(State.PRESSED);
} else if(pSceneTouchEvent.isActionCancel() || !this.contains(pSceneTouchEvent.getX(), pSceneTouchEvent.getY())) {
this.changeState(State.NORMAL);
} else if(pSceneTouchEvent.isActionUp() && this.mState == State.PRESSED) {
this.changeState(State.NORMAL);
if(this.mOnClickListener != null) {
this.mOnClickListener.onClick(this, pTouchAreaLocalX, pTouchAreaLocalY);
}
}
return true;
}
@Override
public boolean contains(final float pX, final float pY) {
if(!this.isVisible()) {
return false;
} else {
return super.contains(pX, pY);
}
}
// ===========================================================
// Methods
// ===========================================================
private void changeState(final State pState) {
if(pState == this.mState) {
return;
}
this.mState = pState;
final int stateTiledTextureRegionIndex = this.mState.getTiledTextureRegionIndex();
if(stateTiledTextureRegionIndex >= this.mStateCount) {
this.setCurrentTileIndex(0);
Debug.w(this.getClass().getSimpleName() + " changed its " + State.class.getSimpleName() + " to " + pState.toString() + ", which doesn't have a " + ITextureRegion.class.getSimpleName() + " supplied. Applying default " + ITextureRegion.class.getSimpleName() + ".");
} else {
this.setCurrentTileIndex(stateTiledTextureRegionIndex);
}
}
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
public interface OnClickListener {
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Methods
// ===========================================================
public void onClick(final ButtonSprite pButtonSprite, final float pTouchAreaLocalX, final float pTouchAreaLocalY);
}
public static enum State {
// ===========================================================
// Elements
// ===========================================================
NORMAL(0),
PRESSED(1),
DISABLED(2);
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Fields
// ===========================================================
private final int mTiledTextureRegionIndex;
// ===========================================================
// Constructors
// ===========================================================
private State(final int pTiledTextureRegionIndex) {
this.mTiledTextureRegionIndex = pTiledTextureRegionIndex;
}
// ===========================================================
// Getter & Setter
// ===========================================================
public int getTiledTextureRegionIndex() {
return this.mTiledTextureRegionIndex;
}
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
// ===========================================================
// Methods
// ===========================================================
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}
}
看看源码,其实按钮就是精灵而已,自定义button很容易,只需要按照源码中的touch的监听方式,复制一遍,改一点就好了。这里写一个我感觉最实用的透明按钮。当然不能和源码一样继承TiledSprite。这里我选择了继承Rectangle,下面上代码:
public class RectButton extends Rectangle{
private OnRectClickListener mOnClickListener;
private boolean mEnabled = true;
private State mState;
public RectButton(float pX, float pY,float width,float height,
VertexBufferObjectManager pVertexBufferObjectManager) {
super(pX, pY, width, height, pVertexBufferObjectManager);
this.setAlpha(0);
}
public boolean isEnabled() {
return this.mEnabled;
}
public void setEnabled(final boolean pEnabled) {
this.mEnabled = pEnabled;
if(this.mEnabled && this.mState == State.DISABLED) {
this.changeState(State.NORMAL);
} else if(!this.mEnabled) {
this.changeState(State.DISABLED);
}
}
public boolean isPressed() {
return this.mState == State.PRESSED;
}
public State getState() {
return this.mState;
}
public void setOnRectClickListener(final OnRectClickListener pOnClickListener) {
this.mOnClickListener = pOnClickListener;
}
@Override
public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
if(!this.isEnabled()) {
this.changeState(State.DISABLED);
} else if(pSceneTouchEvent.isActionDown()) {
this.changeState(State.PRESSED);
} else if(pSceneTouchEvent.isActionCancel() || !this.contains(pSceneTouchEvent.getX(), pSceneTouchEvent.getY())) {
this.changeState(State.NORMAL);
} else if(pSceneTouchEvent.isActionUp() && this.mState == State.PRESSED) {
this.changeState(State.NORMAL);
if(this.mOnClickListener != null) {
this.mOnClickListener.onClick(this, pTouchAreaLocalX, pTouchAreaLocalY);
}
}
return true;
}
@Override
public boolean contains(final float pX, final float pY) {
if(!this.isVisible()) {
return false;
} else {
return super.contains(pX, pY);
}
}
private void changeState(final State pState) {
if(pState == this.mState) {
return;
}
this.mState = pState;
if(this.mState == State.NORMAL){
}else if(this.mState == State.PRESSED){
}else if(this.mState == State.DISABLED){
}
}
public interface OnRectClickListener {
public void onClick(final RectButton pRectButton, final float pTouchAreaLocalX, final float pTouchAreaLocalY);
}
public static enum State {
NORMAL(0),
PRESSED(1),
DISABLED(2);
private final int mTiledTextureRegionIndex;
private State(final int pTiledTextureRegionIndex) {
this.mTiledTextureRegionIndex = pTiledTextureRegionIndex;
}
public int getTiledTextureRegionIndex() {
return this.mTiledTextureRegionIndex;
}
}
}
用法和ButtonSprite一样,当然还可以添加个文字什么的变成文字按钮,添加个图片什么的就是图片按钮了。文笔不好,只能纯贴代码了。恩,就这样了。