Etiketli Işıklar Bulmacası eğitimindeki bu adımı tamamlayarak oyuncunun etkileşime girdiği butona göre bir ışık grubunu nasıl açıp kapatacağını öğreneceksin.
Işıkları Açma/Kapatma
Oyuncu butonla etkileşime girdiğinde bir buton ile butonun açıp kapatacağı ışık grubu arasında eşleştirme yapman gerekir. Bunu yapmak için her bir butonu Lights dizisindeki ışık dizinleriyle eşleştirebilirsin.
Bu örnek, butonlar ile ışıklar arasında aşağıdaki eşleştirmeyi kullanır:
- Buton 1, dizin 0’daki ışık ve dizin 3’teki ışık ile eşleştirilir
- Buton 2, dizin 0’daki ışık, dizin 1’deki ışık ve dizin 2’deki ışık ile eşleştirilir
- Buton 3, dizin 0’daki ışık ve dizin 1’deki ışık ile eşleştirilir
- Buton 4, dizin 1’deki ışık ile eşleştirilir
Bu eşleştirmeyi ButtonsToLights adlı bir diziyle gösterebilirsin. Burada ButtonsToLights dizisinin her bir öğesi ışıkların dizinlerini tutan başka bir dizidir. ButtonsToLights dizisinin türü bu durumda ButtonsToLights dizisinin tamsayı dizilerinden oluşan bir dizi olduğunu belirtmek üzere [][]int olur.
| Dizin | 0 | 1 | 2 | 3 |
| Öğe | array{0, 3} | array{0, 1, 2} | array{0, 1} | array{1} |
Işıkları açıp kapatmak için şu adımları izle:
- Tamsayı dizilerinden oluşan
ButtonsToLightsadlı bir dizi oluştur ve yukarıdaki tabloda açıklanan buton-ışık dizinleri eşleştirmesi ile başlat.ButtonsToLights : [][]int = array{array{0, 3}, array{0, 1, 2}, array{0, 1}, array{1}}Bir dizinin dizinleri (indeksleri) 0’dan başlar ve öğe sayısının 1 eksiğine kadar yükselir. Bu nedenle
ButtonsToLightsdizisinin ilk öğesi dizin 0’da, son öğesi ise dizin 3’tedir. tagged_lights_puzzlesınıfınaToggleLights()adlı yeni bir metot ekle. Bu metot, fonksiyona bir tamsayı dizisi olarak verilen dizinlere göre (ButtonsToLightsdizisinin öğeleriyle eşleştirmek için)Lightsdizinindeki ışıkları açar/kapatır veLightsStateiçindeki aynı dizinlerde bulunan öğeleri günceller.LightIndices : []intparametresiniToggleLights()metoduna ekle veforifadesini kullanarak her bir dizini çıktı günlüğüne yazdır.ToggleLights(LightIndices : []int) : void = for: LightIndex : LightIndices do: Logger.Print("Toggling light at {LightIndex}")- Yöntemi oluştururken test etmek için
OnBegin()içindeToggleLights()yöntemini çağır.ButtonsToLightsdizisinin ilk öğesini test olarak kullan. Dizi içinde dizin oluşturmak bir başarısız olabilir ifade olduğundan diziye bir hata bağlamından erişmen gerekecektir. Bu örnek, hata bağlamı içinififadesini kullanır.
OnBegin<override>()<suspends> : void = SetupPuzzleLights() # ToggleLights yöntemini test etmek için ButtonsToLights dizisinin ilk öğesini kullan if (LightIndices : []int = ButtonsToLights[0]): ToggleLights(LightIndices)- Artık
LightIndexdizinini elde ettiğinde göre dizindekiLightsveLightsStatedizilerine erişerek özelleştirilebilir ışık cihazı referansını ve geçerli durumunu elde edebilirsin. Bir ışığı açıp kapatmak şu anlama gelir: Işık açıksa ışığı kapat, ışık kapalıysa ışığı aç. Işığın yeni durumunun ne olacağını söylemek için yazdırma durumunu güncelle.ToggleLights(LightIndices : []int) : void = for: LightIndex : LightIndices Light := Lights[LightIndex] IsLightOn := LightsState[LightIndex] do: Logger.Print("Turning light at {LightIndex} {if (IsLightOn?) then "Off" else "On"}") - Şimdi özelleştirilebilir ışık cihazının durumunu hem oyun içinde hem de
LightsStatedizisinde güncelle.IsLightOndeğerifalseiseTurnOn()çağrısı yap,IsLightOndeğeritrueiseTurnOff()çağrısı yap. Bir kod bloğundaki son ifade sonuçtur. Bu yüzden son ifade olarakfalseveyatruedeğerini ayarlamak değerinNewLightStateiçinde depolanacağı anlamına gelir.ToggleLights(LightIndices : []int) : void = for: LightIndex : LightIndices Light := Lights[LightIndex] IsLightOn := LightsState[LightIndex] do: Logger.Print("Turning light at {LightIndex} {if (IsLightOn?) then "Off" else "On"}") NewLightState := if (IsLightOn?): Light.TurnOff() yanlış else: Light.TurnOn() trueLightIndexdizinindekiLighsStateöğesiniNewLightStatedurumundaki değerle güncelle. Dizi dizini oluşturma başarısız olabilir bir ifade olduğundanLightsStatebir hata bağlamında paketlenmelidir. Bu örnekte hata bağlamıififadesidir. Durumun güncellendiğini çıktı günlüğüne yazdır.ToggleLights(LightIndices : []int) : void = for: LightIndex : LightIndices IsLightOn := LightsState[LightIndex] Light := Lights[LightIndex] do: Logger.Print("Turning light at {LightIndex} {if (IsLightOn?) then "Off" else "On"}") NewLightState := if (IsLightOn?): Light.TurnOff() yanlış else: Light.TurnOn() true if (set LightsState[LightIndex] = NewLightState): Logger.Print("Updated the state for light at {LightIndex}")
Hata bağlamlarını kullanırken çıktı günlüğüne yazdırmak iyi bir fikirdir. Herhangi bir ifade hata bağlamında başarısız olursa hata bağlamında yapılan tüm değişiklikler hiç yapılmamış gibi geri alınır. Çıktı günlüğüne yazdırırsan değişikliğin başarılı olup olmadığını doğrulamak için sadece oyun içi duruma bağlı kalmadan, metnin çıktı günlüğünde görünüp görünmediğine bakarak değişikliğin yapılıp yapılmadığını ikinci bir kez kontrol edebilirsin.
Butona Basmayı Işıkları Açıp Kapatmaya Bağlama
Işıkları nasıl açıp kapatacağını artık belirlediğine göre bir sonraki adım, butona basma işlemlerini ışıkları açmaya veya kapatmaya bağlamaktır.
Butonun InteractedWithEvent olayına abone olarak bunu yapabilirsin. Olay aboneliği hakkında daha ayrıntılı bilgi için Cihaz Etkileşimlerinin Kodlanması bölümüne bakabilirsin.
InteractedWithEvent bir InPlayer : agent parametresi ve void dönüş türüne sahip bir olay işleyici bekler ancak olay işleyicinin ToggleLights() yöntemini çağırabilmesi için olayları gönderen butonun hangi ışıklara bağlı olduğunu bilmesi ve aynı zamanda tagged_lights_puzzle adlı Verse cihazının bir referansını bulundurması gerekir.
Tüm bu bilgileri, abone olmak için dizinleri ve işlevi içeren yeni bir sınıf oluşturarak bir özel objede paketleyebilirsin. Bu şekilde her buton, bu yeni sınıfla temsil edilen kendi kişisel durumuna ve olay işleyicisine sahip olur.
Olay işlemeye yönelik özel bir obje oluşturmak için aşağıdaki adımları izle:
button_event_handleradlı yeni bir sınıf oluştur. Sınıf tanımı aşağıdakileri içermelidir:Indicesadlı bir tamsayı dizisi.ToggleLights()yöntemini çağırabilmen için Verse cihazının referansı olanPuzzleDeviceadlı birtagged_lights_puzzlealanı.InPlayer : agentparametresine vevoiddönüş türüne sahip olupPuzzleDevicecihazındaToggleLights()çağrısı yapanOnButtonPressed()adlı bir yöntem.button_event_handler := class(): # Bu butonun kontrol ettiği ışıklara erişmek için kullanılan konumlar. Indices : []int # Üzerinde fonksiyonlar çağırabilmemiz için bu button_event_handler işleyicisini oluşturan tagged_lights_puzzle. PuzzleDevice : tagged_lights_puzzle OnButtonPressed(InPlayer : agent) : void = # PuzzleDevice cihazına bu butonun kontrolündeki konumlarda bulunan ışıkları açıp kapatmasını söyler. PuzzleDevice.ToggleLights(Indices)
- Oyuncunun etkileşimde bulunabileceği butonlara referans vermek için
tagged_lights_puzzlesınıfında düzenlenebilir birbutton_devicedizi alanı oluştur:@editable Buttons : []button_device = array{} - Şimdi
tagged_lights_puzzlesınıfındakiOnBegin()değerini güncelleyerek her bir buton için birbutton_event_handlerörneği oluştur. Button_event_handler aşağıdaki bilgilere ihtiyaç duyar:forifadesi tarafından sağlananButtonIndexdizinini kullanarakButtonsToLightsdizisinden alabileceğin, butonla ilişkili ışıkların dizinleri. Bunu tümButtonsaracılığıyla yinelemek için kullanılanforifadesinin filtre koşulu olarak alabilirsin. Bu aynı zamanda kodun geçersiz verilerin dizinini oluşturmasını önleyen bir koruma olarak görev yapar. Dizin oluşturma başarısız olursa başarısız olan yineleme atlanacağı için program yine de geçerli olacaktır (ButtonsToLightssayısınıButtonssayısı ile eşleştirmeyi unutursan bu hata oluşabilir).tagged_lights_puzzleVerse cihazının örneğine bir referans. Bir sınıf tanımının içinden geçerli objenin referansını almak içinSelfişlevini kullanabilirsin.- Bu verilerle bir
button_event_handlerobjesi oluşturma işlemi aşağıdaki gibi görünür:OnBegin<override>()<suspends> : void = SetupPuzzleLights() for: ButtonIndex -> Button : Buttons LightIndices := ButtonsToLights[ButtonIndex] do: button_event_handler{Indices := LightIndices, PuzzleDevice := Self}
- Şimdi yeni oluşturulan işleyicinin
OnButtonPressed()işlevini kullanarak Buton cihazınınInteractedWithEventolayına abone olabilirsin.OnButtonPressed()işlevi çağrıldığında ışık dizinlerine erişime ve oyuncunun etkileşimde bulunduğu butonla ilişkilitagged_lights_puzzlecihazının referansına sahip olursun.OnBegin<override>()<suspends> : void = SetupPuzzleLights() for: ButtonIndex -> Button : Buttons LightIndices := ButtonsToLights[ButtonIndex] do: Button.InteractedWithEvent.Subscribe(button_event_handler{Indices := LightIndices, PuzzleDevice := Self}.OnButtonPressed) - Kodu Visual Studio Code içinde kaydet.
- UEFN araç çubuğunda Verse Kodları Oluştur seçeneğine tıklayarak bölümdeki Verse cihazını yeni kodunla güncelleyebilirsin.
- Anahat Düzenleyicisi menüsünden tagged_lights_puzzle cihazını seçerek Ayrıntılar panelini aç.
- Ayrıntılar panelinde
Buttonsdizisine dört öğe ekle ve her biri için farklı bir buton ata. Kod, diğer özellikleri dolduracağı için başka bir özelliği değiştirmen gerekmez. - UEFN araç çubuğunda Oyna butonuna tıklayarak bölüme oynanış testi uygula.
Artık bölümünün oynanış testini yaptığında butonlarla etkileşime girebilmelisin ve her buton ButtonsLightsIndices ayarına göre farklı bir ışık kümesini açıp kapatmalı. GetCreativeObjectsWithTag() işlevinin belirli bir sırayı garanti etmediğini, bu nedenle koddaki sıraya göre açılıp kapatılan ışıkların bölümde gördüğün sırayla eşleşmeyebileceğini aklında bulundur.

Sonraki Adım
Bu eğitimin bir sonraki adımında bir eşya oluşturabilmek ve bulmacayla daha fazla etkileşim olmasını önlemek için oyuncunun bulmacayı çözdüğünün nasıl algılanacağını öğreneceksin.