Fungsi panggilan rutin Sheduler nyaman, sistem pengkondisian saya

Alat tersebut awalnya ditulis untuk membantu Anda mengembangkan game kasual sederhana di Unity, setidaknya di sana cukup berguna.



Tapi saya rasa saya akan menggunakannya di proyek lain, dan tidak hanya di unit.



Dan, mungkin, ini akan berguna juga bagi Anda!



Tautan sumber






Jadi, untuk apa dia?



Bayangkan sebuah situasi: Anda menulis permainan kasual sederhana di mana Anda perlu mengetuk layar sepuluh kali untuk menyelesaikan satu level, dan mengirimkannya ke bos Anda (atau pelanggan manja) untuk pratinjau.



Diikuti dengan tugas satu per satu:



  1. Mari tambahkan iklan di akhir setiap 1,5 menit?
  2. Dan mari kita setelah itu di suatu tempat di awal akan ada jendela: "Beli premium sehingga tidak ada iklan"?
  3. Sesuatu yang ditekan jendela ini dengan tajam, tetapi biarlah setelah iklan, tetapi hanya ketika pemain menekan mulai dan melewati dua level?
  4. Dan pada level 10, 20, 30, akan ada jendela "berbagi dengan teman"?
  5. Dan mulai dari level 10 setiap 2 level akankah ada jendela "Beri nilai kami!"?
  6. Dan banyak lagi!


Bahkan setelah melalui eksekusi yang kejam dan pemblokiran tanpa henti terhadap anak Anda, setelah melakukan pemeriksaan keseratus lokasi jendela, cepat atau lambat Anda akan menghadapi masalah seperti itu: jendela yang terikat ke pengatur waktu dapat menimpa jendela yang terikat dengan level itu sendiri!



Ini menjadi semakin sulit untuk mengulang ini - lagipula, pemeriksaan bersyarat sudah sampai leher, ditambah kolega Anda bisa menambahkan jendela mereka sendiri dengan kode yang sama sekali tidak terbaca! Apa yang harus dilakukan?






Tugas



Panggil jendela pada saat tertentu (misalnya, menekan tombol), dan hanya jika semua kondisi yang ditentukan terpenuhi (waktu telah berlalu, titik yang diperlukan telah tercapai, dll.)






Keputusan



Untuk ini, saya membuat kelas Kondisi, berikut bidang utamanya:



  1. timer int setedSeconds
  2. lewati int setedSkips
  3. List &ltint&gt checkPoints


, , . .



, , . , , , NextSkip(). = 0, ,

. - , START() — .

, StartTimer() ResetSkips(). , IsReady()

true , (value > 0), START() .



: — ( ) setedSeconds, , , !



IsReady() , START() , , .



    public Condition myCondition;

    void Start(){
        myCondition = new Condition("");
        myCondition.setedSeconds = 120; // 2 
        myCondition.setedSkips = 5;
        myCondition.START(); //      
    }

    //    
    public void FinishRound(){
        myCondition.NextSkip(); //  ,  

        if (myCondition.IsReady())
        {
            //    ,      ...

            myCondition.START(); //   START()    . ,     IsReady == true
        }
    }


, , — List &ltint&gt checkPoints. - , , , ., , - . , : , ( , ). , Sheduler , , — .



    public Condition myCondition;

    void Start(){
        myCondition = new Condition("",new List<int> { 1, 2, 5 }); //    ,   
        myCondition.setedSeconds = 120;
        myCondition.setedSkips = 5;
        myCondition.START();
    }

    public void FinishRound(){
        myCondition.NextSkip(); 

        if (myCondition.IsReady() || myCondition.HasCheckPoint(currentLevel)) //          
        {
            //    ,      ...

            myCondition.START();
        }
    }


, , =) AutoInvoke(Action CallBack, int checkPoint = 0) , NextSkip() START() , START() .



    public Condition myCondition;

    void Start(){
        myCondition = new Condition("",new List<int> { 1, 2, 5 });
        myCondition.setedSeconds = 120;
        myCondition.setedSkips = 5;
        myCondition.START(); 
    }

    public void FinishRound(){

        myCondition.AutoInvoke(() => Debug.Log("hello World"), currentLevel); 
        //   currentLevel,                                                                                
    }




Satu objek kondisi akan membantu Anda dengan cepat menyediakan satu set kondisi yang diperlukan untuk pengoperasian satu fungsi !!!



Jika tugas Anda di TK sedikit lebih sulit daripada panggilan sederhana, misalnya, panggilan setiap kali atau setelah beberapa waktu, akan berguna untuk menggunakan kondisi tersebut, karena ini adalah abstraksi dan keterbacaan - Anda hanya perlu meluncurkannya dan memeriksa kesiapannya.




Saya telah menambahkan atribut unit yang berguna ke bidang kondisi untuk memudahkan inisialisasi melalui inspektur!





Hal utama adalah fleksibilitas, dan jika tiba-tiba seseorang muncul dengan fungsionalitasnya sendiri yang seharusnya tidak bertentangan dengan kondisi Anda, Anda hanya perlu membuat perencana umum ...






Tugas selanjutnya



Secara fleksibel menambahkan jendela yang berbeda (panggilan fungsi) dari berbagai tempat dalam program, menjaga sinkronisasi dan menghindari konflik overlay!






Solusi:



Dan sekarang kita sampai pada kelas Sheduler utama , perencana kondisi kita!

Lebih baik menginisialisasi objek kelas ini sedini mungkin. Khususnya dalam sebuah unit, lebih baik objek tersebut adalah DontDestroyOnLoad .



Jika Anda melihat ke dalam Sheduler , Anda dapat melihat bidang berikut:



  1. Pos pemeriksaan saat ini int currentheckPoint
  2. Kumpulan semua kondisi tambahan dan perilakunya Dictionary & ltCondition, Action & gt ConditionHandlers - sehingga

    perencana mengetahui peran apa yang harus dimainkan oleh kondisi yang diselesaikan
  3. Dictionary &ltint,Condition&gt CheckPoints — Sheduler, Dictionary, , . .
  4. Queue &ltCondition&gt WaitingConditions ,



Sheduler menyimpan perilaku setiap kondisi dan dipicu menurut kelas ini, ia disetel pada saat menambahkan kondisi public void Add (Condition newCondition, Action CallBack) , di mana ada delegasi yang diperlukan dalam argumen. Metode itu sendiri membaca nama kondisi dan menampilkan pengecualian jika kosong atau sudah ditambahkan - ini diperlukan jika karena alasan tertentu Anda perlu mengambil kondisi dari jadwal bernama List & ltCondition & gt GetConditions (params string [] conditionName) . Juga, metode add Add () Segera menjalankan Start () dari kondisi yang ditambahkan. Ini berguna jika Anda menjalankan Start ()kondisi tambahan akan dilupakan oleh pengembang mana, dan juga untuk menghindari pelepasan fungsi ini secara konstan dari Sheduler. Jika Anda membutuhkan tempat yang berbeda untuk memulai kondisi, Anda hanya bekerja dengan kondisi seperti sebelumnya, Anda selalu dapat mengubah penghitungnya. Inilah keindahan Sheduler - ia menangani di mana kondisi sudah siap, dan di mana ia telah mengubah kesiapannya, dan membuat kalkulasi ini pada saat memanggil metode utamanya Condition Invoke (params Condition [] badges) . Dalam argumen, Anda dapat menentukan lencana tertentu, yaitu, kondisi yang harus berfungsi secara eksklusif, dan yang gilirannya telah tiba, tetapi tidak muncul dalam daftar lencana, maka mereka tidak akan berfungsi. Tetapi, jika Anda tidak menentukan apa pun, maka, seperti yang diharapkan, setiap orang berhak menelepon di puncak antrian!



Pastikan untuk memikirkan di mana pos pemeriksaan akan dihitung untuk Sheduler NextCheckPoint () , misalnya, pada metode, di akhir atau di awal ronde,

contoh lengkap tentang apa yang diperlukan untuk bekerja dengan Sheduler:



    public Condition OfferBuyVip;
    public Condition OfferToShareWithFriends;
    public Condition OfferToVisitSite;

    public Sheduler OfferSheduler;

    public void Start(){
        OfferSheduler = new Sheduler(currentLevel); //      

        /*
         *         
         */

        OfferSheduler.Add(OfferBuyVip, () => Debug.Log("     VIP"));
        OfferSheduler.Add(OfferToShareWithFriends, () => Debug.Log("    "));
        OfferSheduler.Add(OfferToVisitSite, () => Debug.Log("     ,   "));
    }

    public void FinishRound(){
        OfferSheduler.NextCheckPoint(currentLevel); //  ,      
        OfferSheduler.Invoke(OfferBuyVip, OfferToShareWithFriends) //      ,    
    }

    public void StartRound(){
        OfferSheduler.Invoke(OfferToVisitSite); //     
        //   ,   ,           Sheduler
    }





Ini adalah bagaimana kami mencapai bahwa tiga fungsi kondisi kami dipanggil di tempat yang berbeda, sementara mereka saling menghormati dan tidak merayapi semuanya, tetapi mengamati antrian (seperti antrian digital modern untuk kupon), dan pengguna, dengan cepat melompat dari garis finish ke awal permainan , tidak akan terbebani dari jumlah proposal. Dengan Sheduler, ia mempertahankan harmoni yang jelas antara kesederhanaan dan fleksibilitas, karena dengan Sheduler dan delegasi yang diteruskan kepadanya melalui metode Add (Condition newCondition, Action CallBack) , dimungkinkan untuk mengimplementasikan koneksi apa pun antar jendela.



Misalnya, saat meminta spanduk iklan, tawaran untuk membeli Premium tanpa iklan muncul setelah dua level:



    void Start(){
        OfferSheduler = new Sheduler(currentLevel);

        callAddBanner = new Condition(" ");
        callAddBanner.setedSeconds = 80; //    80 
        OfferBuyVip = new Condition("  VIP  ");

        OfferSheduler.Add(callAddBanner, 
            delegate()
            {
                Debug.Log(" ");
                OfferBuyVip.setedSkips = 2; //   
                OfferBuyVip.START();  // 
            }
           );
        OfferSheduler.Add(OfferBuyVip,
            delegate ()
            {
                Debug.Log("     VIP");
                OfferBuyVip.setedSkips = 0; //  !  
 //,  
            }
           );
        }
        
        void Finish(){
            OfferSheduler.NextCheckPoint(currentLevel); //    
// 
            OfferSheduler.Invoke(); //     
//    
        }


Sama seperti itu, sekarang setiap 80 detik iklan yang tidak mengganggu akan dipicu (lagipula, itu tidak disebut selama putaran penting, tetapi di garis finish) dan juga meminta tawaran untuk membeli iklan ketika Anda mau! Dan yang terbaik adalah sekarang setiap pengembang dalam tim dapat menambahkan proposal mereka ke Sheduler, dan Sheduler akan mendistribusikan semuanya.



All Articles