2016-05-15 25 views
7

KISA ÖZETİAndroid değil senkron

döngü ve gecikme Ben bir etkinlik oyunu var. Kullanıcı görüntüleri tıklama:

First level of game

Second level of game

Kullanıcı 5 saniye tıkla ve doğru olanını seçmek zorunda. 5 saniye sonra, doğru görüntü çekimi, dikkat çekmek için farklı şekilde gösterilecek ve 5 saniye sonra kullanıcı bir sonraki seviyeyi görecektir.

kullanıcı 5 saniye beklemeden tıklanabilir, bu yüzden tıklandığında hemen bir sonraki seviyeye gitmelidir.

Görüntüleme ve görüntü görünümlerini dinamik olarak oluşturuyorum. Resim görüntülemeleri yerel veritabanı sqlitesinden bayt olarak geliyor.

Benim yöntem, oncreate yönteminin içinde oluşturuyor. Ve ben ya da döngü boyunca kullanıyorum. Her yineleme bir oyun seviyesidir. Her seviye farklı görüntü görüntülemelerine ve farklı görüntü görüntülemelerine sahiptir.

5 + 5 saniye geciktirmek için, işleyicileri, iş parçacıklarını ve geri sayım hatalarını kullanmalıydım. Her biri sorunlara neden oldu.

İşleyicileri kullanırken, kullanıcı 5 saniyeden önce tıkladığında, geçerli oturumu sonlandıramadım.

Bunun doğru yol olup olmadığını bilmiyorum.

UZUN AÇIKLAMA VE KODLARI

zamanlayıcı:

nCreate() { 
      for (int i = 0; i < 2; i++) { 
       handler.postDelayed(new Runnable() { 
        public void run() { 

         imageAnswer.setImageBitmap(bmp); 

         imageAnswer.setId(R.id.imgAnswer); 
         //adding image to screen 
         finalRLayout.removeAllViews(); 
         finalRLayout.addView(imageAnswer, rLayParams); 

         //starting timer, if no answer in 5 seconds, run again timer 
         startTimer(); 

         //clicklisterner 
         imageAnswer.setOnClickListener(new View.OnClickListener() { 
          @Override 
          public void onClick(View view) { 
           //if clicks true, cancel timer and go to next iteration of for loop 
           if (view == findViewById(R.id.imgAnswer)) { 
            Log.d(TAG, "clicked"); 
            //PUT IN CODE HERE TO GET NEXT IMAGE 
            cancelTimer(); 

           } else { //if not true, run again timer for last chance 
            Log.d(TAG, "nonclick"); 
            cancelTimer(); 
            startTimer(); 

           } 
          } 
         }); 
        } 
       }, 2000 * i); 


      } //for end 

     } //oncreate end 

    //start timer function 
    void startTimer() { 
     cTimer = new CountDownTimer(5000, 1000) { 
      public void onTick(long millisUntilFinished) { 
       Log.d(TAG, "ontick"); 
      } 
      public void onFinish() { 
       Log.d(TAG, "timer onfinish"); 
      } 
     }; 
     cTimer.start(); 
    } 


    //cancel timer 
    void cancelTimer() { 
     Log.d(TAG, "canceltimer"); 
     if (cTimer != null) 
      cTimer.cancel(); 
    } 

3 farklı iplik işlemleri ancak işe yaramadı

Aşağıda benim kodlarını görebilirsiniz. Bunlardan biri ekranın siyah ekranına girdi. diğer ikisi de döngüleri engellemedi. Oyununuzu uygulanması daha profesyonel bir şey kullanmalıdır Oyun geliştirme için

runnable version 






    for (int i = 0; i< 20 ; i++) { 
      Log.d(TAG, "for i2="+ i); 
      final int finalI = i; 
      final RelativeLayout finalRLayout = rLayout; 



      final Runnable r=new Runnable() { 

       @Override 
       public void run() { 
        Log.d(TAG, "for finali2="+ finalI); 
        TrainingObject trainingObject = new TrainingObject(); 
        trainingObject = trainingObjectList.get(finalI); 
        objectCount = 2; 
//test icin 
        Log.d(TAG,"testicin trainingobjectid: "+trainingObject.getTrainingobjectID()); 
        object = dbHandler.getObjectObject(trainingObject.getTrainingobjectAnswer()); 




        RelativeLayout.LayoutParams rLayParams = new RelativeLayout.LayoutParams(140,140); 

        rLayParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); 
        rLayParams.addRule(RelativeLayout.CENTER_IN_PARENT); 

        imgBytes = object.getObjectImageBlob(); 
        bmp = BitmapFactory.decodeByteArray(imgBytes, 0, imgBytes.length); 

        imageAnswer.setImageBitmap(bmp); 
        imageAnswer.setTag(trainingObject.getTrainingobjectAnswer()); 
        imageAnswer.setId(R.id.imgAnswer); 
        finalRLayout.removeAllViews(); 
        finalRLayout.addView(imageAnswer,rLayParams); 

       } 
      }; 
      Log.d(TAG, "3000i2 sonrasi"); 

      handler.postDelayed(r, 6000 * i); 
      imageAnswer.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View view) { 
        if (view == findViewById(R.id.imgAnswer)) { 
         Log.d(TAG, "clicked");handler.removeCallbacks(r); handler.postDelayed(r, 0); 
         //PUT IN CODE HERE TO GET NEXT IMAGE 

        } 
        else{ 
         Log.d(TAG, "nonclick"); 
         handler.removeCallbacks(r); handler.postDelayed(r, 6000); 

        } 
       } 
      }); 

     }//for end 
+2

Bu soruyu aşağıdan okuyor muyuz? – fiipi

+2

Bu bir soru değil. – Simas

+0

[AlarmManager] 'ı kullanmayı denediniz mi (https://developer.android.com/reference/android/app/AlarmManager.html) –

cevap

2

, seni Size öğrenebilirler çeşitli seçeneklerle 2D ve 3D oyunlara temel var bu kitabı Beginning Android Games 2nd Edition okumak tavsiye ederiz. Şimdi kodu için ben harici parçacığı üzerinde zaman iz ve bunu ana oyun aktivitesinde Örnek uygulamak bir arayüze geri aramalar göndermek yapmak öneririz:

TimeThread.java

import android.util.Log; 

public class TimeThread implements Runnable { 
    Thread thread = null; 

    TimeTickListener listener; 
    volatile boolean running = false; 

    public TimeThread(TimeTickListener listener) { 
     this.listener = listener; 

    } 

    public void resume() { 

     thread = new Thread(this); 
     running = true; 
     if (thread != null) 
      thread.start(); 
    } 

    @Override 
    public void run() { 

     while (running) { 
      // sending callbacks to the mainActivity 
      listener.onTimeTick(); 

     } 
    } 

    public void pause() { 
     running = false; 
     while (true) { 
      try { 
       thread.join(); 
       Log.v("my", "joined "); 
       break; 
      } catch (InterruptedException e) { 
       Log.v("my", "not joined cause : " + e.getMessage()); 

      } 

     } 

    } 

} 

arayüz kullandığımız: burada

public interface TimeTickListener { 
public void onTimeTick(); 
} 

ve MainActivity gerektiği gibi göründüğüne ilişkin bir örnektir:

MainActivity.java

public class MainActivity extends Activity implements TimeTickListener { 

    long startTime = System.nanoTime(); 
    // the interface method that we implemented 
    @Override 
    public void onTimeTick() { 
     // keep trace of the time untill it sums up to 1 sec then do an action 
     // in your situation you can make it to count 5 sec 
     // and make your action here 
     if ((System.nanoTime() - startTime)/1000000000 >= 1) { 

      totalTime += 1; 

      // this handler is because you should change the textView from its 
      // original thread 
      // and it is not allowed to be edited from another thread 
      // in your case you should change the imageViews like this in the main thread 
      mainHandler.post(new Runnable() { 

       @Override 
       public void run() { 
        text.setText(totalTime + " seconds passed "); 
       } 
      }); 

      startTime = System.nanoTime(); 

//   and this is how to terminate the thread manually (optional) 
      if (totalTime >= 10) { 

       timeThread.pause(); 
      } 

     } 

    } 

    Handler mainHandler; 
    TextView text; 
    float totalTime = 0; 
    TimeThread timeThread; 
    TimeTickListener listener; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     text = new TextView(this); 
     text.setText("wait..."); 
     setContentView(text); 
// initializing the handler with the main activity looper 
     mainHandler = new Handler(getMainLooper()); 
//getting our implemented listener to pass it to the timeThread for the callbacks 
     listener = (TimeTickListener) this; 
     timeThread = new TimeThread(listener); 
     // resume method will launch the thread and make it start calling the interface method (onTimeTick) 
     timeThread.resume(); 

    } 

    @Override 
    protected void onPause() {  

//  don't forget to pause the thread here 
     timeThread.pause(); 
     super.onPause(); 
    } 
} 

Bu kod test edilmiş ve büyük başarı kazandı, zaman almaktadır doğru ve çok iyi senkronize edilmiştir.

Yine de biraz karmaşık ve az kaynak tüketiyor çünkü ikinci iş parçacığındaki while döngüsü ancak çok fazla avantajı var ve uygulamanızı doğru şekilde kontrol etmenize izin veriyor.

Bu yanıt, doğru zamanı elde etmek, zamanı takip eden iş parçacığıyla nasıl baş edeceğinizi ve eyleminizi nerede yapacağınızı öğrenmek için ancak oyun mantığı sorunları yaşıyorsanız ya da görüntüleri saklamakta ve bunları bu durumda kullanıcıya göstermekte zorlanıyorsanız İstediğiniz cevap bu yüzden bana söyleyin ve size yardımcı olmaya çalışacağım. Siz sadece amaca ulaşmak için işleyicisi kullanabilirsiniz

3

, yapmanız gereken bu bir çalıştırılabilir oluşturmak ve işleyicisi dışında beyan sonra postDelayed işleyicisi içinde onun ismiyle kullanmak ve kullanıcı tıklandığında ise, sadece kaldırmak tüm işleyici geri bildirimleri:

// first create runnable 
Runnable r = new Runnable{ 
    public void run(){ 
     //do what you need to do after 5 seconds 
    } 
} 

// then create handler 
Handler mHandler = new Handler(); 

// then in your onCreate method 
nCreate() { 
     for (int i = 0; i < 2; i++) { 
      handler.postDelayed(new Runnable() { 
       public void run() { 

        imageAnswer.setImageBitmap(bmp); 

        imageAnswer.setId(R.id.imgAnswer); 
        //adding image to screen 
        finalRLayout.removeAllViews(); 
        finalRLayout.addView(imageAnswer, rLayParams); 

        //starting handler, if no answer in 5 seconds, run again timer 
        mHandler.postDelayed(r, 5000); 

        //clicklisterner 
        imageAnswer.setOnClickListener(new View.OnClickListener() { 
         @Override 
         public void onClick(View view) { 
          //if clicks true, cancel timer and go to next iteration of for loop 
          if (view == findViewById(R.id.imgAnswer)) { 
           Log.d(TAG, "clicked"); 
           //PUT IN CODE HERE TO GET NEXT IMAGE 
           myHandler.removeCallbacks(r); 

          } else { //if not true, run again timer for last chance 
           Log.d(TAG, "nonclick"); 
           // stop the handler 
           myHandler.removeCallbacks(r); 
           // run a new one 
           mHandler.postDelayed(r, 5000); 

          } 
         } 
        }); 
       } 
      }, 2000 * i); 


     } //for end 

    } //oncreate end 
İlgili konular