Invalidate() не вызывает onDraw
Вчера я задал вопрос, относящийся к графике Android, и теперь, когда у меня есть готовая база, я сделал цикл рендеринга внутри своего пользовательского класса представления.
protected void render() {
long startTime = System.nanoTime();
long elapsedTime;
while (Main.running) {
Bitmap image = Bitmap.createBitmap(Main.WIDTH, Main.HEIGHT, null); //creates new Bitmap to draw onto
Canvas canvas = new Canvas(image); //new Canvas with the attached blank Bitmap
long newTime = System.nanoTime();
elapsedTime = newTime - startTime;
if (elapsedTime >= 1000000000/60) { //if enough time has passed for it to update
startTime = newTime;
Main.player.render(canvas); //this renders a test object, see below
}
display = Bitmap.createBitmap(image); //this writes to the display Bitmap that is drawn in onDraw, see below
invalidate(); //invoke onDraw()
}
}
Вот код для рисования моего изображения игрока (который работает, если я рисую его один раз, а не в цикле.)
public void render(Canvas c) {
int xp = (int) x;
int yp = (int) y;
c.drawBitmap(Images.box, xp, yp, null);
}
И внутри onDraw:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(display, 0, 0, null);
}
Если я просто отрендерить игрока и позвонить invalidate()
один раз, вместо того, чтобы зацикливать его несколько раз, он отображается нормально (и модно). Однако, когда я помещаю его в блок цикла, он не рендерится.
Согласно моей регистрации, цикл функционирует и вызывает invalidate()
, но это никогда не входит в onDraw
метод во время цикла.
Если кто-нибудь может объяснить, почему это происходит, это будет очень грандиозно, и если вам нужна дополнительная информация, пожалуйста, дайте мне знать, и я предоставлю.
РЕДАКТИРОВАТЬ: В моем основном классе Activity, у меня есть поток для игровой логики, а затем после запуска логического потока войти в цикл рендеринга с основным потоком.
Thread update = new Thread() { //game logic thread
public void run() {
loop(); //game logic loop
}
};
update.start(); //start logic thread
surface.render(); //start render loop (surface is the name of my custom view)
Я попытался создать отдельный поток для рендеринга и входа в игровой цикл с моим основным потоком, однако это все равно не сработало.