LibGdx学习过程(六)事件监听
事件监听
之前有对于HTML了解过的同学对于监听应该不会陌生。
在之前的一系列学习下我们在界面内创建了screen,stage,group,actor等界面组成元素,那我们在初始化了这些配置之后如何根据元素的变化进行相应的处理呢?
这个时候我们需要用到事件监听。
事件有很多,包括鼠标点击事件,键盘事件,屏幕触摸事件等等。我们需要给每个元素的我们想要观测并反应的一些事件加载一个监听,当该元素发生了预期中的事件的时候我们执行我们需要的逻辑变换。
事件监听几乎可以加载在你想加载的任意一个元素上,但是每一种元素的监听加载方式略有不同。
@Override
public boolean addListener(EventListener listener) {
return super.addListener(listener);
}
我们可以在一个stage里面直接重写一个addListener函数,也可以直接使用封装好的键盘事件或者鼠标事件,stage里面很细致的帮我们划分了包括键盘按下事件,鼠标点击事件,鼠标移动事件等等具体的事件情况。
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
return super.touchDown(screenX, screenY, pointer, button);
}
@Override
public boolean mouseMoved(int screenX, int screenY) {
return super.mouseMoved(screenX, screenY);
}
而在actor中我们可以使用另一种方式来创建事件监听
Actor actor;
actor = new Actor();
actor.addListener(new ClickListener(){
@Override
public void clicked(InputEvent event, float x, float y) {
super.clicked(event, x, y);
}
});
在父容器中创建一个actor,直接在actor上添加一个事件监听,具体添加一个什么样的监听可以自由发挥,代码中以鼠标点击事件为例。
libgdx中还提供了其他一些事件监听的使用方式,还需慢慢探索。
碰撞检测
说过了事件监听我们就不可避免联想到一个问题,输入性的事件可以通过如上的方式进行监听,那么图形界面中本身发生的变化需要怎样处理呢?
比方说我们写一个马里奥的小游戏,那么怎么判断人物,子弹和怪兽之间的碰撞呢?
libgdx给我们提供了一个包装类Rectangle(矩形),我们只需要把所需要的图形的位置和大小传进去他就可以帮助我们判断两个图形的相对位置关系。
public class MainGame extends ApplicationAdapter {
public static final float WORLD_WIDTH = 480;
public static final float WORLD_HEIGHT = 800;
private Stage stage;
private Texture badlogicTexture;
private Texture logoTexture;
private Image badlogicActor;
private Image logoActor;
// actor的包围矩形
private final Rectangle badlogicRect = new Rectangle();
private final Rectangle logoRect = new Rectangle();
@Override
public void create() {
stage = new Stage(new StretchViewport(WORLD_WIDTH, WORLD_HEIGHT));
badlogicTexture = new Texture(Gdx.files.internal("badlogic.jpg"));
logoTexture = new Texture(Gdx.files.internal("logo.png"));
badlogicActor = new Image(badlogicTexture);
logoActor = new Image(logoTexture);
badlogicActor.setPosition(
stage.getWidth() / 2 - badlogicActor.getWidth() / 2,
stage.getHeight() / 2 - badlogicActor.getHeight() / 2
);
logoActor.setPosition(0, 0);
stage.addActor(badlogicActor);
stage.addActor(logoActor);
MoveToAction action = Actions.moveTo(150, 700, 5.0F);
logoActor.addAction(action);
}
@Override
public void render() {
// 白色清屏
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act();
checkCollision();
stage.draw();
}
/**
* 碰撞检测
*/
private void checkCollision() {
/*
* 获取演员的包围矩形
*/
badlogicRect.set(
badlogicActor.getX(),
badlogicActor.getY(),
badlogicActor.getWidth(),
badlogicActor.getHeight()
);
logoRect.set(
logoActor.getX(),
logoActor.getY(),
logoActor.getWidth(),
logoActor.getHeight()
);
// 判断两个演员是否碰撞, 如果碰撞, 则将 badlogicActor 设置为半透明
if (badlogicRect.overlaps(logoRect)) {
badlogicActor.getColor().a = 0.5F;
} else {
badlogicActor.getColor().a = 1.0F;
}
}
@Override
public void dispose() {
// 当应用退出时释放资源
if (stage != null) {
stage.dispose();
}
if (badlogicTexture != null) {
badlogicTexture.dispose();
}
if (logoTexture != null) {
logoTexture.dispose();
}
}
}
这次上一个长代码,我们创建两个Image,为其中一个Image添加一个moveto的action,在这个过程中它会途经另一个Image。
当两个Image发生碰撞的期间,固定的Image将被设置为半透明。
让我们看下效果,录制不易我们图片展示
开始执行,动图在左下角,截慢了一点
发生碰撞,笑脸变成了半透明。
碰撞结束,恢复原本的透明度。
这里我们使用的是overlaps方法来判断碰撞,Rectangle中还有contains/merge等其他的事件判断,自己去探索吧。