Kamis, 28 Mei 2026

Belajar Pemrograan Scratch. Bab 7

 7
Pengulangan: Penjelasan Lebih Mendalam tentang Loop

Anda telah melihat beberapa struktur pengulangan Scratch sebelumnya, tetapi bab ini membahasnya secara lebih detail.

Saatnya membahas blok baru yang membuat loop, loop bersarang, dan rekursi. Pada akhir bab ini, kita akan mempelajari konsep pemrograman berikut:

• Struktur pengulangan untuk mengeksekusi pernyataan berulang kali

• Cara memvalidasi input pengguna

• Loop yang dikendalikan penghitung dan loop yang dikendalikan peristiwa

• Prosedur yang dapat memanggil dirinya sendiri dengan rekursi

Meskipun kebanyakan orang menganggap tugas berulang membosankan, komputer tampaknya sangat menyukainya. Struktur pengulangan, yang lebih dikenal sebagai loop, adalah perintah pemrograman yang memberi tahu komputer untuk mengeksekusi pernyataan atau serangkaian pernyataan secara berulang. Jenis loop paling sederhana adalah loop pasti, yang mengulangi serangkaian pernyataan dalam jumlah tertentu. Loop ini


Loop juga disebut loop terkontrol penghitung atau loop terhitung. Jenis loop lain terus berulang hingga suatu kondisi terjadi; ini disebut loop terkontrol kondisi atau loop tak tentu. Loop lain, yang disebut loop tak terbatas, berulang selamanya.

Dalam bab ini, Anda akan mempelajari berbagai struktur pengulangan yang tersedia di Scratch. Saya akan menjelaskan loop terkontrol penghitung dan loop terkontrol kondisi secara detail, dan saya akan memperkenalkan Anda pada blok berhenti, yang dapat Anda gunakan untuk mengakhiri loop tak terbatas. Anda juga akan mempelajari cara menggunakan loop untuk memvalidasi input pengguna.

Bab ini juga membahas loop bersarang (loop yang berisi loop lain) dan menunjukkan beberapa contoh penggunaannya. Kita juga akan membahas rekursi—prosedur yang memanggil dirinya sendiri—sebagai cara lain untuk mencapai pengulangan. Terakhir, kita akan mengembangkan sejumlah aplikasi menarik yang menggunakan loop dan kondisi, dan kita akan melihat cara menggabungkan loop ke dalam program praktis.


Blok Perulangan Lainnya di Scratch
Seperti yang telah Anda pelajari di Bab 2, blok perulangan memungkinkan Anda untuk mengulang perintah atau serangkaian perintah dalam sebuah program. Scratch mendukung tiga blok pengulangan yang ditunjukkan pada Gambar 7-1.


Gambar 7-1: Blok pengulangan Scratch

Anda telah menggunakan dua blok ini, blok repeat dan forever dalam banyak contoh di seluruh buku ini. Di bagian ini, kita akan memeriksa jenis blok perulangan ketiga—blok repeat until—dan menjelaskan beberapa istilah teknis yang terkait dengan perulangan secara umum.

Setiap pengulangan perulangan disebut iterasi, dan kata count sering digunakan untuk menggambarkan jumlah kali perulangan diulang. Blok repeat, yang sudah sangat Anda kenal, adalah perulangan yang dikendalikan oleh penghitung karena mengulang perintahnya sejumlah kali tertentu. Kita biasanya menggunakan perulangan ini ketika kita mengetahui jumlah pengulangan yang perlu dijalankan oleh perulangan, seperti ketika kita ingin menggambar poligon dengan jumlah sisi yang diketahui.

Di sisi lain, blok repeat until adalah perulangan yang dikendalikan oleh kondisi. Pernyataan di dalam blok ini diulang berdasarkan kebenaran atau kepalsuan ekspresi ujinya. Kita menggunakan blok ini ketika kita tidak tahu sebelumnya berapa kali loop perlu diulang dan ingin pengulangan berlanjut hingga suatu kondisi terpenuhi. Misalnya, Anda dapat mengatakan, "Ulangi perintah tanya hingga pengguna memasukkan angka positif." Atau, "Ulangi penembakan rudal hingga tingkat energi pemain turun di bawah nilai tertentu." Bagian berikut menjelaskan loop yang dikontrol kondisi secara lebih rinci.



Blok Ulangi Hingga
Misalnya, Anda sedang mengembangkan sebuah game yang menyajikan pertanyaan matematika dasar kepada pemain. Jika jawaban pemain salah, game akan mengajukan pertanyaan yang sama lagi untuk memberi pemain kesempatan lain. Dengan kata lain, game akan mengajukan pertanyaan yang sama hingga pemain memasukkan jawaban yang benar. Jelas, blok ulangi tidak tepat untuk tugas ini karena Anda tidak tahu sebelumnya berapa kali pemain perlu memasukkan jawaban yang benar; percobaan pertama mungkin berhasil, atau mungkin membutuhkan 100 percobaan. Blok ulangi hingga dapat membantu Anda dalam skenario seperti ini. Struktur blok ulangi hingga diilustrasikan pada Gambar 7-2.


Gambar 7-2: Blok ulangi hingga memungkinkan Anda untuk mengeksekusi serangkaian instruksi berulang kali hingga suatu kondisi terpenuhi.

Blok ini berisi ekspresi Boolean yang nilainya diuji pada awal loop. Jika ekspresi tersebut salah, perintah di dalam loop akan dieksekusi. Ketika perintah terakhir dalam loop dieksekusi, loop dimulai kembali, dan ekspresi diuji lagi. Jika ekspresi masih salah, perintah di dalam loop dieksekusi lagi. Siklus ini berulang hingga ekspresi uji menjadi benar. Ketika itu terjadi, perintah di dalam loop dilewati, dan program beralih ke perintah yang segera mengikuti loop.

Perhatikan bahwa jika kondisi uji sudah benar sebelum program menjalankan loop untuk pertama kalinya, perintah di dalam loop tidak akan dieksekusi. Selain itu, blok repeat until tidak akan berakhir kecuali ada perintah (baik di dalam loop atau di bagian aktif program lainnya) yang menyebabkan kondisi uji menjadi benar. Jika hasil kondisi uji tidak pernah menjadi benar, kita akan masuk ke dalam loop tak terbatas.


Gambar 7-3 menunjukkan contoh praktis penggunaan blok repeat until.

Dalam contoh ini, selama sprite Pemain berjarak lebih dari 100 langkah dari sprite Penjaga, sprite Penjaga akan terus bergerak ke arah saat ini (horizontal dalam kasus ini), memantul ketika menyentuh tepi kiri atau kanan Panggung. Jika jarak antara kedua sprite menjadi kurang dari 100, blok ulangi hingga akan berakhir, dan sprite Penjaga akan mulai mengejar sprite Pemain. Kode untuk pengejaran tidak ditampilkan dalam gambar. Jarak ke blok dapat ditemukan di palet Penginderaan.



Gambar 7-3: Contoh sederhana yang menunjukkan blok ulangi sampai beraksi

coba 7-1
Buka aplikasi Chase.sb2 dan jalankan. Gunakan tombol panah untuk menggerakkan sprite Pemain mendekat ke Penjaga untuk melihat pengejarannya. Bagaimana Anda akan mengubah kondisi pengujian untuk melepaskan sprite Penjaga jika posisi y sprite Pemain keluar dari rentang tertentu (misalnya, –50 hingga 50)? Terapkan perubahan ini untuk memeriksa solusi Anda.

Membangun Blok if selamanya

Loop tak terbatas berguna dalam banyak situasi pemrograman. Pada bab-bab sebelumnya, misalnya, Anda menggunakan blok selamanya untuk memutar musik latar, dan Anda menganimasikan sprite dengan mengubah kostumnya secara terus menerus. Blok selamanya adalah loop tak terbatas tanpa syarat karena tidak memiliki kondisi pengujian yang mengontrol eksekusi perintah di dalamnya.

Namun, Anda dapat dengan mudah mengubahnya dengan menyisipkan blok if di dalam blok selamanya untuk membuat loop tak terbatas bersyarat, seperti yang ditunjukkan pada Gambar 7-4.


Kondisi pengujian blok if diuji di awal setiap iterasi, dan perintahnya hanya dieksekusi ketika kondisi pengujian benar. Perhatikan bahwa karena blok forever seharusnya dieksekusi selamanya, Anda tidak dapat menyisipkan blok perintah setelahnya.

Gambar 7-4: Anda dapat membuat loop forever/if dengan menggabungkan blok forever dengan blok if.



Struktur gabungan forever/if sering digunakan untuk mengontrol pergerakan sprite dengan tombol panah keyboard, seperti yang ditunjukkan pada Gambar 7-5.


Gambar 7-5: Skrip ini memungkinkan Anda untuk menggerakkan sprite menggunakan tombol panah keyboard.

Setiap skrip merespons salah satu dari empat tombol.Ketika ikon bendera hijau ditekan, keempat tombol panah keyboard (kiri, kanan, atas, dan bawah) dipantau dalam empat loop tak terbatas yang independen. Ketika salah satu tombol ini ditekan, loop yang sesuai menyebabkan perubahan pada koordinat x atau y dari sprite.

Buat skrip ini di Scratch (atau buka ArrowKeys1.sb2) dan jalankan programnya. Perhatikan bahwa jika Anda menekan tombol panah atas dan kanan secara bersamaan, sprite akan bergerak secara diagonal ke arah timur laut. Cobalah kombinasi tombol panah lainnya untuk melihat bagaimana aplikasi merespons.

Cara lain untuk mengontrol pergerakan sprite dengan tombol panah ditunjukkan di bawah ini. Cara lain untuk mengontrol pergerakan sprite dengan tombol panah ditunjukkan di bawah ini. Bandingkan metode ini dengan yang ditunjukkan pada Gambar 7-5. Manakah yang lebih responsif terhadap penekanan tombol keyboard? Bagaimana perilaku skrip alternatif jika Anda menekan dua tombol (misalnya, atas dan kanan) secara bersamaan? Sekarang, coba tempatkan keempat blok if pada Gambar 7-5 bersama-sama dalam satu loop selamanya dan tekan dua tombol panah pada waktu yang bersamaan. Bagaimana perilaku sprite berubah?



Perintah Berhenti
Misalnya, Anda sedang menulis program untuk menemukan bilangan bulat pertama kurang dari 1.000 yang habis dibagi 3, 5, dan 7. Anda dapat menulis skrip yang memeriksa angka 999, 998, 997, dan seterusnya, satu per satu, dalam sebuah loop. Anda ingin menghentikan pencarian ketika Anda menemukan angka yang Anda cari (945 dalam contoh ini).

Bagaimana Anda dapat memberi tahu Scratch untuk mengakhiri loop dan menghentikan skrip? Anda dapat menggunakan perintah berhenti (dari palet Kontrol) untuk mengakhiri skrip yang aktif. Menu tarik-turun menyediakan tiga opsi yang ditunjukkan pada Gambar 7-6.


Gambar 7-6: Menggunakan perintah berhenti di Scratch

Opsi pertama langsung mengakhiri skrip yang memanggilnya. Opsi kedua, di sisi lain, menghentikan semua skrip yang berjalan di aplikasi Anda; ini setara dengan ikon berhenti merah yang terletak di bagian atas Stage.

Perhatikan bahwa Anda tidak dapat menambahkan perintah apa pun setelah blok berhenti saat Anda menggunakan salah satu dari dua opsi ini.

Opsi berhenti ketiga memungkinkan sprite atau Stage untuk mengakhiri semua skripnya kecuali skrip yang memanggil blok berhenti. Perintah ini berbentuk blok tumpukan, sehingga Anda dapat menambahkan blok di bawahnya untuk dieksekusi setelah menangguhkan skrip sprite lainnya. Mari kita lihat perintah ini dalam aksi dalam permainan sederhana, yang diilustrasikan pada Gambar 7-7.


Gambar 7-7: Dalam permainan ini, pemain menggerakkan penyihir di Stage sambil mencoba menghindari dua bola.



Dua bola dalam gambar ini bergerak di sekitar Panggung dan mengejar penyihir.

Pemain menggerakkan sprite penyihir dengan keyboard dan mencoba menghindari sentuhan kedua bola. Jika bola merah menyentuh pemain kapan saja, permainan berakhir. Jika bola hijau menyentuh pemain, bola hijau akan berhenti mengejar pemain, tetapi bola merah akan mulai bergerak sedikit lebih cepat—yang membuat melarikan diri menjadi tantangan nyata.

Skrip untuk menggerakkan sprite penyihir mirip dengan yang ada pada Gambar 7-5, jadi saya tidak akan menunjukkannya di sini. Skrip untuk kedua bola ditunjukkan pada Gambar 7-8—mari kita lihat.


Gambar 7-8: Skrip untuk bola hijau (kiri) dan bola merah (kanan)

Ketika bola hijau menyentuh pemain, ia meningkatkan variabel kecepatan (yang mengatur kecepatan gerakan bola merah), dan ia memanggil perintah stop this script untuk mengakhiri skripnya. Semua skrip lain dalam permainan akan terus berjalan normal. Menggunakan perintah stop this script berfungsi dengan baik di sini karena kita hanya ingin mempercepat bola merah sekali saja. Namun, jika bola merah menyentuh pemain, perintah stop all akan dieksekusi, yang menyebabkan semua skrip yang berjalan di aplikasi berhenti.


Cobalah 7-3
Muat game ini dan mainkan untuk melihat cara kerjanya. Perhatikan apa yang terjadi pada batas kuning di sekitar dua skrip pada Gambar 7-8 ketika bola hijau dan merah menyentuh Pemain.


Anda juga dapat menggunakan blok stop untuk mengakhiri prosedur dan membuatnya kembali ke pemanggil pada titik mana pun selama eksekusinya. Bagian selanjutnya menunjukkan konsep ini dalam praktiknya.



Mengakhiri Perulangan Komputasi
Misalnya, kita ingin mencari pangkat pertama dari 2 yang lebih besar dari 1.000. Kita akan menulis prosedur yang memeriksa angka 21, 22, 23, 24, dan seterusnya, dalam sebuah perulangan. Ketika kita menemukan angka yang kita butuhkan, kita ingin program tersebut menyebutkan jawabannya dan menghentikan prosedur. Gambar 7-9 menunjukkan dua cara untuk mengimplementasikan pendekatan ini.


Gambar 7-9: Dua cara untuk menemukan pangkat pertama dari 2 yang lebih besar dari 1.000

Prosedur di sebelah kiri pada Gambar 7-9 menginisialisasi variabel hasil ke 2, yang merupakan pangkat pertama dari 2 yang akan diperiksa, dan memasuki perulangan tak terbatas untuk mencari jawabannya. Prosedur ini memeriksa nilai hasil di setiap iterasi perulangan. Jika hasil lebih besar dari 1.000, prosedur tersebut memanggil perintah hentikan skrip ini untuk berhenti dan kembali ke pemanggil. Jika tidak, perintah setelah blok if (yang mengalikan nilai result sebelumnya dengan 2) akan dieksekusi, dan iterasi berikutnya dari loop dimulai. Jika Anda menelusuri prosedur ini, Anda akan melihat bahwa blok if menemukan result bernilai 2 pada iterasi pertama, 4 pada iterasi kedua, 8 pada iterasi ketiga, dan seterusnya. Ini berlanjut hingga result melebihi 1.000; pada titik ini, prosedur berhenti dan kembali ke pemanggil, yang menampilkan hasilnya menggunakan blok say.


Gambar 7-9 (kanan) menunjukkan cara lain untuk mengimplementasikan prosedur tersebut.

Di sini, kami menggunakan blok repeat until yang terus berulang hingga result menjadi lebih besar dari 1.000. Seperti pada implementasi pertama, loop terus menggandakan nilai result hingga melebihi 1.000. Ketika ini terjadi, loop berakhir secara alami, dan prosedur kembali ke pemanggil. Perhatikan bahwa kita tidak perlu menggunakan blok stop dalam kasus ini.

Blok berhenti juga berguna ketika Anda perlu memvalidasi input dari pengguna. Anda akan melihat contoh aplikasi praktis ini selanjutnya.

Memvalidasi Input Pengguna
Saat Anda menulis aplikasi yang membaca beberapa data dari pengguna, Anda harus selalu memeriksa apakah nilai yang dimasukkan valid sebelum mulai memproses data. Struktur pengulangan dapat membantu Anda dalam tugas ini. Jika input pengguna tidak valid, Anda dapat menggunakan perulangan untuk menampilkan pesan kesalahan yang sesuai dan meminta pengguna untuk memasukkan kembali nilainya.



Sebagai contoh, misalkan Anda sedang mengembangkan game dengan dua level dan Anda ingin membiarkan pengguna memilih level untuk dimainkan. Satu-satunya entri yang valid dalam kasus ini adalah angka 1 dan 2. Jika pengguna memasukkan angka selain kedua angka ini, Anda ingin menawarkan kesempatan lain untuk memasukkan nilai yang dapat diterima.

Salah satu cara untuk menerapkan pemeriksaan ini ditunjukkan pada Gambar 7-10.


Gambar 7-10: Validasi input menggunakan blok forever

Prosedur GetLevel meminta pengguna untuk memasukkan pilihan dan memeriksa jawabannya di dalam loop forever. Jika jawaban pengguna tidak valid, loop meminta pengguna untuk memasukkan kembali level. Jika pengguna memasukkan angka yang valid, prosedur memanggil stop this script untuk mengakhiri loop dan mengakhiri prosedur. Ketika ini terjadi, skrip utama, yang telah dengan sabar menunggu prosedur GetLevel untuk kembali, melanjutkan untuk mengeksekusi perintah say. Gambar 7-11 menunjukkan cara mencapai tugas yang sama menggunakan blok repeat until.


Gambar 7-11: Validasi input menggunakan blok repeat until

Prosedur pada Gambar 7-11 meminta pengguna untuk memasukkan pilihan dan menunggu jawabannya. Jika pengguna memasukkan 1 atau 2, kondisi di header blok repeat until akan bernilai benar, yang secara alami mengakhiri loop dan prosedur. Di sisi lain, jika pengguna memasukkan angka selain 1 atau 2, kondisi loop akan bernilai salah, dan perintah ask di dalam loop akan dieksekusi. Perintah ini menunggu input pengguna lagi, dan blok repeat until akan terus meminta input hingga pengguna memasukkan pilihan yang valid. Sekali lagi, perhatikan bahwa implementasi ini tidak memerlukan blok stop.



Penghitung
Terkadang, Anda perlu melacak jumlah iterasi yang dilakukan oleh sebuah loop.

Misalnya, jika Anda ingin memberi pengguna hanya tiga kesempatan untuk memasukkan kata sandi yang benar, Anda harus menghitung upaya mereka dan memblokir akses mereka setelah percobaan ketiga.

Anda dapat menangani skenario pemrograman seperti itu dengan menggunakan variabel (biasanya disebut sebagai penghitung loop) yang menghitung jumlah iterasi loop.

Mari kita langsung masuk dan menjelajahi beberapa contoh yang menunjukkan cara praktis untuk menggunakan penghitung loop.


Memeriksa Kata Sandi
Program pada Gambar 7-12 meminta pengguna untuk memasukkan kata sandi untuk membuka kunci laptop. Sprite Laptop memiliki dua kostum: gambar mati menunjukkan bahwa laptop terkunci, dan gambar menyala menunjukkan bahwa laptop tidak terkunci. Pengguna akan ditolak aksesnya ke laptop jika kata sandi yang tidak valid dimasukkan tiga kali.


Gambar 7-12: Skrip ini memberi pengguna tiga kesempatan untuk memasukkan kata sandi yang benar.

Saat bendera hijau diklik, sprite Laptop beralih ke kostum mati dan memanggil prosedur GetPassword untuk mengautentikasi pengguna.

Prosedur ini diharapkan mengembalikan hasil pemeriksaan kata sandi ke skrip utama menggunakan flag gotPass. Saat prosedur kembali, blok if/else memeriksa flag gotPass untuk memutuskan apakah pengguna diizinkan mengakses sistem atau tidak. Jika gotPass diatur ke 1, yang berarti pengguna memasukkan kata sandi yang benar, blok if menjalankan perintah say yang menampilkan "Akses diberikan" dan mengubah kostum laptop ke gambar menyala. Jika tidak, skrip menampilkan "Akses ditolak!" dan sprite terus menampilkan kostum mati awalnya.

Prosedur GetPassword mengatur flag gotPass ke 0, untuk menunjukkan bahwa belum menerima kata sandi yang valid, dan menginisialisasi variabel failCount (penghitung loop kita) ke 0. Kemudian menjalankan loop repeat dengan jumlah pengulangan maksimum tiga. Selama setiap iterasi loop, pengguna diminta untuk memasukkan kata sandi. Jika pengguna memasukkan kata sandi yang benar (Pass123 dalam contoh ini), flag gotPass diatur ke 1, prosedur berhenti dengan memanggil perintah stop this script, dan eksekusi kembali ke pemanggil.

Jika tidak, jika pengguna belum menggunakan ketiga percobaan, pesan kesalahan akan ditampilkan, dan pengguna diberi kesempatan lain. Jika pengguna gagal tiga kali berturut-turut, loop pengulangan akan otomatis berakhir, dan prosedur kembali ke pemanggil dengan nilai flag gotPass masih diatur ke 0.


Cobalah 7-4
Buka aplikasi ini dan jalankan. Apa yang terjadi jika Anda memasukkan paSS123 (bukan Pass123) untuk kata sandi? Apa yang dapat Anda simpulkan tentang perbandingan string di Scratch? Cobalah untuk mengimplementasikan prosedur GetPassword menggunakan blok repeat until.


Menghitung dengan Jumlah Konstan
Tentu saja, Anda tidak selalu harus menambah penghitung Anda sebanyak 1 setiap kali melalui loop. Skrip pada Gambar 7-13 di u, misalnya, memiliki sprite penghitung dari 5 hingga 55 dengan kelipatan 5. Skrip di v menyebabkan sprite menghitung mundur dari 99 ke 0 dengan pengurangan 11—dengan kata lain, 99, 88, 77, ... , 11, 0.

Gambar 7-13: Anda dapat menambah dan mengurangi penghitung dengan jumlah selain 1.

Untuk melihat teknik penghitungan ini dalam aplikasi praktis, katakanlah bahwa kita ingin menemukan jumlah semua bilangan bulat genap dari 2 hingga 20 (termasuk). (Yaitu, kita menginginkan jumlah 2 + 4 + 6 + 8 + ... + 20.) Skrip pada Gambar 7-14 melakukan persis seperti itu.



Gambar 7-14: Skrip ini menemukan jumlah semua bilangan genap dari 2 hingga 20.

Skrip ini dimulai dengan menginisialisasi variabel sum ke 0 dan variabel count ke 2, lalu memasuki loop bersyarat yang berulang hingga count melebihi 20. Setiap kali loop berulang, nilai count ditambahkan ke jumlah saat ini dan variabel count ditambah 2 untuk mendapatkan bilangan genap berikutnya dalam urutan tersebut. Prediksi output dari skrip ini lalu jalankan untuk memeriksa jawaban Anda.

Jumlah Pengulangan Non-Bilangan Bulat
Menurut Anda apa yang akan terjadi jika Anda meminta Scratch untuk mengulang loop sebanyak 2,5 kali? Tiga contoh yang ditunjukkan di bawah ini menunjukkan bagaimana Scratch menangani jumlah pengulangan non-bilangan bulat.

Tentu saja, tidak ada yang namanya "ulangi 2,5 kali," tetapi Scratch tidak mencegah Anda memasukkan nilai tersebut. Alih-alih memberikan pesan kesalahan, Scratch secara otomatis membulatkan jumlah pengulangan desimal ke bilangan bulat terdekat.

Meninjau Kembali Perulangan Bersarang

Kembali di “Kotak yang Diputar” pada halaman 34, kita menggunakan perulangan bersarang untuk menggambar kotak yang diputar. Satu perulangan (perulangan dalam) bertanggung jawab untuk menggambar kotak, sementara perulangan lainnya (perulangan luar) mengontrol jumlah rotasi. Di bagian ini, Anda akan mempelajari cara menggunakan konsep penghitung perulangan bersamaan dengan perulangan bersarang untuk membuat iterasi dalam dua (atau lebih) dimensi.

Teknik ini merupakan bagian penting dari pemrograman dan, seperti yang akan Anda lihat sebentar lagi, dapat digunakan untuk menyelesaikan berbagai masalah pemrograman.

Untuk mempersiapkan konteksnya, katakanlah sebuah restoran lokal menawarkan empat jenis pizza (P1, P2, P3, dan P4) dan tiga jenis salad (S1, S2, dan S3). Jika Anda makan di sana, Anda akan memiliki 12 kombinasi yang mungkin untuk dipilih; Anda dapat memiliki P1 dengan salah satu dari tiga jenis salad, P2 dengan salah satu dari tiga jenis salad, dan selanjutnya. Pemilik restoran ingin mencetak menu yang mencantumkan kombinasi pizza/salad yang tersedia beserta harga gabungan dan kandungan kalorinya. Mari kita lihat bagaimana perulangan bersarang dapat digunakan untuk menghasilkan daftar semua kemungkinan kombinasi. (Saya akan menyerahkan perhitungan harga dan kandungan kalori sebagai latihan untuk Anda.)

Jika Anda memikirkannya, Anda akan melihat bahwa kita hanya membutuhkan dua perulangan: satu perulangan (perulangan luar) untuk menelusuri jenis pizza dan perulangan lain (perulangan dalam) untuk menelusuri jenis salad. Perulangan luar dimulai dengan P1, sedangkan perulangan dalam mencoba S1, S2, dan S3. Perulangan luar kemudian beralih ke P2, dan perulangan dalam kembali memilih S1, S2, dan S3. Ini berlanjut hingga perulangan luar telah melewati keempat jenis pizza. Implementasi dari ide ini diilustrasikan pada Gambar 7-15.


Gambar 7-15: Visualisasi perulangan bersarang. Variabel P mengontrol loop luar dan variabel S mengontrol loop dalam.

Skrip ini menggunakan dua loop dan dua penghitung. Penghitung untuk loop luar diberi nama P, dan penghitung untuk loop dalam diberi nama S. Pada iterasi pertama loop luar (di mana P = 1), nilai penghitung S diatur ke 1, dan loop dalam diulang tiga kali. Setiap kali, ia menjalankan perintah say untuk menampilkan nilai P dan S saat ini, dan kemudian ia menambah S sebesar 1.

Dengan demikian, iterasi pertama loop luar menyebabkan sprite mengucapkan “P1,S1” dan “P1,S2” dan “P1,S3.”



Ketika loop dalam berakhir setelah berulang tiga kali, P ditambah 1, dan iterasi kedua dari loop luar dimulai. Nilai S diatur ulang menjadi 1, dan loop dalam dieksekusi lagi. Ini menyebabkan sprite mengucapkan “P2,S1” dan “P2,S2” dan “P2,S3.” Proses berlanjut dengan cara yang serupa, menyebabkan sprite mengucapkan “P3,S1” dan “P3,S2” dan “P3,S3” dan akhirnya “P4,S1” dan “P4,S2” dan “P4,S3” sebelum skrip berakhir. Telusuri skrip ini untuk memastikan Anda memahami cara kerjanya.

Sekarang setelah Anda melihat apa yang dapat dilakukan oleh loop bersarang, mari kita terapkan teknik ini untuk menyelesaikan masalah matematika yang menarik. Kita ingin menulis program

untuk menemukan tiga bilangan bulat positif n1, n2, dan n3 sedemikian sehingga n1 + n2 + n3 = 25 dan (n1)² + (n2)² + (n3)² = 243. Karena komputer mahir dalam tugas-tugas berulang, rencana kita adalah mencoba semua kemungkinan kombinasi angka (teknik yang disebut pencarian menyeluruh) dan membiarkan komputer melakukan pekerjaan yang sulit.

Berdasarkan persamaan pertama kita, angka pertama, n1, dapat memiliki nilai apa pun antara 1 dan 23 karena kita perlu menambahkan dua angka ke dalamnya untuk mendapatkan 25. (Anda mungkin telah memperhatikan bahwa n1 tidak boleh lebih dari 15 karena 16² = 256, yang lebih besar dari 243. Tetapi kita akan mengabaikan persamaan kedua kita untuk saat ini dan tetap menetapkan batas atas loop menjadi 23.)

Angka kedua, n2, dapat berupa nilai apa pun antara 1 dan 24 – n1. Sebagai contoh, jika n1 adalah 10, nilai maksimum yang mungkin untuk n2 adalah 14 karena n3 harus setidaknya 1. Jika kita mengetahui n1 dan n2, kita dapat menghitung n3 sebagai 25 – (n1 + n2). Kemudian, kita perlu memeriksa apakah jumlah kuadrat dari ketiga angka ini adalah 243. Jika ya, kita selesai. Jika tidak, kita perlu mencoba kombinasi n1 dan n2 yang berbeda. Anda dapat melihat skrip yang sudah selesai untuk menemukan n1, n2, dan n3 pada Gambar 7-16.


Gambar 7-16: Skrip ini mencari tiga angka positif yang jumlahnya 25 dan jumlah kuadratnya adalah 243.

Loop luar mencoba semua nilai n1 dari 1 hingga 23. Untuk setiap nilai n1, loop dalam mencoba semua nilai n2 dari 1 hingga (24 – n1). Untuk setiap kombinasi n1 dan n2, skrip menetapkan n3 sama dengan 25 – (n1 + n2), dan kemudian memeriksa apakah jumlah kuadrat dari ketiga angka ini adalah 243. Jika ya, skrip akan menampilkan jawabannya dan berhenti.


Cobalah 7-5

Buat skrip yang ditunjukkan pada Gambar 7-16 dan jalankan untuk menemukan n1, n2, dan n3. Jika Anda mempelajari skrip dengan saksama, Anda akan menemukan bahwa skrip tersebut mencoba beberapa kombinasi (n1, n2) lebih dari sekali. Misalnya, angka (1, 2) diuji pada iterasi pertama loop luar, sedangkan angka (2, 1) dicoba pada iterasi kedua. Kedua pengujian ini berlebihan; kita hanya membutuhkan salah satunya. Anda dapat memperbaikinya dengan membuat loop dalam dimulai dari n1, bukan 1. Lakukan perubahan ini pada skrip dan kemudian jalankan untuk memastikan skrip masih berfungsi seperti yang diharapkan.


Rekursi: Prosedur yang Memanggil Dirinya Sendiri

Struktur pengulangan yang telah diperkenalkan sejauh ini memungkinkan kita untuk mengulang sebuah perintah atau serangkaian perintah melalui iterasi. Teknik ampuh lainnya yang menghasilkan pengulangan adalah rekursi. Rekursi memungkinkan sebuah prosedur untuk memanggil dirinya sendiri secara langsung atau melakukannya secara tidak langsung melalui prosedur lain (misalnya, A memanggil B, B memanggil C, lalu C memanggil A). Mungkin tidak jelas mengapa Anda ingin melakukan ini, tetapi ternyata rekursi dapat menyederhanakan solusi dari banyak masalah ilmu komputer. Mari kita demonstrasikan konsep ini dengan mempertimbangkan contoh sederhana yang ditunjukkan pada Gambar 7-17.


Gambar 7-17: Sebuah prosedur rekursif

Prosedur Tic mengeksekusi dua perintah say (yang pertama mengatakan "Tic" dan yang kedua mengatakan "Tac"), lalu memanggil dirinya sendiri lagi. Panggilan kedua melakukan hal yang sama, dan sprite akan terus mengatakan, "Tic Tac" selamanya jika tidak ada tindakan eksternal yang menghentikannya. Tentu saja, satu-satunya cara untuk menghentikannya dalam kasus ini adalah dengan mengklik ikon berhenti berwarna merah. Dengan memanggil prosedur dengan cara ini, kita dapat mengulang dua perintah "say" selamanya tanpa menggunakan blok perulangan apa pun. Bentuk rekursi yang digunakan dalam contoh ini disebut rekursi ekor karena panggilan rekursif terletak di bagian paling akhir prosedur. Scratch juga memungkinkan panggilan rekursif untuk datang sebelum baris terakhir, tetapi kita tidak akan membahas jenis rekursi itu dalam buku ini.



Karena rekursi tak terbatas umumnya bukan ide yang baik, Anda harus mengontrol eksekusi prosedur rekursif dengan kondisi. Misalnya, prosedur tersebut dapat menyertakan blok if yang menentukan apakah panggilan rekursif harus dilakukan. Untuk mendemonstrasikan teknik ini, Gambar 7-18 menunjukkan prosedur rekursif yang menghitung dari beberapa angka awal (ditentukan oleh parameter count) hingga 0.

Gambar 7-18: Blok if digunakan untuk menentukan apakah (atau tidak) panggilan rekursif harus dilakukan.

Mari kita bahas bagaimana CountDown bekerja ketika dipanggil dengan argumen tiga. Saat prosedur dimulai, perintah say menampilkan angka 3, kemudian memeriksa apakah count lebih besar dari 0. Karena 3 lebih besar dari 0, prosedur mengurangi 1 dari count untuk memanggil dirinya sendiri dengan argumen 2.

Pada panggilan kedua, prosedur menampilkan angka 2 dan, karena 2 lebih besar dari 0, memanggil dirinya sendiri sekali lagi dengan argumen 1. Ini berlanjut hingga panggilan CountDown(0) dilakukan. Setelah menampilkan angka 0 dalam gelembung suara, prosedur memeriksa apakah count lebih besar dari 0. Karena ekspresi di header blok if bernilai false, tidak ada panggilan rekursif lebih lanjut yang akan dilakukan, dan prosedur kembali. Cobalah untuk mengikuti jalur kembali yang ditunjukkan pada Gambar 7-18.

Sekarang setelah kita membahas dasar-dasar rekursi ekor, kita dapat menerapkannya pada aplikasi yang lebih menarik. Mari kita pertimbangkan, misalnya, prosedur Blade yang ditunjukkan pada Gambar 7-19.


Gambar 7-19: Menggunakan arah sprite untuk menghentikan rekursi

Kita mengasumsikan bahwa sprite yang menjalankan prosedur ini dimulai di suatu tempat di Stage yang mengarah ke arah 90°. Setelah menggambar segitiga sama sisi, sprite bergerak 12 langkah ke depan dan kemudian berputar 10° berlawanan arah jarum jam. Prosedur kemudian memeriksa arah baru sprite. Jika sprite tidak mengarah ke arah 90°, prosedur akan memanggil dirinya sendiri lagi untuk menggambar segitiga berikutnya dalam urutan tersebut. Jika tidak, panggilan rekursif tidak terjadi, dan prosedur berakhir setelah menggambar mata gergaji yang ditunjukkan pada Gambar 7-19.


Untuk contoh sederhana seperti yang ditunjukkan di sini, mungkin lebih mudah untuk menggunakan blok pengulangan untuk mencapai pengulangan yang diinginkan. Tetapi seperti yang saya sebutkan di awal bagian ini, ada banyak masalah yang lebih mudah dipecahkan dengan rekursi daripada iterasi.


Cobalah 7-
Apa yang dilakukan prosedur berikut? Implementasikan dan panggil dengan argumen yang berbeda untuk memeriksa jawaban Anda.


Proyek Scratch
Sekarang Anda tahu cara menggunakan pengulangan untuk keuntungan Anda dalam skrip Scratch, saatnya untuk menerapkan apa yang telah kita pelajari dalam bab ini ke beberapa penggunaan praktis. Di bagian ini, saya akan memandu Anda melalui berbagai proyek untuk membantu Anda memperkuat pemahaman Anda tentang pemrograman dan memberi Anda beberapa ide untuk proyek Anda sendiri.

Jam Analog
Blok saat ini dari palet Sensing dapat melaporkan tahun, bulan, tanggal, hari dalam seminggu, jam, menit, atau detik saat ini, tergantung pada apa yang Anda pilih dari menu tarik-turun. Proyek pertama kita akan menggunakan blok ini untuk mengimplementasikan jam analog yang ditunjukkan pada Gambar 7-20. Aplikasi ini berisi empat sprite: sprite Detik, Menit, dan Jam, yang mewakili tiga jarum jam, dan sprite Waktu (titik putih kecil), yang menampilkan waktu dalam format digital (lihat gelembung pikiran pada gambar).



Gambar 7-20: Aplikasi Jam Analog

Jam mulai berjalan ketika bendera hijau diklik. Sebagai respons, keempat sprite memulai perulangan tanpa akhir untuk memperbarui statusnya berdasarkan waktu sistem saat ini. Skrip untuk sprite Detik dan Menit ditunjukkan pada Gambar 7-21.


Gambar 7-21: Skrip untuk sprite Detik dan Menit

Jumlah detik dan menit yang dilaporkan oleh blok saat ini berkisar dari 0 hingga 59. Ketika sistem melaporkan 0 detik, sprite Detik harus menunjuk ke atas (menuju 0°), pada 15 detik, sprite Detik harus menunjuk ke kanan (menuju 90°), dan seterusnya. Setiap detik, jarum Detik harus berputar 6° (360° dibagi 60 detik) searah jarum jam. Alasan serupa berlaku untuk jarum Menit. Jika Anda mengamati jam ini berjalan, Anda akan melihat jarum Detik melompat setiap detik dan jarum Menit melompat setiap menit. Sekarang, mari kita lihat skrip untuk sprite Jam, yang ditunjukkan pada Gambar 7-22.


Gambar 7-22: Skrip untuk sprite Jam

Blok current(hour) melaporkan jam sistem sebagai angka dari 0 hingga 23. Kita perlu jarum Jam menunjuk ke arah 0° (yaitu, ke atas) untuk jam 0, 30° untuk jam satu, 60° untuk jam dua, dan seterusnya, seperti yang diilustrasikan pada gambar. Tentu saja, jika waktu saat ini, katakanlah, 11:50, kita tidak ingin jarum Jam menunjuk tepat ke 11 tetapi lebih ke arah 12. Kita dapat melakukan penyesuaian ini dengan memperhitungkan menit saat ini.

Karena setiap jam (atau 60 menit) sesuai dengan 30° pada permukaan jam, setiap menit bernilai 2°. Oleh karena itu, setiap menit, kita perlu menyesuaikan sudut jarum jam dengan jumlah menit saat ini dibagi 2, seperti yang ditunjukkan dalam skrip.

Skrip untuk sprite Waktu sangat sederhana dan tidak ditampilkan di sini. Skrip ini menggunakan blok gabungan bersarang untuk membuat string tampilan dalam bentuk jam:menit:detik dan menampilkan string ini dalam gelembung pikiran, seperti yang ditunjukkan pada Gambar 7-20.


Cobalah 7-7
Buka aplikasi dan jalankan. Ubah skrip untuk sprite Menit agar bergerak dengan mulus, alih-alih melompat setiap menit. (Petunjuk: Gunakan ide yang sama yang telah kita terapkan untuk menghaluskan pergerakan jarum jam.) Selain itu, ubah skrip sprite Waktu untuk menampilkan string dalam bentuk “3:25:00 pm” (format 12 jam) alih-alih “15:25:00” (format 24 jam). Pikirkan cara lain untuk meningkatkan aplikasi dan coba terapkan juga.


Permainan Menembak Burung
Sekarang, mari kita buat permainan sederhana yang menggunakan sebagian besar blok yang telah kita perkenalkan di bab ini. Tujuan pemain adalah untuk menjatuhkan dua burung dari langit, dan Anda dapat melihat antarmuka pengguna pada Gambar 7-23.


Gambar 7-23: Antarmuka pengguna permainan menembak burung



Seperti yang ditunjukkan, permainan ini berisi lima sprite: Burung1, klon Burung1, Burung2, seorang penembak, dan sebuah peluru. Pemain dapat menggerakkan penembak secara horizontal menggunakan tombol panah kiri dan kanan pada keyboard. Menekan spasi akan menembakkan peluru ke langit. Jika peluru mengenai Burung1 atau klonnya, pemain mendapatkan satu poin. Burung2 adalah spesies yang terancam punah, jadi pemain tidak diperbolehkan menembaknya; jika peluru mengenai sprite tersebut, permainan berakhir. Pemain memiliki waktu satu menit untuk menembak sebanyak mungkin burung.

Setiap burung menggunakan dua kostum. Saat berganti antara kedua kostum ini, burung-burung tersebut tampak mengepakkan sayapnya. Panggung memiliki dua latar belakang bernama awal dan akhir. Latar belakang awal ditunjukkan pada Gambar 7-23. Latar belakang akhir identik, dengan tambahan kata-kata Game Over di tengah gambar. Skrip yang milik Panggung ditunjukkan pada Gambar 7-24.


Gambar 7-24: Skrip untuk Stage dalam permainan penembak burung

Ketika ikon bendera hijau ditekan, Stage beralih ke latar belakang awal, mengatur ulang timer, dan memulai loop yang memperbarui dan memeriksa sisa waktu permainan, yang dilacak oleh variabel TimeLeft.

Ketika TimeLeft mencapai 0 atau ketika Stage menerima pesan siaran GameOver, ia menjalankan handler GameOver. Skrip ini menunggu sebentar untuk memungkinkan burung-burung menyembunyikan diri, beralih ke latar belakang akhir, dan memanggil stop all untuk mengakhiri skrip yang sedang berjalan. Seperti yang akan Anda lihat sebentar lagi, pesan GameOver akan dikirim oleh sprite Bullet ketika mengenai Bird2. Sekarang mari kita lihat skrip untuk sprite Shooter, yang ditunjukkan pada Gambar 7-25.


Gambar 7-25: Skrip untuk sprite Shooter

Skrip ini dimulai dengan memposisikan penembak di tengah tepi bawah Stage. Skrip kemudian memasuki loop tak terbatas yang mendeteksi apakah tombol panah kiri atau kanan telah ditekan dan menggerakkan penembak ke arah yang sesuai. Sekarang mari kita beralih ke skrip untuk Bird1, ditunjukkan pada Gambar 7-26.


Gambar 7-26: Skrip untuk sprite Bird1

Saat permainan dimulai, Bird1 mengkloning dirinya sendiri, bergerak ke tepi kiri Stage, dan memanggil prosedur Start. Klon juga mulai di tepi kiri Stage (tetapi pada ketinggian yang berbeda) dan memanggil Start. Prosedur ini menggunakan loop selamanya untuk menggerakkan burung dan klonnya secara horizontal di Stage, dari kiri ke kanan dengan langkah acak. Ketika burung mendekati tepi kanan stage, ia dipindahkan kembali ke tepi kiri, seolah-olah ia berputar dan muncul kembali. Skrip terakhir menyembunyikan kedua burung ketika pesan GameOver disiarkan.

Skrip untuk Bird2 sangat mirip dengan skrip Bird1, jadi kami tidak akan menunjukkannya di sini. Saat bendera hijau diklik, Bird2 bergerak ke tepi kanan Stage pada ketinggian 40 dan kemudian menjalankan loop mirip dengan prosedur Start pada

Gambar 7-26. Burung tersebut hanya bergerak dari kiri ke kanan, berputar kembali saat mencapai tepi kanan Stage. 

Bird2 juga merespons siaran GameOver dengan menyembunyikan dirinya. Tentu saja, pemain tidak dapat mengenai burung apa pun hanya dengan menggerakkan penembak, dan di situlah sprite Peluru berperan. Skrip utama untuk sprite ini ditunjukkan pada Gambar 7-27.


Gambar 7-27: Skrip utama dari sprite Peluru

Saat bendera hijau diklik, skrip ini menginisialisasi variabel Fired (jumlah peluru yang ditembakkan) dan Hits (berapa banyak burung yang telah terkena) menjadi 0. Kemudian mengarahkan sprite Peluru ke atas dan menyembunyikannya. Setelah itu, skrip memasuki loop tak terbatas untuk berulang kali memeriksa status tombol spasi.

Saat spasi ditekan, skrip menambah nilai Fired sebanyak 1 dan membuat klon dari sprite Peluru untuk menggerakkan peluru ke atas, seperti yang akan kita lihat selanjutnya. Skrip kemudian menunggu beberapa saat untuk mencegah pemain menembakkan peluru lain terlalu cepat. Sekarang kita siap mempelajari skrip dari peluru yang dikloning, seperti yang ditunjukkan pada Gambar 7-28.

Pertama, Peluru dipindahkan ke tengah Penembak dan dibuat terlihat u. Peluru kemudian digerakkan ke atas dengan kelipatan 10 langkah menggunakan blok ulangi sampai v. Jika koordinat y peluru melebihi 160, maka Peluru telah mencapai tepi atas Panggung tanpa menyentuh burung apa pun. Dalam hal ini, blok ulangi sampai keluar y, dan klon dihapus. Namun, pemeriksaan benturan dilakukan setiap kali peluru bergerak. Jika peluru mengenai Bird1 (atau klonnya) w, skrip akan meningkatkan variabel Hits dan memutar suara untuk membuat permainan lebih seru. Di sisi lain, jika peluru mengenai Bird2 x, skrip akan menyiarkan GameOver untuk menandai akhir permainan. Dalam kedua kasus, klon akan dihapus karena telah menyelesaikan tugasnya.

Permainan sekarang berfungsi penuh, tetapi Anda dapat menambahkan banyak fitur ke dalamnya.

Berikut dua saran:

• Beri pemain jumlah peluru yang terbatas dan catat skor berdasarkan jumlah tembakan yang meleset.

• Tambahkan lebih banyak burung dan buat mereka bergerak dengan kecepatan berbeda. Beri penghargaan kepada pemain dengan lebih banyak poin karena mengenai burung yang lebih cepat.


Gambar 7-28: Penanganan awal dari Peluru yang dikloning


coba 7-8
Buka permainan dan mainkan untuk melihat cara kerjanya. Modifikasi permainan dengan


Simulasi Jatuh Bebas
Pada bagian ini, saya akan menyajikan sebuah aplikasi yang mensimulasikan gerakan sebuah benda yang jatuh. Dengan mengabaikan efek daya apung dan hambatan udara, ketika sebuah benda yang diam dijatuhkan dari ketinggian tertentu, jarak d (dalam meter) yang ditempuh benda tersebut selama waktu t (dalam detik) diberikan oleh d = ½ gt², di mana g = 9,8 m/s² adalah percepatan gravitasi. Tujuan dari simulasi ini adalah untuk menunjukkan posisi benda yang jatuh pada waktu 0,5 s, 1,0 s, 1,5 s, 2,0 s, dan selanjutnya, hingga benda tersebut mencapai tanah. Antarmuka untuk simulasi ini ditunjukkan pada Gambar 7-29.


Gambar 7-29: Antarmuka pengguna untuk simulasi jatuh bebas

Sebuah benda yang diam (bola pada gambar) akan dibiarkan jatuh dari ketinggian 35 m. Substitusi sederhana pada rumus di atas menunjukkan bahwa objek akan mencapai tanah setelah t = (2 × 35)/ 9,8 = 2,67 s. Aplikasi ini memiliki satu sprite (disebut Bola) yang memiliki dua kostum seperti yang ditunjukkan pada gambar.

Ketika tiba waktunya untuk menunjukkan posisi bola yang jatuh, sprite berubah sejenak ke kostum penanda, membuat cap, dan beralih kembali ke kostum bola.

Simulasi dimulai ketika bendera hijau diklik. Sebagai respons, sprite Bola menjalankan skrip yang ditunjukkan pada Gambar 7-30.

Selama inisialisasi u, sprite bergerak ke posisi awalnya, beralih ke kostum bola, menghapus gelembung suaranya dari eksekusi sebelumnya, dan menghapus Panggung dari cap sebelumnya. Kemudian menginisialisasi t dan counter ke 0. Variabel t mewakili durasi jatuh, dan counter melacak jumlah pengulangan loop.

Skrip kemudian memasuki loop tak terbatas v untuk menghitung parameter simulasi pada interval waktu yang berbeda. Skrip melakukan perhitungan tersebut dan memperbarui posisi bola setiap 0,05 s w untuk memastikan pergerakan bola yang mulus.

Setiap 0,05 s, nilai variabel waktu t diperbarui, dan jarak jatuhnya bola (d) dihitung. Nilai variabel penghitung juga ditambah 1.


Gambar 7-30: Skrip untuk sprite Bola dalam simulasi jatuh bebas

Jika bola mencapai tanah (yang terjadi pada d ≥ 35), skrip mengatur posisi y bola ke posisi tanah, menampilkan durasi sebenarnya perjalanan, dan menghentikan skrip untuk mengakhiri simulasi x.

Jika tidak, skrip mengatur posisi vertikal bola sesuai dengan jarak jatuhnya y. Karena ketinggian 35 m sesuai dengan 268 piksel pada Panggung (lihat Gambar 7-29), jarak d meter sesuai dengan 268 * (d / 35). Posisi y akhir ditentukan dengan mengurangi angka ini dari posisi y awal, yaitu 136.

Karena durasi iterasi adalah 0,05 s, dibutuhkan 10 iterasi untuk mendapatkan 0,5 s. Jadi, ketika penghitung menjadi 10, 20, 30, dan seterusnya, sprite Bola beralih ke (dan memberi cap) kostum penanda untuk menunjukkan posisi bola yang jatuh pada saat-saat z tersebut.


Gambar 7-31 mengilustrasikan hasil menjalankan simulasi ini. Perhatikan bagaimana jarak yang ditempuh dalam setiap interval waktu meningkat seiring jatuhnya objek. Karena gravitasi, bola berakselerasi—kecepatannya meningkat—dengan laju 9,8 m/s².


Cobalah 7-9 
Buka aplikasi dan jalankan untuk memahami cara kerjanya. Cobalah mengubah simulasi menjadi permainan di mana pemain menjatuhkan bola untuk mengenai objek bergerak di tanah. Anda dapat menambahkan skor, mengubah kecepatan target, atau bahkan mengatur aksi di planet lain (mengubah percepatan gravitasi).



Gambar 7-31: Keluaran simulasi jatuh bebas Simulator Gerak Proyektil

Pertimbangkan sebuah bola yang ditembakkan dengan kecepatan awal (v0) dari sebuah meriam yang mengarah pada sudut q dari horizontal. Anda dapat menganalisis lintasan bola dengan menguraikan vektor kecepatan (v0) menjadi komponen horizontal dan vertikalnya pada waktu yang berbeda. Komponen horizontal tetap konstan, tetapi komponen vertikal dipengaruhi oleh gravitasi. Ketika gerakan yang sesuai dengan kedua komponen ini digabungkan, lintasan yang dihasilkan adalah parabola.

Mari kita periksa persamaan yang mengatur gerak proyektil (dengan mengabaikan hambatan udara).

Titik asal sistem koordinat kita adalah titik di mana bola memulai penerbangannya, sehingga koordinat x bola pada waktu t tertentu diberikan oleh x(t) = v0xt, dan koordinat y adalah y(t) = v0yt − (0,5)gt2, di mana v0x = v0 cos q adalah komponen x dari v0; v0y = v0 sin q adalah komponen y dari v0; dan g = 9,8 m/s2 adalah percepatan gravitasi. Dengan menggunakan persamaan-persamaan ini, kita dapat menghitung total waktu penerbangan, ketinggian maksimum, dan jangkauan horizontal bola. Persamaan untuk besaran-besaran ini ditunjukkan pada Gambar 7-32.


Gambar 7-32: Lintasan parabola sebuah bola

Informasi ini adalah semua yang kita butuhkan untuk mensimulasikan gerakan bola secara realistis, jadi mari kita buat program Scratch agar kita dapat melihat fisika ini beraksi dan memperdalam pemahaman kita tentang lintasan. Antarmuka pengguna dari simulasi ditunjukkan pada Gambar 7-33.


Gambar 7-33: Antarmuka pengguna untuk simulator gerak proyektil

Seperti yang ditunjukkan, aplikasi ini berisi empat sprite. Sprite Roda menyediakan poros rotasi untuk meriam, sementara sprite Meriam, yang berputar sesuai dengan penggeser sudut, memberikan indikasi visual dari sudut peluncuran. Sprite Tembak adalah tombol yang diklik pengguna untuk menembakkan bola, dan sprite Bola berisi skrip utama untuk menghitung koordinat bola dan menggambar lintasannya. Pengguna menentukan sudut peluncuran dan kecepatan awal menggunakan dua kontrol penggeser, lalu mengklik tombol Tembak. Bola mulai dari titik (–180, –140) pada Panggung dan menggambar lintasan parabola untuk parameter yang ditentukan. Dua monitor di sudut kanan bawah Panggung menunjukkan waktu penerbangan dan jangkauan horizontal selama penerbangan.

Simulasi dimulai ketika ikon bendera hijau diklik. Skrip untuk sprite Meriam (tidak ditampilkan di sini) mengarahkan meriam ke arah yang ditentukan oleh kontrol penggeser sudut. Pengguna juga dapat menentukan sudut dengan mengklik dan menyeret meriam. Ketika pengguna mengklik tombol Tembak, tombol tersebut mengirimkan pesan Tembak, yang diterima dan diproses oleh sprite Bola melalui skrip yang ditunjukkan pada Gambar 7-34.

Untuk bersiap menembak, Bola bergerak di depan Meriam dan Roda dan memposisikan dirinya di titik peluncuran. Bola meletakkan pena dan menghapus semua tanda pena dari Panggung. Skrip kemudian menghitung komponen horizontal (atau x) dan vertikal (atau y) dari kecepatan awal (masing-masing bernama vx dan vy) dan menginisialisasi variabel waktu (t) ke 0.


Gambar 7-34: Skrip untuk sprite Bola

Skrip kemudian memasuki loop tak terbatas v, yang menghitung dan memperbarui posisi bola setiap 0,02 s. Pertama, jarak vertikal (dy) dari sprite dihitung w. Jika nilai yang dihitung negatif, maka bola telah mencapai permukaan tanah. Ketika ini terjadi, perintah stop this script dipanggil untuk mengakhiri simulasi. Jika dy tidak negatif, jarak horizontal (d) dihitung x.

Kedua jarak (dy dan d) kemudian diskalakan sesuai dengan latar belakang Stage. Dalam arah vertikal, kita memiliki 320 langkah (dari –140 hingga 180) yang sesuai dengan 100 m, dan dalam arah horizontal, kita memiliki 420 langkah (dari –180 hingga 240) yang sesuai dengan 100 m. Ini berarti jarak vertikal dy meter setara dengan 320 * dy / 100 langkah, dan jarak horizontal d meter setara dengan 420 * d / 100 langkah. Koordinat x dan y bola diperbarui, dan bola dipindahkan ke posisi saat ini pada lintasannya. Variabel waktu (t) kemudian ditambah dengan sejumlah kecil (0,02 s dalam kasus ini), dan loop diulang untuk menghitung posisi bola berikutnya.

Sebagai contoh, jika bola diluncurkan dengan sudut peluncuran 70° dan kecepatan awal 30 m/s, seperti yang ditunjukkan pada Gambar 7-33, waktu penerbangan total adalah 5,75 s, dan jangkauannya adalah 59 m. Pemeriksaan monitor pada Gambar 7-33 menunjukkan bahwa simulasi kami sangat akurat. Kita dapat meningkatkan simulasi dengan memperbarui perhitungan kita lebih sering (misalnya, setiap 0,01 s, bukan setiap 0,02 s), tetapi itu akan memperlambat simulasi. Perlu untuk menyesuaikan parameter ini untuk mencapai kompromi yang baik antara kecepatan dan akurasi.



Cobalah 7-10
Buka aplikasi dan jalankan untuk memahami cara kerjanya. Kemudian coba ubah simulasi ini menjadi permainan. Misalnya, Anda dapat menampilkan objek pada ketinggian acak di tepi kanan panggung dan meminta pemain untuk mencoba mengenainya. Jika pemain meleset dari target, permainan dapat memberikan beberapa petunjuk tentang penyesuaian sudut dan kecepatan tembakan.


Aplikasi Lainnya
Sumber daya tambahan untuk buku ini (tersedia di http://nostarch.com/learnscratch/) berisi tiga permainan lagi yang dapat Anda jelajahi sendiri, dengan penjelasan lengkap untuk setiap skrip. Yang pertama adalah permainan edukatif yang dapat digunakan untuk menguji kemampuan berhitung siswa sekolah dasar.

Permainan ini menampilkan sejumlah uang dalam koin dan meminta pemain untuk menemukan jumlah koin terkecil yang dibutuhkan untuk mendapatkan jumlah tersebut.

Aplikasi kedua adalah simulasi gerak planet untuk tata surya sederhana yang berisi matahari dan satu planet. Aplikasi ketiga juga merupakan simulasi, yang satu ini mendemonstrasikan dinamika gerak saat satu molekul gas bertabrakan dengan dinding wadah.

Buka aplikasi-aplikasi ini, jalankan, dan baca penjelasan saya untuk memahami cara kerjanya. Jika Anda merasa terinspirasi untuk mengasah kemampuan pemrograman Anda, coba modifikasi skrip untuk membuatnya melakukan hal-hal baru!


Ringkasan

Dalam bab ini, kita telah menjelajahi berbagai cara untuk mengulang perintah di Scratch.

Pertama, kita memeriksa berbagai blok perulangan dan menjelaskan istilah teknis yang terkait dengannya. Kemudian, kita membahas perulangan pasti dan tak pasti, dan perbedaan antara perulangan yang dikendalikan penghitung dan perulangan yang dikendalikan kondisi. Kita menjelajahi blok ulangi sampai dan struktur jika selamanya dan menggunakannya dalam beberapa contoh. Saya juga menjelaskan perintah berhenti Scratch dan bagaimana Anda dapat menggunakannya untuk menghentikan perulangan dan prosedur tak terbatas. Dari sana, kita melanjutkan untuk membahas penggunaan perulangan untuk memvalidasi data dari input pengguna.

Anda kemudian mempelajari cara menggunakan penghitung untuk melacak berapa banyak iterasi dari sebuah loop yang telah berlalu dan cara menggunakan penghitung dengan loop bersarang untuk membuat iterasi dalam dua dimensi atau lebih. Setelah itu, kita melihat rekursi—sebuah prosedur yang memanggil dirinya sendiri—sebagai cara lain untuk mencapai pengulangan.

Pada bagian terakhir, kita mengembangkan beberapa aplikasi yang menghubungkan konsep-konsep baru ini untuk membuat program praktis.

Bab selanjutnya akan memperluas topik yang telah Anda pelajari di sini dan mengajarkan Anda cara menggunakan penghitung dan loop untuk memproses string dan membuat kelas program menarik yang berbeda, seperti konverter biner ke desimal, permainan tebak kata, dan tutor matematika untuk mengajar pecahan.

Jika Anda ingin mengeksplorasi lebih lanjut konsep-konsep baru dari bab ini, saya sarankan untuk mencoba beberapa soal berikut.


Soal

1. Buat loop validasi input yang hanya menerima angka dalam rentang 1 hingga 10.

2. Tulis skrip yang menanyakan kepada pengguna, “Apakah Anda yakin ingin keluar [Y, N]?”

Skrip kemudian memeriksa input pengguna dan hanya menerima huruf Y dan N sebagai jawaban yang valid.

3. Tulis program yang menghitung dan menampilkan jumlah semua bilangan bulat antara 1 dan 20.

4. Tulis program yang menghitung dan menampilkan jumlah semua bilangan ganjil antara 1 dan 20.

5. Tulis program yang menampilkan 10 angka pertama dalam urutan berikut (menggunakan

perintah say): 5, 9, 13, 17, 21, ....

6. Apa yang dilakukan skrip di kanan? Implementasikan skrip tersebut dan jalankan untuk memeriksa jawaban Anda.

7. Jika sisa pembagian suatu bilangan bulat (x) dengan bilangan bulat lainnya (y) adalah 0, kita katakan bahwa y adalah faktor dari x. Misalnya, 1, 2, 4, dan

8 adalah faktor dari 8. Skrip di bawah ini menemukan dan menampilkan semua faktor dari suatu bilangan (selain bilangan itu sendiri). Pelajari skrip ini dan jelaskan cara kerjanya. Apa saja output dari skrip ini ketika angka inputnya adalah 125, 324, dan 419?

8. Suatu bilangan bulat dikatakan prima jika hanya habis dibagi oleh 1 dan dirinya sendiri. Misalnya, 2, 3, 5, 7, 11 adalah bilangan prima, tetapi 4, 6, dan 8 bukan. Prosedur pada halaman berikutnya menguji apakah suatu bilangan adalah bilangan prima atau bukan. Pelajari prosedur ini dan jelaskan cara kerjanya. Apa saja output dari prosedur ini untuk input 127, 327, dan 523?

9. Meskipun prosedur pada soal nomor 8 memeriksa semua bilangan bulat hingga setengah dari nilai masukan, cukup dengan menetapkan batas atas ke akar kuadrat dari nilai masukan. Lakukan perubahan ini pada prosedur dan uji untuk melihat apakah masih memberikan jawaban yang sama.

10. Deret angka 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 .... disebut deret Fibonacci. Dua angka pertama dalam deret tersebut adalah 0 dan 1. Setiap angka berikutnya kemudian dihitung sebagai jumlah dari dua angka sebelumnya. Tulis program yang menghitung suku ke-n dari deret Fibonacci, di mana n dimasukkan oleh pengguna.

11. Perhatikan program berikut dan output yang dihasilkannya. Buat ulang program tersebut dan jalankan untuk melihat cara kerjanya. Ubah sudut putaran (dari 10°) dan argumen dalam panggilan rekursif (menjadi sisi + 1 atau sisi + 3, dan seterusnya) untuk menemukan apa lagi yang dapat Anda buat.