알아낸 것.
World 클래스의 생성 직후, 3가지를 진행한다.
1. 소멸을 관리하는 클래스 등록
2. 렌더링 클래스 등록
3. 충돌 콜백 등록
그리고!!!
디버그드로우는
그리기 위해 반드시 플래그 비트를 설정한다.
-----------------------------------------------------------------------------
각설, 테스트베드 동작은...
Model과 Test와 Testbed와 Controller와 Panel과 Frame이 상호작용한다.
Model은 디버그드로우, 패널, 현재 테스트 등 많은 정보를 가진다.
Panel은 마우스 이벤트들을 등록한다. 이미지를 그리기 위해 더블 버퍼링을 사용하며, render 메서드로 준비하고 paintScreen 메서드로 버퍼링을 수행한다. 이 동작은 Controller에 있으며 이곳에서 스레드로 run을 돌며 update문을 계속 호출한다. 이 update문에 testbed의 step 메서드가 들어 있다. 물론 Controller에서 초기에 init을 호출하며 이는 우측 리스트의 메뉴가 바뀌었을 때, Model내에서 이벤트를 받아 자동적으로 처리한다. Controller에서 마우스의 움직임을 받아 내부 화면 좌표로 변환하는 처리를 하는 듯하다. 이 처리를 하지 않았을 때, 마우스의 이벤트 처리가 제대로 동작하지 않았다. 프레임은 하는 게 거의 없다. 단지 패널을 BoderLayout에 등록하고 setVisible(true)하고 EXIT_ON_CLOSE 설정으로 종료하고 Controller에 첫 test요소를 등록하고 이후 controller.start()하는 것 밖에는 없다.
[그림 1]
이게 Main의 끝.
첫줄은 매우 간단.
둘째 줄은 모델을 인자로 넣음. 여긴 좀 복잡.
1. 패널에 패널의 사이즈와 배율이 변수로 있음.
2. 내부서 Debugdraw와 TestModel 멤버변수를 각각 생성/대입.
3. 마우스 이벤트 등록.
셋째 줄 생략.
넷째 줄, 프레임의 생성, 여기 많아서 복잡한 듯 했으나 간단.
[그림 2]
..하므로 사진으로.
[그림 2]에서!
controller = new TestbedController(model, argPanel, behavior); 부분!!!
[그림 3]
이 생성 부분, 나머지는 거의 이벤트 등록하는 부분. 맨 마지막 줄 위의 addListeners(); 가 이 부분.
중요한 부분은
protected void loopInit() {
panel.grabFocus();
if (currTest != null) {
currTest.init(model);
}
}
protected void update() {
if (currTest != null && updateBehavior == UpdateBehavior.UPDATE_CALLED) {
currTest.update();
}
}
이 메서드와
public void run() {
long beforeTime, afterTime, updateTime, timeDiff, sleepTime, timeSpent;
float timeInSecs;
beforeTime = startTime = updateTime = System.nanoTime();
sleepTime = 0;
animating = true;
loopInit();
while (animating) {
//다음 장면 선택시 장면 교환
//프레임율 측정
if(panel.render()) { //장면 다 지워짐...
update(); //장면 그려짐. world.drawDebugData()에 의하여.
panel.paintScreen();//버퍼스왑.
}
//프레임에 알맞게 sleep 하고 프레임수 측정
} // end of run loop
}
이 메서드인데 귀찮아서 중요한 부분만 보임.
저 Update에 step이 있으니 중요함.
public void update() {
//저장, 로딩, 재시작 여부 측정
m_textLine = 20;
if (title != null) {
model.getDebugDraw().drawString(model.getPanelWidth() / 2, 15, title, Color3f.WHITE);
m_textLine += 15;
}//좌상단에 제목 출력
//위 진한 글씨는 항상 0.0f를 리턴했다...
// process our input
//입력 큐를 확인함
step(model.getSettings()); //그리고 이것을 호출!!
//Setting에는 설정 요소 정보가 들어있음. 가령 Testbed의 우측 버튼들의 클릭 여부
}
여기서 저 step은
public synchronized void step(TestbedSettings settings) {
//출력 주파수 구하고 DebugDraw 인스턴스 얻어오고 정지 처리함.
//비트 셋팅 및 몇 설정정보 셋팅
pointCount = 0; //충돌 점 숫자 계산하는 건데 무시한다.
m_world.step(timeStep, settings.getSetting(TestbedSettings.VelocityIterations).value,
settings.getSetting(TestbedSettings.PositionIterations).value);
m_world.drawDebugData();
//이하는 모두 화면에 정보들 출력하는 내용
}
이것들로 동작하였다.
---------------------------------------------------------------------
아까의
protected void loopInit() {
panel.grabFocus();
if (currTest != null) {
currTest.init(model);
}
}
부분에서 놀라운 일이 일어난다.
[그림 4]
이 TestbedTest의 메서드가 실행되며, 여기서 m_world가 초기화된다.
물론, 마지막 줄의 init(m_world, false)는 더욱 놀라웠다.
[그림 5]
필요한 세 가지 정보가 입력된다.
argWorld.setDestructionListener(destructionListener);
argWorld.setContactListener(this);
argWorld.setDebugDraw(model.getDebugDraw());
TestbedTest는 많은 Listener 들을 구현하고 있었다. 충돌 콜백도 마찬가지다.
-------------------------------------------------------------------
남기는 것, Panel과 DebugDraw는 서로를 참조하고 있었다.
댓글 없음:
댓글 쓰기