수색…


비고

Ashley Entity SystemLibGDX 조직 하에 관리되며 게임 개발에 적합하고 적합한 엔티티 시스템 라이브러리입니다. LibGDX 유틸리티 클래스에 의존하지만 LibGDX 기반이 아닌 다른 Java 게임 프레임 워크와 함께 사용할 수 있습니다.

엔티티 시스템은 상속으로 객체 클래스를 풍부하게 만들지 않고도 많은 객체 세트를 대상으로 데이터와 기능을 관리하는 다른 방법을 제공합니다.

Ashley를 활용하면 Unity가 제공하는 것과 같은 객체 모델링 접근법을 찾는 사람들에게 유용한 접근 방식이 될 수 있지만 게임 엔진 대신 프레임 워크의 범위가 유용 할 것입니다.

구성 요소 만들기

구성 요소는 Ashley 구성 요소 클래스를 구현하는 단순한 인스턴스입니다.

import com.badlogic.ashley.core.Component;
import com.badlogic.ashley.core.ComponentMapper;

public class Position implements Component {
    public static final ComponentMapper<Position> Map = 
                                 ComponentMapper.getFor(Position.class);

    public float x = 0f, 
                 y = 0f;
}

구성 요소 맵은 엔티티의 구성 요소에 빠르게 액세스 할 수있는 방법을 제공합니다. 구성 요소 맵을 관리하는 두 가지 일반적인 방법은 구성 요소 클래스 내에 정적 인스턴스를 유지하거나 모든 구성 요소에 대한 모든 매퍼가 포함 된 클래스 / 열거 형을 유지하는 것입니다.

응용 프로그램에서 구성 요소 유형에 대한 매퍼를 두 번 이상 선언 할 필요가 없습니다.

엔티티 시스템 만들기

엔티티 시스템은 엔티티 집합에서 기능적 연산을 수행하는 방법입니다. 구성 요소에는 엔티티 시스템의 작업과 같이 일반적으로 데이터 또는 다른 구성 요소 인스턴스의 상태를 인식하는 논리가 연결되어 있지 않아야합니다. 엔티티 시스템은 한 번에 둘 이상의 엔진에 등록 될 수 없습니다.

엔티티 시스템은 둘 이상의 유형의 기능을 수행하면 안됩니다. MovementSystem은 위치 지정 등을 처리해야하는 반면 RenderSystem과 같은 엔티티 도면은 처리해야합니다.

import com.badlogic.ashley.core.Entity;
import com.badlogic.ashley.core.EntitySystem;
import com.badlogic.ashley.core.Family;

public class MovementSystem extends EntitySystem {
    //the type of components necessary for entities to have to be operated on
    private static final Family FAMILY = Family.all(Position.class).get();

    public MovementSystem () {
        super();
    }

    /**
     * The update method called every tick.
     * @param deltaTime The time passed since last frame in seconds.
     */
    public void update (float deltaTime) {
        for (Entity e : this.getEngine().getEntitiesFor(FAMILY)) {
            Position pos = Position.Map.get(e);
            
            // do entity movement logic on component
            ...
        }
    }

때로는 EntityListener에서 찾은 것과 같은 추가 기능으로 EntitySystem을 확장하면 매 사이클마다 엔진의 모든 엔티티를 반복하는 대신 작동하고자하는 엔티티 유형 만 추적 할 수 있습니다. EntityListener는 시스템이 등록 된 동일한 엔진에 엔티티가 추가 될 때마다 트리거됩니다.

import com.badlogic.ashley.core.EntityListener;
import com.badlogic.gdx.utils.Array;

public class MovementSystem extends EntitySystem implements EntityListener {
    Array<Entity> moveables = new Array<>();
    ...

    @Override
    public void entityAdded(Entity entity) {
        if (FAMILY.matches(entity)) {
            moveables.add(entity);
        }
    }

    @Override
    public void entityRemoved(Entity entity) {
        if (FAMILY.matches(entity)) {
            moveables.removeValue(entity, true);
        }
    }

    public void update (float deltaTime) {
        for (Entity e : this.moveables) {
            Position pos = Position.Map.get(e);
            
            // do entity movement logic on component
            ...
        }
    }
}

시스템이 처리하는 엔티티의 하위 집합을 항상 추적하는 것이 또한 최적 일 수 있습니다. 원하는 경우 엔 관련 구성 요소를 제거하거나 전체 엔진에서 엔진을 제거하지 않고도 특정 엔티티를 해당 시스템 처리에서 제거 할 수 있습니다.

정렬 된 엔터티 시스템 만들기

간단한 EntitySystem a로 지정된 순서로 소정의 가족의 각 엔티티를 처리 comparator 및 호출 processEntity() 각 엔티티에 대한마다 EntitySystem 갱신된다. 이는 렌더링 시스템이 정렬 된 방식으로 엔티티 목록을 반복하는 경향이 있으므로 실제로는 편의 클래스입니다. 엔터티를 추가하면 엔터티 목록이 재정의됩니다. 정렬 기준을 변경하면 forceSort() 호출하십시오. 자세한 내용은 SortedIteratingSystem을 참조하십시오 .

아래 코드 예제에서 zindex로 정렬 된 순서로 스프라이트를 렌더링하는 가장 좋은 방법입니다.

public class SpriteComponent implements Component {
     public TextureRegion region;
     public int z = 0;
}

public class Mapper {
     public static ComponentMapper<SpriteComponent> sprite = ComponentMapper.getFor(SpriteComponent.class);
}

public class RenderingSystem extends SortedIteratingSystem {

    public RenderingSystem () {
         super(Familly.all(SpriteComponent.class).get(), new ZComparator())
    }

    public void processEntity(Entity entity, float deltaTime) {
         if(checkZIndexHasChangeValue()) {
              forceSort();
         }
    }

    private static class ZComparator implements Comparator<Entity> {
        @Override
        public int compare(Entity entityA, Entity entityB) {
            return (int)Math.signum(Mapper.sprite.get(entityA).z - Mapper.sprite.get(entityB).z);
        }
    }

}

간격 반복 시스템 만들기

프레임마다 한 번은 아니지만 일정 간격 후에 엔터티 패밀리를 처리하는 간단한 EntitySystem 입니다. 엔티티 처리 로직은 processEntity(Entity) 위치해야합니다. 자세한 내용은 IntervalIteratingSystem을 참조하십시오.

아래의 코드 예제에서 가장 좋은 사용법은 물리 세계의 단계입니다.

public class Constants {
     public final static float TIME_STEP = 1 / 60.0f; // 60 fps
     public final static int VELOCITY_ITERATIONS = 6;
     public final static int POSITION_ITERATIONS = 2;
}

public class PhysicsSystem extends IntervalIteratingSystem {
    public PhysicsSystem () {
         super(Family.all(PhysicsComponent.class), Constants.TIME_STEP);
    }

    @Override
    protected void processEntity(Entity entity) {
         // process the physics component here with an interval of 60fps
    }

    @Override
    protected void updateInterval() {
        WorldManager.world.step(Constants.TIME_STEP, Constants.VELOCITY_ITERATIONS, Constants.POSITION_ITERATIONS);
        super.updateInterval();
    }

}


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow