Ashley使用实例

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载自夜明的孤行灯

本文链接地址: https://www.huangyunkun.com/2014/08/20/ashley-superjumper-for-libgdx/

上一篇文章提到了Ashley,但是没给出具体的例子,加之wiki资料不全,可能使用上有些困难。

superjumper是Libgdx的一个demo,siondream使用Ashley改造了整个项目,特别适合学习入门。

地址是:https://github.com/siondream/ashley-superjumper

组件

components是entity system的主要构成,这里就成为组件吧。

组件只包含具体的值,比如宽度,高度,状态等等。

比如我们的主角Bob

publicclass BobComponent extends Component {
publicstaticfinalint STATE_JUMP =0;
publicstaticfinalint STATE_FALL =1;
publicstaticfinalint STATE_HIT =2;
publicstaticfinalfloat JUMP_VELOCITY =11;
publicstaticfinalfloat MOVE_VELOCITY =20;
publicstaticfinalfloat WIDTH =0.8f;
publicstaticfinalfloat HEIGHT =0.8f;

publicfloat heightSoFar =0.0f;
}

而对于金币Coin

publicclass CoinComponent extends Component {
publicstaticfinalfloat WIDTH =0.5f;
publicstaticfinalfloat HEIGHT =0.8f;
publicstaticfinalint SCORE =10;

publicstaticfinalint STATE_NORMAL =1;
}

对于整个游戏的状态,比如时间、分数等等

publicclass StateComponent extends Component {
privateint state =0;
publicfloat time =0.0f;

publicintget() {
return state;
}

publicvoidset(int newState) {
state = newState;
time =0.0f;
}
}

这些都是游戏中需要用到的Value Object,但是对于游戏常有的一些组件也需要处理,比如Camera和Texture

publicclass TextureComponent extends Component {
public TextureRegion region =null;
}
publicclass CameraComponent extends Component {
public Entity target;
public OrthographicCamera camera;
}

系统

System是整体的逻辑所在,但是System和Component不是一一对应的。

以人物的移动为例,这个MovementSystem需要MovementComponent和TransformComponent。

MovementSystem需要处理的就是人物的移动,读取当前的移动方向,然后改变坐标.

MovementSystem继承Ashley的IteratingSystem类。

publicclass MovementSystem extends IteratingSystem {
private Vector2 tmp =new Vector2();
privateboolean pause =false;

publicMovementSystem() {
super(Family.getFamilyFor(TransformComponent.class, MovementComponent.class));
}

@Override
publicvoidprocessEntity(Entity entity,float deltaTime) {
TransformComponent pos = entity.getComponent(TransformComponent.class);
MovementComponent mov = entity.getComponent(MovementComponent.class);

tmp.set(mov.accel).scl(deltaTime);
mov.velocity.add(tmp);

tmp.set(mov.velocity).scl(deltaTime);
pos.pos.add(tmp.x, tmp.y,0.0f);
}

@Override
publicbooleancheckProcessing() {
return !pause;
}

publicvoidpause(boolean pause) {
this.pause = pause;
}
}

再看看StateSystem,对于SuperJumper而言,主要就是记录时间,所以相对简单。同样继承于Ashley之中的IteratingSystem类。

publicclass StateSystem extends IteratingSystem {
privateboolean pause =false;

publicStateSystem() {
super(Family.getFamilyFor(StateComponent.class));
}

@Override
publicvoidprocessEntity(Entity entity,float deltaTime) {
entity.getComponent(StateComponent.class).time += deltaTime;
}

@Override
publicbooleancheckProcessing() {
return !pause;
}

publicvoidpause(boolean pause) {
this.pause = pause;
}
}

使用

Ashley的使用主要就是声明所需的System,然后把所有组件都加入Engine就可以了。

world =new World(engine);

engine.addSystem(new BobSystem(world));
engine.addSystem(new SquirrelSystem());
engine.addSystem(new PlatformSystem());
engine.addSystem(new CameraSystem());
engine.addSystem(new BackgroundSystem());
engine.addSystem(new GravitySystem());
engine.addSystem(new MovementSystem());
engine.addSystem(new BoundsSystem());
engine.addSystem(new StateSystem());
engine.addSystem(new AnimationSystem());
engine.addSystem(new CollisionSystem(world, collisionListener));
engine.addSystem(new RenderingSystem(game.batcher));
engine.addSystem(new RemovalSystem());

engine.getSystem(BackgroundSystem.class).setCamera(engine.getSystem(RenderingSystem.class).getCamera());

world.create();

在update中直接调用engine.update(deltaTime);即可。

Ashley内置的系统

Ashley目前只内置了一种系统,即IteratingSystem。

它对于每一个实体都调用processEntity()来处理。

如果有其他需要可以通过继承EntitySystem类来自己扩展。

参考资料

Ashley文档

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载自夜明的孤行灯

本文链接地址: https://www.huangyunkun.com/2014/08/20/ashley-superjumper-for-libgdx/

发表评论