2016-08-30 2 views
1

내 렌더링 메소드 내의 모든 게임 객체를 포함하는 배열에서 특정 객체를 선택하려고합니다. 내 렌더링 메서드 내부에 있기 때문에 멤버 변수를 사용하여 가비지 수집기를 피하려고합니다. 제 목표는 Renderable의 인스턴스 인 tmpRenderArray GameObject를 넣는 것입니다. 그런 다음 해당 객체를 정렬하여 렌더링해야합니다. 이전에, 내가 충분히 장소 거기 보장하기 위해 게임 오브젝트 크기로 내 tmpRenderArray 크기를 설정 한gdx.utils.Array에 액세스하면 ClassCastException이 시작됩니다.

private Array<GameObject> gameObjects = new Array<>(); 
private Array<Renderable> tmpRenderArray = new Array<>(); 

//... 

@Override 
public void render(float delta) 
{ 
    Gdx.gl.glClearColor(1f, 0.7f, 0.7f, 1f); 
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 

    batch.setProjectionMatrix(camera.combined); 
    batch.begin(); 

    int i = 0; 
    for(GameObject object : gameObjects) 
     if(object instanceof Renderable) 
      tmpRenderArray.set(i++, (Renderable)object); 

    tmpRenderArray.sort(Renderable.PRIORITY_COMPARATOR); 
    //PRIORITY_COMPARATOR = (a, b) -> Float.compare(a.getPriority(), b.getPriority()); 

    for(; i-- > 0;) 
     tmpRenderArray.items[i].render(); //<-- That line 

    batch.end(); 

    //... 
} 

:

여기 내 코드입니다. tmpRenderArray.setSize(gameObjects.size); tmpRenderArray 및 gameObjects는 모두 기본 생성자로 생성 된 일반 Array 객체 (com.badlogic.gdx.utils.Array)입니다. 지정된 어레이 이외의 다른 작업은이 어레이에서 수행되지 않습니다. (add 메소드를 호출하여 GameObject를 생성하는 것을 제외하고)

역순으로 렌더링하기 때문에 null 객체를 렌더링 할 가능성이 없습니다. 그러나 내 의견으로는 "너무 늦었습니다"지정된 줄에 클래스 캐스트 예외가 나타납니다. Exception in thread "LWJGL Application" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Lme.winter.project2d.Renderable;

맞다면 [L은 배열을 의미하지만 배열을 전송하지는 않습니다. items는 멤버 변수이므로 아무 작업도 액세스하지 않습니다. 배열에 액세스하여 예외를 시작할 수 있습니까? 측면 버그 (지수 실수)하지만 주요 문제를 해결하기위한 Tenfour04에

편집

덕분에 여전히 살아있다. 나는 또한 Array 객체의 clear와 add 메소드를 사용하는 것을 고려할 것이지만, 지금은이 버그를 수정하거나 적어도 그것을 이해하고 싶습니다. 작은 수정으로 아래 코드를 업데이트했습니다. 나는이 렌더링 방법이 최고라고 주장하지 않거나 Tenfour04가주는 것보다 낫다. 나는 지금 무슨 일이 일어나고 있는지 알고 싶다.

나는 무슨 일이 일어나고 있는지 확인하기 위해 디버거를 사용 : 우리가 볼 수 있듯이 debug

이 tmpRenderArray.items는 [내가] I = 1, (렌더링 가능한입니다) 차를 반환 할 때하지만 난에 단계 때 , 나는 catch 절에서 LwjglApplication :: initialize로 바뀌었고 원래 예외가 발생합니다. 질문은 동일하게 유지됩니다. 배열에 액세스 할 때 어떻게 배열됩니다? 내가 액세스하는 배열은 일반 java입니다. Array 객체 내부의 멤버 변수이므로 다른 코드 나 LibGDX가 실행되지 않습니다.

답변

1

documentation of Array에는 명시 적으로 클래스를 지정하는 Array 생성자를 사용하지 않은 경우 items에 액세스 할 수 없다고 나와 있습니다. Java에서 런타임시 제네릭 형식을 제거하기 때문에 배열은 items에서 액세스하는 해당 개체의 형식을 알 수 없습니다. LibGDX Array를 사용하면 쉽게 오용 할 수있는 내용에 액세스 할 수 있습니다. 필요한 경우 코드를 매우 최적화 할 수 있습니다.

tmpRenderArray.get(i).render(); 

tmpRenderArray.items[i].render(); 

를 교체하고 그것은 당신이 i되는 것을 첫 번째 요소의 경우 IndexOutOfBoundsException를 제외하고 잘 작동합니다 하나 너무 높은 (아래 참조).


원래 대답은 - 이러한 버그는

귀하의 버그 당신이 당신의 임시 배열을 삭제하지 않는 것이있는 CCE의 소스 아니었다, 그리고 i은해야보다 하나 더 큰 것을 위의 for 루프에 i++이 있기 때문입니다. 이 객체는 null이 아니지만 일부 객체는 이전 프레임에서 남겨 둡니다. i-1에서 시작하고 i++ 대신 ++i을 사용해야합니다. 또는 두 번째 루프 전에 1 씩 감소시킵니다.

즉, 일부 코드는 다소 복잡합니다. 이처럼 간단 수 :

Gdx.gl.glClearColor(1f, 0.7f, 0.7f, 1f); 
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 

batch.setProjectionMatrix(camera.combined); 
batch.begin(); 

tmpRenderArray.clear(); 
for(Renderable object : gameObjects) 
    tmpRenderArray.add(object); 

tmpRenderArray.sort(Renderable.PRIORITY_COMPARATOR); //invert this comparator 
//PRIORITY_COMPARATOR = (b, a) -> Float.compare(b.getPriority(), a.getPriority()); 

for(Renderable renderable : tmpRenderArray) 
    renderable.render(); 

batch.end(); 

//... 
+0

내가 내 노트북에 큰 FPS 드롭을 만들기 때문에 (또한 배열의 크기를 조정하는) (0으로 배열의 크기를 조정) 배열을 지우고 매번 항목을 추가하지 싶습니다 . 인덱스 위치 오류가 내 부분에서 매우 어리 석다. 나는 내일 시험 할 수있을 때 당신의 대답을 받아 들일 것입니다. 당신은 왜 NullPointerException 대신에 ClassCastException을 얻고 있는지 알 수 있습니까? 내 gameObjects 및 tmpRenderArray 모두에서 Renderables * (또는 null 요소) 만 있습니다. * 내 테스트 케이스에서만 나중에 다른 것들을 갖습니다. – Winter

+0

비 Renderables를 도입하지 않은 경우 NPE를 기대할 수 있으므로 확실하지 않습니다. 이 배열은 얼마나 큽니까? 하나의 게임에서 랩톱을 제거하는 것이 충분히 큰 것을 상상하는 것은 어렵습니다. LibGDX 배열 클래스는 선택을 취소 할 때 여분의 요소를 null로 남 춥니 ​​다. 실제로는 기본 Java 배열의 할당을 해제하지는 않습니다. – Tenfour04

+0

FPS 드롭은 내가 지우지 않았기 때문입니다. 당신의 해결책이 나를 위해 최선일지도 모른다. 주요 질문은 아직 답이 없다. 정말 고맙지 만 주요 문제에 답할 수있는 경우에만 대답을 수락합니다. – Winter