官网:https://github.com/libgdx/ashley
引入依赖:
allprojects {
apply plugin: "eclipse"
version = '1.0'
ext {
appName = "My GDX Game"
gdxVersion = '1.12.1'
roboVMVersion = '2.3.21'
box2DLightsVersion = '1.5'
ashleyVersion = '1.7.4'
aiVersion = '1.8.2'
gdxControllersVersion = '2.2.1'
}
repositories {
mavenLocal()
mavenCentral()
google()
gradlePluginPortal()
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
maven { url "https://oss.sonatype.org/content/repositories/releases/" }
maven { url "https://jitpack.io" }
}
}
dependencies {
implementation "com.badlogicgames.gdx:gdx:$gdxVersion"
implementation "com.badlogicgames.gdx:gdx-backend-lwjgl:$gdxVersion"
implementation "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
implementation "com.badlogicgames.ashley:ashley:$ashleyVersion"
testImplementation "junit:junit:4.12"
}
在这个ashley框架中,分为
Component
EntitySystem
PooledEngine
EntityListener
好理解吧。以下我用代码来演示
PooledEngine engine = new PooledEngine();
MovementSystem movementSystem = new MovementSystem();
PositionSystem positionSystem = new PositionSystem();
engine.addSystem(movementSystem);
engine.addSystem(positionSystem);
Listener listener = new Listener();
engine.addEntityListener(listener);
Entity entity = engine.createEntity();
entity.add(new PositionComponent(10, 0));
-
PooledEngine engine = new PooledEngine();
这行代码创建了一个PooledEngine
的实例。PooledEngine
是Engine
的一个子类,它可以重用实体和组件,从而减少内存分配和垃圾回收,提高性能。 -
MovementSystem movementSystem = new MovementSystem();
创建了一个MovementSystem
的实例,这是一个自定义的系统,用于处理实体的移动逻辑。 -
PositionSystem positionSystem = new PositionSystem();
创建了一个PositionSystem
的实例,这是另一个自定义的系统,用于处理实体的位置更新。 -
engine.addSystem(movementSystem);
engine.addSystem(positionSystem);
这两行代码将MovementSystem
和PositionSystem
添加到PooledEngine
中。这样,当引擎更新时,这些系统也会被更新。 -
Listener listener = new Listener();
创建了一个Listener
的实例,这是一个实体监听器,它会在实体被添加或移除时收到通知。 -
engine.addEntityListener(listener);
将Listener
添加到PooledEngine
中,使其成为实体事件的监听器。 -
Entity entity = engine.createEntity();
创建了一个新的Entity
实例。在Ashley中,实体是组件的容器,组件用于存储数据。 -
entity.add(new PositionComponent(10, 0));
向刚创建的实体添加了一个PositionComponent
实例,初始化位置为 (10, 0)。PositionComponent
是一个自定义的组件,用于存储实体的位置信息。
每个人物或者标签都可以称之为实体,比如说一个马里奥游戏,马里奥、乌龟和金币都可以被视为实体。每个实体都可以拥有一组组件,这些组件定义了实体的数据和状态。例如,马里奥可能有位置组件(PositionComponent)、移动组件(MovementComponent)和图形组件(GraphicsComponent)等。
这里的实体就是Entity entity = engine.createEntity(); 实体添加
组件就是entity.add(new PositionComponent(10, 0)); 而PositionSystem就是各个组件合在一起的逻辑原理
-
private ComponentMapper<PositionComponent> pm = ComponentMapper.getFor(PositionComponent.class);
这行代码创建了一个ComponentMapper
对象,专门用于PositionComponent
类型的组件。这意味着你可以通过这个映射器快速访问任何实体的PositionComponent
。 -
private ComponentMapper<MovementComponent> mm = ComponentMapper.getFor(MovementComponent.class);
类似地,这行代码创建了一个ComponentMapper
对象,专门用于MovementComponent
类型的组件。这使得你可以快速访问任何实体的MovementComponent
。
在MovementSystem里面的两行代码,将每个实体里面的MovementComponent和PositionComponent组件都进行移动。这样的例子在
我的libgdx学习代码的
里面的RenderSystemTest文件,运行起来会让一百个硬币移动
@Override
public void update (float deltaTime) {
for (int i = 0; i < entities.size(); ++i) {
Entity e = entities.get(i);
PositionComponent p = pm.get(e);
MovementComponent m = mm.get(e);
p.x += m.velocityX * deltaTime;
p.y += m.velocityY * deltaTime;
}
log(entities.size() + " Entities updated in MovementSystem.");
}
演示一个简单案例吧
MovementComponent
package com.badlogic.ashley.tests.components;
import com.badlogic.ashley.core.Component;
public class MovementComponent implements Component {
public float velocityX;
public float velocityY;
public MovementComponent (float velocityX, float velocityY) {
this.velocityX = velocityX;
this.velocityY = velocityY;
}
}
PositionComponent
package com.badlogic.ashley.tests.components;
import com.badlogic.ashley.core.Component;
public class PositionComponent implements Component {
public float x, y;
public PositionComponent (float x, float y) {
this.x = x;
this.y = y;
}
}
MovementSystem
public static class MovementSystem extends EntitySystem {
public ImmutableArray<Entity> entities;
private ComponentMapper<PositionComponent> pm = ComponentMapper.getFor(PositionComponent.class);
private ComponentMapper<MovementComponent> mm = ComponentMapper.getFor(MovementComponent.class);
@Override
public void addedToEngine (Engine engine) {
entities = engine.getEntitiesFor(Family.all(PositionComponent.class, MovementComponent.class).get());
log("MovementSystem added to engine.");
}
@Override
public void removedFromEngine (Engine engine) {
log("MovementSystem removed from engine.");
entities = null;
}
@Override
public void update (float deltaTime) {
for (int i = 0; i < entities.size(); ++i) {
Entity e = entities.get(i);
PositionComponent p = pm.get(e);
MovementComponent m = mm.get(e);
p.x += m.velocityX * deltaTime;
p.y += m.velocityY * deltaTime;
}
log(entities.size() + " Entities updated in MovementSystem.");
}
}
PositionSystem
public static class PositionSystem extends EntitySystem {
public ImmutableArray<Entity> entities;
@Override
public void addedToEngine (Engine engine) {
entities = engine.getEntitiesFor(Family.all(PositionComponent.class).get());
log("PositionSystem added to engine.");
}
@Override
public void removedFromEngine (Engine engine) {
log("PositionSystem removed from engine.");
entities = null;
}
}
Listener
public static class Listener implements EntityListener {
@Override
public void entityAdded (Entity entity) {
log("Entity added " + entity);
}
@Override
public void entityRemoved (Entity entity) {
log("Entity removed " + entity);
}
}
public static void log (String string) {
System.out.println(string);
}
主类:
public static void main (String[] args) {
PooledEngine engine = new PooledEngine();
MovementSystem movementSystem = new MovementSystem();
PositionSystem positionSystem = new PositionSystem();
engine.addSystem(movementSystem);
engine.addSystem(positionSystem);
Listener listener = new Listener();
engine.addEntityListener(listener);
for (int i = 0; i < 10; i++) {
Entity entity = engine.createEntity();
entity.add(new PositionComponent(10, 0));
if (i > 5) entity.add(new MovementComponent(10, 2));
engine.addEntity(entity);
}
log("MovementSystem has: " + movementSystem.entities.size() + " entities.");
log("PositionSystem has: " + positionSystem.entities.size() + " entities.");
for (int i = 0; i < 10; i++) {
engine.update(0.25f);
if (i > 5) engine.removeSystem(movementSystem);
}
engine.removeEntityListener(listener);
}
具体代码可以看: