입니다. 즉, 드로잉 및 로직 업데이트 코드를 별도의 두 구성 요소/스레드에 배치하십시오. 이렇게하면 게임 논리가 프레임 속도와 완전히 독립적입니다.
논리 업데이트는 마지막 업데이트 이후 경과 한 시간을 기준으로해야합니다 (delta
라고 부름). 따라서 개체가 개체 이런 식으로 뭔가를해야 할 각 업데이트하는 동안 다음, 1 x 1 픽셀/밀리 초에 이동이있는 경우 :
가
public void update(int delta) {
this.x += this.speed * delta;
}
그래서 지금 FPS가 지연 되더라도, 그것은 개체의 이동 속도에 영향을주지 않습니다, 델타가 커질 것이기 때문에 객체를 멀리 옮겨서 보정해야합니다 (경우에 따라서는 합병증이 있지만 그것이 그 요지입니다).
그리고 이것은 로직 업데이트 개체 내에서 델타를 계산하는 방법 중 하나는 (일부 스레드 루프에서 실행)입니다 : 도움이
private long lastUpdateTime;
private long currentTime;
public void update() {
currentTime = System.currentTimeMillis();
int delta = (int) (currentTime - lastUpdateTime);
lastUpdateTime = currentTime;
myGameObject.update(delta); // This would call something like the update method above.
}
희망을! 다른 질문이 있으면 물어보십시오. 나는 안드로이드 게임을 직접 만들고있다. :)
샘플 코드 :
복사 두 조각 (1 개 활동과 1 개보기) 및 코드를 실행합니다. 결과는 FPS가 무엇이든 관계없이 화면 아래로 부드럽게 떨어지는 흰색 점이어야합니다. 코드는 좀 복잡하고 길어 보이지만 실제로는 아주 간단합니다. 의견은 모든 것을 설명해야합니다.
이 활동 등급은 그다지 중요하지 않습니다. 당신은 그 안에있는 대부분의 코드를 무시할 수 있습니다.
public class TestActivity extends Activity {
private TestView view;
public void onCreate(Bundle savedInstanceState) {
// These lines just add the view we're using.
super.onCreate(savedInstanceState);
setContentView(R.layout.randomimage);
RelativeLayout rl = (RelativeLayout) findViewById(R.id.relative_layout);
view = new TestView(this);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
10000, 10000);
rl.addView(view, params);
// This starts our view's logic thread
view.startMyLogicThread();
}
public void onPause() {
super.onPause();
// When our activity pauses, we want our view to stop updating its logic.
// This prevents your application from running in the background, which eats up the battery.
view.setActive(false);
}
}
이 수업은 재미있는 부분입니다!
public class TestView extends View {
// Of course, this stuff should be in its own object, but just for this example..
private float position; // Where our dot is
private float velocity; // How fast the dot's moving
private Paint p; // Used during onDraw()
private boolean active; // If our logic is still active
public TestView(Context context) {
super(context);
// Set some initial arbitrary values
position = 10f;
velocity = .05f;
p = new Paint();
p.setColor(Color.WHITE);
active = true;
}
// We draw everything here. This is by default in its own thread (the UI thread).
// Let's just call this thread THREAD_A.
public void onDraw(Canvas c) {
c.drawCircle(150, position, 1, p);
}
// This just updates our position based on a delta that's given.
public void update(int delta) {
position += delta * velocity;
postInvalidate(); // Tells our view to redraw itself, since our position changed.
}
// The important part!
// This starts another thread (let's call this THREAD_B). THREAD_B will run completely
// independent from THREAD_A (above); therefore, FPS changes will not affect how
// our velocity increases our position.
public void startMyLogicThread() {
new Thread() {
public void run() {
// Store the current time values.
long time1 = System.currentTimeMillis();
long time2;
// Once active is false, this loop (and thread) terminates.
while (active) {
try {
// This is your target delta. 25ms = 40fps
Thread.sleep(25);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
time2 = System.currentTimeMillis(); // Get current time
int delta = (int) (time2 - time1); // Calculate how long it's been since last update
update(delta); // Call update with our delta
time1 = time2; // Update our time variables.
}
}
}.start(); // Start THREAD_B
}
// Method that's called by the activity
public void setActive(boolean active) {
this.active = active;
}
}
안녕하세요 Andy, 게임 루프를 포함하도록 제 질문을 업데이트했습니다. 이것이 당신이 그것을 구현하는 것에 대해 말하는 방식입니까? 필자에게는 물리학을위한 것과, 그림을위한 것의 두 가지 기능이 있습니다. 물리학 내부에는 경과 시간 또는 "델타 (delta)"라는 답이 나와 있습니다. 어떤 이유로 그래픽을 지터 롭습니다. 델타가 계속 변동하기 때문에 떨어지는 물체가 일정한 속도로 떨어지지 않는다고 생각합니다. – Cameron
물리 및 드로잉 기능이 두 개의 개별 스레드에 있는지 확인하십시오. 별도의 스레드 두 개를 사용하면 서로 독립적으로 시간을 실행할 수 있습니다. 지 터링에 관해서는 델타를 올바르게 계산하고 있습니까? (현재와 마지막 업데이트 사이의 시간)? 또한 업데이트가 호출 된 횟수 대신 게임의 모든 물리가 해당 델타에 의존하는지 확인하십시오. 괜찮 으면 더 자세한 조언을 제공 할 수 있도록 해당 코드 일부를 게시하십시오. 게시 할 코드를 찾으려고 노력할 것입니다. 감사! –
그들은 2 개의 분리 된 스레드에 있지 않으며 동일한 스레드의 다른 기능을 가지고 있지 않습니다. 동일한 활동에 2 개의 스레드를 추가 할 수 있습니까? – Cameron