2015-09-19 1 views
1

Я пытаюсь разработать игру, используя прозрачный холст и поверхностьView, я использую холст для рисования, и он отлично работает.Один холст, несколько нитей

Теперь я хочу добавить объекты, которые будут перемещаться по экрану, например, прыгающие шары. Я хочу использовать новую нить для шаров (потому что иначе, если это тот же поток поверхностиView, он не движется плавно).

У меня возникли проблемы с этим. Не могли бы вы посоветовать мне, как и когда я должен отправить тот же холст новому объекту шара, а затем вернуть его обратно на поверхность.
Я не уверен, что лучший способ справиться с этим: Я попытался использовать шар в качестве вида в макете xml, и он отлично работал на другом потоке, но не имеет смысла создавать 1000 просмотров, когда я можно просто нарисовать их на холсте.

Любое понимание будет полезно!

Это мой код:

public class SurfaceMyPaint extends SurfaceView implements Runnable 
    { 
     Thread t; 
     SurfaceHolder holder; 
     Bitmap brush; 
     boolean isItOk = false; 

    public SurfaceMyPaint(Context context) 
    { 
     super(context); 
     holder = getHolder(); 
     initial(); 
    } 

    public void initial() 
    { 
     brush= BitmapFactory.decodeResource(getResources(), R.drawable.brush2);  
    } 

    public boolean onTouchEvent(MotionEvent event) 
    { 
     if(event.getAction()== MotionEvent.ACTION_DOWN) 
     {    
      x= event.getX(); 
      y= event.getY(); 
     } 

     if(event.getAction()== MotionEvent.ACTION_MOVE) 
     { 
     x = event.getX(); 
     y= event.getY(); 
     } 
     return true; 
    } 


    public void run() 
    { 
     while (isItOk == true) 
     { 
     if (!holder.getSurface().isValid()) 
      continue; 
     myCanvas_w = getWidth(); 
     myCanvas_h = getHeight(); 
     if (result == null) 
     result = Bitmap.createBitmap(myCanvas_w, myCanvas_h, Bitmap.Config.ARGB_8888); 
     Canvas c = new Canvas(result); 
     canvas = holder.lockCanvas(null); 
     c.drawBitmap(brush, x - (brush.getWidth()/2), y - (brush.getWidth()/2), null); 
     canvas.drawBitmap(result, 0, 0, null); 

// Как я могу добавить это здесь: Шариковая = новый шар (холст) ????

 holder.unlockCanvasAndPost(canvas); 
     } 
    } 

    public void pause(){ 
    isItOk = false; 
    while (true){ 
     try { 
      t.join(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     break; 
    } 
    t=null; 
    } 
    public void resume() 
    { 
     isItOk = true; 
     t = new Thread(this); 
     t.start(); 
    } 

}

ответ

0

Резюмируя свой код визуализации:

  1. Создать экран размером закадровым растровое а, который вы держите в переменной, названной «результат», который не объявлен в код, который вы показываете. Я предполагаю, что это поле, и распределение происходит только один раз?
  2. Каждый раз вы создаете новый холст для этого растрового изображения.
  3. Вы рисуете растровое изображение, с drawBitmap().
  4. Вы копируете растровое изображение на поверхность с помощью drawBitmap().

Вы хотите добавить шаг # 5, "draw Ball".

Очевидное место для рисования шарика находится на шаге 3, но я предполагаю, что вы не делаете его там, потому что у него есть относительно статический контент, который вы обновляете нечасто, но хотите смешать в каждом кадре ,

В этом случае вы должны просто нарисовать шары на холсте, который вы получили от SurfaceHolder. То, что вы не должно do, хранит ссылку на холст Surface в самом объекте Ball, который, по вашему мнению, вы хотите сделать (на основе new Ball(canvas)). Как только вы позвоните unlockCanvasAndPost(), вы больше не должны использовать этот холст.

Я действительно не вижу преимущества использования нескольких потоков с вашим текущим кодом. Если «фоновый» битмап также менялся, вы могли бы визуализировать это с другим потоком и сливаться в текущей версии при рисовании, но я подозреваю, что это будет больше проблем, чем это стоит - вам придется иметь дело с проблемами синхронизации , и я не думаю, что это решит вашу негладкость.

+0

Спасибо за ваш ответ. Но предположим, что я хочу добавить 1000 падающих шаров на мой холст, я не вижу, как он может работать без другой нити, так как мой холст уже «занят» рисует мою кисть. И я уже пробовал, и мяч не двигался плавно. Какие у меня есть другие варианты? – SHAI

+1

Я не понимаю, почему вы считаете, что использование дополнительного потока решит вашу проблему. Я обеспокоен тем, что вы решили решение, не понимая проблемы, в частности: почему мяч не двигается плавно? Одиночный шар не движется плавно? Каким образом это не гладко - непротиворечивые, но медленные обновления, несогласованная частота кадров, изменения направления движения, мерцания, ...? Профилировали ли вы свой код? Проблема исчезнет, ​​если вы замените копию кисти-Bitmap на простой экран? – fadden

+0

Да, сейчас я говорю об одном шаре. DrawBitmap шара получает различную Y-позицию 'y = y ++' каждый раз (внутри цикла run-while), таким образом, похоже, что мяч падает. Под «негладкой» я подразумеваю, что это непротиворечиво, я имею в виду, что он идет вниз, но я думаю, что некоторые итерации обрабатываются быстрее, чем другие, что заставляет мяч идти «быстро», а затем «медленно» (не сильно отличается между «быстрыми» и «медленными»). – SHAI