# Table of Contents - [O‘yin yaratish orqali loyiha asosida Python o‘rganish | Python-Pygame Zero](#o-yin-yaratish-orqali-loyiha-asosida-python-o-rganish-python-pygame-zero) - [2. Dasturlash muhitini tayyorlash | Python-Pygame Zero](#2-dasturlash-muhitini-tayyorlash-python-pygame-zero) - [1. Pygame Zero kutubxonasi | Python-Pygame Zero](#1-pygame-zero-kutubxonasi-python-pygame-zero) - [4. O'yin siklini tushunish | Python-Pygame Zero](#4-o-yin-siklini-tushunish-python-pygame-zero) - [3. "Hello World" dasturidan boshlaylik | Python-Pygame Zero](#3-hello-world-dasturidan-boshlaylik-python-pygame-zero) - [10. Pongni tarmoq o‘yiniga aylantirish | Python-Pygame Zero](#10-pongni-tarmoq-o-yiniga-aylantirish-python-pygame-zero) - [5.6 Flappy Bird o‘yiniga qo‘shimcha funksiyalarni joriy qilish (ball funksiyasi) | Python-Pygame Zero](#5-6-flappy-bird-o-yiniga-qo-shimcha-funksiyalarni-joriy-qilish-ball-funksiyasi-python-pygame-zero) - [Ilova | Python-Pygame Zero](#ilova-python-pygame-zero) - [5.2 Flappy Bird(obyekt)ni ekranga chiqarish va harakatlantirish | Python-Pygame Zero](#5-2-flappy-bird-obyekt-ni-ekranga-chiqarish-va-harakatlantirish-python-pygame-zero) - [5.5 Flappy Bird va quvurlar o‘rtasida to‘qnashuvni amalga oshirish | Python-Pygame Zero](#5-5-flappy-bird-va-quvurlar-o-rtasida-to-qnashuvni-amalga-oshirish-python-pygame-zero) - [5.1 Ekranga fon rasmi(obyekti)ni chiqarish | Python-Pygame Zero](#5-1-ekranga-fon-rasmi-obyekti-ni-chiqarish-python-pygame-zero) - [10.4 Tarmoqli o‘yinga aylantirish 2 | Python-Pygame Zero](#10-4-tarmoqli-o-yinga-aylantirish-2-python-pygame-zero) - [5.4 Quvur(obyekt)ni ekranga chiqarish va harakatlantirish | Python-Pygame Zero](#5-4-quvur-obyekt-ni-ekranga-chiqarish-va-harakatlantirish-python-pygame-zero) - [Entry-Python darsturlash asoslari | Entry-Python](#entry-python-darsturlash-asoslari-entry-python) - [6.2 Aktyorlarning harakatlarini amalga oshirish | Python-Pygame Zero](#6-2-aktyorlarning-harakatlarini-amalga-oshirish-python-pygame-zero) - [8.5 Obyektga yo‘naltirilgan dasturlash 1 | Python-Pygame Zero](#8-5-obyektga-yo-naltirilgan-dasturlash-1-python-pygame-zero) - [9.1 Protseduraviy dasturlash 1 | Python-Pygame Zero](#9-1-protseduraviy-dasturlash-1-python-pygame-zero) - ["Pygame Zero" yordamida Python o'rganish | Pygame Zero boshlang'ich](#-pygame-zero-yordamida-python-o-rganish-pygame-zero-boshlang-ich) - [O'yinimizni EXE fayliga aylantirish | Python-Pygame Zero](#o-yinimizni-exe-fayliga-aylantirish-python-pygame-zero) - [8.2 Protseduraviy dasturlash 2 | Python-Pygame Zero](#8-2-protseduraviy-dasturlash-2-python-pygame-zero) - [6.4 To‘qnashuv testini o‘tkazishda e’tiborga olish kerak bo‘lgan narsalar | Python-Pygame Zero](#6-4-to-qnashuv-testini-o-tkazishda-e-tiborga-olish-kerak-bo-lgan-narsalar-python-pygame-zero) - [5. Flappy Bird o'yinini yaratish | Python-Pygame Zero](#5-flappy-bird-o-yinini-yaratish-python-pygame-zero) - [9.3 Obyektga yo‘naltirilgan dasturlash 1 | Python-Pygame Zero](#9-3-obyektga-yo-naltirilgan-dasturlash-1-python-pygame-zero) - [6.1 O‘yin sahnasiga fon va aktyorlarni qo'shish | Python-Pygame Zero](#6-1-o-yin-sahnasiga-fon-va-aktyorlarni-qo-shish-python-pygame-zero) - [10.3 Tarmoqli o‘yinga aylantirish 1 | Python-Pygame Zero](#10-3-tarmoqli-o-yinga-aylantirish-1-python-pygame-zero) - [9.6 Obyektga yo‘naltirilgan dasturlash 3 | Python-Pygame Zero](#9-6-obyektga-yo-naltirilgan-dasturlash-3-python-pygame-zero) - [8.7 (Bonus) Pygame Zero misoli versiyasi 1 | Python-Pygame Zero](#8-7-bonus-pygame-zero-misoli-versiyasi-1-python-pygame-zero) - [5.3 Flappy Bird(obyekt)ning ekrandagi tabiiy harakatini yaratish | Python-Pygame Zero](#5-3-flappy-bird-obyekt-ning-ekrandagi-tabiiy-harakatini-yaratish-python-pygame-zero) - [6. Breakout o‘yinini yaratish | Python-Pygame Zero](#6-breakout-o-yinini-yaratish-python-pygame-zero) - [9.4 Obektga yo‘naltirilgan dasturlash nazariyasi (interfeys) | Python-Pygame Zero](#9-4-obektga-yo-naltirilgan-dasturlash-nazariyasi-interfeys-python-pygame-zero) - [10.1 Tarmoqli o‘yinlarni tushunish va kutubxonani o‘rnatish | Python-Pygame Zero](#10-1-tarmoqli-o-yinlarni-tushunish-va-kutubxonani-o-rnatish-python-pygame-zero) - [7. TwinBee otishma o‘yinini yaratish | Python-Pygame Zero](#7-twinbee-otishma-o-yinini-yaratish-python-pygame-zero) - [7.1 Skrol fon obyektini yaratish, fon musiqasi, aktyorlar (dushman, qahramon) ni tanishtirish | Python-Pygame Zero](#7-1-skrol-fon-obyektini-yaratish-fon-musiqasi-aktyorlar-dushman-qahramon-ni-tanishtirish-python-pygame-zero) - [5.8 Flappy Bird o‘yini uchun qo‘shimcha funksiyalar (Flappy Bird animatsiyasi) | Python-Pygame Zero](#5-8-flappy-bird-o-yini-uchun-qo-shimcha-funksiyalar-flappy-bird-animatsiyasi-python-pygame-zero) - [6.3 To‘pni aks ettirish va bloklarni sindirishni amalga oshirish | Python-Pygame Zero](#6-3-to-pni-aks-ettirish-va-bloklarni-sindirishni-amalga-oshirish-python-pygame-zero) - [7.4 Qo‘shimcha vazifalar | Python-Pygame Zero](#7-4-qo-shimcha-vazifalar-python-pygame-zero) - [6.5 (Bonus) Original o‘yin kabi yaratib ko‘rish | Python-Pygame Zero](#6-5-bonus-original-o-yin-kabi-yaratib-ko-rish-python-pygame-zero) - [5.7 Flappy Bird o'yini uchun qo'shimcha funksiyalar (quvur pozitsiyalarini tasodiylashtirish) | Python-Pygame Zero](#5-7-flappy-bird-o-yini-uchun-qo-shimcha-funksiyalar-quvur-pozitsiyalarini-tasodiylashtirish-python-pygame-zero) - [8. Pong o‘yinini yaratish | Python-Pygame Zero](#8-pong-o-yinini-yaratish-python-pygame-zero) - [7.3 To‘qnashuvni boshqarish va boshqa ma‘lumotlar(hisob va o‘yin yakuni)ni ko‘rsatish | Python-Pygame Zero](#7-3-to-qnashuvni-boshqarish-va-boshqa-ma-lumotlar-hisob-va-o-yin-yakuni-ni-ko-rsatish-python-pygame-zero) - [9. Battle city o‘yinini yaratish | Python-Pygame Zero](#9-battle-city-o-yinini-yaratish-python-pygame-zero) - [8.3 Obyektga Yo‘naltirilgan Dasturlash nazariyasi (Obyektga Yo‘naltirilgan dizayn nima) | Python-Pygame Zero](#8-3-obyektga-yo-naltirilgan-dasturlash-nazariyasi-obyektga-yo-naltirilgan-dizayn-nima-python-pygame-zero) - [Mu editorining tezkor tugmalari | Python-Pygame Zero](#mu-editorining-tezkor-tugmalari-python-pygame-zero) - [8.6 Obyektga yo‘naltirilgan dasturlash 2 | Python-Pygame Zero](#8-6-obyektga-yo-naltirilgan-dasturlash-2-python-pygame-zero) - [8.1 Protseduraviy dasturlash 1 | Python-Pygame Zero](#8-1-protseduraviy-dasturlash-1-python-pygame-zero) - [8.4 Obyektga Yo‘naltirilgan Dasturlash nazariyasi (foydalanuvchi aniqlagan obyekt yaratish, meros) | Python-Pygame Zero](#8-4-obyektga-yo-naltirilgan-dasturlash-nazariyasi-foydalanuvchi-aniqlagan-obyekt-yaratish-meros-python-pygame-zero) - [7.2 Aktyorlarning harakati va o‘q otish hujumini amalga oshirish | Python-Pygame Zero](#7-2-aktyorlarning-harakati-va-o-q-otish-hujumini-amalga-oshirish-python-pygame-zero) - [10.2 Rele serverini ishga tushurish va mijozning ulanishi | Python-Pygame Zero](#10-2-rele-serverini-ishga-tushurish-va-mijozning-ulanishi-python-pygame-zero) - [9.2 Protseduraviy dasturlash 2 | Python-Pygame Zero](#9-2-protseduraviy-dasturlash-2-python-pygame-zero) - [8.8 (Bonus) Pygame Zero misoli versiyasi 2 | Python-Pygame Zero](#8-8-bonus-pygame-zero-misoli-versiyasi-2-python-pygame-zero) - [9.7 Obyektga yo‘naltirilgan dasturlash 4 | Python-Pygame Zero](#9-7-obyektga-yo-naltirilgan-dasturlash-4-python-pygame-zero) - [9.5 Obyektga yo‘naltirilgan dasturlash 2 | Python-Pygame Zero](#9-5-obyektga-yo-naltirilgan-dasturlash-2-python-pygame-zero) - [Dasturimizni EXE fayliga aylantirish | Pygame Zero boshlang'ich](#dasturimizni-exe-fayliga-aylantirish-pygame-zero-boshlang-ich) - [4.3 Hodisaga asoslangan (Event-Driven) | Entry-Python](#4-3-hodisaga-asoslangan-event-driven-entry-python) - [3.2 Kiritish/Chiqarish (Input/Output) | Entry-Python](#3-2-kiritish-chiqarish-input-output-entry-python) - [5.1.2 Kuchuk va mushuk Salom aytadi2 (Ketma-ketlik) | Pygame Zero boshlang'ich](#5-1-2-kuchuk-va-mushuk-salom-aytadi2-ketma-ketlik-pygame-zero-boshlang-ich) - [2. Entry-Python bilan ishlashni boshlash | Entry-Python](#2-entry-python-bilan-ishlashni-boshlash-entry-python) - [1. Entry vs Entry-Python | Entry-Python](#1-entry-vs-entry-python-entry-python) - [3. Entry-Python yordamida Python sintaksisining asoslarini o‘rganamiz | Entry-Python](#3-entry-python-yordamida-python-sintaksisining-asoslarini-o-rganamiz-entry-python) - [4. Entry-Python yordamida dasturlashning asosiy tushunchalarini o‘rganamiz | Entry-Python](#4-entry-python-yordamida-dasturlashning-asosiy-tushunchalarini-o-rganamiz-entry-python) - [Ilova | Entry-Python](#ilova-entry-python) - [1. "Pygame Zero" kutubxonasi | Pygame Zero boshlang'ich](#1-pygame-zero-kutubxonasi-pygame-zero-boshlang-ich) - [Dasturlashni o‘rganish uchun bepul kitoblar | Tanishuv kitoblari](#dasturlashni-o-rganish-uchun-bepul-kitoblar-tanishuv-kitoblari) - [4.4 Obyektga yo‘naltirilgan (Object-Oriented) | Entry-Python](#4-4-obyektga-yo-naltirilgan-object-oriented-entry-python) - [4.2 Protsessual (Procedural) | Entry-Python](#4-2-protsessual-procedural-entry-python) - [2. Dasturlash muhitini tayyorlash | Pygame Zero boshlang'ich](#2-dasturlash-muhitini-tayyorlash-pygame-zero-boshlang-ich) - [Kirish | Pygame Zero boshlang'ich](#kirish-pygame-zero-boshlang-ich) - [Ilova | Pygame Zero boshlang'ich](#ilova-pygame-zero-boshlang-ich) - [5. Entry boshlang'ich darajali kitobini kodlash | Pygame Zero boshlang'ich](#5-entry-boshlang-ich-darajali-kitobini-kodlash-pygame-zero-boshlang-ich) - [4. O'yin siklini tushunish | Pygame Zero boshlang'ich](#4-o-yin-siklini-tushunish-pygame-zero-boshlang-ich) - [3. "Hello World" dasturidan boshlaylik | Pygame Zero boshlang'ich](#3-hello-world-dasturidan-boshlaylik-pygame-zero-boshlang-ich) - [3.3 O‘zgaruvchi (Variable) | Entry-Python](#3-3-o-zgaruvchi-variable-entry-python) - [3.7 Tasodifiy son (Random) | Entry-Python](#3-7-tasodifiy-son-random-entry-python) - [3.5 Takrorlash (Loop) | Entry-Python](#3-5-takrorlash-loop-entry-python) - [3.6 Ro‘yxat (List) | Entry-Python](#3-6-ro-yxat-list-entry-python) - [3.1 "Hello World" namuna kodini tushunish | Entry-Python](#3-1-hello-world-namuna-kodini-tushunish-entry-python) - [5.2 Bitta gulbargdan gul yasash (Takrorlash) | Pygame Zero boshlang'ich](#5-2-bitta-gulbargdan-gul-yasash-takrorlash-pygame-zero-boshlang-ich) - [4.1 Ketma-ket/Parallel ishlov berish (Serial/Parallel) | Entry-Python](#4-1-ketma-ket-parallel-ishlov-berish-serial-parallel-entry-python) - [5.5 Qo'llarni cho'zgan holda sakrashlar sonini sanang (O'zgaruvchi) | Pygame Zero boshlang'ich](#5-5-qo-llarni-cho-zgan-holda-sakrashlar-sonini-sanang-o-zgaruvchi-pygame-zero-boshlang-ich) - [Mu editorining tezkor tugmalari | Pygame Zero boshlang'ich](#mu-editorining-tezkor-tugmalari-pygame-zero-boshlang-ich) - [3.4 Shart (Condition) | Entry-Python](#3-4-shart-condition-entry-python) - [3.8 Funksiya (Function) | Entry-Python](#3-8-funksiya-function-entry-python) - [5.1.1 Kuchuk va mushuk Salom aytadi1 (Ketma-ketlik) | Pygame Zero boshlang'ich](#5-1-1-kuchuk-va-mushuk-salom-aytadi1-ketma-ketlik-pygame-zero-boshlang-ich) - [5.6 Xazina sandig'ini ochish uchun parolni kiriting (Kiritish/Chiqarish) | Pygame Zero boshlang'ich](#5-6-xazina-sandig-ini-ochish-uchun-parolni-kiriting-kiritish-chiqarish-pygame-zero-boshlang-ich) - [5.7 Ko'rsichqon o'yini yasash (Jamlash) | Pygame Zero boshlang'ich](#5-7-ko-rsichqon-o-yini-yasash-jamlash-pygame-zero-boshlang-ich) - [5.1.3 Kuchuk va mushuk Salom aytadi3 (Ketma-ketlik) | Pygame Zero boshlang'ich](#5-1-3-kuchuk-va-mushuk-salom-aytadi3-ketma-ketlik-pygame-zero-boshlang-ich) - [5.4 O'zingizga rasm chizish taxtasini yasang (Hodisa) | Pygame Zero boshlang'ich](#5-4-o-zingizga-rasm-chizish-taxtasini-yasang-hodisa-pygame-zero-boshlang-ich) - [5.3 Robot changyutkich to'siqga duch kelsa nima bo'ladi? (Shart) | Pygame Zero boshlang'ich](#5-3-robot-changyutkich-to-siqga-duch-kelsa-nima-bo-ladi-shart-pygame-zero-boshlang-ich) - [Entry-Pythonning tezkor tugmalari | Entry-Python](#entry-pythonning-tezkor-tugmalari-entry-python) --- # O‘yin yaratish orqali loyiha asosida Python o‘rganish | Python-Pygame Zero Python dasturlash tili matnli dasturlash tillari orasida eng oson va shu bilan birga inson tiliga eng yaqin deb tanilgan. Bu tilni o‘rganish oson degan gap keng tarqalgan bo‘lsada, dunyoda hech qanday xorijiy til (hatto kompyuter bilan muloqot qilish uchun ishlatiladigan dasturlash tili ham xorijiy tilning bir turi sifatida qaralishi mumkin) qanchalik oson bo‘lmasin, uni hech qanday qiyinchiliklarsiz o‘rganish imkoni bo‘lganmi? Hech bo‘lmaganda mening xotiramda bunday holat bo‘lmagan. Til o‘rganish murakkab va sabr-toqat talab qiladigan jarayon bo‘lsada, kamroq charchatadigan o‘qitish uslublari mavjud. Shuni esga olib, bu blokli dasturlashda bir qancha ko‘nikmalarni hosil qilgan va endi matnli dasturlashga jiddiy kirishga tayyorlanganlar uchun uchinchi kitobdir. Agar siz faqat blokli dasturlashni bilsangiz va matnli dasturlash tajribangiz bo‘lmasa, “[Entry-Pythonarrow-up-right](https://roboticsware.gitbook.io/entry-python) ” va “[Entry boshlang‘ich kitobidagi 7 ta misoldan foydalanib Python o‘rganisharrow-up-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic) ” nomli ikki kitobni avval o‘rganib chiqishingiz tavsiya etiladi. Shunda ushbu kitob siz uchun qulay darajada bo‘ladi. Ammo ayrim o‘quvchilar Pythonning asosiy sintaksisini ma’lum darajada bilaman deb hisoblasalar, to‘g‘ridan-to‘g‘ri ushbu kitobdan o‘rganishni boshlashlari mumkin. **Bu kitob sizni tezda charchatadigan mavjud til grammatikasiga qaratilgan kitob emas**, balki blokli kodlash jarayonida son-sanoqsiz marta boshdan kechirgan va shu tarzda o‘sib borgan **"Loyihaga asoslangan o‘rganish" deb nomlangan mavjud o‘sish yo‘limizni qo‘llaydigan o‘yin ishlab chiqarishga asoslangan Python tilini o‘rganish usulidan foydalanadi.** Ushbu kitob, avvalgi kitob kabi, PyGame o‘yinlar kutubxonasining soddalashtirilgan versiyasi bo‘lgan PyGame Zero kutubxonasidan foydalanish orqali oson yondashishga harakat qiladi. Biroq, kutubxona oson bo‘lgani uchun, kodlash oson ekanligini kafolatlat qilish qiyin. Ammo oldindan tashvishlanmang, chunki ushbu kitob muallifi sizga do‘stona yo‘l ko‘rsatuvchi bo‘ladi va kodlashni o‘rganish sayohatingizda hamroh bo‘ladi. ### [hashtag](https://roboticsware.gitbook.io/python-pygame_zero#ozgarishlar-tarixi) O'zgarishlar tarixi: Versiya Sana Tavsif v1 2025/4/18 Birinchi versiya chiqishi ### [hashtag](https://roboticsware.gitbook.io/python-pygame_zero#muallif-jj-comseong-gmail.com) **Muallif : JJ (** [**comseong@gmail.com**arrow-up-right](https://jjlee.gitbook.io/python-pygame_zero#jj-comseong-gmail.com) **)** ### [hashtag](https://roboticsware.gitbook.io/python-pygame_zero#ozbek-tiliga-tarjima-komron-knmv2311-gmail.com) **O'zbek tiliga tarjima: Komron (**[knmv2311@gmail.comenvelope](mailto:knmv2311@gmail.com) **)** ### [hashtag](https://roboticsware.gitbook.io/python-pygame_zero#malumot-materiallari) **Malumot materiallari:** [https://pygamezero-bird.readthedocs.io/en/latest/index.htmlarrow-up-right](https://pygamezero-bird.readthedocs.io/en/latest/index.html) [https://github.com/StanislavPetrovV/Python-Arkanoid-Breakoutarrow-up-right](https://github.com/StanislavPetrovV/Python-Arkanoid-Breakout) [https://github.com/WokLibCodeClub/breakoutarrow-up-right](https://github.com/WokLibCodeClub/breakout) [https://m.blog.naver.com/elpissoft/120185941500arrow-up-right](https://m.blog.naver.com/elpissoft/120185941500) [https://aposteriori.trinket.io/game-development-with-pygame-zeroarrow-up-right](https://aposteriori.trinket.io/game-development-with-pygame-zero) ### [hashtag](https://roboticsware.gitbook.io/python-pygame_zero#mualliflik-huquqi-https-creativecommons.org-licenses-by-nc-sa-4.0) **Mualliflik huquqi:** [**https://creativecommons.org/licenses/by-nc-sa/4.0/**arrow-up-right](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.ko) ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FjLwYdWGwpC1oUOZRAocj%252Fimage.png%3Falt%3Dmedia%26token%3D8f2f42be-5d77-4039-bf7c-a052fbd9fa07&width=768&dpr=3&quality=100&sign=28b25ac9&sv=2) [Next1\. Pygame Zero kutubxonasichevron-right](https://roboticsware.gitbook.io/python-pygame_zero/pygame_zero_lib) Last updated 5 months ago --- # 2. Dasturlash muhitini tayyorlash | Python-Pygame Zero Bu har bir dasturlash tilini o'rganish kitobida paydo bo'ladigan birinchi bob. Chunki, sarlavhadan xulosa qilishingiz mumkinki, bu kodlashni boshlash uchun oldindan o'rnatilishi kerak bo'lgan dasturlar mavjudligini anglatadi va ularni o'rnatish va sozlashdan so'ng kodlashni boshlash mumkin bo'ladi. Odatda, bu jarayon uchun ikkita asosiy talab mavjud. Birinchisi, siz foydalanmoqchi bo'lgan dasturlash tilini (bu holda Python) o'zini o'rnatish, ikkinchisi kodlashni (yoki dasturlashni) osonroq va qulayroq qiladigan yordamchi dasturni o'rnatish, bu kod editori yoki integratsiyalashgan dasturlash muhiti (Integrated Development Environment — IDE) — bu o'rnatilgan til yordamida kompyuter bilan aloqa qilish uchun mazmunli jumlalar va matnlar ya’ni kodlarni yozishni osonlashtiradi. circle-info **Integrated Development Environment (IDE)**: bitta dastur doirasida dasturiy ta'minotni ishlab chiqish bilan bog'liq barcha funksionalliklarni ta'minlaydigan muhitga ega dastur. Dasturiy ta'minotni ishlab chiqish bilan bog'liq barcha ishlar kodni tahrirlash, kompilyatsiya qilish, errorlarni to'g'rilash (debug), birlashtirish(building), binar tarqatish va boshqa dasturchilar bilan hamkorlik qilishni anglatadi. Mashhur mahsulotlarga Microsoft Visual Studio, Google Android Studio kiradi, va faqat Pythonga ixtisoslashtirilgan IDE — PyCharm kiradi. Biroq, ushbu jarayonlar har safar yangi kodlash tilidan foydalanishni boshlaganda bajarilishi kerak bo'lgan odatiy vazifalar bo'lishiga qaramay, ular yangi boshlovchilar uchun hali ham noqulay va murakkab bo'lishi mumkin. Misol uchun, agar o'rnatish jarayonida muammolarga duch kelsa va muammolarni bartaraf etishda muammo yuzaga kelsa, ular matnli dasturlash qiyin degan noto'g'ri fikrni rivojlantirishi mumkin. Yaxshiyamki, shunga o'xshash tashvishlarga duch kelgan chet ellik dasturchilar/o'qituvchilarning yana bir guruhi bor va ular ["Mu Editor" deb nomlangan ochiq manbali loyihaarrow-up-right](https://github.com/mu-editor/mu) ni boshladilar, bu kod editori dasturlash muhitiga qo'shimcha o'rnatmalarsiz darhol kodlashni boshlash uchun zarur bo'lgan hamma narsaga ega. Shuning uchun, **kodlashdan tashqari muhim bo'lmagan vazifalarni osonlashtirish va soddalashtirish niyatimizga muvofiq, biz Mu editoridan faqat matnli dasturlash mohiyatiga e'tibor qaratish uchun foydalanamiz, bu bizga uni tushunish va o'zlashtirishga chuqurroq kirishga imkon beradi.** ### [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/dev_env#mu-editori-kod-editori-kodni-tahrirlash-vositalari) Mu editori (Kod editori, Kodni tahrirlash vositalari) O‘rnatish uchun [Mu editorining rasmiy saytiarrow-up-right](https://codewith.mu/en/download) ga kiring va kompyuteringiz muhiti(kompyuteringizning operatsion tizimi)ga qarab eng so‘nggi o‘rnatuvchini yuklab oling va o‘rnating. circle-info Ma'lumot uchun, **men hozirgi vaqtda manba kodini o‘zgartirish orqali ochiq manbali Mu Editorning maxsus versiyasini yaratmoqdaman, bundan maqsad ta'lim uchun avvalgidan ham qulayroq bo‘lishdir.** Kerakli manbalar (masalan, rasmlar va o‘rnatishni talab qilinadigan qo‘shimcha modullar)ni editorga oldindan kiritmoqdaman. **Bu editorni dastlabki o‘rnatilganidan so‘ng, resurslarni alohida onlayn o‘rnatishga hojat qolmasligi uchun amalga oshirilmoqda, bu esa hamma narsani oflayn muhitda faqat bitta editor bilan qamrab olishga imkon beradi.** **Bundan tashqari, asl editorda yo'q bo'lgan qo'shimcha funksiyadir. U o'zimiz yaratgan o'yinlarni do'stlarga va boshqalarga tarqatishni osonlashtirish uchun qo'shilgan, bu bizga** [**o'yinlarni bitta EXE faylga aylantirib**arrow-up-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/ilova/exe_fayliga) **bahramand bo'lish imkonini beradi.** **Ushbu maxsus editor versiyasini sinab ko'rmoqchi bo'lganlar uni** [**bu yerdan**arrow-up-right](https://github.com/roboticsware/mu/releases/) **yuklab olishlari mumkin.** ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FdfDSKBl8SXLrozmMNRq9%252Fimage.png%3Falt%3Dmedia%26token%3D78824140-bf1d-4b64-8ed0-49a66f4e91d7&width=768&dpr=3&quality=100&sign=e12ff5e7&sv=2) Mu Editorning rasmiy sayti Mu editoriga, dasturlash yordamchisi dasturi sifatida, nima yaqinroq: "oddiy kod editori"mi yoki "integratsiyalashgan dasturlash muhiti (IDE) dasturi"mi? Javob ba'zan IDEga, ba'zan esa kod editoriga yaqinroq bo'lishi mumkin. Mu editorining foydalanuvchilariga **istagan turli xil dasturlash muhitlari (rejimlar deb ataladi)** o'rtasida osongina almashishga imkon beradigan xususiyatni taqdim etadi. Python dasturlash bo'yicha turli vazifalarni (masalan, umumiy dasturiy ta'minotni dasturlash, o'yin yaratish, qurilmalarni boshqarish va boshqalar) osongina bitta editor bilan bajarish yangi boshlaganlar uchun juda qulay. Ushbu rejimlarni tanlash uchun siz editorning yuqori qismidagi menyuda **Rejim** tugmasini bosishingiz va kerakli (dasturlash) rejimini tanlashingiz mumkin (televizorning masofadan boshqarish pulti bilan televizor kanallarini o'zgartirishga o'xshash) va biz Pygame Zero yordamida o'yin yaratishni rejalashtirayotganimiz sababli, keling Pygame Zero rejimini tanlaylik. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252F3s365O9dts53XdkPyEh0%252Fimage.png%3Falt%3Dmedia%26token%3D3204a085-9246-407e-860b-f04c24a2921d&width=768&dpr=3&quality=100&sign=ffc35b6b&sv=2) Rejimni tanlash tugmasi ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FAgYVYqLNAvxoM2uTVC0O%252Fimage.png%3Falt%3Dmedia%26token%3Dbc9a2b5c-d313-4081-bd45-0f74c37b7b0f&width=768&dpr=3&quality=100&sign=2bd19201&sv=2) Rejimni tanlash oynasi Biz tanlagan dasturlash rejimining to'g'riligini joriy tanlangan dasturlash muhiti nima ekanligini ko'rsatadigan holat satri orqali yana bir bor tasdiqlashimiz mumkin. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FJZ5IXZ4nUHOjLk4CB9bu%252Fimage.png%3Falt%3Dmedia%26token%3D50ba2211-8722-4f02-ab3c-97762c428033&width=768&dpr=3&quality=100&sign=63dcf147&sv=2) ### [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/dev_env#mu-editorning-ozbek-tili-tarjimasi-loyihasi) Mu Editorning o'zbek tili tarjimasi loyihasi circle-info **Yuqoridagi editor oynasi avval aytib o'tilganidek, ishlab chiqarilayotgan maxsus versiyadir. Ko'rib turganingizdek, ba'zi o'zbekcha tarjimalar qo'llanilgan va maqsad uni o'zbek tiliga to'liq tarjima qilishdir. Biroq, to'liq tarjima ko'p vaqt talab etadi, biz sizning ishtirokingizni kutmoqdamiz. Tarjimani tezda yakunlash uchun iloji boricha ko'proq odamlarning ishtirokini intiqlik bilan kutamiz va umid qilamizki, hamma birgalikda imtiyozlardan bahramand bo'ladi. Biz har doim o'z vaqtini hamma uchun bag'ishlashga va ixtiyoriy ravishda ishtirok etishga tayyor bo'lganlarni kutamiz.** 🙏 Tarjimaga qo'shilish havolasi: [https://crowdin.com/project/mu-editorarrow-up-right](https://crowdin.com/project/mu-editor) Shu bilan biz kodlashni boshlash uchun dastlabki tayyorgarlikni yakunladik va endi keyingi mashg'ulotdan boshlab bizning ta'limimiz uchun optimallashtirilgan maxsus Mu editori yordamida haqiqiy Python kodlashni boshlaymiz. [Previous1\. Pygame Zero kutubxonasichevron-left](https://roboticsware.gitbook.io/python-pygame_zero/pygame_zero_lib) [Next3\. "Hello World" dasturidan boshlaylikchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/hello-world) Last updated 7 days ago --- # 1. Pygame Zero kutubxonasi | Python-Pygame Zero [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/pygame_zero_lib#pygame-kutubxonasi) Pygame kutubxonasi ------------------------------------------------------------------------------------------------------------------------ Biz bu kitobda foydalanadigan **o‘yin ishlab chiqish uchun mo‘ljallangan kutubxona**ni (agar "kutubxona" nima ekanligi haqida tushuncha kerak bo‘lsa, [avvalgi kitobarrow-up-right](https://roboticsware.gitbook.io/entry-python/boshlash/hello_world#kutubxona-nima) ga murojaat qiling) tanishtirib o‘tamiz. Bu — Python tilida 2D o‘yinlar yaratish uchun ishlatiladigan kutubxona bo‘lib, 2000-yilda birinchi marta chiqarilgan va 20 yildan ortiq vaqt mobaynida xizmat ko‘rsatib, hanuzgacha takomillashtirib kelinayotgan "ochiq manba kodli o‘yin ishlab chiqish kutubxonasi"dir. Uning nomi Python uchun mo‘ljallangan kutubxona degan ma'noni anglatuvchi "py" prefiksi bilan **pygame** deb nomlangan. Agar yanada batafsil va professional darajadagi ma’lumotni bilmoqchi bo‘lsangiz, [rasmiy veb-saytarrow-up-right](https://pygame.org/) ga murojaat qilishingiz tavsiya etiladi. Ushbu kutubxonaning logotipi quyidagicha. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252Fi7V0X1NwO7Bn6KF09OBi%252Fimage.png%3Falt%3Dmedia%26token%3D0dfd5103-ac00-44eb-8bf1-977011881b5a&width=768&dpr=3&quality=100&sign=1566b8c0&sv=2) Pygame logotipi Odatda, agar o‘yin ishlab chiqishda bunday kutubxona yordamisiz barcha kodlarni noldan (Zero-based) boshlab birma-bir yozib ishlab chiqmoqchi bo‘lsak, bu imkonsiz bo‘lmasada, nihoyatda juda juda ko‘p vaqt talab qiladi. Chunki o‘yinlar o‘ziga xos tarzda yig‘ma san’at deb ataladigan darajada ko‘plab texnologiyalarni (ayniqsa matematik va fizik qonuniyatlarni) o‘z ichiga oladi va tasvirlar, tovushlar, videolar kabi turli multimedia elementlarini bir vaqtda boshqarishni talab qiladi. Natijada kodlarning miqdori ham, murakkabligi ham ancha yuqori darajada bo‘ladi. Shu sababdan, texnik tafsilotlarni to‘liq bilmasak ham, ularni qulay tarzda foydalanish imkonini beruvchi bunday kutubxonalar mavjudligi biz uchun haqiqiy najotdir. Agar orangizda "shu bilan tijorat o‘yinini ishlab chiqish mumkin emasmi?" degan umid qilayotganlar bo‘lsa, afsuski, bunday umidan erta voz kechishingiz ma’qul. Bu kutubxona bunday darajada yoki maqsadda ishlatish uchun yaratilmagan, eng muhimi esa, Python dasturlash tili hali tijorat o‘yinlari ishlab chiqishda keng qo‘llaniladigan asosiy til emas. Shunga qaramay, biz bu kutubxona orqali o‘zimiz, atrofimizdagi do‘stlarimiz va tanishlar uchun maroqli o‘ynaladigan yengil indie(independent - mustaqil) o‘yinlarni yaratishimiz mumkin bo‘ladi. [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/pygame_zero_lib#pygame-zero-kutubxonasi) Pygame Zero kutubxonasi ---------------------------------------------------------------------------------------------------------------------------------- Pygame kutubxonasi orqali dasturlash Python boshlovchilari uchun rostini aytganda oson emas. Shu sababli, boshlovchilarning o‘rganishini yengillashtirish uchun yanada pastroq to‘siq yaratish zarurati tug‘ildi. Xuddi shu tashvishlarni o‘ylagan bir dasturchi, "Pygame Zero" nomidan ham ko‘rinib turibdiki, _mavjud_ _**"Pygame" kutubxonasiga asoslanib uni yanada soddalashtirdi va minimal kod yozish orqali ham o‘yin yaratish imkonini beradigan, murakkablik darajasi pastroq yangi Pygame kutubxonasini ishlab chiqdi**_ _va uni_ [_ochiq manba kod_arrow-up-right](https://github.com/lordmauve/pgzero) _li tarzda e’lon qildi. Ushbu kutubxonani_ [_tanishtirgan veb-sayt_arrow-up-right](https://pygame-zero.readthedocs.io/) _da aytilishicha, bu kutubxona asosan dasturlashni o‘rgatish uchun mo‘ljallangan bo‘lib, endigina matnli kodlashni boshlagan va ayniqsa Python tili orqali dasturlashga kirayotgan foydalanuvchilarni qiziqtirib, o‘rgatishda foydali bo‘lishi kutiladi._ ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252Foc9nkxaeCe2cR03c2wzr%252Fimage.png%3Falt%3Dmedia%26token%3D44947fed-2618-45b5-86cf-ed589b757fe3&width=768&dpr=3&quality=100&sign=a4d32440&sv=2) Pygame Zero logotipi Biroq, afsuslanarli jihati shundaki, ushbu kutubxona doimiy ravishda rivojlanib va yangilanib borilmayapti, va 2021-yilgi 1.2.1-versiyadan beri uzoq vaqt davomida yangilanishsiz qolgan. Shunga qaramay, hech bo‘lmaganda biz ko‘zlagan maqsad — Python tilidan foydalanib matnli kodlashni yaxshiroq o‘rganish uchun mo‘ljallangan ta’limiy darajadagi rivojlanish — allaqachon yetarli darajada amalga oshirilgan deb baholash mumkin. _Ushbu kitob o‘yin yaratishni mukammal o‘rgatish uchun yozilmagan, balki Python dasturlash tili orqali matnli kodlashni yanada yaxshiroq o‘rganish maqsadida o‘yin ishlab chiqish vosita sifatida tanlagan deb tushunish kerak. Biz ilgari Entry/Scratch orqali blokli kodlash bilan o‘yin yaratib, dasturlashga qiziqishni rivojlantirgan edik. Endi esa, bizning yangi maqsadimiz — Pygame Zero kutubxonasi va Python matnli kodlash tili kombinatsiyasi orqali o‘yin yaratish orqali blokli kodlashdan bir qadam oldinga o‘tib, matnli kodlash olamida ham dasturlash zavqini his qilishdir._ [PreviousO‘yin yaratish orqali loyiha asosida Python o‘rganishchevron-left](https://roboticsware.gitbook.io/python-pygame_zero) [Next2\. Dasturlash muhitini tayyorlashchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/dev_env) Last updated 7 days ago --- # 4. O'yin siklini tushunish | Python-Pygame Zero To'liq miqyosli o'yin ishlab chiqarishni boshlashdan oldin, biz yaratadigan o'yin dasturining asosiy operatsion tuzilishini tushunishimiz kerak. Keling, avvalam bor Entry blokli kodlashda umumiy kodlash qanday bo'lganini eslaylik. Odatda, birinchi navbatda, ekranda paydo bo'ladigan bir yoki bir nechta asosiy belgilar obyektlari chaqiriladi va ekranga joylashtiriladi, so'ngra har bir obyekt o'yinda bajarishi kerak bo'lgan harakatlar uchun alohida kodlanadi. Tugallangan o'yin o'ynalganda, har bir obyekt mustaqil ravishda va bir vaqtning o'zida ishga tushadi va hatto "boshlash tugmasi bosilganda" bir obyektga ikki yoki undan ko'p marta qo'yilgan bo'lsa ham, u parallel ravishda harakat qilayotgandek harakat qildi ([tafsilotlar uchun oldingi kitobga qarangarrow-up-right](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/ketma_ketlik-parallel) ). Pygame Zero kutubxonasi bilan Python tilida dasturlash blokli kodlashga biroz o'xshaydi, ammo sezilarli farqlar ham mavjud. Afsuski, eng katta farq shundaki, endi biz har bir asosiy obyektni mustaqil va parallel ravishda harakat qildira olmaymiz, va biz barcha asosiy obektlarning harakatlari bir joyda (o'yin sikli) boshqariladi deb hisoblab kodlashimiz kerak. Agar biz uni diagrammada ifodalasak, o'yin doimiy ravishda takrorlanib turuvchi cheksiz sikl(**o'yin sikli** deb ataladi, chunki u o'yinlar uchun maxsus ishlatiladigan davomiy taqrorlashaga o'xshash)da bajariladi: ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252F7kDsxZUmSkY3PiPXq8Tq%252Fimage.png%3Falt%3Dmedia%26token%3Dfa8d86f0-4285-4b3d-a2ca-fc6828b9ae88&width=768&dpr=3&quality=100&sign=67caaa5b&sv=2) Manba: [https://inventwithpython.com/pygame/chapter2.htmlarrow-up-right](https://inventwithpython.com/pygame/chapter2.html) Rasmda tasvirlanganidek, **o'yin siklida uchta asosiy vazifalar(ekranda o'yin obyektini chizish, o'yin obyektlarining harakatlarini boshqarish,** [**klaviatura va sichqoncha kabi hodisalarni ishlov qilish**arrow-up-right](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/event-driven) **)ni doimiy ravishda qayta ishlanadi.** Agar biz Pygame Zero o‘rniga Pygame kutubxonasi bilan kodlayotgan bo‘lsak, ushbu o‘yin siklining tuzilishini yaratish bizning vazifamizdir va biz uni o‘zimiz kodlashimiz kerak. **Biroq, Pygame Zero ataylab yangi boshlovchilar uchun bu qismni** **yashiradi, va u oldindan belgilangan 3ta** [**kolbek funksiyalari**arrow-up-right](https://roboticsware.gitbook.io/entry-python/boshlash/hello_world#kolbek-callback-funksiyasi-nima) **(draw, update on\_mouse/on\_key) tayyor. Ushbu kolbek funksiyalariga muvofiq kodlash orqali Pygame Zero yangi boshlanuvchilar uchun yanada qulay tuzilmani taklif etadi.** Yaxshiyamki, biz Pythonda Entry-Pythonda kolbek funksiyasi asosida kodlashni sinab ko‘rganimiz uchun, biz ushbu tuzilishga qiyinchiliksiz moslasha olishimiz kerak. Keyingi mashg'ulotdan boshlab biz ushbu tushunchaga asoslangan to'liq o'yinni kodlashga harakat qilamiz. [Previous3\. "Hello World" dasturidan boshlaylikchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/hello-world) [Next5\. Flappy Bird o'yinini yaratishchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird) Last updated 7 days ago --- # 3. "Hello World" dasturidan boshlaylik | Python-Pygame Zero Bu dasturlashdagi birinchi qadam. Har doimgidek, lekin bu safar siz bilan, biz "[Hello Worldarrow-up-right](https://uz.wikipedia.org/wiki/Hello,_World!) " dasturini birgalikda o'rganishdan boshlashimiz kerak. Biroq, Pygame Zero dasturlash tilining o'zi emas, balki kutubxona bo'lgani uchun biz tanish bo'lgan Hello World dasturini yaratmaymiz. Buning o'rniga, avvalgi Hello World dasturiga nisbatan Pygame Zero kutubxonasi bilan kodlashda zarur bo'lgan minimal koddan iborat eng kichik dastur misolini ko'rib chiqamiz. Birinchidan, Mu Editorni ochaylik. Faylni ochish va birinchi kodlashni boshlash uchun menyu panelidagi **Yangi fayl** tugmasini bosing. Quyidagi bitta chiziqli kodni yozamiz. Copy TITLE = 'Hello World!' Kodlash amalga oshirildi. Ajoyib! Bu juda oddiy emasmi? Ha, shunday. Shuning uchun _Pygame Zero Python kodlash orqali o'yin yaratishni soddalashtiradi, xuddi bizning Entry-Pythondagi Python kodlash tajribamiz kabi. Shunday qilib, Pygame Zero orqali Python dasturashni o'rganish matnli dasturlashni yangi o'rganayotganlar uchun juda mos tanlov bo'lishi mumkin._ Faqat bitta qator kod bilan biz 'Hello World' nomli juda oddiy bo'sh oyna dasturini yaratdik. Endi kodni **hello\_world** nomi bilan faylga saqlash uchun menyu panelidagi **Saqlash** tugmasini bosamiz. Keyin, uni bajarish uchun menyu panelidagi **Boshlash** tugmasini bosing va qanday ishlashini tekshiring. **hello\_world** nomli bo'sh oyna ilovasi biz kutgandek to'g'ri ishladimi? ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252F236UNeGCD6ZNcBKejUbG%252Fimage.png%3Falt%3Dmedia%26token%3Dd37eb9e4-889b-42f5-b6c5-736764e6330f&width=768&dpr=3&quality=100&sign=be8220f4&sv=2) ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FqnL7jcRL3udqPXNoquZv%252Fimage.png%3Falt%3Dmedia%26token%3D465b990f-3edc-44df-b6a5-120ae35f4f11&width=768&dpr=3&quality=100&sign=3a65c52b&sv=2) "Hello World" nomli ijro ekrani Kodlashga qaytish uchun biz hozirgina bajarilgan dasturni yopishimiz kerak. Ishga tushrilgan dastur o'zi oynasidagi 'x' tugmasini (dastur o'chirish tugmasi) bosish orqali o'yin ilovasini yopish mumkin bo'lsa-da, **Mu editorida kodlashni davom etish uchun har doim to'g'ri chiqish uchun Menyu panelidagi To'xtatish tugmasini bosishni unutmang**. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FQZdFpP3PXx7y61oXsbsI%252Fimage.png%3Falt%3Dmedia%26token%3Da6017111-4f08-4136-8908-9139a92b63cc&width=768&dpr=3&quality=100&sign=776e7c36&sv=2) Biroq, bitta qatorli kod bo'lishiga qaramay, keling, uni tushunish uchun kodni tahlil qilaylik. Biz ilova nomini **TITLE** deb nomlangan o'zgaruvchida saqladik. O'zgaruvchining nomi nega TITLE ekanligini intuitiv ravishda taxmin qilishingiz mumkin, u biz yaratmoqchi bo'lgan ilovaning nomini (sarlavhasini) ko'rsatish uchun ishlatiladi. Lekin nima uchun o'zgaruvchining nomi TITLE bo'lishi kerak? Nima uchun o'zgaruvchi kichik harflarda bo'lishi mumkin emas yoki nega men uni shunchaki xohlaganimdek APPNAME deb nomlay olmayman deb o'ylashingiz mumkin. Afsuski, bu tarzda ishlamaydi. Agar siz bu haqiqat yoki yo'qligini tekshirmoqchi bo'lsangiz, o'zgaruvchining nomini boshqa narsaga o'zgartirib, tajriba o'tkazishingiz va kerakli natijaga erishganingizni bilish uchun ilovani qayta ishga tushirishingiz mumkin. Siz kerakli natijaga erisha olmasligingizni bilib olasiz. Pythonni birinchi marta o'rganganimizda biz avval o'rgangan [**oldindan o'rnatilgan funksiyalar**arrow-up-right](https://roboticsware.gitbook.io/entry-python/boshlash/kiritish_chiqarish) va **oldindan o'rnatilgan o'zgaruvchilar** kabi tushunchalarni eslaysizmi? Ushbu o'zgaruvchi shu tushunchalarga o'xshaydi. Agar kutubxonalar haqida avvalgi darslarimizdan eslasangiz, [**kutubxona**arrow-up-right](https://roboticsware.gitbook.io/entry-python/boshlash/hello_world#kutubxona-nima) **dan foydalanish kutubxona yaratuvchisi tomonidan belgilangan qoidalarni o'rganish va shu qoidalarga muvofiq kodlashni anglatadi**. Xuddi shunday, _Pygame Zerodan foydalanish Pygame Zero yaratuvchisi tomonidan belgilangan qoidalarni o'rganish va shunga mos ravishda kodlashni anglatadi. Biz o'rgangan TITLE o'zgaruvchisi yaratuvchi tomonidan allaqachon belgilangan to'g'ri ismga o'xshaydi. Ilova nomini o'zgaruvchida saqlash uchun faqat shu o'zgaruvchi nomidan foydalanish ilova bajarilganda ilova nomi to'g'ri ko'rsatilishini ta'minlaydi._ Endi o'yin ilovamizni biroz kengaytiraylik. Endi quyidagi 2 qator kodlarni qo'shib, bizda jami 3 qator kod mavjud. Ushbu 3ta qatorli kod yordamida biz ilova nomi asosida 'Hello World' nomli 400 x 300 piksel o'lchamdagi bo'sh ekranli juda oddiy dastur yaratdik. Boshlash tugmasini bosib, uni ishga tushiramiz. Copy TITLE = 'Hello World!' WIDTH = 400 HEIGHT = 300 ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FsiJUphDb1ajqLwAuOzS0%252Fimage.png%3Falt%3Dmedia%26token%3Da8b4218b-7761-47e9-b374-cb5d461f18fb&width=768&dpr=3&quality=100&sign=a50ff47a&sv=2) Gorizontal ravishda 400 piksel va vertikal ravishda 300 piksel o'lchamdagi ilovani ishga tushirish oynasi Xo'sh, biz dastlab yaratgan birinchi bitta qatorli dastur va ushbu dastur o'rtasidagi farq nima? Ha, biz mos ravishda **WIDTH** va **HEIGHT** ya'ni kenglik va balandlik nomli o'zgaruvchilar yordamida qo'shimcha kodlashni qo'shdik. Siz intuitiv ravishda his qilganingizdek, xuddi o'zgaruvchi TITLE kabi, bu o'zgaruvchi nomlari Pygame Zero kutubxonasida oldindan belgilangan o'zgaruvchilar bo'lib, ilova hajmini aniqlaydi. Ulardan foydalanish tufayli biz endi kerakli o'lchamdagi ilovalarni yaratishimiz mumkin. Hello World dasturini yaratish tugagani uchun, keling, haqiqiy o'yinlarni birma-bir yaratish orqali Python dasturlahni o'rganishdan zavqlanaylik! [Previous2\. Dasturlash muhitini tayyorlashchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/dev_env) [Next4\. O'yin siklini tushunishchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/game_loop) Last updated 7 days ago --- # 10. Pongni tarmoq o‘yiniga aylantirish | Python-Pygame Zero Bu bobda 8-bobda yaratib ko‘rgan Pong o‘yinini tarmoqli o‘yin shakliga keltirib, avvalgidek faqat kompyuterga qarshi o‘ynash yoki bitta kompyuterda ikki kishi lokal tarzda o‘ynaydigan o‘yin emas, balki tarmoq orqali uzoqda joylashgan boshqa kompyuter oldida o‘tirgan haqiqiy inson foydalanuvchi (user) bilan birga bellashsa bo‘ladigan tarmoqli o‘yin shakliga aylantirib ko‘raylik. [Previous9.7 Obyektga yo‘naltirilgan dasturlash 4chevron-left](https://roboticsware.gitbook.io/python-pygame_zero/battle_city/9.7_oop_dev4) [Next10.1 Tarmoqli o‘yinlarni tushunish va kutubxonani o‘rnatishchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.1_nethelper_install) Last updated 7 months ago --- # 5.6 Flappy Bird o‘yiniga qo‘shimcha funksiyalarni joriy qilish (ball funksiyasi) | Python-Pygame Zero Endi biz qo‘shmoqchi bo‘lgan funksiyalar — o‘yinning sifatini yaxshilash uchun qo‘shimcha bo‘lib, bularni bonus bo‘limlar deb hisoblash mumkin. Bu kodlashni o‘rganayotgan va ayni paytda mukammalroq o‘yin yaratmoqchi bo‘lganlar uchun foydali bo‘ladi. Avvalo quyidagidek Flappy Bird quvurlar orasidan muvaffaqiyatli o‘tgan sonini ekran yuqori markazida hisob ko‘rinishida ko‘rsatadigan kodni qo‘shib ko‘raylik. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FrGDIhuAe0oqgsoMm0zQz%252Fimage.gif%3Falt%3Dmedia%26token%3D166f5efa-cc63-44ad-84d4-707c97135523&width=768&dpr=3&quality=100&sign=d3479cdb&sv=2) Copy TITLE = 'Flappy Bird' WIDTH = 400 HEIGHT = 708 GRAVITY = 0.3 drop_speed = 0 GAP = 140 PIPE_SPEED = -3 bird_alive = True score = 0 # Actor obyektlari flappy_bird = Actor('bird1', (75, 350)) top_pipe = Actor('top', (350,0)) bottom_pipe = Actor('bottom', (350, top_pipe.height + GAP)) def draw(): screen.blit('background', (0, 0)) flappy_bird.draw() top_pipe.draw() bottom_pipe.draw() screen.draw.text( str(score), color = 'white', midtop = (WIDTH/2, 10), fontsize = 70, shadow = (1, 1) ) def update(): global drop_speed, bird_alive, score drop_speed += GRAVITY flappy_bird.y += drop_speed top_pipe.x += PIPE_SPEED bottom_pipe.x += PIPE_SPEED # quvurning cheksiz sikli if top_pipe.right < 0 or bottom_pipe.right < 0: top_pipe.x = WIDTH bottom_pipe.x = WIDTH if bird_alive == True: score += 1 # quvur bilan to'qnashuv if flappy_bird.colliderect(top_pipe) or flappy_bird.colliderect(bottom_pipe): flappy_bird.image = "birddead" bird_alive = False # o'yinni qayta ishga tushurish if flappy_bird.y > HEIGHT or flappy_bird.y < 0: flappy_bird.image = "bird1" bird_alive = True flappy_bird.center = (75, 350) drop_speed = 0 top_pipe.x = WIDTH bottom_pipe.x = WIDTH score = 0 def on_mouse_down(): global drop_speed if bird_alive == True: drop_speed = -6.5 🔢 Ball qo‘shish — bu ball qachon olinishi kerakligini aniqlovchi algoritmni yaxshi o‘ylab chiqilsa, uni amalga oshirishning o‘zi unchalik murakkab emas. Flappy Bird quvurdan yaxshi o‘tgan payt ball olinishi kerak bo‘lgan lahzadir, aslida aniqlik bilan qaralsa, animatsiyadagi Flappy Bird va quvurning hozirgi joylashuvini bir vaqtda aniqlab, Flappy Bird tirik holatda bo‘lganida uning chap tomoni (flappy\_bird.left) quvur obyektining o‘ng tomoni (pipe.right) joylashuv ma’lumotidan o‘tgan-o‘tmaganini doimiy tekshirish kerakmi, kabi masalalar tufayli bu biroz murakkablashishi mumkin, biroq bunga bunchalik aniqlik bilan yondashmasdan, soddalashtirib o‘ylasak, Flappy Bird o‘yin ekrani chap qismidan unchalik uzoqlashmagan degan taxminga asoslanib, quvur harakatlanib o‘yin ekranining chapiga yetib, yana o‘yin ekranining o‘ngidagi boshlang‘ich holatga qaytadigan vaqtda Flappy Bird tirik qolgan bo‘lsa, demak, Flappy Bird quvurga tegmasdan xavfsiz o‘tib ketdi deb hisoblashda hech qanday muammo yo‘q. Bunday sodda algoritmni qo‘llash orqali uni amalga oshirish osonlashadi, va har bir lahzada joylashuvlarni hisoblash bilan bog‘liq bo‘lgan hisoblash yukining ortishi sababli o‘yin samaradorligi tushib ketishi mumkin bo‘lgan muammoni ham bir vaqtning o‘zida hal qilish mumkin bo‘ladi. Buni qo‘llagan kod asosan 3 qismdan iborat bo‘lib, avvalo 10-qatorida score global o‘zgaruvchi sifatida yaratilgan, 42–43-qatorlarda quvur ekran tashqarisiga chiqib ketgunicha Flappy Bird o‘lmagan bo‘lsa, ball oshiriladi va 58-qatorida o‘yin qayta boshlanganda ball ham yana 0 dan boshlanishi uchun qayta boshlang‘ich holatga keltirilgan. 🔢 Endi qolgan kod ballni ekranga chizib ko‘rsatish qismidir. Buning uchun kutubxonadagi screen obyekti ichida tayyorlangan funksiya mavjud bo‘lib, bu draw.text funksiyasidir. draw.text funksiyasining batafsil foydalanish usuli [kutubxona hujjatlariarrow-up-right](https://pygame-zero.readthedocs.io/en/latest/ptext.html) da berilgan, 24~28-qatorlarda ko‘rganimizdek, ushbu funksiyaga jami 5 ta argument (kiritiladigan qiymat) uzatiladi: birinchi qiymat ekranga chiqariladigan matn bo‘lib, biz bu yerda score qiymatini chizmoqchimiz, biroq muammo shundaki, scorening ma’lumot turi raqam bo‘lib, bu matn (string) emas, shuning uchun Pythonning ichki funksiyasi bo‘lgan str funksiyasidan foydalanib, ma’lumot turini matnga o‘zgartiramiz va shundan so‘ng qiymatni uzatamiz. Ikkinchi argument bu matnning rangi, uchinchi esa ekranda chiziladigan joy bo‘lib, ekranning yuqori markaz qismi (midtop) qo‘llanilgan, to‘rtinchi qiymat bu shriftning o‘lchami, oxirgisi esa shadow qiymati bo‘lib, bu chiziladigan matnga soyali effekt berish uchun ishlatiladi; bu qiymat (1, 1) ko‘rinishidagi tuple bo‘lib, bu soyani asl matndan x va y yo‘nalishida qanchaga siljitib chizish kerakligini bildiradi. Bu yerga qadar yaxshi amalga oshirilgan bo‘lsa, ushbu bobning boshidagi o‘yin ishga tushirish ekrani misolidagidek, quvurdan o‘tganda ekranning yuqori qismida ball (score) yaxshi tarzda oshib borayotganini ko‘rish mumkin. Endi esa o‘yin qiziqarliroq bo‘lishi uchun amalga oshiriladigan keyingi narsa har safar quvur paydo bo‘lganda uning joylashuvini tasodifiylashtirish orqali o‘yinning qiziqarliligini oshirishdan iborat. [Previous5.5 Flappy Bird va quvurlar o‘rtasida to‘qnashuvni amalga oshirishchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.5_collision) [Next5.7 Flappy Bird o'yini uchun qo'shimcha funksiyalar (quvur pozitsiyalarini tasodiylashtirish)chevron-right](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.7_pipe_random) Last updated 1 day ago --- # Ilova | Python-Pygame Zero [O'yinimizni EXE fayliga aylantirishchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/appendix/packaging) [Mu editorining tezkor tugmalarichevron-right](https://roboticsware.gitbook.io/python-pygame_zero/appendix/shortcuts) [Previous10.4 Tarmoqli o‘yinga aylantirish 2chevron-left](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.4_dev_net_2) [NextO'yinimizni EXE fayliga aylantirishchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/appendix/packaging) --- # 5.2 Flappy Bird(obyekt)ni ekranga chiqarish va harakatlantirish | Python-Pygame Zero Endi bizning o‘yin qahramonimiz — Flappy Bird obyektini ekranga chiqarish navbati keldi. Bu murakkab emas. Quyidagi kodda, avvalgi kodga atigi 2 ta (5 va 9-qatorlar) yangi qatordan iborat qo‘shimcha kiritamiz. So‘ng uni ishga tushiring. Flappy Bird o‘yin ekranida chap markaz atrofida (aniqrog‘i, obyektning markazi (x, y) koordinatasi bo‘yicha (75, 350)) to‘g‘ri joylashgan holda paydo bo‘ladi. Copy TITLE = 'Flappy Bird' WIDTH = 400 HEIGHT = 708 flappy_bird = Actor('bird1', (75, 350)) def draw(): screen.blit('background', (0, 0)) flappy_bird.draw() ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FjpZqlIx9yRlcA1QECFvW%252Fimage.png%3Falt%3Dmedia%26token%3Dc704b5a0-3792-4ad0-a749-ff71e3b2d297&width=768&dpr=3&quality=100&sign=70956309&sv=2) 🔢 Endi kodni tahlil qilish vaqti keldi. Birinchi, biz hali ham obyektga yo‘naltirilgan paradigmada kod yozayotganimizni yodga olaylik. Keling, qo‘shilgan 5-qatorni ko‘rib chiqamiz. Siz bu kodni ko‘rgan zahoti **Actor** degan funksiya chaqirib, undan qaytgan natija **flappy\_bird** degan o‘zgaruvchiga saqlayotgan deb o‘ylashingiz mumkin. Ammo bu yerda katta tushunmovchilik bor. **Actor** **— bu funksiya chaqiruvi emas, balki obyekt (object) yaratish jarayonidir.** Buni darrov qanday bilish mumkin? **Bu Python sintaksis qoidalariga (faqat Python emas, boshqa dasturlash tillarida ham bu xuddi shunday) bog‘liq: funksiyalar nomi kichik harf bilan yozilishi kerak,** [**klass**arrow-up-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/kuchuk-mushuk_2) **(class – obyektni aniqlash uchun ishlatiladigan sintaksis bo‘lib, funksiyalarni aniqlashda foydalanilgan def bilan o‘xshash) nomi esa katta harf bilan boshlanishi kerak degan odatiy qoidaga asoslangan.** Actor katta harf bilan boshlanganini ko‘rib, bu Actor degan klass (class) ekanini va bu klass orqali obyekt yaratilganini tushunish mumkin. Ushbu **yaratilgan obyekt** (obyektga yo‘naltirilgan paradigmada klassdan yaratilgan obyekt maxsus “instance” deb ataladi) **flappy\_bird** nomli o‘zgaruvchiga saqlanmoqda. **Obyektni yaratishda ham funksiyani chaqirishga o‘xshash tarzda, yaratish paytida klassga uzatilishi kerak bo‘lgan argumentlar bo‘lishi yoki bo‘lmasligi mumkin.** Bu holatda esa 2 ta argument talab qilinmoqda. **blit** funksiyasida ishlatilganiga o‘xshash 2 xil ma’lumot (Actor obyektining tashqi ko‘rinishi bo‘ladigan rasm faylining nomi va ushbu rasm ekranning qaysi joyiga chizilishi kerakligi haqidagi joylashuv ma’lumoti (aniqrog‘i, ushbu rasmning markaz (center) nuqtasi ekranda joylashishi kerak bo‘lgan koordinata)) obyekt yaratish uchun klassga argument sifatida uzatilmoqda. Unda, kutubxona muallifi biz uchun oldindan taqdim etgan Actor klassining maqsadi va vazifasini qanday bilish mumkin? Ha, o‘tgan darsda o‘rganganimizdek, [kutubxona hujjati(dokumentatsiyasi)arrow-up-right](https://pygame-zero.readthedocs.io/en/latest/builtins.html#actors) ni qidirsak, muallifning o‘zi bu klassning maqsadi va foydalanish usullarini batafsil tushuntirib bergan bo‘ladi. Ammo, _Actor klassining maqsadini hujjatni ko‘rmasdan ham, uning nomidan — “aktyor” degan ma’noni anglatuvchi nom orqali — bevosita sezish mumkin: bu klass o‘yin sahnasida harakatlana oladigan aktyor (obyekt) yaratish uchun mo‘ljallangan. Masalan, bizning o‘yin sahnamizda asosan 2 ta aktyor bo‘lishi mumkin(Flappy Bird aktyori va Flappy Bird to‘qnashmasdan o‘tib ketishi kerak bo‘lgan quvir (pipe) aktyori). Hozir esa ulardan birini — Flappy Bird aktyor (Actor) obyektini yaratamiz._ 🔢 Obyekt muvaffaqiyatli yaratildi va endi uni faqat ekranga chiqarish qolgan. 9-qatordagi kodda ko‘rsatilgandek, Actor obyekti tomonidan taqdim etilgan **draw** funksiyasini chaqirish orqali uni ekranga chizish mumkin. Hozirda yaratilgan obyektni ko‘rsatuvchi (murojaat qilayotgan) o‘zgaruvchi flappy\_bird orqali ushbu funksiyaga murojaat qilinadi. Flappy bird obyekti ekranga muvaffaqiyatli chiqdi. Endi bizga qolgan ish — bu o‘yin mohiyatiga mos ravishda Flappy Bird ning asosiy harakatini amalga oshirishdir. Asosiy harakatlar quyidagicha: birinchidan, Flappy Bird tortish kuchi ta’siri tufayli harakatsiz tursa pastga qulab tushadi; ikkinchidan, bu kuchni yengish uchun har safar sichqoncha bosilganda u ma’lum bir masofaga havoga ko‘tarilish harakatini bajaradi. 🔢 Avval Flappy Bird obyektining pastga qulash harakati — ya’ni tortish kuchi ta’sirini amalga oshiraylik. Boshqacha aytganda, bu obyektning pastga qulash harakatini ko‘rsatuvchi animatsiyani amalga oshirish demakdir. Animatsiyaning asosiy amalga oshirish printsipi — bizga yaxshi ma’lumki, juda qisqa vaqt ichida tasvirning (bu yerda obyektning) juda ozgina o‘zgarishlarini tezda foydalanuvchiga ko‘rsatish orqali ko‘zimizga u harakatlanayotgandek ko‘rinadigan illyuziyani hosil qilishdir. Bu aniqrog‘i “afterimage” effekti deb ataladigan illyuziya bo‘lib, tasvirlar (obyektlar) o‘rtasida qisqa uzilishlar bo‘lsa ham, uzluksiz ko‘rinishda davom etayotgandek ko‘rinish hodisasini anglatadi. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FV23q8pRgCWTvpwJQMcsa%252Fimage.png%3Falt%3Dmedia%26token%3Dc34ecf76-4c03-4e58-b903-76bdb3773d30&width=768&dpr=3&quality=100&sign=799d1ea5&sv=2) Manba: [https://theappliancesreviews.com/why-frame-rate-is-25-30-or-29-97-fpsarrow-up-right](https://theappliancesreviews.com/why-frame-rate-is-25-30-or-29-97-fps/) Agar bizdan animatsiya mexanizmini to‘liq o‘zimiz amalga oshirish talab qilinsa, to‘satdan chalkashlikka tushib qolishimiz mumkin. Ammo bilamizki, Pygame Zero o‘yin yaratishni iloji boricha oson kodlash bilan maqsad qilganligi sababli, bu kabi murakkab jarayonlar allaqachon ichki tomondan bajarilgan. Bizdan talab qilinadigan narsa faqat har bir tasvir(obyekt)ning harakatdagi o‘zgarishlarini kod orqali ifodalashdir. **Oldin biz kutubxona tomonidan talab qilinadigan** _**draw**_ **kolbek(callback) funksiyasi orqali obyektni ekranga chizgan bo‘lsak, animatsiya uchun esa kutubxona tomonidan chaqiriladigan** _**update**_ **kolbek(callback) funksiyasi orqali obyektning harakatini ifodalashimiz kerak bo‘ladi.** Ammo bu yerda esa tasvir(obyekt)ning o‘zida hech qanday o‘zgarish bo‘lmasdan, faqatgina tortish kuchining ta’sirini animatsiyaga aylantirib, kodda ifodalash quyidagicha bo‘ladi. Copy TITLE = 'Flappy Bird' WIDTH = 400 HEIGHT = 708 flappy_bird = Actor('bird1', (75, 350)) def draw(): screen.blit('background', (0, 0)) flappy_bird.draw() def update(): flappy_bird.y += 1 Kutubxona **update kolbek(callback)** funksiyasini soniyada 60 marta (60 FPS – Frame Per Second — **kadr soniyada** deb ataladi) avtomatik tarzda chaqiradi. Har safar chaqirilganda bajarilishi kerak bo‘lgan ish — Flappy Bird obyekti ekran bo‘ylab juda oz (1 piksel) pastga qarab harakatlanishidir. 12-qatorida **flappy\_bird.y += 1** degan kod yozilgan. Bu yerda yaratilgan obyekt(instance)ni **ko‘rsatuvchi flappy\_bird o‘zgaruvchisi** yuqorida ko‘rib chiqqanimizdek, yaratilgan obyektga murojaat qilish uchun ishlatiladigan **murojaat nuqtasidir**. Bu o‘zgaruvchi orqali obyektning foydalanuvchilariga taqdim etilgan funksiyalarni ham, obyektda mavjud bo‘lgan xususiyatlarni(bu yerda x, y koordinatalari orqali ifodalangan ekrandagi joylashuv ma’lumotlarini)ham chaqirish mumkin. Biz bu yerda obyektning y koordinatasiga murojaat qilib, uning qiymatini har safar 1 pikselga oshiryapmiz. Bu qiymatni oshirish orqali obyektni ekranning pastki qismiga siljitishimizning sababi — biz oldingi darsda ko‘rib chiqqan Pygame Zerodagi [ekran koordinatalari tizimi](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.1_background#pygame-zero-ning-ekran-koordinata-tizimi) da y ko‘rsatkichi oshgan sayin obyekt pastga siljiydi. Dastur ishga tushirilganda Flappy Bird obyekti xuddi unga tortish kuchi ta’sir qilayotgandek erkin tushish harakatini bajaradi. Agar siz uni yanada tezroq erkin tushishini xohlasangiz, nima qilish kerak? To‘g‘ri — har bir harakatda o‘zgaradigan piksel qiymatini 1 dan kattaroq raqamga o‘zgartirish kerak bo‘ladi. Ikkinchi navbatda, sichqoncha tugmasi bosilganda flappy bird obyektini hozirgi joylashuvdan yuqoriga harakatlantirish funksiyasini kodlaymiz. Buni qanday qilib kodlasak bo‘ladi? Agar siz blokli dasturlashdagi tajribangizga asoslanib yoki aniqrog‘i, oldingi kitoblarda o‘rgangan [hodisaga asoslangan (Event-Driven yoki Event-Based) dasturlash paradigmasiarrow-up-right](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/event-driven) ni qo‘llasak bo‘ladimi deb o‘ylayotgan bo‘lsangiz — demak siz matnli kodlash olamiga asta-sekin moslashayotgan ekansiz ^^ Copy TITLE = 'Flappy Bird' WIDTH = 400 HEIGHT = 708 flappy_bird = Actor('bird1', (75, 350) def draw(): screen.blit('background', (0, 0)) flappy_bird.draw() def update(): flappy_bird.y += 1 def on_mouse_down(): flappy_bird.y -= 50 🔢 Mavjud kodga 14~15-qatorlarda **on\_mouse\_down** (sichqoncha bosilganda kutubxona tomonidan avtomatik chaqiriladigan) kolbek funksiyasini qo‘shdik. Kolbek funksiyasi bo‘lganligi sababli, bu funksiya nomini biz ixtiyoriy tanlamaymiz — u kutubxona tomonidan allaqachon belgilangan ([kutubxona hujjatiga qarangarrow-up-right](https://pygame-zero.readthedocs.io/en/latest/hooks.html#on_mouse_down) ), shuning uchun aynan shu nomdagi funksiyani ishlatishimiz kerak bo‘ladi. Bizdan talab qilinadigan narsa — bu funksiya kutubxona tomonidan chaqirilganida nima bajarilishi kerakligini funksiyaning ichida yozishdir. Bajarilishi kerak bo‘lgan ish quyidagicha: 15-qatorda yozilganidek, flappy bird obyektini joriy joylashuvdan 50 piksel yuqoriga ko‘tarib, xuddi havoga sakrayotgandek harakatni hosil qilamiz. Bu, avval yuqorida bajargan erkin qulash (gravitatsiya) funksiyasiga juda o‘xshash va tushunilishi qiyin emas. Faqat shuni yodda tutish kerakki, mavjud joylashuvdan -50 qilishimiz sababi — [Pygame Zero dagi koordinatalar tizimi](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.1_background#pygame-zero-ning-ekran-koordinata-tizimi) dir: ekranning yuqori tomoni kichikroq y qiymatiga ega, shuning uchun yuqoriga harakat qilish uchun y qiymatini kamaytirish (minus qilish) kerak bo‘ladi. Hozirgacha yozilgan kodni ishga tushirib ko‘raylik. Kutilganidek, erkin qulayotgan flappy bird sichqonchani bosish orqali havoga ko‘tarilishi mumkin. Bu yerga qadar yaxshi bajargan bo‘lsangiz, endi Pygame Zero yordamida ozgina kod yozish orqali ham osonlik bilan o‘yin yaratish mumkinligini tushuna boshlagan bo‘lsangiz kerak. Hozirgacha yozilgan kod ham yomon emas, ammo uni ishga tushirganingizda flappy bird harakatida biroz kamchilik borligini sezishingiz mumkin. Bu kamchilik — havoga ko‘tarilish harakati tabiiy ko‘rinmasligi, ya’ni harakat uzluksiz emas, balki to‘satdan sakrab chiqqandek, keskin fazoviy o‘zgarish bo‘lib tuyulishidir. Xo‘sh, bu harakatni qanday qilib tabiiyroq, silliqroq qilish mumkin? Bu haqda keyingi bobda ko‘rib chiqamiz. [Previous5.1 Ekranga fon rasmi(obyekti)ni chiqarishchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.1_background) [Next5.3 Flappy Bird(obyekt)ning ekrandagi tabiiy harakatini yaratishchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.3_flying_gravity) Last updated 7 days ago --- # 5.5 Flappy Bird va quvurlar o‘rtasida to‘qnashuvni amalga oshirish | Python-Pygame Zero Agar siz ushbu bo‘limgacha o‘rgangan bo‘lsangiz, Flappy Bird o‘yinining asosiy funksiyalari deyarli to‘liq amalga oshirilgan bo‘lasiz. Endi qolgan kodni kuchliroq harakat qilib birgalikda yakunlaylik. Ushbu bo‘limda, sarlavhadan ko‘rinib turibdiki, Flappy Bird quvurlar bilan to‘qnashadigan holatni ko‘rib chiqamiz. Bunday holatda o‘yin tugashi kerak bo‘ladi. Biroq, to‘qnashgan zahoti darhol o‘yinni tugatish o‘yinning qiziqarli tomonini pasaytirishi mumkin. Shuning uchun quyidagi yondashuv yaxshiroq bo‘ladi: Flappy Bird quvurga tegishi bilan o‘lik holatga o‘tib, shunchaki pastga qulash animatsiyasi davom etadi. Va faqat qulagan Flappy Bird o‘yin ekranining pastki chegarasidan chiqib ketgan paytda — o‘yin boshidan qayta boshlanadi. Ushbu talablarni quyidagi kod orqali amalga oshirish mumkin. Copy TITLE = 'Flappy Bird' WIDTH = 400 HEIGHT = 708 GRAVITY = 0.3 drop_speed = 0 GAP = 140 PIPE_SPEED = -3 bird_alive = True # Actor obyektlari flappy_bird = Actor('bird1', (75, 350)) top_pipe = Actor('top', (350,0)) bottom_pipe = Actor('bottom', (350, top_pipe.height + GAP)) def draw(): screen.blit('background', (0, 0)) flappy_bird.draw() top_pipe.draw() bottom_pipe.draw() def update(): global drop_speed, bird_alive drop_speed += GRAVITY flappy_bird.y += drop_speed top_pipe.x += PIPE_SPEED bottom_pipe.x += PIPE_SPEED # quvurning cheksiz sikli if top_pipe.right < 0 or bottom_pipe.right < 0: top_pipe.x = WIDTH bottom_pipe.x = WIDTH # quvur bilan to'qnashuv if flappy_bird.colliderect(top_pipe) or flappy_bird.colliderect(bottom_pipe): flappy_bird.image = "birddead" bird_alive = False def on_mouse_down(): global drop_speed if bird_alive == True: drop_speed = -6.5 🔢 Biz ikki obyektning to‘qnashuvini tekshirishda Entry dagi kodlashni eslasak, to‘qnashuvni aniqlash uchun maxsus blok ("~ga tegdimi?" bloki) mavjud edi. Xuddi shuningdek, Pygame Zero da ham bu maqsad uchun alohida tayyorlangan funksiya (metod) mavjud. **Actor obyekti o‘ziga xos xatti-harakat(Behavior)lardan biri sifatida boshqa Actor obyekti bilan to‘qnashuvni tekshira oladigan** _**colliderect**_ **nomli funksiya(metod)ni o‘z ichiga oladi. Bu funksiyadan foydalanib, to‘qnashuvni juda oson kodlash mumkin.** ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FJtQhNdwPTj3ZtTTTQPN5%252Fimage.png%3Falt%3Dmedia%26token%3D30e0a7c6-1b97-49c3-bd4b-d24ef0830852&width=768&dpr=3&quality=100&sign=e4984e32&sv=2) Manba: [https://kidscancode.org/blog/2016/08/pygame\_shmup\_part\_5/arrow-up-right](https://kidscancode.org/blog/2016/08/pygame_shmup_part_5/) **update** funksiyasi ichida, ya’ni ekranda animatsiya sodir bo‘ladigan joyda, 35-qator orqali Flappy Bird yuqori quvur yoki pastki quvurdan biri bilan (bu maqsadda solishtirish ifodasi ichida _**or**_ ishlatilganiga e’tibor bering!) to‘qnashganini doimiy ravishda tekshirib boramiz. Agar to‘qnashuv aniqlansa, Flappy Birdning tasviri o‘lik holatdagi(birddead) rasmga almashtiriladi. Qo‘shimcha ravishda, Flappy Birdning tirik yoki o‘lik holatini bildiruvchi **bird\_alive** nomli global o‘zgaruvchining (funktsiyadan tashqarida e’lon qilingan) qiymati **False** (ya’ni o‘lganini bildiradi) ga o‘zgartiriladi. **bird\_alive** o‘zgaruvchisi nima uchun kerak bo‘ldi? Buni 41-qatorga qo‘shilgan shart operatoridan tushunish mumkin: allaqachon o‘lgan holatdagi Flappy Birdni xuddi tirikdek ko‘rsatib, havoga ko‘tarilish (uchib chiqish) harakatiga yo‘l qo‘ymaslik kerak edi. Shu sababli, hozirgi vaqtda Flappy Bird tirikmi yoki o‘lganmi — shuni farqlash zarur bo‘ldi. **bird\_alive** global o‘zgaruvchisi aynan shu maqsadda ishlatiladi. Shu joygacha yozilgan kod bilan Flappy Bird rejalashtirilganidek quvurga tegishi bilan (hatto tashqi ko‘rinishigacha) o‘lgan holatga o‘tadi va qulashni boshlaydi. Endi qolgan narsa — u ekran pastki qismiga qulab tushganida o‘yinni qayta boshlash funksiyasini qo‘shishdir. Ammo o‘yinni qayta boshlash holati faqatgina quvur bilan to‘qnashuv natijasida yuz berishi shart emas. Chunki foydalanuvchi Flappy Birdni ataylab harakatsiz qoldirib, uni faqat tortish kuchi ta’sirida avtomatik qulab, ekran pastiga chiqib ketadigan holatni yuzaga keltirishi mumkin. Yoki foydalanuvchi sichqoncha tugmasini juda tez-tez bosish orqali Flappy Birdni haddan tashqari balandga — ya’ni ekran yuqorisidan tashqariga chiqarib yuborishi ham mumkin. Bunday holatlarda ham o‘yinni qayta boshlash foydali bo‘ladi. Xulosa qilib aytganda, Flappy Bird tirik bo‘ladimi yoki o‘lgan bo‘ladimi — ekranning eng yuqori yoki eng pastki chegarasidan chiqib ketgan holatlarga tekshiruv kiritish kerak bo‘ladi. Aslida bu, ilgari amalga oshirgan quvurning cheksiz aylanishi (infinite pipe loop) kodiga juda o‘xshash. Bu funksiyani quyidagicha kod orqali amalga oshirish mumkin. Copy TITLE = 'Flappy Bird' WIDTH = 400 HEIGHT = 708 GRAVITY = 0.3 drop_speed = 0 GAP = 140 PIPE_SPEED = -3 bird_alive = True # Actor obyektlari flappy_bird = Actor('bird1', (75, 350)) top_pipe = Actor('top', (350,0)) bottom_pipe = Actor('bottom', (350, top_pipe.height + GAP)) def draw(): screen.blit('background', (0, 0)) flappy_bird.draw() top_pipe.draw() bottom_pipe.draw() def update(): global drop_speed, bird_alive drop_speed += GRAVITY flappy_bird.y += drop_speed top_pipe.x += PIPE_SPEED bottom_pipe.x += PIPE_SPEED # quvurning cheksiz sikli if top_pipe.right < 0 or bottom_pipe.right < 0: top_pipe.x = WIDTH bottom_pipe.x = WIDTH # quvur bilan to'qnashuv if flappy_bird.colliderect(top_pipe) or flappy_bird.colliderect(bottom_pipe): flappy_bird.image = "birddead" bird_alive = False # o'yinni qayta ishga tushurish if flappy_bird.y > HEIGHT or flappy_bird.y < 0: flappy_bird.image = "bird1" bird_alive = True flappy_bird.center = (75, 350) drop_speed = 0 top_pipe.x = WIDTH bottom_pipe.x = WIDTH def on_mouse_down(): global drop_speed if bird_alive == True: drop_speed = -6.5 🔢 40-qatorida shart operatori orqali Flappy Bird o‘yin ekrani chegarasidan chiqib ketgan-ketmaganini doimiy ravishda tekshirib boradi, va agar chiqib ketsa, o‘yinni dastlabki holatga qaytadan boshlash uchun kerakli qiymatlarni aynan shu shart blokida qayta boshlash kodlarini yozish kifoya. Qayta boshlash jarayoni 41-qatorda Flappy Bird tasvirini yana tirik holatdagi rasmga almashtirish bilan boshlanadi, 42-qatorida uning tirik yoki o‘lgan holatini bildiruvchi qiymat (bird\_alive) ham tirik (True) holatga o‘zgartiriladi, 38-qatorda to‘planib borayotgan qulash tezligi (drop\_speed) yana 0 ga tenglashtiriladi, va nihoyat o‘yin boshida Flappy Bird va quvurlar turishi kerak bo‘lgan boshlang‘ich joylashuvga qaytariladi. Shu bilan Flappy Bird o‘yinining asosiy funksional qismlarini yaratish yakunlandi. Albatta, o‘yinga qiziqish qo‘shish uchun bir nechta qo‘shimcha funksional talablar (quvurning joylashuvini tasodifiy qilish, quvurga urilmay o‘tganda ball berish, o‘yin musiqasi qo‘shish va hokazo) mavjud bo‘lishi mumkin, biroq shuni ta’kidlash kerakki, atigi 50 qatorli kod orqali ham to‘laqonli o‘yin yaratish mumkinligi Pygame Zeroning eng katta afzalliklaridan biri hisoblanadi. Qo‘shimcha funksiyalarni yaratish bo‘yicha alohida bobda batafsil aytib o‘tamiz. Hozirgacha Flappy Bird o‘yinini yaratish orqali Pygame Zeroga muvaffaqiyatli kirib kelgan barchangizni yana bir bor tabriklayman. Kelgusida davom etadigan bir nechta boblar orqali bir nechta katta-kichik o‘yin yaratish loyihalarini amalga oshirib ko‘rib, Python dasturlash tili orqali matnli kod yozishning chinakam zavqini kashf qilishingizga umid qilaman. [Previous5.4 Quvur(obyekt)ni ekranga chiqarish va harakatlantirishchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.4_pipes) [Next5.6 Flappy Bird o‘yiniga qo‘shimcha funksiyalarni joriy qilish (ball funksiyasi)chevron-right](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.6_score) Last updated 7 days ago --- # 5.1 Ekranga fon rasmi(obyekti)ni chiqarish | Python-Pygame Zero Keling, Entry blokli dasturlashdagi tajribangizni eslaylik. O‘yin yaratishda siz birinchi bo‘lib nima qilgandingiz? Ehtimol, o‘yinda qatnashadigan obyektlarni ekranga joylashtirish ishidan boshlagansiz. Matnli dasturlashda ham bu holatga o‘xshash. Biz ham o‘yinni yaratishni fon va bosh qahramon (Flappy Bird) kabi obyektlarni ekranga chiqarishdan boshlamoqchimiz. Entryda bo‘lgani kabi, o‘yinda foydalaniladigan obyektlar Entryga oldindan o‘rnatilgan obyektlar ichida bo‘lmasa, siz o‘yinda ishlatiladigan rasm fayllarini alohida chaqirib, Entryga ro‘yxatdan o‘tkazgandan keyingina blokli kod yozishni boshlashingiz mumkin edi. Xuddi shunday, bizning birinchi qiladigan ishimiz — o‘yinimizda ishlatiladigan barcha rasm fayllarining arxiv faylini quyidagi [yuklab olish havolasiarrow-up-right](https://kinolien.github.io/gitzip/?download=https://github.com/andyborrell/pygamezero_bird/tree/master/images) orqali yuklab olib, arxivni ochishdir. So‘ngra, Mu editori o‘rnatilganda _avtomatik yaratiladigan ishchi papka yo‘li (__**foydalanuvchi\_nomi/mu\_code**__) ichidagi_ _**images**_ _nomli papka —_ _**standart rasm saqlanadigan joy**__ga arxivdagi fayllarni saqlab qo‘yish kerak bo‘ladi._ Agar siz [maxsus Mu editoriarrow-up-right](https://github.com/roboticsware/mu/releases) dan foydalanayotgan bo‘lsangiz, unda foydalanuvchi\_nomi\\mu\_code\\examples\\pygame\_zero\\images manzilidagi ishchi papkadan fayllarni nusxalab olib ishlatishingiz mumkin. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252Frwx0XMgnBSmYIGRG3peY%252Fimage.png%3Falt%3Dmedia%26token%3Db45774c2-8bef-4608-8c58-e2f6f22d9b08&width=768&dpr=3&quality=100&sign=667f312a&sv=2) Agar siz ushbu papkaning joylashuvini aniqlamoqchi bo‘lsangiz, Mu editoridagi menyu panelida joylashgan **“Rasmlar”** tugmasini bosing — bu tugma orqali kodlashda foydalaniladigan rasmlar saqlanadigan papka ochiladi. Odatda bu papkada allaqachon bir nechta namunaviy rasm fayllari bo‘ladi va siz o‘zingizning rasm fayllaringizni ham shu yerga saqlashingiz mumkin. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FTjEcSipzLWsqA7GWvAsi%252Fimage.png%3Falt%3Dmedia%26token%3D15056919-58b0-4a73-a404-d905e93c5364&width=768&dpr=3&quality=100&sign=ec05a132&sv=2) ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FNXOgqTdIexzOyT5lfiUd%252Fimage.png%3Falt%3Dmedia%26token%3Dd0155e1e-9116-46a0-bbdd-b6e7d9804f20&width=768&dpr=3&quality=100&sign=244c50d2&sv=2) images papkasiga saqlangan o‘yin rasmlari circle-info Aytgancha, **o'yinni dasturlashda zarur bo'lgan resurslarni (rasmlar, fontlar, ovoz effektlari, fon musiqasi) saqlaydigan papkalarni yaratish uchun siz Pygame Zero kutubxonasining asosiy cheklovlarida o'rnatilgan ushbu pastki papkalar uchun oldindan belgilangan nomlarga (tartibda: images(rasmlar), fonts(fontlar), sounds(effektlar), music(ovozlar)) rioya qilishingiz kerak**. Ushbu muvofiqlik Mu editorining menyu panelidagi tugmalarining nomlari aytib o'tilgan papkalarning nomlariga mos kelishi bilan bog'liq. Shuning uchun, tegishli tugmalarni bosish orqali resurs turiga mos papkalarni avtomatik ravishda ochishga qaratilgan dasturlash, resurslarni topa olmaslik bilan bog'liq ish vaqtida xatolar ehtimolini kamaytiradigan qulay usuldir. Shunga tegishli Mu editorining qo'llanmasiga qarang: [https://codewith.mu/en/howto/1.2/pgzero\_sounds\_imagesarrow-up-right](https://codewith.mu/en/howto/1.2/pgzero_sounds_images) Endi editor oynasiga quyidagi 6 qatorlik o‘yinimizning birinchi kodini yozing, so‘ng menyudagi **Play(boshlash) tugmasini bosib**, uni ishga tushirib ko‘raylik. Copy TITLE = 'Flappy Bird' WIDTH = 400 HEIGHT = 708 def draw(): screen.blit('background', (0, 0)) O'yinning fon rasmini ko'rsatadigan o'yin ilovamiz to'g'ri ishlaydi. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FCrhSHZmH6JTh0MPevTNr%252Fimage.png%3Falt%3Dmedia%26token%3De9f0f55c-d5bf-4f65-bb33-99ea3dca43b6&width=768&dpr=3&quality=100&sign=a1790a85&sv=2) 🔢 Endi esa kod tahliliga navbat keldi. 1–3-qatordagi kodlar oldingi darsda allaqachon foydalanilgan bo‘lgani uchun ularni tushunishda qiyinchilik bo‘lmasligi kerak. 5–6-qatorlarda esa **draw** nomli _qayta chaqirish(callback)_ funksiyasi ichida pygame kutubxonasining ichki funksiyasi bo‘lgan **blit** funksiyasi **screen.blit** shaklida, joylashuv ma’lumotlari bilan birga chaqirilmoqda. Bu yerda **screen.blit** deb yozilgani bois, buni **screen** degan modul bor va uning ichida **blit** funksiyasi mavjud deb o‘ylashingiz mumkin. Ammo aslida bu yerda shunchaki **screen** degan modul emas balki, avvalgi darslar([Entry misollari orqali Python o‘rganisharrow-up-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic) )da aytilganidek, bir vaqtni o'zida [obyektarrow-up-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/kuchuk-mushuk_2#obyekt-nima) ham hisoblanadi. Shunday ekan, **screen.blit** degani — bu **screen** obyektining ichida mavjud bo‘lgan **blit** funksiyasini chaqirish deganidir. [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.1_background#obyektlarni-tushunish) Obyektlarni tushunish ----------------------------------------------------------------------------------------------------------------------------------------- Obyektdan foydalanilgan holda matnli dasturlash ushbu kitobda birinchi marta paydo bo‘lgani sababli, avvalgi darslardagi obyektga bo‘lgan tushunchamizni yanada chuqurlashtirish kerak bo‘ladi. _**Obyekt degani, so‘zma-so‘z olganda, haqiqiy dunyo(real world)dagi mavjud bo'lgan obyekt(object), masalan, mashina, hayvon, odam kabi obyektlarning xususiyatlarini dastur dunyosi(program world)da foydalanish uchun modellashtirilgan shakli bo‘lishi mumkin. Bazi obyektlar esa haqiqiy hayotda mavjud bo‘lmay, faqatgina dasturiy muhitda mavjud bo‘ladi — masalan, mahluq(monster) kabi xayoliy obyektlar yoki animatsiya(animation) kabi texnik usullar va hokazo.**_ _**Obyekt o‘zi mustaqil bo‘lgan bir birlik bo‘lganligi sababli, u o‘zining xususiyat(attribute)larini ifodalash uchun o‘zgaruvchilar va o‘zi bajara oladigan har qanday dinamik harakat(action) yoki xatti-harakat(behavior)ni ifodalash uchun funksiyalarni (ayniqsa, obyekt ichida mavjud bo‘lgan funksiyalar metod(method) deb ataladi) bir butun holatda o‘z ichiga oladi.**_ Masalan, agar biz avtomobil modellashtirgan obyektini yaratmoqchi bo‘lsak, u holda avtomobilga xos bo‘lishi mumkin bo‘lgan **xususiyatlar** — kuzov shakli, dvigatel turi, g‘ildirak turi kabi elementlar o‘zgaruvchilar orqali ifodalanadi va avtomobilning bajara oladigan harakatlari — yurish(drive), to‘xtash(brake), burilish(turn) kabi **xatti-harakatlar** esa funksiyalar orqali ifodalanadi. Yuqorida **screen** — bu Pygame Zero kutubxonasi muallifi tomonidan yaratilgan kutubxona ichidagi modul bo‘lishi bilan birga obyekt ham ekani aytilgan edi. **Kutubxona mualliflari odatda o‘z kutubxonalari ichidagi barcha narsalarni foydalanuvchilar maqsadga muvofiq aniq foydalanishlari uchun alohida qo‘llanmani taqdim qilishadi.** Shuning uchun [screen obyektiga oid qo‘llanmaarrow-up-right](https://pygame-zero.readthedocs.io/en/latest/builtins.html#screen) ni ham muallif joylashtirgan [internet repozitoriyasi(ombori)arrow-up-right](https://pygame-zero.readthedocs.io/) dan topish mumkin. Qo‘llanma bo‘yicha, **screen** obyekti — bu ilovaning ekranini obyektga aylantirilgan ko‘rinishi bo‘lib, ushbu **screen** obyekti bajarishi mumkin bo‘lgan xatti-harakatlar(behavior)dan biri sifatida [blit funksiyasi(metodi)arrow-up-right](https://pygame-zero.readthedocs.io/en/latest/builtins.html#Screen.blit) orqali ma’lum bir tasvirni ekranning muayyan joyiga chizish vazifasini bajaradi. Xulosa qilib aytganda, biz fon tasvirini ekranga chizish kabi maqsadimizga erishish uchun **screen** obyektidagi **blit** funksiyasidan foydalanamiz va **blit** funksiyasida talab qilinadigan 2 ta parametr quyidagilardir: birinchisi — ekranga nima chizilishi kerakligi, ya’ni chizilishi kerak bo‘lgan tasvir faylining nomi; ikkinchisi — ushbu tasvir ekranda qayerga chizilishi kerakligi haqidagi joylashuv ma’lumoti (aniqrog‘i, tasvirning chap-ustki burchagi (topleft) ekranning qayerida joylashishi kerakligi). Shunday qilib, bizning funksiya chaqiruvimiz yakuniy tarzda quyidagicha ko‘rinishga ega bo‘ladi: **screen.blit('background', (0, 0))** **blit** funksiyasi haqida yana bilishimiz kerak bo‘lgan jihatlar mavjud. Bu funksiyaga uzatiladigan haqiqiy qiymatlar (bunga _argument_) orasida, birinchi argument bo‘lgan '**background**' — bu **images** papkasiga saqlangan o‘yin fon rasmi fayli nomi ekanini intuitiv ravishda tushunish mumkin. Ammo, ikkinchi argument bo‘lgan (0, 0) — bu joylashuv ma’lumoti esa, avvalgi darslarda biz o‘rganmagan ma’lumot turi(type)ga ega. Bu (x koordinata, y koordinata) ko‘rinishida bitta emas, balki ikkita qiymatni birdan (x, y koordinata) uzatmoqda. Oldingi boblarda o‘rganganimizdek, faqat bitta qiymat emas, balki bir nechta qiymatlarni saqlash mumkin bo‘lgan Python tomonidan taqdim etilgan xotira maydoni qanday nomlanardi, esingizdami? Ha, siz: "Bu qiymatlarni ro‘yxatga (List) joylab yuborsak bo‘ladi", deb o‘ylashingiz mumkin. Ro‘yxatning yozilish qoidalari yodingizdami? To‘g‘ri burchakli qavslarga \[ \] qiymatlarni joylashtirish kifoya. Demak, bu holatda \[x koordinatasi, y koordinatasi\] tarzida qiymatlarni yozib, **blit** funksiyasiga uzatsak bo‘lmaydimi? Albatta, bu mumkin. Lekin ushbu funksiyani yaratgan kishi biz — foydalanuvchilarga — bu qiymatlarni to‘g‘ri burchakli qavslar **\[\]** orqali emas, yumaloq qavslar **()** orqali yozishimiz kerak bo‘lgan cheklovni qo‘ygan. **To‘g‘ri burchakli va yumaloq qavslar orasidagi farq nimada? Dasturlash olamida har bir nuqta, har bir bo‘shliq ahamiyatga ega va qavs turining o‘zgarishi ham albatta ma’noni o‘zgartiradi.** Yumaloq qavslarga qiymatlarni joylashtirish — bu biz ilgari o‘rganmagan ([oldingi kitobarrow-up-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic) ni o‘qib chiqmaganlar uchun) yangi turdagi ma’lumot shaklidir. Bu turdagi ma’lumot **tupl** (tuple) deb ataladi. [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.1_background#tupl-tuple) Tupl (Tuple) --------------------------------------------------------------------------------------------------------------------- Avvalo, **tupl** qanday ishlatilishini ko‘rib chiqaylik. Haqiqatan ham, ro‘yxat(list)dagi to‘g‘ri burchakli qavs \[ \] o‘rniga **yumaloq qavs ( )** ishlatilganidan boshqa tashqi ko‘rinishda hech qanday farq yo‘q. > Tupl\_nomi = (matn, son va boshqa turli qiymatlar. Faqat, qiymatlar vergul (,) bilan ajratiladi) Ro‘yxat (list) va tupl (tuple) o‘rtasidagi asosiy farq — **qiymatlarni keyinchalik o‘zgartirish mumkinmi yoki yo‘qmi** degan masaladir. Bu — **tahrirlanadigan** (modifiable) va **faqat o‘qiladigan** (read-only) ma’lumotlar o‘rtasidagi farqdir. **Tupl** — bu faqat o‘qiladigan (read-only) turga kiradi. Uni shunday qilib belgilashning sababi — dasturchi dastlab belgilagan qiymatni himoya qilish, ya’ni keyinchalik o‘zi yoki boshqa dasturchi uni xatolik bilan o‘zgartirishining oldini olishdir. Bu — **avvaldan xatoliklarning oldini olishga qaratilgan niyatli cheklov** hisoblanadi. Shunday ekan, biz har doim funksiyani yaratgan muallifning niyati bilan belgilangan bu kabi **cheklovlarga rioya qilishimiz kerak**. Axir biz boshqa birov yozgan funksiyalar yoki kutubxonalarni ishlatayotgan foydalanuvchilarmiz, shuning uchun ularga nisbatan norozilik bildirishning hojati yo‘q. Aksincha, **muallif belgilagan doirada ishlashni** qulay va xavfsiz deb bilishimiz kerak. Shuning uchun, **blit** funksiyasini ishlatmoqchi bo‘lsak, **ekranda rasm chizilishi kerak bo‘lgan x, y koordinata qiymatlarini tupl ichiga joylab, funksiyaga argument sifatida uzatishimiz kerak** deb tushunsak kifoya. Va aynan shunday tarzda kod yozamiz. [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.1_background#pygame-zero-ning-ekran-koordinata-tizimi) Pygame Zero ning ekran koordinata tizimi ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Endi so‘nggi savolga javob topamiz. Joylashuv ma’lumotining turi **tupl** ekanini bildik. Ammo nega joylashuv qiymatlari, ya’ni **x va y koordinatalar** aynan (0, 0) bo‘lishi kerak? Buni tushunish uchun **Pygame kutubxonasidagi koordinata tizimini bilish zarur. Bu tizim biz ilgari ishlatib kelgan Entry yoki Scratch dasturlaridan farqlanadi. Entry/Scratch da koordinata tizimi ekran markaziga (0, 0) nuqtasi sifatida asoslanadi va barcha joylashuvlar shu markazdan hisoblanadi. Biroq, Pygame da koordinata tizimi boshqacha — bu yerda ekran markazi emas, balki ekranning chap yuqori burchagi (0, 0) nuqta hisoblanadi. Ya’ni, x koordinata o‘ngga qarab oshadi, y koordinata esa pastga qarab oshib boradi.** ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252Fdjd0gA7hDO3or5R69s1U%252Fimage.png%3Falt%3Dmedia%26token%3D06893fc9-c960-4802-8c64-278ec77f5ea4&width=768&dpr=3&quality=100&sign=91536d0b&sv=2) Pygame-da koordinatalar tizimiga misol Endi siz tushungandirsiz — **fon rasm**ni ekranga to‘liq to‘ldirish uchun, uning **chap yuqori burchagi** (0, 0) koordinatadan chizilishi kerak bo‘ladi. Quyidagi bobni yakunlashdan oldin ba’zi odamlarning hali hal qilinmagan savollari qolgan bo‘lishi mumkin, boshqalar esa bunday savolga ega bo‘lmasligi mumkin. Bu savol quyidagicha: biz **draw** funksiyasini faqat **ta’rifladik** (definition), lekin hech qayerda bu funksiyani chaqirganimiz yo‘q. Shunday bo‘lsada, qanday qilib bu funksiya chaqirilib, ilova ishga tushib, fon rasmi to‘g‘ri chizilmoqda? Agar siz oldingi boblarda **kolbek(callback) funksiyasi** tushunchasini to‘g‘ri tushungan bo‘lsangiz, bu savol sizda paydo bo‘lmagan bo‘lardi. Ammo agar sizda bu savol hanuz qolayotgan bo‘lsa, demak kolbek(callback — ya'ni "qayta chaqiruvchi") funksiyasi tushunchasi hali sizga to‘liq tushunarli emas. Bunday holda, sizga oldingi kitobga qaytib, o‘sha bo‘limni yana bir bor o‘qib chiqishni tavsiya qilamiz. Ha, **draw funksiyasi — bu kolbek funksiyasi. Bu nimani anglatadi? Bu shuni anglatadiki: Pygame Zero kutubxonasi oldindan belgilangan qoidaga ega: agar siz ekranga nimadir chizmoqchi bo‘lsangiz, albatta draw deb nomlangan maxsus funksiyani yozishingiz kerak. Shunda kutubxona shu nomdagi funksiyani avtomatik ravishda chaqiradi — biz chaqirmasak ham. Shu sababli, draw funksiyasini o‘zimiz chaqirmasligimiz kerak, chunki uni kutubxonaning o‘zi biz uchun avtomatik ravishda chaqiradi.** Keyingi bobda esa, asosiy qahramon obyektimiz — **Flappy Bird**ni ekranga chizib, uni harakatlantirishni davom ettiramiz. [Previous5\. Flappy Bird o'yinini yaratishchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird) [Next5.2 Flappy Bird(obyekt)ni ekranga chiqarish va harakatlantirishchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.2_flying) Last updated 7 days ago --- # 10.4 Tarmoqli o‘yinga aylantirish 2 | Python-Pygame Zero Avvalgi bo‘limda aytilganidek, avvalo o‘yinni boshlashni boshqarish va to‘pning harakatini qayta ishlash haqida bilib olaylik. Har kim avvalgidek bo‘sh joy tugmasini bosib o‘yinni boshlashi mumkin. Biroq, tarmoqli o‘yinning tabiati tufayli, guruh xonasida o‘yinni boshlash uchun zarur bo‘lgan barcha ishtirokchilar kirganini qo‘shimcha ravishda tekshirish zarur (37-qator) va bu tasdiqlangandan keyingina o‘yin boshlanishi mumkin. O‘yin boshlangach, uzoqda joylashgan raqib ham darhol o‘yinni boshlashi uchun unga **game\_start** xabarini yuborish zarur bo‘ladi (40-qator). Copy class Ball(Rect): ... def collide_wall(self, sound_only=False): # Yuqori yoki pastki devor if self.top < 0 or self.bottom > HEIGHT: if not sound_only: self.vy = -self.vy # Tezlikning y yo'nalishini teskari o'zgartirish sounds.wall.play() # chap devor if self.left < 0: if not sound_only: self.reset() sounds.die.play() return 'b2' # o'yin boshlanish shartlari if self.right > WIDTH: if not sound_only: self.reset() sounds.die.play() return 'b1' return '' ... def update(): global num_peers ... # o'yin boshlanish shartlari if score.is_game_over(): # Har kim birinchi bo'lib o'yinni boshlashi mumkin if num_peers == MAX_PEERS and keyboard.space: score.reset() ball.reset() net.send_msg(peer_id, 'game_start', True) else: # to'p if is_host: ball.move() net.send_msg('Player2', 'ball_pos', {'center': ball.center, 'vel': (ball.vx, ball.vy)}) who_win = ball.collide_wall() if who_win: # hisob score.add(who_win) net.send_msg('Player2', 'score', who_win) ball.reset() else: # Player2 ball.move() ball.collide_wall(sound_only=True) ... Keyingisi, 41-qatorlardan keyingi to‘p harakati haqida bo‘lib, bu avval ko‘rib chiqqan reflektor harakatini qayta ishlashga juda o‘xshash. To‘p harakatini boshqarish uchun javobgarlik **host** zimmasida, u to‘pning joriy joylashuv ma’lumotini **ball\_pos** xabari orqali doimiy ravishda raqibga yuborib turadi; shunda raqib ham o‘z ekranida to‘pning joylashuvini real vaqtda yangilashi mumkin (44-qator). To‘p joylashuvi ma’lumoti to‘pning markaz koordinatasi (ball.center) va tezligi (ball.vx, ball.vy) bo‘yicha tupl (tuple) qiymatidan iborat bo‘lib, **{'center':ball.center, 'vel':(ball.vx, ball.vy)}** ko‘rinishida [lug‘at](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.4_dev_net_2#lugat-dictionary) turidagi ma’lumot sifatida uzatilishini e’tiborga olish kerak. [Lug‘at](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.4_dev_net_2#lugat-dictionary) deb ataladigan ma’lumot turi bu kitobda birinchi marta uchrayotgani sababli, uning paydo bo‘lish maqsadi va qo‘llanish qoidalarini o‘rganib olish zarur. [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.4_dev_net_2#lugat-dictionary) Lug‘at (Dictionary) ----------------------------------------------------------------------------------------------------------------------------------- Avvalo, dictionary so‘zi o‘z nomidan ma’lumki, lug‘at degan ma’noni bildiradi. Lug‘atni ma’lum bir so‘z va o‘sha so‘zning ma’nosini juft(pair) ko‘rinishida jamlagan to‘plam deb tasavvur qilish mumkin. **Python**dagi lug‘at(dictionary) ma’lumot turi ham shunday. Agar ro‘yxat(list) oddiygina turli xil ma’lumotlar to‘plami (obyekt) bo‘lsa, _lug‘at esa_ _**har bir ma’lumot (qiymat (Value) deb ataladi)**_ _va_ _**o‘sha ma’lumotni bildiradigan aniq nom (kalit (Key) deb ataladi)**_ _ni birgalikda juftlab bog‘lagan ma’lumotlar to‘plami (obyekt)_ deb aytish mumkin. Ro‘yxatda qiymatga murojaat qilish uchun indeks ishlatilgan bo‘lsa, lug‘atda indekssiz, uning o‘zini bildiruvchi tarzda oldindan belgilangan nomi (key) orqali qiymatga murojaat qilinadi. Quyidagi foydalanish sintaksisini ko‘rsangiz, yanada oson tushunasiz > **dictionary nomi = {****kalit: qiymat** **juftliklari ko‘rinishida tashkil topgan bir nechta qiymatlar. Faqat, kalit va qiymat juftliklari orasida vergul (,) bilan ajratiladi}** Lug‘at misol kodi Copy person = {'name': 'Bob', 'occupation': 'Engineer'} print(person['name']) # chiqish: nom (kalitlar yordamida qiymatlarga kirish) person['age'] = 25 # yangi kalit-qiymat juftligini qo'shish person['occupation'] = 'Software Engineer' # mavjud kalitning qiymatini o'zgartirish del person['age'] # muayyan kalit-qiymat juftligini o'chirish print(person) # chiqish: {'ism': 'Bob', 'kasb': 'Dasturiy ta'minot muhandisi'} Endi to‘p devorga urilgan holatni qayta ishlashga keladigan bo‘lsak, mavjud **collide\_wall** a’zo funksiyasiga ba’zi o‘zgarishlar kiritildi, ya’ni to‘p ekran chap yoki o‘ng devoriga urilganda, ya’ni yutish yoki yutqazish holatida, tarmoq orqali masofadan turib hisobni yangilash (48-qatorda) zarur bo‘lganligi sababli, shu qismga oid kod qo‘shilgan. collide\_wall funksiyasini batafsil ko‘rsak, avvalgi holatda g‘alaba balli yuzaga kelganda obyekt o‘zi hisobni bevosita yangilagan bo‘lsa, endilikda g‘alabani kim qo‘lga kiritganini bildiruvchi qiymat (b1 yoki b2) qaytariladi xolos (16, 23-qatorlar), hisobni yangilash esa bu qiymatni qabul qilgan tomon zimmasiga yuklanadi (45~47-qatorlar). Shuningdek, collide\_wall funksiyasiga **sound\_only** nomli parametr ham qo‘shilgan bo‘lib, bu ham oldingi reflektor holatidagi kabi, host bo‘lmagan oddiy foydalanuvchi holatida to‘pning aks etishiga faqat tovush effekti bilan javob qaytarish maqsadida kiritilgan. Keyingi bosqichda esa, ilgari ko‘rib chiqilishi kechiktirilgan qabul qilingan xabarlarni qayta ishlash qismi bilan tanishamiz. Qabul xabarlarini umumlashtirib qayta ishlash uchun **handle\_recv\_messages** funksiyasi ichida bu jarayon amalga oshiriladi. Copy def handle_recv_messages(): # Barcha xabarlarni qabul qilish net.process_recv() # Muayyan xabarlarni ajratib ko'rsatish game_start = net.get_msg(peer_id, 'game_start') bar_pos = net.get_msg(peer_id, 'bar_pos', clear=False) ball_pos = net.get_msg("Player1", 'ball_pos', clear=False) who_win = net.get_msg("Player1", 'score') # o'yinni boshlash if game_start: score.reset() ball.reset() # to'p if ball_pos: ball.pos_update(ball_pos['center'], ball_pos['vel']) # reflektor if bar_pos: if is_host: bar2.pos_update(bar_pos) else: # Player2 bar1.pos_update(bar_pos) # hisob if who_win: score.add(who_win) def update(): global num_peers # tarmoqdagi qabul qilingan xabarlar qayta ishlanmoqda handle_recv_messages() ... Eslab qolgan bo‘lsangiz, jo‘natish tarafida xabarlar bilan ishlashda biz yubormoqchi bo‘lgan xabarlarni vaqtinchalik **bufer**da to‘plab, ularni davriy ravishda (paket qilib) yuborish usulini qo‘llagan edik. Qabul qilish tarafida ham xuddi shunday: tarmoq orqali uzluksiz kelib turadigan xabarlar **qabul buferi** deb ataladigan joyda yig‘ib boriladi va ular ma’lum oraliqlarda bir yo‘la qayta ishlanadi. Shuning uchun bunday ishlov jarayonini amalga oshirish uchun **NetNode** obyektidagi **process\_recv** a’zo funksiyasini muntazam ravishda chaqirib turish zarur (3-qator). Avvalo, qarshi tomondan kelgan xabarlarni alohida ajratib olish kerak, keyin esa ajratilgan xabarlarga mos ravishda ishlov beriladi. Xabarlarni ajratish **NetNode** obyektining **get\_msg** a’zo funksiyasi orqali amalga oshiriladi. Bu funksiya 3 ta parametr qabul qiladi. Birinchisi, ushbu (axborot maqsadidagi) xabarning qabul qiluvchisining guruh xonasidagi **id** qiymati; bu yerda argument sifatida **peer\_id** uzatiladi. Xuddi oldingi bo‘limdagi **connect\_server** funksiyasida bu qiymat oldindan o‘rnatilgan bo‘ladi. Ya’ni, host bo‘lgan o‘yinchi oddiy foydalanuvchiga, oddiy foydalanuvchi esa hostga xabar yuboradi. Ikkinchi parametr, xabar qabul qiluvchiga yetib kelganda, ko‘plab xabarlar orasidan muayyan xabarni ajratib olish uchun xizmat qiladigan xabar identifikatori (bir turdagi id). Uchinchi parametr sifatida **clear** mavjud bo‘lib, zarur bo‘lsa ishlatiladi, kerak bo‘lmasa uni uzatish shart emas. Ushbu parametrning maqsadi — qabul buferidan xabar o‘qilgach, o‘sha xabarni qabul buferidan o‘chirib tashlash-tashlamaslikni belgilash. Keling, bunday parametr nima uchun kerakligini o‘ylab ko‘raylik. Bu qiymat tarmoqning o‘ziga xos xususiyatidan kelib chiqadigan istisnoviy ehtiyoj sabab mavjud, chunki tarmoqda almashilayotgan ma’lumotlar orasida [kechikish(delay)arrow-up-right](https://en.wikipedia.org/wiki/Network_delay) yuz berishi mumkinligini yodda tutish kerak. Masalan, raqibning real vaqtdagi joylashuvi kabi axborot xabari kech yetib kelsa, mening ekranimda raqib to‘xtab qolgandek ko‘rinishi yoki harakatda uzilishlar paydo bo‘lib, juda tabiiy bo‘lmagan ko‘rinishga olib kelishi mumkin. Shunday holatlarga tayyor turish uchun **clear** qiymatini **False** qilib belgilasak, mos xabar **id**\-siga ega yangi xabar kelguncha mavjud xabarni o‘chirib yubormay saqlab turish orqali, ekrandagi **UI**da "muzlab qolish" holatini kamaytiramiz. Bu yerda to‘p harakati (**ball\_pos**), reflektor harakati (**bar\_pos**) bo‘yicha ikkita real vaqt harakati uchun **clear=False** qilib qo‘yilgan. Qo‘shimcha ravishda **clear** qiymati haqida batafsilroq bilmoqchi bo‘lsangiz, [kutubxona muallifi bevosita tushuntirgan mazmunarrow-up-right](https://github.com/QuirkyCort/nethelper/tree/main/examples#remember_commandspy) ga murojaat qilishingiz mumkin. Endi qolgan narsa — har bir qabul qilingan xabarni batafsil qayta ishlashga oid 11~29-qatorlar bo‘lib, ularni intuitiv tarzda tushunish mumkin; qo‘shimcha izohsiz ham buni yetarlicha anglab olishingizni kutaman. Shunday qilib, Pong o‘yinini tarmoqli o‘yinga aylantirish bo‘yicha barcha jarayonlar yakunlandi. Shu kabi o‘yinlarga qo‘shimcha ravishda tarmoq kodlash elementi qo‘shilgani uchun murakkablik darajasi yanada yuqoriroq bo‘ladi. Biroq, tarmoq hozirda kundalik hayotimizdan ajralmas qism bo‘lib qolgani sababli u barcha dasturlash jihatlarida doimo uchraydi; shuning uchun uni chetlab o‘tib bo‘lmaydi va uni albatta nazariy jihatdan ham tushunish va qabul qilish zarur. Endi esa ushbu o‘yinning umumiy dastur kodini ko‘rib chiqish bilan yakunlaymiz. pong\_net.py Copy import random import math from nethelper import NetNode # o'yin oynasi TITLE = 'pong' WIDTH = 800 HEIGHT = 600 # reflektor BAR_H = 100 BAR_W = 15 GAP_FROM_SCR = 20 # to'p BALL_RADIUS = 10 VELOCITY = 5 SPEED_UP = 1.08 # hisob FINAL_SCORE = 11 # tarmoq SERVER_IP = 'localhost' # rele server IP manzili is_host = False # host sifatida zimat qiladimi peer_id = '' # aloqadagi sherikdin 'id'si MAX_PEERS = 2 # o'yinchilar maksimal soni num_peers = 0 # o'yinchilarning hozirgi soni my_bar = '' class Score(): ''' Ekranda hisob, g'alaba va mag'lubiyatlarning UI ko'rinishi ''' def __init__(self, final_score): self._final_score = final_score self._b1_score = -1 self._b2_score = -1 def _gameover_draw(self): winner = '' if self._b1_score == self._final_score: winner = 'Player1' elif self._b2_score == self._final_score: winner = 'Player2' if winner: screen.draw.text(winner + ' Win!!', (WIDTH/3, HEIGHT/2 - 50), color='blue', fontsize=70) screen.draw.text('Press Space to play again', (WIDTH/4, HEIGHT/2 + 50), color='skyblue', fontsize=50) def is_game_over(self): if (self._b1_score == self._final_score or self._b2_score == self._final_score) \ or (self._b1_score == -1 and self._b2_score == -1): return True else: return False def add(self, who): if who == 'b1': self._b1_score += 1 elif who == 'b2': self._b2_score += 1 def reset(self): self._b1_score = 0 self._b2_score = 0 def reinit(self): self._b1_score = -1 self._b2_score = -1 def draw(self): screen.draw.text(str(self._b1_score), (WIDTH/4, GAP_FROM_SCR), color='yellow', fontsize=60) screen.draw.text(str(self._b2_score), ((WIDTH/4)*3, GAP_FROM_SCR), color='yellow', fontsize=60) if self.is_game_over(): self._gameover_draw() class Ball(Rect): ''' To'pning harakati (joylashuvi, harakalanishi) va to'qnashuvni tekshirish ''' def __init__(self, start_pos, velocity, score): super().__init__(0, 0, BALL_RADIUS * math.sqrt(2), BALL_RADIUS * math.sqrt(2)) self.center = start_pos self._velocity = velocity self.vx = self.vy = self._velocity self._score = score def pos_update(self, center, vel): self.centerx, self.centery = center self.vx, self.vy = vel def reset(self): if self._score.is_game_over(): self.vx = self.vy = 0 else: self.vx = self.vy = self._velocity self.vx *= random.choice([-1, 1]) # Markaziy chiziqdan tasodifiy chapga va o'ngga tashlash self.center = (WIDTH/2 , random.randint(BALL_RADIUS*2, \ HEIGHT - BALL_RADIUS*2)) def move(self): # To'pni vx va vy tezliklari bilan harakatlantirish self.move_ip(self.vx, self.vy) def collide_wall(self, sound_only=False): # Yuqori yoki pastki devor if self.top < 0 or self.bottom > HEIGHT: if not sound_only: self.vy = -self.vy # Tezlikning y yo'nalishini teskari o'zgartirish sounds.wall.play() # chap devor if self.left < 0: if not sound_only: self.reset() sounds.die.play() return 'b2' # o'ng devor if self.right > WIDTH: if not sound_only: self.reset() sounds.die.play() return 'b1' return '' def draw(self): screen.draw.filled_circle(self.center, BALL_RADIUS, 'white') class Bar(Rect): def __init__(self, x, y, ball): super().__init__(x, y, BAR_W, BAR_H) self.ball = ball def up(self): if self.y > 0: self.y -= 7 def down(self): if self.y + self.height < HEIGHT: self.y += 7 def pos_update(self, center): self.centerx, self.centery = center def collide_ball(self, sound_only=False): if self.colliderect(self.ball): if not sound_only: # Avval 10 piksel oldinga o'tish if self.ball.vx < 0: # bar1 holatida self.ball.x += 10 else: # bar2 holatida self.ball.x -= 10 self.ball.vx = -self.ball.vx * SPEED_UP # Tezlikning x yo'nalishini teskari o'zgartirish ''' To‘p yuqori tomondan kirib, reflektorning yuqori qismiga urilganda yoki to‘p pastki tomondan kirib, reflektorning pastki qismiga urilganda, kirish yo‘nalishi o‘zgarmay aks etadi ''' if (self.ball.vy > 0 and self.ball.centery < self.centery) or \ (self.ball.vy < 0 and self.ball.centery > self.centery): self.ball.vy = -self.ball.vy * SPEED_UP sounds.bar.play() def draw(self): screen.draw.filled_rect(self, 'white') # qahramon obyektlarini yaratish score = Score(FINAL_SCORE) ball = Ball((WIDTH/2, HEIGHT/2), VELOCITY, score) bar1 = Bar(GAP_FROM_SCR, HEIGHT/2 - BAR_H/2, ball) bar2 = Bar(WIDTH - BAR_W - GAP_FROM_SCR, HEIGHT/2 - BAR_H/2, ball) bars = [bar1, bar2] net = NetNode() def connect_server(): global is_host, peer_id, my_bar # Birinchi bo'lib ulangan kishi host (Player1) rolini o'z zimmasiga oladi if net.connect(SERVER_IP, "Player1", "pong_game", wait=True): is_host = True peer_id = "Player2" my_bar = bar1 print("Connected as host (Player 1)") else: # Agar xost allaqachon mavjud bo'lsa, peer (Player2) roli if net.connect(SERVER_IP, "Player2", "pong_game", wait=True): is_host = False peer_id = "Player1" my_bar = bar2 print("Connected as peer (Player 2)") else: print("Failed to connect. The group is full.") exit() # O'yinni boshlashdan oldin rele serveri bilan aloqa o'rnatish connect_server() def draw(): screen.clear() screen.draw.line((WIDTH/2, GAP_FROM_SCR), (WIDTH/2, HEIGHT - GAP_FROM_SCR), \ color='grey') if not score.is_game_over(): ball.draw() bar1.draw() bar2.draw() score.draw() if num_peers < MAX_PEERS: screen.draw.text('Waiting for a peer connection...', (WIDTH/6, HEIGHT/2), color='blue', fontsize=50) def handle_recv_messages(): # Barcha xabarlarni qabul qilish net.process_recv() # Muayyan xabarlarni ajratib ko'rsatish game_start = net.get_msg(peer_id, 'game_start') bar_pos = net.get_msg(peer_id, 'bar_pos', clear=False) ball_pos = net.get_msg("Player1", 'ball_pos', clear=False) who_win = net.get_msg("Player1", 'score') # o'yinni boshlash if game_start: score.reset() ball.reset() # to'p if ball_pos: ball.pos_update(ball_pos['center'], ball_pos['vel']) # reflektor if bar_pos: if is_host: bar2.pos_update(bar_pos) else: # Player2 bar1.pos_update(bar_pos) # hisob if who_win: score.add(who_win) def update(): global num_peers # tarmoqdagi qabul qilingan xabarlar qayta ishlanmoqda handle_recv_messages() # reflektor if keyboard.a or keyboard.up: my_bar.up() if keyboard.z or keyboard.down: my_bar.down() net.send_msg(peer_id, 'bar_pos', my_bar.center) for bar in bars: if is_host: bar.collide_ball() else: # Player2 bar.collide_ball(sound_only=True) # o'yin boshlanish shartlari if score.is_game_over(): # Har kim birinchi bo'lib o'yinni boshlashi mumkin if num_peers == MAX_PEERS and keyboard.space: score.reset() ball.reset() net.send_msg(peer_id, 'game_start', True) else: # to'p if is_host: ball.move() net.send_msg('Player2', 'ball_pos', {'center':ball.center, 'vel':(ball.vx, ball.vy)}) who_win = ball.collide_wall() if who_win: # hisob score.add(who_win) net.send_msg('Player2', 'score', who_win) ball.reset() else: # Player2 ball.move() ball.collide_wall(sound_only=True) # Aloqa qarama-qarshi tomon tomonidan uzildi num_peers = len(net.get_peers()) if num_peers < MAX_PEERS: if is_host: score.reinit() ball.reset() else: # Player2 print("The host is disconnected.") exit() # host tugashi bilan xona yopiladi # Xabar yuborish net.process_send() Ma’lumot uchun, endi bu o‘yinni faqat **localhost** ichida emas, balki haqiqiy masofadagi foydalanuvchi bilan o‘ynashni xohlaysiz. Bu holda rele serveri dasturini mahalliy tarmoq (LAN) ichida yoki butun dunyo bo‘ylab masofaviy foydalanuvchilar ulana oladigan [klaud (cloud)arrow-up-right](https://en.wikipedia.org/wiki/Cloud_computing) ga o‘rnatishga to‘g‘ri kelishi mumkin. Shuningdek, server dasturi o‘rnatiladigan operatsion tizim (OS: Operating System)ga qarab [xavfsizlik devori (firewall)arrow-up-right](https://en.wikipedia.org/wiki/Firewall_(computing)) sozlamalarini to‘g‘rilab, ishlayotgan rele serveri dasturiga silliq masofaviy ulanish bo‘lishi uchun tarmoq sozlamalarini ham moslashtirish kerak bo‘ladi. Buning batafsil tushuntirishi [kutubxonaning server sozlamalari qo‘llanmasiarrow-up-right](https://github.com/QuirkyCort/nethelper?tab=readme-ov-file#computer-within-lan) da keltirilgan. Agar yuqorida tilga olingan o‘rnatish va sozlashlar to‘liq bajarilib, rele serveri dasturi tarmoqda odatdagidek ishlayotgan bo‘lsa, endi o‘yin dasturimiz ushbu serverga ulanishi kerak. Buning uchun, avvalo [10.2-bo‘lim](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.2_server_connection) da aytilganidek, atigi bitta qatorni o‘zgartirish kifoya: rele serveri ishlayotgan kompyuterning internetdagi yagona IP manzilini **SERVER\_IP** qiymatiga o‘rnatish kerak. [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.4_dev_net_2#xulosa) Xulosa ------------------------------------------------------------------------------------------------------------ Shu tariqa siz ushbu kitobning butun sayohatini yakunladingiz. Avvalo, bu sayohatni yakunlaganingiz uchun chin dildan olqishlayman. Ushbu kitob [oldingi kitobarrow-up-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic) ga nisbatan ancha murakkabroq edi, ammo shunday biroz og‘riqli(?) jarayondan o‘tarkan, shubhasiz, avvalgidan ancha ko‘proq o‘sganingizga ishonaman. Yaxshiyamki, bu yo‘lda yolg‘iz emasligingizni unutmasangiz va siz bilan birga sayohat qiladigan kimdir borligini yodingizda tutsangiz — bundan kuch topasiz. Muallif kelgusidagi sayohatingizda ham sizga hamroh bo‘lib, doimiy ravishda qo‘llab-quvvatlab va yordam berib borishni va’da qiladi. Keyingi, yana bir kitobda siz bilan qayta uchrashishni intiqlik bilan kutaman. [Previous10.3 Tarmoqli o‘yinga aylantirish 1chevron-left](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.3_dev_net_1) [NextIlovachevron-right](https://roboticsware.gitbook.io/python-pygame_zero/appendix) Last updated 6 days ago --- # 5.4 Quvur(obyekt)ni ekranga chiqarish va harakatlantirish | Python-Pygame Zero Endi bizning o‘yin sahnamizda zarur bo‘lgan pipe (quvur) obyekt aktyorlarini (Actor) sahnaga chiqarish vaqti keldi. **Kodlashga kirishishdan oldin, avvalo bu obyektlar haqida o‘ylab ko‘raylik.** Haqiqiy kod yozishni boshlashdan oldin qanday kodlash haqida oldindan fikr yuritish va umumiy qolipni shakllantirish — har doim avval bajarilishi kerak bo‘lgan ishdir. Avvalo bizga 2 ta quvur obyekti kerak bo‘ladi. Chunki ekranning yuqori qismiga osilgan quvur ham, pastki qismiga ulangan quvur ham zarur bo‘ladi, va bu ikki quvur orasida muayyan masofadagi bo‘shliq bo‘lishi kerak — bu o‘yinning asosiy maqsadi Flappy Bird quvurga tegmasdan shu bo‘shliqdan o‘tib ketishi kerakligidir. Oxirgi navbatda quvur obyektlarining harakati (animatsiyasi) haqida o‘ylaylik. Ular ekranning o‘ng chetidan paydo bo‘lib, chap tomonga qarab harakatlanib, ekranning chap chetigacha yetib borib, undan chiqib ketganidan so‘ng, yana dastlabki kabi o‘ng tomondan qayta paydo bo‘lishi kerak bo‘ladi. Faqat bu vaqtda o‘yin qiziqarli bo‘lishi uchun quvur har safar bir xil joyda paydo bo‘lmasligi kerak — balki har safar paydo bo‘lishida tasodifiy (random) joylashuv o‘zgarishi bo‘lishi zarur bo‘ladi. Aynan mana shu bizning quvur obyektimizga qo‘yiladigan talabdir. Keling, buni kodda qanday ifodalash mumkinligini ko'rib chiqaylik Copy TITLE = 'Flappy Bird' WIDTH = 400 HEIGHT = 708 GRAVITY = 0.3 drop_speed = 0 # Actor obyektlari flappy_bird = Actor('bird1', (75, 350)) top_pipe = Actor('top', (350,0)) bottom_pipe = Actor('bottom', (350, 500)) def draw(): screen.blit('background', (0, 0)) flappy_bird.draw() top_pipe.draw() bottom_pipe.draw() def update(): global drop_speed drop_speed += GRAVITY flappy_bird.y += drop_speed def on_mouse_down(): global drop_speed drop_speed = -6.5 🔢 10~11-qatorlarda _ekranning yuqori qismidagi quvur va pastki qismidagi quvurni alohida Actor obyektlari sifatida yaratib, ularni mos ravishda_ _**top\_pipe**_ _va_ _**bottom\_pipe**_ _nomli o‘zgaruvchilarga saqladik (boshqacha aytganda, ushbu o‘zgaruvchilarga yaratilgan obyektlarga murojaat qilish mumkin bo‘lgan referensiya nuqtasi biriktirildi)._ Avvalgi boblarda qilganimiz kabi obyektlarni yaratdik va draw callback funksiyasi ichida ularni ekranga chizdik — bu kodlar allaqachon tanish bo‘lgani uchun tushunishda qiyinchilik bo‘lmaydi. Kodni ishga tushirganimizda esa bitta muammo paydo bo‘ladi: yuqori va pastki quvurlar bir-biriga yopishib chizilgan holatda ko‘rinadi. Biroq, bizning o‘yin sahnamizdagi quvur aktyorlariga (Actor) qo‘yilgan talab — ular orasida Flappy Bird o‘ta oladigan darajada ma’lum bir masofa bo‘lishidir. Endi aynan shu bo‘shliqni yaratadigan qismni kodlaylik. Copy TITLE = 'Flappy Bird' WIDTH = 400 HEIGHT = 708 GRAVITY = 0.3 drop_speed = 0 GAP = 140 # Actor obyektlari flappy_bird = Actor('bird1', (75, 350)) top_pipe = Actor('top', (350,0)) bottom_pipe = Actor('bottom', (350, top_pipe.height + GAP)) def draw(): screen.blit('background', (0, 0)) flappy_bird.draw() top_pipe.draw() bottom_pipe.draw() def update(): global drop_speed drop_speed += GRAVITY flappy_bird.y += drop_speed def on_mouse_down(): global drop_speed drop_speed = -6.5 🔢 Mavjud koddagi o‘zgarishlar ikki joyda amalga oshirildi. Avvalo, 7-qatorda ikkita quvur orasida bo‘lishi kerak bo‘lgan bo‘shliqning o‘lchamini ifodalash uchun **GAP** degan nom berildi (avvalgi bobda aytib o‘tilganidek, bu ataylab katta harflar bilan yozilgan nomdir — bu qat’iy, o‘zgarmas qiymatni bildiradi) va bu bo‘shliqning o‘lchami 140 piksel deb belgilandi. Ikkinchi o‘zgarish esa 12-qatorida amalga oshirildi: pastki quvur joylashuvi yuqori quvur balandligidan GAP qiymaticha pastga surilib belgilandi (ya’ni, mavjud joylashuvdan GAP qiymaticha pastga siljitildi). Bu yerda **top\_pipe.height** degan qiymat intuitiv tarzda nima ekanligini anglash mumkin, ya’ni _yuqoridagi quvur obyektiga tegishli rasm balandligi. Bu qiymat — kutubxona tomonidan barcha Actor obyektlarga standart tarzda taqdim etilgan joylashuv ma’lumotlarini bildiruvchi xususiyatdir. Keyingi bobda bu haqda batafsil ma’lumot beriladi._ ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FzyHYrXYxazOhyQ7G2HvR%252Fimage.png%3Falt%3Dmedia%26token%3D9247883e-b81b-4d8b-93bd-083f9b58d343&width=768&dpr=3&quality=100&sign=22f30904&sv=2) Quvurlar orasidagi bo‘shliq ta’minlangani sababli, endi keyingi talab — ya’ni quvurlarning Flappy Bird joylashgan tomonga harakatlanishi(animatsiya)ni amalga oshirish kerak. Bu esa [5.2-bo‘lim](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.2_flying) da o‘rgangan flappy birdni animatsiya qilish usulidan unchalik farq qilmaydi, shuning uchun kodni tushunishda qiyinchilik bo‘lmaydi. Copy TITLE = 'Flappy Bird' WIDTH = 400 HEIGHT = 708 GRAVITY = 0.3 drop_speed = 0 GAP = 140 PIPE_SPEED = -3 # Actor obyektlari flappy_bird = Actor('bird1', (75, 350)) top_pipe = Actor('top', (350,0)) bottom_pipe = Actor('bottom', (350, top_pipe.height + GAP)) def draw(): screen.blit('background', (0, 0)) flappy_bird.draw() top_pipe.draw() bottom_pipe.draw() def update(): global drop_speed drop_speed += GRAVITY flappy_bird.y += drop_speed top_pipe.x += PIPE_SPEED bottom_pipe.x += PIPE_SPEED def on_mouse_down(): global drop_speed drop_speed = -6.5 🔢 8-raqamli qatorda quvur harakatlanish tezligi o‘zgarmaydigan qiymat bo‘lib, kodni o‘qishni osonlashtirish va keyinchalik talablar o‘zgarganda tez chora ko‘rish uchun raqamli qiymat o‘rniga almashtirish funksiyasi ([Macroarrow-up-right](https://en.wikipedia.org/wiki/Macro_(computer_science)) deb ataladi) ma‘nosida butunlay katta harfli o‘zgaruvchi nomi qo‘llanildi va quvurlar ekranda chap tomonga harakatlanishi kerakligi sababli o‘zgaruvchi qiymati manfiy bo‘ldi. Quvur animatsiyasini yaratish uchun, bir soniyada 60 marta chaqiriladigan (60 FPS (Frames Per Second) deyiladi) update funksiyasi ichida quvurlarning x-koordinata qiymatlari doimiy o‘zgarib boradi. Keling, ushbu kodni ishga tushirib ko‘raylik. Kutilgandek yaxshi ishlaydi. Biroq, bir kamchilik shundaki, chap ekran chekkasigacha yetib borgan quvurlar qayta paydo bo‘lmaydi. Agar biz Entry da shunday turdagi o‘yinlar yasagan bo‘lsak, bunday holatlarga qanday yechim topish kerakligi bo‘yicha bunday algoritm bizga tanish. Ha, _quvur ekranning chap tomonidan chiqib ketishi bilan bir vaqtda uni ekranning ko‘rinmaydigan o‘ng chekkasidagi qismiga zudlik bilan ko‘chirish kerak bo‘ladi. Shu tarzda quvurlar cheksiz aylana (rotation) strukturasi tashkil qiladi._ Buni kod orqali ifoda qilib ko‘raylik. Copy TITLE = 'Flappy Bird' WIDTH = 400 HEIGHT = 708 GRAVITY = 0.3 drop_speed = 0 GAP = 140 PIPE_SPEED = -3 # Actor obyektlari flappy_bird = Actor('bird1', (75, 350)) top_pipe = Actor('top', (350,0)) bottom_pipe = Actor('bottom', (350, top_pipe.height + GAP)) def draw(): screen.blit('background', (0, 0)) flappy_bird.draw() top_pipe.draw() bottom_pipe.draw() def update(): global drop_speed drop_speed += GRAVITY flappy_bird.y += drop_speed top_pipe.x += PIPE_SPEED bottom_pipe.x += PIPE_SPEED if top_pipe.right < 0 or bottom_pipe.right < 0: #cheksiz quvurlar sikli top_pipe.x = WIDTH bottom_pipe.x = WIDTH def on_mouse_down(): global drop_speed drop_speed = -6.5 🔢 Algoritm kutilganidek, 28-qatorda shart operatori (if) orqali nihoyat paydo bo‘lib, har safar quvurning harakat animatsiyasi bajarilganida uning joriy joylashuvini tekshirish zarur bo‘ladi. Yuqoridagi yoki pastki quvurlardan birining (**shu maqsadda solishtirish shartida** _**or**_ **operatori ishlatilganiga e’tibor bering!**) hozirgi joylashuvi ekranning chap tomonidan chiqib ketgan holat (ya’ni, quvurning right qiymati 0 dan kichik bo‘lib qolgan holat) bo‘lsa, demak quvurlarni darhol boshqa joyga — ekranning o‘ng chetiga (bunda x qiymatiga WIDTH qiymati beriladi) ko‘chirishimiz kifoya. Endi qolgan yagona talab — o‘yinning qiziqarli bo‘lishi uchun quvurlar qayta paydo bo‘lganda har safar bir xil joyda emas, balki har doim tasodifiy (random) joylashuv o‘zgarishi bilan chiqishi zarur bo‘ladi. Bu qismdagi kodlashni hozircha keyinroq [qo‘shimcha funksiyani amalga oshirish jarayoni](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.7_pipe_random) ga qoldiraman. Chunki ushbu kitob “yengil darajadagi” versiya bo‘lib, dastlab o‘rganish jarayonida imkon qadar murakkablikni kamaytirishga e’tibor qaratish muhim hisoblanadi. [Previous5.3 Flappy Bird(obyekt)ning ekrandagi tabiiy harakatini yaratishchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.3_flying_gravity) [Next5.5 Flappy Bird va quvurlar o‘rtasida to‘qnashuvni amalga oshirishchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.5_collision) Last updated 7 days ago --- # Entry-Python darsturlash asoslari | Entry-Python Ushbu kitob, Entry blokli kodlashni to'liq o'rganib olib keyin Python matnli kodlashga o‘tishni istaydigan o‘quvchilar va ularga bunda yordam berishni maqsad qilgan o'qituvchilar uchun yozilgan. Entry-Python o‘quvchilarga blokli kodlashdan amaliy matnli kodlashga qiyinchiliksiz o‘tishda yordam beradigan ko'prik bo'lib xizmat qiladi. #### [hashtag](https://roboticsware.gitbook.io/entry-python#ozgarishlar-tarixi) O‘zgarishlar tarixi: Versiya Sana Tavsif v1 2023/11/06 Birinchi versiya chiqishi v1.1 2024/02/25 Funksiya qismida bazi o‘zgarishlar v1.2 2024/7/8 Ketma-ket/parallel bajarishda ba'zi o‘zgarishlar **Muallif: JJ (**[comseong@envelope](mailto:comseong@gmail.com) [mail.comenvelope](mailto:comseong@gmail.com) **)** **O**‘**zbek tiliga tarjima: Komron (**[knmv2311@gmail.comenvelope](mailto:knmv2311@gmail.com) **)** **Malumot materiallari:** [**Entry Python kitobning 1-versiyasi**arrow-up-right](https://t.me/entry_uz/1154) **Mualliflik huquqi:** [**https://creativecommons.org/licenses/by-nc-sa/4.0/**arrow-up-right](https://creativecommons.org/licenses/by-nc-sa/4.0/) ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252Fj9wU6JE0ltUJDvgZdXTz%252Fimage.png%3Falt%3Dmedia%26token%3D9c6ab731-f863-4318-923b-1bb71c021745&width=768&dpr=3&quality=100&sign=b49a080e&sv=2) [Next1\. Entry vs Entry-Pythonchevron-right](https://roboticsware.gitbook.io/entry-python/entry-python_ozi_nima) Last updated 10 months ago --- # 6.2 Aktyorlarning harakatlarini amalga oshirish | Python-Pygame Zero Ushbu bo‘limda biz sahnamizdagi har bir aktyorni harakatlantirib ko‘ramiz. Eng avvalo, ushbu o‘yinda yagona foydalanuvchi tomonidan boshqarilishi mumkin bo‘lgan aks ettiruvchi plastinani(keyinchalik **reflektor**) ekran pastki qismida, ekranning chegarasidan chiqib ketmaydigan tarzda, faqat chap va o‘ng yo‘nalishda harakatlantirishimiz uchun kod yozamiz. Copy TITLE = 'Breakout' WIDTH = 800 HEIGHT = 600 GAP_FROM_SCREEN = 50 ball = Actor('ball', (WIDTH / 2, HEIGHT / 2)) bar = Actor('bar', (WIDTH / 2, HEIGHT - GAP_FROM_SCREEN)) # 4-qator*8-ustundan iborat bloklar to'plamini yaratish blocks = [] for block_row in range(4): for block_col in range(8): block = Actor( 'block', (block_col * 100, block_row * 32 + GAP_FROM_SCREEN), anchor=('left', 'top') ) blocks.append(block) def draw(): screen.blit('space', (0, 0)) ball.draw() bar.draw() for block in blocks: block.draw() def update(): # ekran ichida reflektorning harakatini cheklash if bar.left < 0: bar.left = 0 if bar.right > WIDTH: bar.right = WIDTH def on_mouse_move(pos): x, y = pos bar.centerx = x 🔢 34~36-qatorlarda sichqoncha harakatlanish hodisasi yuz berganida har safar chaqiriladigan **on\_mouse\_move** nomli kolbek(callback) funksiyasidan foydalanamiz. Ushbu funksiyaning to‘liq ishlatilish usuli haqida [Pygame Zero kutubxonasi hujjatlariarrow-up-right](https://pygame-zero.readthedocs.io/en/stable/hooks.html#on_mouse_down) da tanishib chiqish mumkin. Oddiy qilib aytganda, _**on\_mouse\_move**_ _funksiyasining birinchi argumenti bo‘lgan_ _**pos**_ _— bu harakatlanayotgan sichqoncha kursorining joriy koordinatalari(x, y koordinatalari qiymati)ni saqlab turuvchi qiymatdir._ 35-qatorida pos ichidagi bu ikkita qiymat (_x, y koordinatalari qiymati_) alohida x va y o‘zgaruvchilarga ajratiladi, shundan so‘ng biz bu x koordinatasini **bar.centerx** qiymati (bar obyektining markaziy x koordinatasi) bilan birlashtiramiz va natijada sichqonchani harakatlantirganimizda bar obyekti ham uni kuzatib harakatlanadi. Keyinchalik harakatlanayotgan **bar** obyekti o‘yin ekranidan tashqariga chiqib ketmasligi uchun **update** callback funksiyasida 29~32-qatorlardagi shartlar qo‘yiladi: agar u ekran chap chegarasidan chiqib ketgan (bar.left < 0 bo‘lgan) holda manfiy qiymatga ketmasligi uchun eng kichik qiymat bo‘lgan 0 da saqlab qolamiz, va xuddi shuningdek, agar u o‘ng chegaradan chiqib ketsa (bar.right > WIDTH bo‘lsa) bar.right qiymatini maksimal ruxsat etilgan WIDTH qiymatida saqlab qolamiz. Shunday qilib, harakatning maksimal chegarasini belgilash mumkin bo‘ladi. Copy TITLE = 'Breakout' WIDTH = 800 HEIGHT = 600 GAP_FROM_SCREEN = 50 ball = Actor('ball', (WIDTH / 2, HEIGHT / 2)) bar = Actor('bar', (WIDTH / 2, HEIGHT - GAP_FROM_SCREEN)) # 4-qator*8-ustundan iborat bloklar to'plamini yaratish blocks = [] for block_row in range(4): for block_col in range(8): block = Actor( 'block', (block_col * 100, block_row * 32 + GAP_FROM_SCREEN), anchor=('left', 'top') ) blocks.append(block) # to'pning boshlang'ich (yo'nalish) tezligi vx = 5 vy = -5 def draw(): screen.blit('space', (0, 0)) ball.draw() bar.draw() for block in blocks: block.draw() def update(): global vx, vy # ekran ichida reflektorning harakatini cheklash if bar.left < 0: bar.left = 0 if bar.right > WIDTH: bar.right = WIDTH # to'pni x va y yo'nalishlarida vx va vy masofaga mos ravishda harakatlantirish ball.move_ip(vx, vy) def on_mouse_move(pos): x, y = pos bar.centerx = x 🔢 Endi ikkinchi navbatda, to‘pni harakatga keltirish uchun qo‘shilgan kodlarni ko‘rib chiqamiz. _To‘pni harakatlantirish uchun, avvalo Pygame koordinata tizimida qaysi_ _**yo‘nalishda(direction)**_ _va qancha_ _**tezlikda(speed)**_ _harakatlanishini belgilash kerak bo‘ladi. Ushbu ikki parametr — tezlik va yo‘nalish — birlashib fizikada_ _**"vektor tezlik"(velocity)**_ _deb ataladigan kattalikni hosil qiladi._ Hozir fizika darsi emas, shuning uchun buni aniqroq tushunish uchun istasangiz [Wikipediaarrow-up-right](https://en.wikipedia.org/wiki/Velocity) kabi manbalardan qidiring ^^; Ammo buni murakkab deb o‘ylash shart emas — oddiy qilib aytganda, Pygame koordinata tizimiga ko‘ra, x o‘qi bo‘yicha chapga (manfiy yo‘nalish) yoki o‘ngga (musbat yo‘nalish) bir marta harakatlanganda qanchaga siljiydi, y o‘qi bo‘yicha yuqoriga (manfiy) yoki pastga (musbat) harakatlanganda esa qanchaga siljiydi — shularni ifodalaydi. Har ikkala o‘q bo‘yicha boshlang‘ich tezlik qiymatlari bo‘lishi kerak bo‘lganligi uchun bu qiymatlar 21~22-qatorlarda global o‘zgaruvchi sifatida kodlangan. **Global o‘zgaruvchi sifatida ishlatilganining sababi — bu qiymatlar bir nechta funksiyalarda ishlatilishi yoki funksiyalar ichida o‘zgarishi mumkin va bu o‘zgargan qiymat keyingi safar funksiyaga kirganda ham saqlanishi kerak bo‘ladi.** Bu holatda, aynan shunday qiymatni saqlab qolish maqsadida global o‘zgaruvchi sifatida yozilgan. Va, bu kodni **update** funksiyasi ichida qo‘llab, soniyasiga 60 marta chaqiriladigan (5.2-bobda allaqachon aytilgan) update funksiyasi har chaqirilganda obyekti doimiy harakatda bo‘lishi uchun, 41-qatorida **ball** obyektining [**move\_ip funksiyasidan(metodidan)**arrow-up-right](https://www.pygame.org/docs/ref/rect.html#pygame.Rect.move_ip) foydalanildi. Ushbu funksiyaga biz belgilagan ikki o‘q bo‘yicha boshlang‘ich tezlik qiymatlari uzatiladi, shunda har chaqirilganda obyekt hozirgi joylashuvidan shu tezlik bo‘yicha keyingi pozitsiyaga siljiydi. _Agar_ _**move\_ip**_ _funksiyasidan foydalanishni istamasangiz, uning o‘rniga quyidagicha kod yozish ham xuddi shunday natija beradi va aslida bu_ _**ball**_ _obyektining x va y koordinatalarini vx, vy tezlik o‘zgarishlari miqdorida har safar oshirib borish degan ma’noni anglatadi._ Copy ball.x += vx ball.y += vy Oxirgi bo‘limda biz juda ko‘p narsalarni o‘rgandik, shuning uchun siz yodda saqlashingiz kerak bo‘lgan ma’lumotlar ko‘pligi sababli biroz charchagan(?) bo‘lishingiz mumkin, shu sababli bu bo‘limni shu yerda yakunlayman. Keyingi bo‘limda esa to‘plarni aks ettirish va bloklarni yo‘q qilishga oid yanada qiziqarli algoritmlarni o‘rganamiz. [Previous6.1 O‘yin sahnasiga fon va aktyorlarni qo'shishchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.1_bg_actors) [Next6.3 To‘pni aks ettirish va bloklarni sindirishni amalga oshirishchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.3_reflection_breakout) Last updated 7 days ago --- # 8.5 Obyektga yo‘naltirilgan dasturlash 1 | Python-Pygame Zero Pong o‘yinining obyektga yo‘naltirilgan versiyasini yaratish deganda, tuzilish jihatdan qanday ko‘rinishga ega bo‘lishi kerak? Pygame Zero kutubxonasidan baza sifatida foydalanayotganimiz sababli, majburiy callback funksiyalar (draw, update va hokazo) orqali ishlaydigan [o‘yin sikli tuzilmasi](https://roboticsware.gitbook.io/python-pygame_zero/game_loop) o‘zgarishsiz saqlanishi shartligini oldindan qabul qilamiz. Biroq, avvalgi protseduraga yo‘naltirilgan versiyada mavjud bo‘lgan global funksiyalar asosidagi protseduraviy kodlar endi obyekt ko‘rinishiga o‘tkazilib, faqat obyektlararo hamkorlik orqali o‘yin to‘liq ishlashi asosiy maqsad bo‘ladi. Unda keling, Pong o‘yinida kerakli obyektlarni aniqlashdan boshlaymiz. O‘yin sahnasidagi ishtirokchilarni avvalgi protseduraviy usulda ishlatilgan **Rect** asosidagi obyektlarga qarab aniqlash oson — “reflektor 1”, “reflektor 2”, “to‘p”, “hisob” — shularning 4 tasi yetarli bo‘ladi. Aslida, obyektga yo‘naltirilgan paradigma bo‘yicha qilinayotgan birinchi o‘yin sifatida ortiqcha murakkab o‘yinni misol qilib olish shart emas, shu darajadagi oddiylikdan boshlash eng maqbul variantdir. Unda avvalo reflektorlarning vazifasini o‘ylab ko‘raylik. Har ikkala reflektorning maqsadi yuqoriga va pastga harakatlanib, to‘pni tushirib yubormasdan uni qaytarib yuborishdir. Ikkalasi ham bir xil maqsad va bir xil cheklovlarga ega. Faqat farqi shundaki, har bir reflektorni boshqarish uchun ishlatiladigan klaviatura tugmalari boshqacha. Ha, aynan shu nuqtada obyektga yo‘naltirilgan dasturlashning kodni qayta ishlatish afzalligi namoyon bo‘ladi. Bitta **Bar** obyektini klass ko‘rinishida aniqlab, shu **Bar** klassidan ikkita obyekt (reflektor 1 va reflektor 2) yaratib ishlatish kifoya. O‘yin ilk marta boshlanganda ekranda paydo bo‘ladigan obyektlar qaysilar? Yuqorida tilga olingan 4 ta obyektlarning(“reflektor 1”, “reflektor 2”, “to‘p”, “hisob”) barchasi bo‘ladi. Unda bu obyektlarni kim yaratadi? Entry blokli kodlashda buni Entry (tizimi) ichki jarayonda avtomatik bajarib bergan bo‘lsa, endi buni ham biz bevosita kod orqali yozishimiz kerak bo‘ladi. Obyektlar ekranda chizilishi uchun **draw** callback funksiyasi ichida har bir obyektning **draw** metodini chaqirish zarur bo‘ladi, bu esa **draw** callback funksiyasidan oldin obyektlar kamida yaratilgan bo‘lishi shart ekanligini anglatadi. Shunday ekan, hozir aytib o‘tilganlarni asosiy kodini yozib ko‘ramiz. Biroq, dastlab kod juda murakkab ko‘rinib tushunishni qiyinlashtirmasligi uchun hozircha obyektlarning ta’rifini kiritmasdan (ular mavjud deb faraz qilgan holda) faqat ularni ishlatish qismiga e’tibor qaratamiz. pong\_oop.py Copy import random import math from pong_actors import Score, Ball, Bar # o'yin oynasi TITLE = 'pong' WIDTH = 800 HEIGHT = 600 # qaytargich BAR_H = 100 BAR_W = 15 GAP_FROM_SCR = 20 # to'p BALL_RADIUS = 10 VELOCITY = 3 SPEED_UP = 1.05 # hisob FINAL_SCORE = 11 # qahramon obyektlarini yaratish score = Score(FINAL_SCORE) ball = Ball((WIDTH/2, HEIGHT/2), VELOCITY, score) bar1 = Bar(GAP_FROM_SCR, HEIGHT/2 - BAR_H/2, ball) bar2 = Bar(WIDTH - BAR_W - GAP_FROM_SCR, HEIGHT/2 - BAR_H/2, ball) bars = [bar1, bar2] def draw(): screen.clear() screen.draw.line((WIDTH/2, GAP_FROM_SCR), (WIDTH/2, HEIGHT - GAP_FROM_SCR), \ color='grey') # o'rta chiziq if not score.is_game_over(): ball.draw() bar1.draw() bar2.draw() score.draw() def update(): # qaytargich if keyboard.a: bar1.up() if keyboard.z: bar1.down() if keyboard.up: bar2.up() if keyboard.down: bar2.down() for bar in bars: bar.collide_ball() # o'yin boshlanish shartlari if score.is_game_over(): if keyboard.space: score.reset() ball.reset() else: # to'p ball.move() ball.collide_wall() 🔢 25~28-qatorlargacha hisob, to‘p va 2 ta reflektor yaratilmoqda. Avvalgi protseduraviy versiyada sahna aktyorlarini yaratishda **Rect** obyektidan foydalangan edik, endi esa biz bevosita yaratgan foydalanuvchi obyektlari bo‘lgan Score, Ball, Bar klasslaridan foydalanib yaratmoqdamiz. Odatda, **bitta fayl ichida juda ko‘p kod yozish tavsiya etilmaydi; mazmunan ma’noli bo‘laklarga ajratib bir nechta faylga bo‘lib, modullashtirish(modulization) yirik loyihalarni boshqarishda samaralidir.** Shu bois, _foydalanuvchi obyektlarini ta’riflovchi klass e’lonlarini quyidagi kabi, misol uchun,_ _**pong\_actors.py**_ _fayliga alohida ajratib, uni_ _**pong\_oop.py**_ _ichida import qilib ishlatish ma’qul. Biroq, hozirgi darajangizda bir nechta fayl o‘rtasida kodni ko‘rib chiqish va nosozliklarni tuzatish(debugging) qiyin bo‘lishi mumkin, shuning uchun obyektga yo‘naltirilgan dasturlashni o‘rganishga eng ko‘p e’tibor qaratish maqsadida barcha kodni bitta fayl(pong\_oop.py) ichida jamlab yozamiz._ pong\_actors.py Copy class Score(): def __init__(): pass def _gameover_draw(): pass def is_game_over(): pass def reset(): pass def draw(): pass class Ball(Rect): def __init__(): super().__init__() pass def collide_wall(): pass def reset(): pass def draw(): pass class Bar(Rect): def __init__(): super().__init__() pass def up(): pass def down(): pass def collide_ball(): pass 🔢 Tushunishni osonlashtirish uchun, batafsil amalga oshirilmagan, faqat aniqlangan obyektlarning eng oddiy skeletidan boshlagan ma’qul. Avvalo, hisob(Score) obyektini olaylik. Bu obyekt ekranda har bir o‘yinchining joriy hisobini va g‘alaba–mag‘lubiyat UI ni ko‘rsatish uchun mo‘ljallangan bo‘lib, to‘p yoki reflektor kabi doimiy harakatga ega bo‘lishi shart emas, balki qat’iy joylashuvga ega. Shu sababli u Rect nomli ota obyektni meros olmaydi. Shunday bo‘lgani uchun, meros olingan obyektlarda doimo chaqirilishi kerak bo‘lgan **super().\_\_init()\_\_** ota obyektni ishga tayyorlovchi boshlang‘ich funksiyani ham chaqirmaydi. Yaratilishida parametr sifatida qabul qilinadigan yagona qiymat yakuniy g‘olib va mag‘lubni aniqlash uchun kerak bo‘ladigan **final\_score** qiymati. Pastdagi koddagi 6-qatorga qarasak, bu qiymat obyekt ichidagi xususiyat (a’zo o‘zgaruvchi deb ataladi) bo‘lgan self.**\_final\_score** ga qaytadan tayinlanadi. Ushbu a’zo o‘zgaruvchi nomi oldidagi \_ (pastki chiziq yoki underscore) belgisi avvalgi bo‘limda tushuntirilganidek, obyekt ichida faqat ichki foydalanish uchun qo‘yilgan. Obyektga yo‘naltirilgan dasturlash paradigmasida buni **yopiq(private) a’zo o‘zgaruvchi** deb atashadi. [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/pong/8.5_oop_dev1#yopiq-private-metod-yoki-ozgaruvchi-nima) Yopiq(private) metod yoki o**‘**zgaruvchi nima? ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- circle-info Obyektlar o‘rtasidagi o‘zaro ta’sir uchun tashqariga ochiq bo‘lgan a’zo o‘zgaruvchilar va funksiyalardan farqli ravishda, **faqat obyekt ichida foydalanish uchun mo‘ljallangan** a’zo o‘zgaruvchilar va a’zo funksiyalar shu tarzda ataladi. _**Ma’lumot uchun, obyekt klassini ta’riflash jarayonida, quyidagi 2~4-qatorlardagi kabi obyekt nomining ostida uning maqsadi va foydalanish usuli haqida qisqacha izoh(kommentariya) yozib qo‘yish Python dasturlashda odat sifatida uchraydigan holat bo‘lishi bilan birga, kodning o‘qilish darajasini oshiradigan yaxshi odat ham bo‘lishi mumkin.**_ Copy class Score(): ''' Ekranda hisob va g'alaba/mag'lubiyat UI ni ifodalash ''' def __init__(self, final_score): self._final_score = final_score self._b1_score = -1 self._b2_score = -1 Keyin, yakuniy g‘alaba–mag‘lubiyat UI ni chizuvchi **\_gameover\_draw** a’zo funksiyasi qo‘shildi. _A’zo funksiya nomidagi \_ (pastki chiziq) belgisi yuqorida aytilgan maqsaddan farq qilmasligini taxmin qilish mumkin va kutilgandek, bu funksiya obyekt tashqarisidan chaqirib bo‘lmaydi, faqat ichki foydalanish uchun mo‘ljallanganini bildirishga oid odatiy kodlash kelishuvidir._ Obyektga yo‘naltirilgan dasturlash paradigmasida bu, yuqorida tilga olinganidek, **yopiq(private) a’zo funksiya** deb ataladi. Bundan tashqari, joriy vaqtda yakuniy o‘yin g‘olibini aniqlash uchun **is\_game\_over** a’zo funksiyasi, yakuniy natijaga yetib kelishdan avval har bir o‘yinda g‘olib bo‘lgan tomonga ball qo‘shuvchi **add** a’zo funksiyasi va o‘yinni butunlay qayta boshlash uchun hisobni nolga sozlovchi **reset** funksiyasi qo‘shilgan. Va nihoyat, **draw** a’zo funksiyasining vazifasi, yuqorida aytilganidek, amalda ekranga hisob UI ni chizishdir. Copy class Score(): ''' Ekranda hisob va g'alaba/mag'lubiyat UI ni ifodalash ''' def __init__(self, final_score): self._final_score = final_score self._b1_score = -1 self._b2_score = -1 def _gameover_draw(self): if self._b1_score == self._final_score: winner = 'Player1' elif self._b2_score == self._final_score: winner = 'Player2' if winner: screen.draw.text(winner + ' Win!!', (WIDTH/3, HEIGHT/2 - 50), color='blue', fontsize=70) screen.draw.text('Press Space to play again', (WIDTH/4, HEIGHT/2 + 50), color='skyblue', fontsize=50) def is_game_over(self): if (self._b1_score == self._final_score or self._b2_score == self._final_score) \ or (self._b1_score == -1 and self._b2_score == -1): return True else: return False def add(self, who): if who == 'b1': self._b1_score += 1 elif who == 'b2': self._b2_score += 1 def reset(self): self._b1_score = 0 self._b2_score = 0 def draw(self): screen.draw.text(str(self._b1_score), (WIDTH/4, GAP_FROM_SCR), color='yellow', fontsize=60) screen.draw.text(str(self._b2_score), ((WIDTH/4)*3, GAP_FROM_SCR), color='yellow', fontsize=60) if self.is_game_over(): self._gameover_draw() Bitta bo‘lim ichida haddan tashqari ko‘p ma’lumot berilib, mazmunni tushunishda qiyinchilik tug‘ilmasligi uchun, qolgan ikki obyekt haqidagi tushuntirishni keyingi bo‘limda davom ettiraman. [Previous8.4 Obyektga Yo‘naltirilgan Dasturlash nazariyasi (foydalanuvchi aniqlagan obyekt yaratish, meros)chevron-left](https://roboticsware.gitbook.io/python-pygame_zero/pong/oop_inheritance) [Next8.6 Obyektga yo‘naltirilgan dasturlash 2chevron-right](https://roboticsware.gitbook.io/python-pygame_zero/pong/8.6_oop_dev2) Last updated 6 days ago --- # 9.1 Protseduraviy dasturlash 1 | Python-Pygame Zero Quyidagi ekranda biz yaratadigan o‘yinning yakuniy natijasini avval ko‘rib olsak, kodni tushunish ancha osonlashadi. Biroq, ushbu bobning boshida aytilganidek, murakkablikni nazorat qilish uchun original o‘yinning barcha funksiyalarini to‘liq amalga oshirmaymiz. Uning o‘rniga bu o‘yinni ikki xil dasturlash paradigmasida ([protseduraga yo‘naltirilganarrow-up-right](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/procedural) va [obyektga yo‘naltirilganarrow-up-right](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/oop) ) ikkita versiyada yaratamiz. Avvalgi bobda aytib o‘tilganidek, yana bir bor o‘z obyektlarimizni yaratish va ulardan foydalanishni o‘rganish orqali hozir keng tarqalgan obyektga yo‘naltirilgan dasturlashning, avvalgi protseduraga yo‘naltirilgan dasturlashdan qanchalik katta farqga ega ekanini yana bir bor aniq tushunish ushbu bo‘limning asosiy maqsadi bo‘ladi. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252F0LPKC6HPuyo14HPl1m6v%252Fimage.png%3Falt%3Dmedia%26token%3D4e623be1-b5e9-4091-88af-dd0b852b8a10&width=768&dpr=3&quality=100&sign=7490368e&sv=2) Biz 5~8-boblar davomida 4 ta o‘yin ishlab chiqishni(development) muvaffaqiyatli bajarganimiz bois, endi bizni tutorial bosqichidan o‘tgan deb aytish mumkin. Shuning uchun ushbu bobda ham ilgari tushuntirilgan asosiy mazmunni batafsil takrorlamasdan, bevosita asosiy kod qismiga oid tushuntirishlarga e’tibor qaratamiz. Eslatma sifatida, ushbu o‘yinni yaratishda kerak bo‘ladigan rasm, tovush va boshqa resurslarni [shu yerdanarrow-up-right](https://github.com/roboticsware/python-pygame_zero-samples/tree/main/breakout/images) yuklab olishingiz mumkin. O‘yinda ishlatiladigan rasm fayllari kodda ko‘rsatilgan nomlari bilan **images** papkasida, tovush effektlari esa **sounds** papkasida saqlangan deb hisoblab ishni boshlaymiz. Yoki, agar [maxsus Mu Editorarrow-up-right](https://github.com/roboticsware/mu/releases) dan foydalanayotgan bo‘lsangiz, Mu Editorning ishchi katalogi bo‘lgan (foydalanuvchi\_hisobi)\\mu\_code\\examples\\pygame\_zero ichidan ham nusxa olishingiz mumkin. Avvalo, dastlab protseduraga yo‘naltirilgan usulda dasturlashni boshlaymiz. **Battle City** o‘yini avval yaratgan bloklarni sindirish o‘yini va **TwinBee** o‘yinini birlashtirilganiga o‘xshaydi. Copy from pgzhelper import * import random WIDTH = 800 HEIGHT = 600 bullets = [] bullet_delay_cnt = 0 BULLET_DELAY = 50 enemy_bullets = [] explosions = [] winner = '' tank = Actor("tank_blue", (400, 575)) tank.angle = 90 ENEMY_MOVE_DELAY = 20 MAX_ENEMIES = 3 enemies = [] for i in range(MAX_ENEMIES): enemy = Actor("tank_red") enemy.angle = 270 enemy.x = (i + 1) * WIDTH / (MAX_ENEMIES + 1) enemy.y = 25 enemy.move_cnt = 0 enemies.append(enemy) # 50x50 devor maketini yarating walls = [] WALL_SIZE = 50 for x in range(int(WIDTH / WALL_SIZE)): for y in range(int(HEIGHT / WALL_SIZE - 2)): # yuqori/pastki qismini bo'sh qoldiring # tasodifiy devorsiz bo'sh joy yaratish if random.randint(0, 100) < 50: wall = Actor("wall", anchor=("left", "top")) wall.x = x * WALL_SIZE wall.y = y * WALL_SIZE + WALL_SIZE # yuqori qismini bo'shating walls.append(wall) def move_player(player): pass def fire_bullets(player, bullets): pass def collide_bullets(bullets): pass def draw(): screen.blit('grass', (0, 0)) tank.draw() for enemy in enemies: enemy.draw() for wall in walls: wall.draw() for bullet in bullets: bullet.draw() for bullet in enemy_bullets: bullet.draw() for explosion in explosions: explosion.draw() if winner: screen.draw.text(winner + " Win!", \ midbottom=(WIDTH / 2, HEIGHT / 2), fontsize=100) def update(): global bullet_delay_cnt, enemy_move_cnt # tank qahramoni if winner == '': move_player(tank) if bullet_delay_cnt == 0: # kechikish vaqti tugagach qayta o‘q otish mumkin if keyboard.space: sounds.sfx_exp_medium12.play() fire_bullets(tank, bullets) bullet_delay_cnt = BULLET_DELAY else: bullet_delay_cnt -= 1 collide_bullets(bullets) # dushman tanklari for enemy in enemies: choice = random.randint(0, 2) if enemy.move_cnt > 0: # tankni harakatlantirish enemy.move_cnt -= 1 move_player(enemy) elif choice == 0: # harakatni kechiktirish vaqtini boshlash enemy.move_cnt = ENEMY_MOVE_DELAY elif choice == 1: # tankni yo'nalishini o'zgartirish enemy.angle = random.randint(0, 3) * 90 else: # o'q otish fire_bullets(enemy, enemy_bullets) collide_bullets(enemy_bullets) 🔢 Yuqoridagi 37-qatorgacha bo‘lgan kod o‘yin sahnasidagi aktyor obyektlarini yaratadi. To‘siq devorlar to‘plami (walls), bosh qahramon tank (tank) va 3 ta dushman tankini (enemies) yaratadi. Devorlar to‘plamini yaratish qismi avvalgi bloklarni sindirish o‘yini(Breakout)dagi bloklar yaratish qismidan katta farq qilmaydi. Faqat devorlar to‘plamini yaratish algoritmi qisman boshqacha. Devorlar to‘plamining tuzilishini batafsil ko‘raylik. Har bir devor o‘lchami eni-bo‘yi 50 piksel (WALL\_SIZE) bo‘lgan kvadrat. Bu devorlardan 800×600 pikselli ekranga nechta sig‘ishini WIDTH / WALL\_SIZE va HEIGHT / WALL\_SIZE hisoblari orqali oson bilish mumkin. Qiziqarli narsa shundaki, nega bu hisob ifodalarini **int()** nomli ichki funksiyada qo‘lladik? Sababi, Pythonda bo‘lish amali natijani har doim haqiqiy (float) turida qaytaradi. Biz esa bu natijani keyin **range()** ichki funksiyasida ishlatamiz, bu funksiyaning argumenti esa har doim butun (integer) bo‘lishi kerak. _Xulosa qilib aytganda,_ _**int()**_ _funksiyasining maqsadi haqiqiy (float) qiymatni butun (integer) qiymatga aylantirishdir._ 32-qatorda butun vertikal ustundan 2 ni ayirib yuborishning sababini o‘yinning yakuniy natija ekranidan ham ko‘rish mumkin, maqsad ekranning hamma joyini devor bilan to‘ldirish emas, balki yuqori qatorni dushman tank(enemy) joylashishi uchun, pastki qatorni esa bizning tank(tank) joylashishi uchun bo‘sh qoldirishdir. Shuningdek, 34-qator, o‘yin devorlarni butunlay buzadigan blok sindirish o‘yini emas, balki raqib tankiga o‘q otib yo‘q qilish maqsadidagi o‘yin bo‘lgani sababli, ekranni to‘liq devor bilan to‘ldirmay, ba’zi joylarni tasodifiy (random) tarzda bo‘sh qoldirish uchun qo‘yilgan kod. 🔢 Hozircha protseduraga yo‘naltirilgan usulda dastur ishlab chiqishga qaror qilganimiz uchun, zarur funksiyalarni funksiyalashtirishga (functionalize) ehtiyoj borligini o‘rgandik. Bu o‘yinda ham funksiyalashtirishni bajaraylik. **Kod yozishda doim yodda tutish kerak bo‘lgan narsa o‘zimiz va boshqalar uchun o‘qilishi yaxshi bo‘lishi, hamda keyingi tahrirlarga tayyor turadigan texnik xizmat ko‘rsatish (maintenance) jihatini doim e’tiborga olishdir.** Aslida funksiyalar ham aynan shu sabab bilan sahnaga chiqqan, deyish mumkin. Funksiyaning bosh maqsadi kod takrorlanishini kamaytirish; avvalgi TwinBee o‘yinida afsuski umumiy funksionalni funksiya qilib jamlashga uncha mos joy bo‘lmagan edi, biroq bu safargi Battle City o‘yinida bu maqsadga mos 3 ta funksiya(**move\_player**, **fire\_bullets**, **collide\_bullets)**ni yaratish mumkin. Keyingi bo‘limdan yuqorida tilga olingan 3 ta funksiyaning amalga oshirilishini yozamiz, hozir esa bu funksiyalarni hisobga olmagan holda qolgan kodlarni ko‘rib chiqamiz. Shu paytgacha barcha jarayonlarni birga o‘rganib kelganingizdan kelib chiqib, ko‘p qismini avval o‘rgangan narsalarning biroz o‘zgargan shakli sifatida ko‘rib, xotirjam o‘rganishingiz mumkin, deb ishonaman. Biroz begona ko‘rinishi mumkin bo‘lgan joy bu **bullet\_delay\_cnt** va **enemy\_move\_cnt** degan ikkita o‘zgaruvchi bo‘lsa kerak. Bu o‘zgaruvchi qiymatlari yana **BULLET\_DELAY** va **ENEMY\_MOVE\_DELAY** deb nomlangan [makroarrow-up-right](https://en.wikipedia.org/wiki/Macro_(computer_science)) (Macro) qiymatlar bilan to‘ldiriladi (79 va 91-qatorlarda). O‘zgaruvchi nomlaridan yoki makro nomlaridan ham anglash mumkinki, bu kod bajarilishida ataylab kechiktirish(delay) maqsadida ishlatilgan. Nega kechikish kerak? Asosiy sabab, **TwinBee**da ham bo‘lgani kabi, _**update**_ **callback** funksiyasining chaqirilish tezligi(60FPS)dir. Shuning uchun **bullet\_delay\_cnt** ning maqsadi otilgan o‘qning juda tez va juda ko‘p uchib ketishini cheklash, **enemy\_move\_cnt** ning maqsadi esa dushman tanklari odam tomonidan emas, kompyuter tomonidan avtomatik boshqarilishi rejalangani bois ularning juda yuqori tezlikda harakatlanib ketmasligini ta’minlashdir. Xulosa qilib aytganda, otilgan o‘q tezligi bo‘lsin yoki tank harakati, o‘yin jarayoniga xalaqit bermaydigan darajada “o‘rtacha” bo‘lishi shart. Aks holda raqobat turidagi o‘yinlarda bir tomonning ustunligi haddan tashqari ko‘p bo‘ladi, o‘yin jarayoni yomonlashadi va qiziqarli bo‘lmay qolishi hammaga ayon. Nihoyat, kompyuter tomonidan boshqariladigan dushman tankining avtomatik harakatlanish g‘oyasi 3 xil harakat(harakatlanish, yo‘nalishni o‘zgartirish, o‘q otish)ni tasodifiylashtirish(random)ga asoslangan va bu yerda harakatlanish vaqtini ham tasodifiylashtirish orqali yanada o‘zgacha, oldindan taxmin qilib bo‘lmaydigan harakatlarni yuzaga keltirish maqsad qilingan. Endi esa keyingi bo‘limdan boshlab ushbu 3 ta foydalanuvchi funksiyaning amalga oshirilishini batafsil o‘rganamiz. [Previous9\. Battle city o‘yinini yaratishchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/battle_city) [Next9.2 Protseduraviy dasturlash 2chevron-right](https://roboticsware.gitbook.io/python-pygame_zero/battle_city/9.2_procedural_dev2) Last updated 6 days ago --- # "Pygame Zero" yordamida Python o'rganish | Pygame Zero boshlang'ich ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FL622o00JRIZxEKvxPq6e%252FBy%25207%2520Entry%2520examples%252C%2520Learn%2520Python_Cover%2520%281080%2520x%25201350px-A4%29.png%3Falt%3Dmedia%26token%3D6929948c-5d6a-42e5-8a40-364a2824ed44&width=768&dpr=3&quality=100&sign=4416d56a&sv=2) [NextKirishchevron-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kirish) Last updated 10 months ago --- # O'yinimizni EXE fayliga aylantirish | Python-Pygame Zero **Avvalo shuni ma'lum qilmoqchimanki, bu xususiyat umumiy rasmiy Mu editorida mavjud emas va faqat** [**muallif tomonidan ishlab chiqilayotgan Mu editorining maxsus versiyasi**arrow-up-right](https://github.com/roboticsware/mu/releases) **da mavjud.** Foydalanish usuli oddiy. Birinchidan, _agar siz yaratgan o'yin boshqalarga tarqatilishi uchun yetarli darajada to'liq deb hisoblasangiz, barcha manbalarni to'plash orqali o'yinni avtomatik ravishda bitta bajariladigan fayl (Windows platformasi uchun exe fayli) sifatida yaratish uchun editor o'ziga o'rnatilgan funksiyadan foydalanishingiz mumkin. Bu funksiya manba kodi fayllarni, qo'shimcha modullarni va o'yin dasturlash chiqarish uchun zarur bo'lgan resurslarni (rasmlar, ovozlar, fontlar va boshqalar) bitta faylga aylantiradi. Bu sizning o'yiningizni boshqalarga tarqatishni osonlashtiradi va o'yin foydalanuvchilari uchun bitta bajariladigan faylni ikki marta bosish orqali o'yindan zavq olishlari ham qulay._ Misol uchun, keling, [5-bob](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird) da birgalikda yaratgan "Flappy Bird" o'yinini qadoqlab ko'raylik. Birinchi, siz qadoqlamoqchi bo'lgan o'yin manba kodi faylining joylashuvini ko'rib chiqaik. Editorni o'rnatishda u Pygame Zero uchun editor o'zi tomonidan o'rnatilgan standart papka bo'lgan "akkauntingiz nomi/mu\_code" da joylashgan bo'lishi mumkin va albatta, siz uni bu holatda bo'lgani kabi qadoqlab ko'rishingiz mumkin. Biroq, **o'yin bilan bir-biriga bog'liq bo'lmagan fayllarni qadoqlashdan boshqa foyda yo'qligi sababli, bu faqat keraksiz hajmni oshiradi, iloji bo'lsa, faqat o'yin uchun zarur bo'lgan fayllar va resurslarni qadoqlash eng tejamkor usuli bo'ladi.** _Agar siz o'yinni yasashdan boshidanoq tegishli fayllarni alohida papkaga joylashtirgan bo'lsangiz va o'sha joyida dasturlashni boshlagan bo'lsangiz, uni oson qadoqlashga urinib ko'rishingiz mumkin, bo'lmasa, ularni hozir alohida tashkil qilishingiz mumkin._ Quyidagi misol faqat Flappy Bird o'yinida ishlatiladigan manba kodi fayllari va resurslarini alohida papkada tashkil qiladi. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252F55GMbZFDI4wAbfQpl0T0%252Fimage.png%3Falt%3Dmedia%26token%3D04218a97-e417-494c-81c5-db81b401c3d3&width=768&dpr=3&quality=100&sign=3e462bb6&sv=2) Papkalarni tartibga solishda yodda tutish kerak bo'lgan narsa shundaki, [5.1-bo'lim](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.1_background) da o'rganib olgandek resurslarni (rasmlar, fontlar, ovozli effektlari, fon musiqasi) o'z ichiga olgan pastki papkalar nomlari Pygame Zeroning asosiy cheklovlariga muvofiq yaratilishi kerak. Bu ular faqat oldindan belgilangan nomlar (images, fonts, sounds, music) bilan yaratilishi kerakligini bildiradi. Endi siz tayyor bo'lsangiz, jarayon juda oddiy. _Agar sizda editor ichida bir nechta fayllar ochiq bo‘lsa, qadoqlamoqchi bo'lgan o'yinning manba kodi fayl yorlig'ini bosib kiring va quyidagi rasmda ko'rsatilganidek, "__**Exe faylga**__" deb nomlangan menyu belgisini bosing._ ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FcRB7Qu1kAFcjzNYZSMgj%252Fimage.png%3Falt%3Dmedia%26token%3D5947988d-d171-4c0a-80f6-59bee767c0a3&width=768&dpr=3&quality=100&sign=f91cf9c7&sv=2) Tugmani bosganingizdan qadoqlash(packaging) jarayoni boshlanadi va rasmda ko'rsatilgandek, qadoqlash **"... completed successfully"** xabari bilan muvaffaqiyatli tamomlansa, manba fayllari saqlangan joyda **dist** nomli papka yaratilganini ko'rasiz. Uning ichida Flappy Bird o'yini bittan bajariladigan **flappy\_bird.exe** fayliga qadoqlanganini ko'rasiz. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FpMPM7WWPzRnsgfcki8P5%252Fimage.png%3Falt%3Dmedia%26token%3D7cff341e-f956-4f19-9e09-917e2a606749&width=768&dpr=3&quality=100&sign=f8f0639b&sv=2) ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FKjlOzefLsmrVEdo8M3FF%252Fimage.png%3Falt%3Dmedia%26token%3Dd3bd3971-1a64-40c3-ab97-f220e407e4da&width=768&dpr=3&quality=100&sign=3f27f18c&sv=2) [PreviousIlovachevron-left](https://roboticsware.gitbook.io/python-pygame_zero/appendix) [NextMu editorining tezkor tugmalarichevron-right](https://roboticsware.gitbook.io/python-pygame_zero/appendix/shortcuts) Last updated 6 days ago --- # 8.2 Protseduraviy dasturlash 2 | Python-Pygame Zero Bu bo‘limdan boshlab ilgari tilga olingan 4 ta foydalanuvchi funksiyaning amalga oshirilishini batafsil tarzda to‘ldirib chiqadigan vaqt keldi. Avvalo, **reset\_ball** funksiyasidan boshlaymiz. Nomidanoq ma’lumki, bu funksiya to‘pning boshlang‘ich joylashuvi va tezligining boshlang‘ich qiymatini belgilash maqsadiga ega funksiyadir. Original o‘yinni diqqat bilan kuzatgan bo‘lsangiz, har safar yangi o‘yin boshlanganda, to‘p ekranning markaziy chizig‘idan chap yoki o‘ng tarafdagi qaytargich tomonga tasodifiy tarzda otib yuborilishini ko‘rgan bo‘lishingiz mumkin. Biz ham o‘yinda yakuniy hisob(**FINAL\_SCORE**)ga yetguncha shunday harakat qiladigan tarzda o‘xshash implementatsiyani amalga oshirdik. Ayniqsa, chap yoki o‘ngga tasodifiy yo‘nalishni aniqlab beruvchi narsa — bu 13-qatordagi **random.choice** nomli funksiyadir. Unga uzatilgan ro‘yxatda mavjud bo‘lgan ikki qiymat (-1 yoki 1) orasidan birini tasodifiy tanlab berish orqali ishlaydi. Copy def reset_ball(): global vx, vy if b1_score == FINAL_SCORE or b2_score == FINAL_SCORE: vx = 0 vy = 0 else: vx = 5 vy = 5 # Markaziy chiziqdan tasodifiy chapga yoki o'ngga tashlash ball.center = (WIDTH/2, random.randint(BALL_RADIUS*2, HEIGHT - BALL_RADIUS*2) vx *= random.choice([-1, 1]) Keyingisi — **ball\_move\_collide** funksiyasidir. Bu funksiya to‘pning harakatini yaratadi va harakatdan so‘ng to‘qnashuvni tekshiradi. Agar devor (o‘yin oynasining chegarasi) bilan to‘qnashgan nuqta chap/yoki o‘ng tomonda bo‘lsa, qaysi o‘yinchi (**bar1** yoki **bar2**) ball (**b1\_score** yoki **b2\_score**) olishini aniqlaydi va g‘alaba yoki mag‘lubiyat aniqlangani sababli yangi o‘yinni boshlashga tayyorgarlik ko‘riladi. Copy def ball_move_collide(): global vx, vy, b1_score, b2_score # To'pni vx va vy tezliklarida harakatlantirish ball.move_ip(vx, vy) # To'p yuqori yoki pastki devorga tegsa if ball.top < 0 or ball.bottom > HEIGHT: vy = -vy # Tezlikning y yo'nalishini teskari o'zgartirish sounds.wall.play() # To'p chap devorga tegsa if ball.left < 0: b2_score += 1 reset_ball() sounds.die.play() # To'p o'ng devorga tegsa if ball.right > WIDTH: b1_score += 1 reset_ball() sounds.die.play() Keyingisi — **gameover\_draw** funksiyasidir. Bu funksiya o‘yinning yakuniy g‘alaba yoki mag‘lubiyati haqida ekranga UI (foydalanuvchi interfeysi) ni chiqaradi. Juda oddiy amalga oshirilgan funksiyadir, shuning uchun tushunishda alohida qiyinchilik yo‘q. Copy def gameover_draw(): if b1_score == FINAL_SCORE: winner = 'Player1' else: winner = 'Player2' screen.draw.text(winner + ' Win!!', (WIDTH/3, HEIGHT/2 - 50), color='blue', fontsize=70) screen.draw.text('Press Space to play again', (WIDTH/4, HEIGHT/2 + 50), \ color='skyblue', fontsize=50) Oxirgisi — **bar\_move\_collide** funksiyasidir. Nomidan ko‘rinib turibdiki, bu funksiya reflektor (bar) harakatini yaratadi va reflektorga urilgan to‘pga oid ishlov berishni amalga oshiradi. Bu avvalgi blok sindirish (block breaker) o‘yiniga o‘xshash bo‘lgani sababli, kodni tushunishda alohida qiyinchilik yo‘q. Yangi qo‘shilgan qism esa, avvalgi bo‘limda tilga olingan blok sindirish o‘yinining yangi qo‘shimcha funksiyasi sifatida taklif etilgan: o‘yin davomida rally uzluksiz davom etsa, to‘pning tezligi asta-sekin oshib boradigan algoritm va reflektor (bar) hududi yuqori va pastki ikki qismga bo‘linib, yuqori qismga to‘p tegsa va pastki qismga tegsa harakatni farqli qilish orqali o‘yinchining reflektorni boshqarishdagi hujum/mudofaa erkinligini oshirib, o‘yinning qiziqarliligini oshiradigan kod (25~30-qator) qo‘shilgan. circle-info Qo‘shimcha tariqasida, 26~27-qatorlar kabi bir nechta qatorni qamrab olgan kommentariyalar (izohlar) uchun, kommentariyaning boshida va oxirida kichik qo‘shtirnoq (`'`) yoki katta qo‘shtirnoq (`"`) dan uchtasini qo‘yish — bu Python sintaksisining asosiy qoidalaridan biri ekanligini ham biling. Copy def bar_move_collide(bar): global vx, vy if bar == bar1: if keyboard.a: if bar.y > 0: bar.y -= 7 elif keyboard.z: if bar.y + bar.height < HEIGHT: bar.y += 7 else: # bar2 if keyboard.up: if bar.y > 0: bar.y -= 7 elif keyboard.down: if bar.y + bar.height < HEIGHT: bar.y += 7 if bar.colliderect(ball): # Avval 10 piksel oldinga o'tish if vx < 0: # bar1 holatida ball.x += 10 else: # bar2 holatida ball.x -= 10 vx = -vx * SPEED_UP # Tezlikning x yo'nalishini teskari o'zgartirish ''' To‘p yuqori tomondan kirib, reflektorning yuqori qismiga urilganda yoki to‘p pastki tomondan kirib, reflektorning pastki qismiga urilganda, kirish yo‘nalishi o‘zgarmay aks etadi ''' if (vy > 0 and ball.centery < bar.centery) or \ (vy < 0 and ball.centery > bar.centery): vy = -vy * SPEED_UP sounds.bar.play() Shu bilan 4 ta foydalanuvchi funksiyasining amalga oshirilishi va tushunilishi yakunlandi. Oldin ham ta’kidlaganimdek, bu o‘yin avvalgi blok sindirish o‘yinining asosiy bilimlariga ega bo‘lgani uchun, ushbu o‘yinni yaratish va tushunishga o‘ylaganchalik ko‘p vaqt ketmadi, deb o‘ylayman. Oxirida barcha kodlarni umumiy holda taqdim qilib, protsedurali yo‘nalishda yaratilgan Pong o‘yinini yakunlaymiz, keyingi bo‘limlardan esa nihoyat foydalanuvchi aniqlangan obyektlarni yaratishdan boshlab, shu obyektlardan foydalanib, bir xil o‘yinni obyektga yo‘naltirilgan paradigmaning uslubida yaratishga kirishamiz. Copy import math import random # o'yin oynasi TITLE = 'pong' WIDTH = 800 HEIGHT = 600 GAP_FROM_SCR = 20 # reflektor BAR_H = 100 BAR_W = 15 # to'p vx = 5 vy = 5 BALL_RADIUS = 10 SPEED_UP = 1.05 # hisob FINAL_SCORE = 11 b1_score = -1 b2_score = -1 def reset_ball(): global vx, vy if b1_score == FINAL_SCORE or b2_score == FINAL_SCORE: vx = 0 vy = 0 else: vx = 5 vy = 5 # Markaziy chiziqdan tasodifiy chapga yoki o'ngga tashlash ball.center = (WIDTH/2, random.randint(BALL_RADIUS*2, HEIGHT - BALL_RADIUS*2)) vx *= random.choice([-1, 1]) def ball_move_collide(): global vx, vy, b1_score, b2_score # To'pni vx va vy tezliklari bilan harakatlantish ball.move_ip(vx, vy) # To'p yuqori yoki pastki devorga urilganda if ball.top < 0 or ball.bottom > HEIGHT: vy = -vy # Tezlikning y yo'nalishini teskari tomonga o'zgartirish sounds.wall.play() # To'p chap devorga tegsa if ball.left < 0: b2_score += 1 reset_ball() sounds.die.play() # To'p o'ng devorga tegsa if ball.right > WIDTH: b1_score += 1 reset_ball() sounds.die.play() def gameover_draw(): if b1_score == FINAL_SCORE: winner = 'Player1' else: winner = 'Player2' screen.draw.text(winner + ' Win!!', (WIDTH/3, HEIGHT/2 - 50), color='blue', fontsize=70) screen.draw.text('Press Space to play again', (WIDTH/4, HEIGHT/2 + 50), \ color='skyblue', fontsize=50) def bar_move_collide(bar): global vx, vy if bar == bar1: if keyboard.a: if bar.y > 0: bar.y -= 7 elif keyboard.z: if bar.y + bar.height < HEIGHT: bar.y += 7 else: # bar2 if keyboard.up: if bar.y > 0: bar.y -= 7 elif keyboard.down: if bar.y + bar.height < HEIGHT: bar.y += 7 if bar.colliderect(ball): # Avval 10 piksel oldinga o'tish if vx < 0: # bar1 holatida ball.x += 10 else: # bar2 holatida ball.x -= 10 vx = -vx * SPEED_UP # Tezlikning x yo'nalishini teskari o'zgartirish ''' To‘p yuqori tomondan kirib, reflektorning yuqori qismiga urilganda yoki to‘p pastki tomondan kirib, reflektorning pastki qismiga urilganda, kirish yo‘nalishi o‘zgarmay aks etadi ''' if (vy > 0 and ball.centery < bar.centery) or \ (vy < 0 and ball.centery > bar.centery): vy = -vy * SPEED_UP sounds.bar.play() ball = Rect(WIDTH/2, HEIGHT/2, \ BALL_RADIUS * math.sqrt(2), BALL_RADIUS * math.sqrt(2)) bar1 = Rect(GAP_FROM_SCR, HEIGHT/2 - BAR_H/2, BAR_W, BAR_H) bar2 = Rect(WIDTH - BAR_W - GAP_FROM_SCR, HEIGHT/2 - BAR_H/2, BAR_W, BAR_H) bars = [bar1, bar2] def draw(): screen.clear() # o'rta chiziq screen.draw.line((WIDTH/2, GAP_FROM_SCR), (WIDTH/2, HEIGHT - GAP_FROM_SCR), color='grey') # reflektor for bar in bars: screen.draw.filled_rect(bar, 'white') # hisob screen.draw.text(str(b1_score), (WIDTH/4, GAP_FROM_SCR), color='yellow', fontsize=60) screen.draw.text(str(b2_score), ((WIDTH/4)*3, GAP_FROM_SCR), color='yellow', fontsize=60) if b1_score == FINAL_SCORE or b2_score == FINAL_SCORE: gameover_draw() else: # to'p screen.draw.filled_circle(ball.center, BALL_RADIUS, 'white') def update(): global b1_score, b2_score # to'p ball_move_collide() # reflektor for bar in bars: bar_move_collide(bar) # o'yin boshlanish shartlari if (b1_score == FINAL_SCORE or b2_score == FINAL_SCORE) or \ (b1_score == -1 and b2_score == -1): if keyboard.space: b1_score = 0 b2_score = 0 reset_ball() else: # to'p ball_move_collide() [Previous8.1 Protseduraviy dasturlash 1chevron-left](https://roboticsware.gitbook.io/python-pygame_zero/pong/8.1_procedural_dev1) [Next8.3 Obyektga Yo‘naltirilgan Dasturlash nazariyasi (Obyektga Yo‘naltirilgan dizayn nima)chevron-right](https://roboticsware.gitbook.io/python-pygame_zero/pong/ood) Last updated 6 days ago --- # 6.4 To‘qnashuv testini o‘tkazishda e’tiborga olish kerak bo‘lgan narsalar | Python-Pygame Zero Siz ilgari bo‘lim oxirida tilga olingan, hozirgacha amalga oshirilgan o‘yindagi ma’lum bir xato(bug)ni topdingizmi? Ehtimol ikki xil xatoni aniqlagansiz. Ikkalasi ham reflektor (to‘pni qaytaruvchi panel)ning ikki chekkasiga(edge), ya’ni qirralariga to‘p tegishiga bog‘liq yuzaga keladigan holatlardir. Birinchisi shundaki, reflektor to‘pni haqiqatan ham urmagan bo‘lsada (to‘p reflektorga tegmagan bo‘lsa ham), go‘yo teggandek harakat qiladigan xato bor. Sababini topish uchun keling, to‘p tasvirining haqiqati haqida o‘ylab ko‘raylik. To‘g‘ridan-to‘g‘ri grafik muharrir yordamida tasvirlarni yaratish tajribasiga ega bo‘lganlar yaxshiroq tushunadilar. _To‘p tasviri o‘yinda bizning ko‘zimizga doira kabi ko‘rinadi, lekin u haqiqiy doira emas. Bu dastlab kengligi va balandligi 32x32px (piksel) bo‘lgan, barcha piksellarni to‘ldirilgan mukammal kvadrat edi. Inson ko‘ziga ko‘rinadigan piksellar inson ko‘ziga ko‘rinadigan rangga bo‘yalgan va inson ko‘ziga ko‘rinmasligi kerak bo‘lgan piksellar (ayniqsa, koptokning to‘rtta burchaklari dumaloq ko‘rinishda bo‘yalgan va shaxmat taxtasiga o‘xshash) shaffof(transparent) rang bilan (bo‘yalgan). Shuning uchun, aslida bu kvadrat, va aylanaga o‘xshash qilish buning uchun optik illyuziya sifatida ko‘rib chiqish mumkin._ ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FAdiPkQ2f6RqKaHfgEmiR%252Fimage.png%3Falt%3Dmedia%26token%3Dae8d9923-67c8-49a4-a403-916f9442f93c&width=768&dpr=3&quality=100&sign=3780977b&sv=2) Shuning uchun, **o‘yinda ishtirok etayotgan aktyorlar(Actor)ning asl tasvirlari to‘rtburchak(rectangle) shaklida edi va o‘yindagi ushbu tasvirlar o‘zaro tegish yoki to‘qnashuv(collision) deb ataladigan hodisa quyidagi misolda ko‘rsatilgandek, har bir tasvirning to‘rtburchak sohasining bir-biriga tegib-tegmasligini aniqlash orqali baholanadi (to‘qnashuv tekshiruvi).** Shu sababli, pastdagi misolda ichki dasturda haqiqatan tegish yuz bergan bo‘lsada, bizning ko‘zimizga tegmagandek ko‘rinib, noto‘g‘ri ishlash sifatida namoyon bo‘lgan holat yuzaga kelgan. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252F6d4XpbiL1FYR9XStFKzt%252Fimage.png%3Falt%3Dmedia%26token%3D3da69f75-cff5-4a22-b6d7-0cec8042f328&width=768&dpr=3&quality=100&sign=cba3e8d4&sv=2) Ushbu to‘qnashuv tekshiruvining mavjud kodini yana bir bor ko‘rib chiqsangiz, nima uchun ishlatilgan metod (obyektga tegishli funksiya) nomi **colliderect (collide + rectangle)** ekanligini endi tushunishingiz mumkin bo‘ladi. Copy if ball.colliderect(bar) == True: Xo‘sh, endi bu muammoni qanday hal qilish kerakki, noto‘g‘ri ishlashgandek ko‘rinmasdan ko‘zga tabiiyroq ko‘rinishini ta’minlash mumkin? Menimcha, bir nechta fikrlar bo‘lishi mumkin. Eng birinchisi, \*\*to‘rtburchak(rect)\*\*lar o‘rniga, agar biz ko‘rayotgan tasvirlar **aylana(circle)** shakliga yaqinroq bo‘lsa, unda pastdagi rasmning o‘ng tomonidagi kabi to‘qnashuv tekshiruv maydonini aylana shaklida tashkil qilib tekshirish(detection) imkoniyati bo‘lsa, yanada yaxshi bo‘lmasmikan? Bu yaxshi va amaliy fikr. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FMUifUYhuxi4njFqEvDL0%252Fimage.png%3Falt%3Dmedia%26token%3Df7ef7428-e44d-4cc9-b375-787f1786247e&width=768&dpr=3&quality=100&sign=d5af2414&sv=2) Keyingi yana bir fikr nima bo‘lishi mumkin? Mukammal to‘qnashuv tekshiruvi uchun odam ko‘rgan rangli, bo‘yalgan hududlarning o‘zaro to‘qnashishini tekshirish imkonini berish eng mukammal usul bo‘lar edi, deyish mumkin. Buning uchun esa, asl to‘rtburchak shakldan pastdagi kabi faqat rang bilan bo‘yalgan sohalarni alohida ajratib olish (grafik dasturlarda bunga “[nukitagiarrow-up-right](https://namu.wiki/w/%EB%88%84%EB%81%BC) ” deyiladi) bo‘ladi. Shuningdek, haqiqiy to‘qnashuv hududini tekshirishda esa, tartibsiz shakllarning piksellar darajasida tekshirilishi, ya’ni har bir pixellar to‘qnashuvi kabi yanada murakkab hisob-kitoblar talab qilinadi. Shuning uchun, bu usul o‘yin tezligini sekinlashtirishi mumkin, va har bir yechimning o‘ziga xos afzallik va kamchilik(trade-off) tomonlari mavjud. Oxir-oqibat, o‘yin foydalanuvchisiga jiddiy noqulaylik tug‘dirmaydigan murosaga erishish kerak. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FIKXvL8FhM4xmPRK6c9iP%252Fimage.png%3Falt%3Dmedia%26token%3D0de474b0-7045-48d2-b2b1-2658e91fc19f&width=768&dpr=3&quality=100&sign=7b99ee5f&sv=2) Keling, ushbu yechimni qo‘llaymiz va mavjud kodni almashtiramiz. Biroq, afsuski, PygameZero kutubxonasi bunday turdagi to‘qnashuvlarni aniqlash usulini ta'minlamaydi. Biroq, xayriyatki, bu muammoni [5.8-bo‘lim](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.8_animation) da Flappy Bird animatsiyasi uchun ishlatilgan PygameZero funksiyasini kengaytiruvchi qo‘shimcha modul(**pgzhelper**) yordamida hal qilish mumkin. Agar siz maxsus Mu Editorini foydalanuvchisi bo‘lmasangiz va avval ushbu modulni o‘rnatmagan bo‘lsangiz, uni birinchi marta bir marta o‘rnatishingiz kerak bo‘ladi. O‘rnatish jarayoni allaqachon [5.8-bo‘lim](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.8_animation) da batafsil tushuntirilgan, shuning uchun o‘rnatish uchun ushbu bo‘limga qarang. Keyinchalik, yuqorida aytib o‘tilgan birinchi yechimni qo‘llaydigan kodni ko‘rib chiqaylik. Copy from pgzhelper import * TITLE = 'Breakout' WIDTH = 800 HEIGHT = 600 GAP_FROM_SCREEN = 50 ball = Actor('ball', (WIDTH / 2, HEIGHT / 2)) ball.radius = ball.width / 2 bar = Actor('bar', (WIDTH / 2, HEIGHT - GAP_FROM_SCREEN)) # 4-qator*8-ustundan iborat bloklar to'plamini yaratish blocks = [] for block_row in range(4): for block_col in range(8): block = Actor( 'block', (block_col * 100, block_row * 32 + GAP_FROM_SCREEN), anchor=('left', 'top') ) blocks.append(block) # to'pning boshlang'ich (yo'nalish) tezligi vx = 5 vy = -5 def draw(): screen.blit('space', (0, 0)) ball.draw() bar.draw() for block in blocks: block.draw() def update(): global vx, vy # ekran ichida reflektorning harakatini cheklash if bar.left < 0: bar.left = 0 if bar.right > WIDTH: bar.right = WIDTH # to'pni x va y yo'nalishlarida vx va vy masofaga mos ravishda harakatlantirish ball.move_ip(vx, vy) # to'p chap yoki o'ng devorga tegsa, x yo'nalishini teskari tomonga o'zgartirish if ball.left < 0 or ball.right > WIDTH: vx = -vx # Tezlikning x yo'nalishini teskari tomonga o'zgartirish sounds.wall.play() # to'p yuqori devorga yoki reflektorga tegsa, y yo'nalishi teskari bo'ladi if ball.top < 0 or ball.circle_colliderect(bar) == True: vy = -vy # Tezlikning y yo'nalishini teskari tomonga o'zgartirish sounds.wall.play() # to'p blokga tegsa b_index = ball.collidelist(blocks) if b_index != -1: vy = -vy # Tezlikning y yo'nalishini teskari tomonga o'zgartirish sounds.block.play() blocks.pop(b_index) # o'yin tugashi holati if ball.bottom > HEIGHT: sounds.die.play() game.exit() if not blocks: sounds.win.play() vx = 0 vy = 0 def on_mouse_move(pos): x, y = pos bar.centerx = x 🔢 Avvalgi kodda faqat 3 ta qator o‘zgargan. Birinchidan, birinchi qatorda **pgzhelper** modulini import qildik. 8~10-qatorlarda o‘yindagi aktyor obyektlari yaratilayotgan kod ichida, _bizning maqsadimiz shuki, to‘p obyektini to‘rtburchak(rectangle) emas, aylana(circle) sifatida hisoblashdir. Shu sababli, 9-qator kabi obyektga oldindan_ _**radius**_ _qiymatini belgilash zarur._ To‘p rasmi 32x32 piksel o‘lchamdagi to‘rtburchak ichida to‘liq sig‘adigan aylana bo‘lgani uchun, radiusni ball tasvirining yarim uzunligi, ya’ni 16 piksel qilib belgilash kifoya qiladi. Endi haqiqiy to‘qnashuv tekshiruvi bajariladigan 53-qatorda esa **circle\_colliderect** funksiyasidan foydalaniladi. Ushbu funksiya tufayli, reflektor hali ham to‘rtburchak (rect) shaklida bo‘lsada, hech bo‘lmaganda to‘p obyekti aylana shaklida hisoblanib, o‘zaro to‘qnashuv tekshiruvi amalga oshiriladi. Ikkinchi yechimni ham qo‘llash oson. _Obyektdan faqat rangli piksellar asosidagi shaklni kesib olib piksellar darajasidagi to‘qnashuv tekshiruvi uchun_ _**collide\_pixel**_ _metodidan foydalaniladi. Ushbu metod to‘qnashuv bo‘lmasa_ _**None**_ _qiymatini qaytaradi._ Shuning uchun, 53-qator kodini quyidagicha o‘zgartirish kifoya qiladi va shu bilan ish yakunlanadi. Copy if ball.top < 0 or ball.collide_pixel(bar) != None: Endi ikkinchi xatoni ko‘rib chiqish vaqti keldi. Ikkinchi xato shundaki, quyidagi rasmda ko‘rsatilganidek, to‘p reflektorning chetiga tegsa, reflektor bo‘ylab dumalab tushadigan kutilmagan hodisa sodir bo‘ladi. Birinchi navbatda nima uchun bu xato paydo bo‘lishini taxmin qilaylik. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FI3OumHz7J3q6ma1OMl87%252Fimage%2520%282%29.gif%3Falt%3Dmedia%26token%3Dd1b16d15-d444-4395-832b-c7b09db7ce1e&width=768&dpr=3&quality=100&sign=5acb8280&sv=2) To‘g‘ri sababni aniqlash uchun, aylana shaklidagi to‘pning harakatini batafsil ko‘rib chiqaylik. Sizga tushunishni osonlashtirish maqsadida to‘pning harakati sekinlashtirilgan rejimda (slow motion) ko‘rsatilmoqda. Birinchi ishora: to‘p reflektor ichida qamalib harakatlanmoqda. Ikkinchi ishora: to‘p yuqoriga va pastga harakat qilib takroriy siljiyapti. Birinchi muammo reflektorning o‘ng chetiga(edge) tegilganda yuzaga keladi. O‘sha zahoti 54-qator kodida to‘pning tezligi(velocity) qarama-qarshi yo‘nalishga o‘zgartiriladi va bu aslida to‘g‘ri, lekin natijada to‘p reflektor ichki tomoniga qarab yo‘naltiriladi va reflektor ichiga kirib boradigan holat yuzaga keladi. Bu juda jiddiy muammo hisoblanadi. Aslida to‘p reflektor yuzasidan aks etib, reflektorni darhol tark etishi kerak edi, lekin **update** funksiyasi sekundiga 60 marta chaqirilishi sababli, har bir chaqiriqda to‘p pozitsiyasi ozgina o‘zgaradi, ammo hali ham reflektor ichidan chiqmaydi. Shuning uchun har safar to‘p reflektor bilan to‘qnashgan deb hisoblanadi va har chaqiriqda tezlik yo‘nalishi qayta o‘zgartiriladi. Natijada to‘p reflektor ichida qamalib, yuqoriga-pastga siljiydi. Xo‘sh, endi sababni bilsak, uni qanday hal qilishimiz mumkin? Sizda qanday g‘oyalar borligini bilish menga juda qiziq. Bu muammoning ikkita yechimi borga o‘xshaydi. Ikkalasi ham to‘pning reflektorga kirib ketishiga yo‘l qo‘ymaslik haqida. Birinchi g‘oya shundan iboratki, to‘p reflektorning uchidan aks etganda, aks ettirilganda reflektor tomonga burilmaydi, ya’ni to‘p yo‘nalishini o‘zgartirmasdan o‘zi kelgan tomonga qaytib keladi. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FYcYNWAZjqrHqfcEpYXiS%252Fimage.png%3Falt%3Dmedia%26token%3D9c51b94b-46f4-4674-8989-350a017589b5&width=768&dpr=3&quality=100&sign=af883e4f&sv=2) Ikkinchi g‘oya – aks ettirish yo‘nalishini o‘zgartirmaslik, lekin to‘p aks etganda reflektorga ilinib qolishining oldini olish uchun to‘pni dastlab vertikal ravishda reflektordan ma’lum masofaga (10 piksel) uzoqlashtirib, so‘ngra avvalgidek aks ettirish. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FUlJPg4oh7oFc5uBi8AZH%252Fimage.png%3Falt%3Dmedia%26token%3De15f3060-8153-4bbf-aa3b-aa7771048257&width=768&dpr=3&quality=100&sign=a740af85&sv=2) Biz ishlarni murakkablashtirmasdan iloji boricha sodda tarzda amalga oshirishni birinchi o‘ringa qo‘yganimiz sababli, ikkinchi g‘oya ikkalasidan ancha sodda, shuning uchun ushbu yechimni qo‘llagan ushbu o‘yinning yakuniy kodi quyidagicha: Copy from pgzhelper import * TITLE = 'Breakout' WIDTH = 800 HEIGHT = 600 GAP_FROM_SCREEN = 50 ball = Actor('ball', (WIDTH / 2, HEIGHT / 2)) ball.radius = ball.width / 2 bar = Actor('bar', (WIDTH / 2, HEIGHT - GAP_FROM_SCREEN)) # 4-qator*8-ustundan iborat bloklar to'plamini yaratish blocks = [] for block_row in range(4): for block_col in range(8): block = Actor( 'block', (block_col * 100, block_row * 32 + GAP_FROM_SCREEN), anchor=('left', 'top') ) blocks.append(block) # to'pning boshlang'ich (yo'nalish) tezligi vx = 5 vy = -5 def draw(): screen.blit('background', (0, 0)) ball.draw() bar.draw() for block in blocks: block.draw() def update(): global vx, vy # ekran ichida reflektorning harakatini cheklash if bar.left < 0: bar.left = 0 if bar.right > WIDTH: bar.right = WIDTH # to'pni x va y yo'nalishlarida vx va vy masofaga mos ravishda harakatlantirish ball.move_ip(vx, vy) # to'p chap yoki o'ng devorga tegsa, x yo'nalishini teskari tomonga o'zgartirish if ball.left < 0 or ball.right > WIDTH: vx = -vx # Tezlikning x yo'nalishini teskari tomonga o'zgartirish sounds.wall.play() # to'p yuqori devorga tegsa if ball.top < 0: vy = -vy # Tezlikning y yo'nalishini teskari tomonga o'zgartirish sounds.wall.play() # to'p reflektorga tegsa if ball.circle_colliderect(bar) == True: ball.y -= 10 # Avval vertikal ravishda 10 pikselni siljitish vy = -vy # Tezlikning y yo'nalishini teskari tomonga o'zgartirish sounds.bar.play() # to'p blokga tegsa b_index = ball.collidelist(blocks) if b_index != -1: vy = -vy # Tezlikning y yo'nalishini teskari tomonga o'zgartirish sounds.block.play() blocks.pop(b_index) # o'yin tugashi holati if ball.bottom > HEIGHT: sounds.die.play() pygame.exit() if not blocks: sounds.win.play() vx = 0 vy = 0 def on_mouse_move(pos): x, y = pos bar.centerx = x [Previous6.3 To‘pni aks ettirish va bloklarni sindirishni amalga oshirishchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.3_reflection_breakout) [Next6.5 (Bonus) Original o‘yin kabi yaratib ko‘rishchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.5_make_original) Last updated 7 days ago --- # 5. Flappy Bird o'yinini yaratish | Python-Pygame Zero Biz birinchi o‘zimiz bajarib ko‘radigan o‘yin **Flappy Bird** dir. Bu o‘yin 2012-yilda Vetnamlik indie(yakka mustaqil) o‘yin ishlab chiquvchisi tomonidan yaratilgan va butun dunyoda global xitga aylangan, bir vaqtlar o‘ziga tortuvchi o‘yin sifatida ancha mashhur bo‘lgan o‘yindir. Ayniqsa rivojlanayotgan davlat bo‘lgan Vetnamda yosh bir yigit tomonidan erishilgan ulkan muvaffaqiyat hikoyasi sifatida global xitga aylandi va o'sha paytda u kuniga 50 000 dollardan ortiq daromad keltirgan bo'lsada, atigi 3 oy o'tgach, u birdaniga o'yin bilan pul ishlashni to'xtatdi. Bu faktlarning o‘ziyoq o‘yinga qiziqarli [voqelik va hikoya qo‘shadiarrow-up-right](https://www.thisisgame.com/webzine/series/nboard/212/?n=116507&series=26) . Shunday ekan, bu voqealarni bilgan holda o‘yinni yaratish jarayoni yanada maroqli kechadi. Ehtimol, sizlardan ba'zilaringiz bu o‘yinni ilgari Entry/Scratch blokli dasturlash muhiti orqali kloni(clone)ni yaratib ko‘rgan bo‘lishingiz mumkin. Ammo bu o‘yinni endi birinchi marta yaratmoqchi bo‘lganlar ham xavotirlanmasin — agar siz quyidagi videorolik orqali o‘yin qanday o‘ynalishini oldindan ko‘rib chiqsangiz, bu o‘yinni yaratish jarayonini tushunishga yordam beradi. [Previous4\. O'yin siklini tushunishchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/game_loop) [Next5.1 Ekranga fon rasmi(obyekti)ni chiqarishchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.1_background) Last updated 7 days ago sun-brightdesktopmoon sun-brightdesktopmoon --- # 9.3 Obyektga yo‘naltirilgan dasturlash 1 | Python-Pygame Zero Battle City o‘yinining obyektga yo‘naltirilgan versiyasida ilgariga qaraganda obyektga yo‘naltirilgan dizayn (OOD: Object Oriented Design) nuqtai nazaridan yanada ko‘proq fikr yuritish mashqini bajarib ko‘rish foydali bo‘ladi. Obyektga yo‘naltirilgan tarzda yaratish degani tuzilish jihatidan qanday shaklga ega bo‘lishi kerak? Biz Pygame Zero kutubxonasidan asos sifatida foydalanayotganimiz sababli, majburiy **callback** funksiyalar (draw, update funksiyalari va h.k.) orqali [o‘yin sikli](https://roboticsware.gitbook.io/python-pygame_zero/game_loop) (game loop) tuzilishiga tayangan holda ishlaymiz. Unda keling, Battle City o‘yinida kerak bo‘ladigan obyektlarni aniqlashdan boshlaylik. Bizning o‘yin sahnamizdagi rollarni aktyor(Actor) obyektlari asosida ko‘rib chiqish oson bo‘ladi: "asosiy qahramon tanki", "dushman tanki", "devor to‘siqlari", "o‘q", "portlash sahnasi". Kattaroq toifalarga ajratsak, bularni "qahramon", "dushman", "to‘siq", "qurol" rollarini bajaradi, deb aytish mumkin. Aynan shu yerda bizning muammomiz yana boshlanadi. _Ya’ni, bu o‘yinni avvalgi kabi faqat misol darajasida, faqat zaruriy funksiyalarni amalga oshirib, boshqa qo‘shimcha funksiyasiz, qo‘l tegmaydigan holatda qoldirishni istayapmizmi? Yoki shaxsiy qiziqish bilan bu o‘yinni takomillashtirib, rivojlangan shaklga keltirishni xohlab, masalan, dushman sifatida faqat tank emas, boshqa turdagi dushmanlar ham qo‘shilishini, yoki mening ishlatadigan qurolim ham faqat to‘p emas, boshqa turdagi hujum vositalarini ham o‘z ichiga olishini, hozircha faqat devor to‘siqlari mavjud bo‘lsada, boshqa turdagi to‘siqlarni ham o‘ylayotganimizni nazarda tutamizmi? Chunki aynan shunday qarorlarga qarab, hozirdan boshlab qanday chuqurlikda meros olish kerakligi va obyektga yo‘naltirilgan dizayn ko‘lami aniqlanadi._ Hajmni haddan tashqari kattalashtirib dizayn qilish masalasi haqida shuni aytish kerakki, bu kitobning boshlang‘ich o‘quv darajasi nuqtai nazaridan bu yondashuv biroz yuqori darajada bo‘lib, hajman ham ortib ketadi. Shu sababli agar imkon bo‘lsa, bu masalalarni ushbu kitobning keyingi darajadagi qismida davom etishga qaror qilamiz va hozircha bu kitobga mos darajadagi murosaga kelgan holda dizaynni amalga oshiramiz. Unda, avval qahramon va dushman rollarini alohida ko‘rib chiqaylik. Qahramon va dushmanning asosiy maqsadi — harakatlanib bir-biriga o‘q (yoki to‘p) otish orqali hujum qilishdir. Bu paytda ikkovi bir xil quroldan foydalanadi va harakatlanish usuli ham faqat old, orqa, chap va o‘ng yo‘nalishda to‘g‘ri chiziq bo‘ylab harakatlana oladi, ya’ni har ikkisi ham bir xil cheklovlarga ega. Demak, ha, “tank” degan umumiy obyekt yaratiladi va shu obyektdan qayta foydalanib, qahramon tanki va dushman tankini alohida hosil qilish mumkin bo‘ladi. Endi esa boshqa tomondan, tank obyekti zimmasiga olishi kerak bo‘lgan mas’uliyatlar **(ya’ni, tashqi obyektlar foydalanuvchilariga taqdim qilinadigan ma’lumot yoki so‘rovga ko‘ra bajariladigan harakatlar) haqida o‘ylab ko‘raylik. Biroq, mas’uliyatlarni belgilashdan avval, obyektlar o‘zaro qanday hamkorlik qilishini o‘ylab ko‘rish muhim, chunki aynan hamkorlikni tahlil qilish orqali obyektning mas’uliyatlari tabiiy ravishda aniqlanadi.** Ya’ni, _qaysi obyekt tank obyektidan qanday harakatni talab qiladi, degan savol ustida fikr yuritamiz. Eng asosiy talab obyektlarning yaratilishi (creation) bilan boshlanishi mumkin. Har bir obyektni boshidanoq tayyorlab qo‘yib ishga tushurish emas, balki muayyan obyekt boshqa bir obyektni aniq bir vaqtda yaratishini so‘rashi mumkin._ Masalan, bo‘sh joy (space) tugmasi bosilganda “o‘q” obyektining yaratilishi va uchishni boshlashi aynan shunday vaziyatga misol bo‘la oladi. O‘yin ilk bor ishga tushganda ekranda birinchi bo‘lib paydo bo‘ladigan obyektlar qaysilar? Bular “asosiy qahramon tanki”, “dushman tanklari” va “devor to‘siqlari”dir. Shuningdek, obyekt bo‘lmagan oddiy fon tasviri ham bo‘lishi kerak bo‘ladi. Unda bu obyektlarni kim yaratadi? Entry blokli kodlashda bu ishni Entry tizimi ichki tarzda avtomatik bajargan bo‘lsa, endi esa bu ishni ham biz o‘zimiz kod orqali amalga oshirishimiz kerak bo‘ladi. Obyektlar ekranga chizilishi uchun **draw** callback funksiyasi ichida har bir obyektning **draw** metodini chaqirish zarur, ya’ni bu **draw** funksiyasi chaqirilishidan oldin obyektlar allaqachon yaratilgan bo‘lishi kerakligini anglatadi. Endi esa **battle\_city\_oop.py** deb nomlangan faylda yuqorida tilga olingan mazmunning asosiy kodini yozib chiqamiz. battle\_city\_oop.py Copy import random from actors import Tank WIDTH = 800 HEIGHT = 600 # 50x50 devor maketini yarating walls = [] WALL_SIZE = 50 for x in range(int(WIDTH / WALL_SIZE)): # tank joylashadigan birinchi va oxirgi qatordan iborat jami 2 qatorni bo'sh qoldirish uchun -2 qilib yaratilgan for y in range(int(HEIGHT / WALL_SIZE - 2)): if random.randint(0, 100) < 50: # kerakli miqdordadi devorlarni yaratish wall = Actor("wall", anchor=("left", "top")) wall.x = x * WALL_SIZE wall.y = y * WALL_SIZE + WALL_SIZE # birinchi qatorni bo'shatish uchun oxirigacha pastga surish walls.append(wall) # tank qahramonini yaratish tank = Tank("tank_blue", (400, 575)) # dushman tanklarini yaratish enemies = [] MAX_ENEMIES = 3 for i in range(MAX_ENEMIES): enemies.append(Tank("tank_red", (400, 25)) def draw(): screen.blit("grass", (0, 0)) # fon rasmini chizish tank.draw() for enemy in enemies: enemy.draw() for wall in walls: wall.draw() 🔢 Devor to‘siqlarini yaratish kodi ilgari ishlatilgan jarayonga yo‘naltirilgan versiyadagisi bilan bir xil bo‘lgani sababli, alohida tushuntirishga hojat yo‘q. 20~26-qatorlarda asosiy qahramon tanki va 3 ta dushman tanki yaratilmoqda, lekin bu yerda e’tiborga molik jihat — ilgari aktyor obyektlarini Actor klassi orqali yaratgan bo‘lsak, endi esa biz o‘zimiz yaratgan foydalanuvchi obyektlari bo‘lgan MyTank va EnemyTank klasslari orqali yaratmoqdamiz. Ushbu foydalanuvchi obyektlarini battle\_city\_oop.py faylining ichida yozish ham mumkin bo‘lardi, biroq bitta faylga haddan tashqari ko‘p kod yozish tavsiya qilinmaydi. Aksincha, **kodni mazmunli tarzda bir nechta faylga ajratib, modul ko‘rinishida tashkil qilish(modulization) kattaroq loyihalarni boshqarishda samaraliroq va odatiy yondashuvdir**. Shu sababli, _bizning foydalanuvchi obyektlarimiz_ _**actors.py**_ _deb nomlangan fayl ichida joylashgan bo‘lib, ularni_ _**battle\_city\_oop.py**_ _faylida foydalanish uchun 2-qatorda_ _**from-import**_ _operatori orqali_ _**actors**_ _modulidan (bu orqali fayl nomini modul nomi bo‘lishini tushunamiz) kerakli klasslarni_ _**import**_ _qilib ishlatilmoqda._ actors.py Copy from pgzhelper import * class Bullet(Actor): def __init__(): super().__init__() pass class Explosion(Actor): def __init__(): super().__init__() pass class Tank(Actor): def __init__(): super().__init__() pass def move(): pass def fire(): pass 🔢 Tushunishni osonlashtirish uchun, to‘liq implementatsiyasiz bo‘lsada, aniqlangan obyektlarning juda asosiy skeletidan boshlash foydali bo‘ladi. Avval tank obyektidan boshlab, asta-sekin fikr yuritaylik. Tank obyekti Actor obyektidan meros olgani sababli, u odatdagi Actor sifatida ko‘rilishi mumkin va shu sababli oddiy aktyor obyektini yaratishda bo‘lgani kabi obyekt ko‘rinishini belgilovchi **rasm** nomi va boshlang‘ich ekrandagi **joylashuv**i kabi ikkita parametr orqali yaratish mumkin. Biroq, yaxshilab o‘ylab ko‘radigan bo‘lsak, o‘yin boshida dushman va qahramon obyektlari bir-biriga qarab turgan holatda bo‘lishi kerak, shuning uchun obyekt yaratilayotganda **angle** (burchak) xususiyati ham boshlang‘ich parametr sifatida birga berib yuborish yaxshi bo‘ladi. Ma’lumot uchun, angle xususiyati asl Actor obyektida mavjud emas, lekin actors.py faylining yuqorisida **pgzhelper** modulini **import** qilganimiz sababli, bu Actor obyekti ichida mavjud bo‘ladigan qo‘shimcha xususiyat sifatida tanilmoqda — bu haqida siz yaxshi bilsangiz kerak. Umumiy hisobda 3 ta parametr bor: **img\_name** va **pos** qiymatlari ota obyekt bo‘lgan asl Actor obyektining boshlang‘ich holatini o‘rnatish uchun uzatiladi, **angle** qiymati esa hosila obyektning o‘z xususiyati sifatida saqlanadi. Unda, hozirgacha tilga olingan mazmunni kod ko‘rinishida quyidagicha ifodalash mumkin bo‘ladi. Copy class Tank(Actor): def __init__(self, img_name, pos, angle): super().__init__(self, img_name, pos) self.angle = angle 🔢 Keyingisi, tankning harakatiga oid **move** metodining implementatsiyasi haqida o‘ylab ko‘rishdir. Ota klass barcha farzandlar bilan umumiy bo‘lgan funksiyalarni o‘zida jamlash uchun mo‘ljallangan, shunda uni meros olgan farzand obyektlar otaning funksiyalaridan bevosita foydalanishlari mumkin bo‘ladi. Hozirgacha aniqlangan tanklar uchun umumiy bo‘lgan xatti-harakat bu asosiy harakat funksiyasi bo‘lib, **move** metodi har safar chaqirilganda, tank hozir qarab turgan yo‘nalish bo‘yicha belgilangan masofaga to‘g‘ri chiziqli harakatni amalga oshiradi. Endi, shu fikrlarni o‘z ichiga olgan holda umumiy kod ko‘rinishida quyidagicha ifodalash mumkin. Copy class Tank(Actor): def __init__(self, img_name, pos, angle): super().__init__(self, img_name, pos) self.angle = angle def move(self): if self.angle == 180: self.x -= 2 elif self.angle == 0: self.x += 2 elif self.angle == 90: self.y -= 2 elif self.angle == 270: self.y += 2 Tank harakati haqida biz e’tibordan chetda qoldirgan(?) jihatlardan biri shuki, tank harakati cheklovlarga ega. Bu cheklovlar ilgari protseduraviy dasturlashda ham e’tiborga olingan bo‘lib, tank devor orasidan o‘tib keta olmaydi va butun o‘yin ekranining chegarasidan chiqib ketishi ham mumkin emas. _Bu ikki cheklov harakat cheklovi nuqtai nazaridan o‘xshash ko‘rinsada, amaliy implementatsiya jihatidan farqlidir: ekranning chegarasi bilan bog‘liq cheklov bu oddiy oraliq tekshiruvidir, devor bilan bog‘liq cheklov esa esa ikki obyekt (tank va devor) to‘qnashuvini aniqlagandan so‘ng harakatni cheklashga asoslanadi, ya’ni ular mazmunan har xil._ Shu o‘rinda savol tug‘iladi, birinchi holat, ya’ni ekran chegarasi bilan bog‘liq tekshiruv, faqat tank obyektigagina tegishlimi? Boshqa obyektlarga kerak emasmi? O‘ylab ko‘radigan bo‘lsak, bu aynan “o‘q” obyektiga ham tegishlidir. Chunki, o‘q ekrandan chiqib ketgach, u obyektni darhol o‘chirish (ya’ni, xotiradan o‘chirish) kerak bo‘ladi. Demak, **bu kabi funksiyalar barcha obyektlarga emas, balki ba’zi obyektlarga kerak bo‘ladi. Aynan shu kabi vazifalarni amalga oshirish uchun obyektga yo‘naltirilgan dasturlashda bilishimiz zarur bo‘lgan yana bir muhim tushuncha paydo bo‘ladi — bu** _**abstrakt klass**_ **yoki** _**interfeys (interface)**_ **tushunchasidir.** Bu mavzu nazariy tushunishni talab qiladi va mazmunan biroz uzunroq bo‘lishi mumkin, shu sababli keyingi bo‘limda bu haqda batafsilroq tushuntirib o‘tamiz. [Previous9.2 Protseduraviy dasturlash 2chevron-left](https://roboticsware.gitbook.io/python-pygame_zero/battle_city/9.2_procedural_dev2) [Next9.4 Obektga yo‘naltirilgan dasturlash nazariyasi (interfeys)chevron-right](https://roboticsware.gitbook.io/python-pygame_zero/battle_city/oop_interface) Last updated 6 days ago --- # 6.1 O‘yin sahnasiga fon va aktyorlarni qo'shish | Python-Pygame Zero Ushbu bo‘limda kod yozishning birinchi bosqichi bo‘lganligi sababli, o‘yinimiz sahnasi bo‘lgan o‘yin ekraniga fon joylashtirib, o‘yin sahnasining aktyorlari bo‘lgan blok to‘plami, blok to‘plamidagi bloklarni yo‘q qiladigan to‘p, va foydalanuvchi tomonidan boshqarilishi kerak bo‘lgan to‘pni aks ettiruvchi plastina (ingliz tilida paddle deb ataladi, lekin biz bar nomini ishlatamiz) ni sahnaga chiqarishni ko‘rib chiqamiz. Biz yaratmoqchi bo‘lgan o‘yinning yakuniy natijasi quyidagicha bo‘ladi. Dastlab natija ekranini ko‘rib chiqsangiz, kodni tushunish ancha osonlashadi. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FKRj1AoANemBLgW6nUWZV%252Fimage.png%3Falt%3Dmedia%26token%3D1f57a45e-785b-4b19-ac76-34474dfd6a48&width=768&dpr=3&quality=100&sign=66c65902&sv=2) Yakuniy o'yin ekrani Copy TITLE = 'Breakout' WIDTH = 800 HEIGHT = 600 GAP_FROM_SCREEN = 50 ball = Actor('ball', (WIDTH / 2, HEIGHT / 2)) bar = Actor('bar', (WIDTH / 2, HEIGHT - GAP_FROM_SCREEN)) # 4-qator*8-ustundan iborat blok to‘plamini yaratish blocks = [] for block_row in range(4): for block_col in range(8): block = Actor( 'block', (block_col * 100, block_row * 32 + GAP_FROM_SCREEN), anchor=('left', 'top') ) blocks.append(block) def draw(): screen.blit('space', (0, 0)) ball.draw() bar.draw() for block in blocks: block.draw() 🔢 21-qatordagi o‘yin fonini chizish qismi bu kitobning birinchi o‘yinini yaratish jarayonida 5.1-bobda to‘liq tushuntirib berilganligi sababli, o‘quvchilar buni yetarlicha yaxshi tushungan deb hisoblab, qo‘shimcha tushuntirishga hojat yo‘q deb o‘ylayman. Ma’lumot uchun, ushbu o‘yinni yaratishda kerakli bo‘ladigan tasvirlarni [ushbu manzilarrow-up-right](https://github.com/roboticsware/python-pygame_zero-samples/tree/main/breakout/images) dan yuklab olish mumkin. Yoki agar siz [maxsus Mu Editorarrow-up-right](https://github.com/roboticsware/mu/releases) dan foydalanayotgan bo‘lsangiz, Mu Editorning ishchi katalogi bo‘lgan (foydalanuvchi nomi)\\mu\_code\\examples\\pygame\_zero\\images papkasidan nusxa olib ishlatishingiz mumkin. Faqat esda tutish kerak bo‘lgan narsa shuki, 5.1-bobda allaqachon ta’kidlanganidek, **biz kod yozayotganda foydalanadigan tasvirlar har doim kod yozilayotgan manba kod fayli joylashgan papka(direktoriya)ning ichki papkasi sifatida mavjud bo‘lishi kerak va bu papkaning nomi images bo‘lishi zarur, shunda u to‘g‘ri tanilib ishlatiladi** degan qoida yana bir bor yodda bo‘lishi kerak. 🔢 6~7-qatorlarda avval, ikkita asosiy aktyor bo‘lgan to‘p (ball) va aks ettiruvchi plastina (bar) uchun aktyor (Actor) obyektlari yaratilgan bo‘lib, bu yerda tasvir nomi va ushbu tasvir o‘yinda joylashadigan koordinata ma’lumoti — shu ikki parametrdan foydalanilgan. Keyin, to‘p tegib sindirishi kerak bo‘lgan bloklar to‘plami deb ataladigan blok obyektlari majmuasi yaratilishi kerak bo‘ladi. Qaraganda bitta butun tuyuladi, lekin aslida to‘p tegib sindirgan har bir blok — bu alohida, mustaqil blok obyektidir. Bunga kirishishdan oldin, yuqorida ko‘rib chiqqan ushbu o‘yinning yakuniy ekranini diqqat bilan kuzatsak, _bloklar to‘plami o‘yin ekranining (screen) yuqori qismidan ma’lum bir masofada pastda joylashganini, va bloklar bir guruh bo‘lib yig‘ilganini hamda aks ettiruvchi plastina ham ekranning eng pastki qismidan biroz yuqoriroqda joylashganini ko‘rish mumkin. Bu masofa biz tomonidan ixtiyoriy belgilanadi va 5-qatorda ushbu ma’noni anglatuvchi o‘zgaruvchiga_ _**GAP\_FROM\_SCREEN**_ _deb nom berilib, unga 50px (piksel) masofa qiymati berilgan._ Endi blok to‘plamining tuzilishini batafsil ko‘rib chiqamiz. Gorizontal bo‘yicha 8ta, vertikal bo‘yicha esa 3 qatordan iborat shaklga ega. 2-qatorida belgilangan o‘yin ekranining gorizontal o‘lchami 800px (piksel) bo‘lganligi sababli, ushbu kenglik ichida 8 ta blokni ketma-ket joylashtirish uchun bir qatorga qo‘yilsa, taxmin qilish mumkinki, bitta blokning gorizontal uzunligi 100px bo‘lishi kerak. Bu taxmin to‘g‘ri va bitta blok obyektining (blok tasviri) o‘lchami gorizontal va vertikal bo‘yicha (100 x 32px) dir. 🔢 Endi ushbu ma’lumotlarga asoslanib kod yozish kerak bo‘ladi. Avvalo _mustaqil alohida blok obyektlarini ketma-ket joylashtirib bitta blok to‘plamini yaratish uchun joy kerak bo‘ladi, bunda aynan ro‘yxat (List) ma’lumot turi mos keladi va shu sababli 10-qatorida_ _**blocks**_ _nomli bo‘sh ro‘yxat yaratildi._ Keyinchalik, ushbu ro‘yxatga har bir yaratilgan mustaqil bloklarni ekranda ko‘rsatiladigan tartibga ketma-ket joylashtirish kerak bo‘ladi. Bu yerda ekranda ko‘rsatiladigan tartib — birinchi navbatda qatorni to‘ldirib, keyin ustunga o‘tish tarzida yoki aksincha ustunni to‘ldirib qatorni oshirish tarzida bo‘lishi mumkin, bu tanlov ixtiyoriy va foydalanuvchiga bog‘liq. Ushbu kitobda esa avval bir qatorni to‘ldirib, so‘ngra keyingi qatorga o‘tish usuli tanlangan bo‘lib, bunday holatda mos keladigan kod tuzilmasi 11~12-qatorlarda ko‘rsatilgan ikkitalik for sikl operatori (nested loop statements) hisoblanadi. Bu for sikli ichida joylashgan for sikli strukturasidir, ichki for sikli bir qator ichida 8 ta blokni to‘ldiradi, tashqi for sikli esa keyingi qatorga o‘tishni ta’minlaydi. Natijada 13~17-qatorlarda yaratilgan har bir mustaqil blok obyekti **blocks** ro‘yxatiga ketma-ket qo‘shiladi (18-qator). _Ro‘yxatga qiymat qo‘shish uchun List obyekti (aslida List ham obyekt ekanligini esda tuting) tomonidan taqdim etilgan_ _**append**_ _nomli funksiyadan foydalanish mumkin._ 🔢 Endi takrorlovchi siklini tushunib olaylik. [Oldingi kitobarrow-up-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic) ni o‘qimaganlar uchun _**for-in range()**_ **sintaksisini yana bir bor tushuntirib o‘tamiz, bu takrorlashda ishlatiladigan sintaksis bo‘lib, biz Entry blokli kodlashda juda ko‘p marta ishlatgan “nechadir marta takrorlash” kod blokiga o‘xshatish mumkin.** _Avvalo, ushbu sintaksisda_ _**for-in**_ _va_ _**range**_ _funksiyalarini alohida ko‘rib chiqish kerak bo‘ladi._ Avvalo, [range funksiyasiarrow-up-right](https://docs.python.org/3/library/functions.html#func-range) bu Python tilining ichki funksiyasi bo‘lib, juda soddalashtirilgan holda (bu kitob yengil versiya ekanligi sababli hozircha shu darajada bilib o‘tish kifoya) quyidagicha ishlaydigan funksiya hisoblanadi. circle-info **range(n) funksiyasi** n parametri: musbat butun son qiymati chiqish qiymati: 0 dan n-1 gacha bo‘lgan ketma-ket butun sonlar to‘plamini qaytaradi. Misol tariqasida **list(range(4))** ni ishga tushiramiz va qanday natija qaytarilishini ko‘ramiz. Copy print(list(range(4))) output: [0, 1, 2, 3] **range** funksiyasining natijasi **range** obyekti bo‘lganligi sababli, uni **list** funksiyasi bilan o‘rab, **list** ko‘rinishiga o‘tkazish orqali biz bu obyektning asl mohiyatini bir qarashda tushunishimiz osonlashadi. Ya’ni, agar argument sifatida 4 ni bersak, u 0 dan boshlanib 3 gacha bo‘lgan ketma-ket butun sonlarni o‘z ichiga oladi deb tushunish mumkin. Endi **for-in** sintaksisini tushunib olaylik. Bu yerda “ketma-ket obyekt” degani — ro‘yxat (list) kabi bir nechta qiymatni o‘zida saqlaydigan ma’lumot turini anglatadi. circle-info **for** (ketma-ket obyekt)ichidagi element qiymati uchun o‘zgaruvchi nomi **in** ketma-ket obyekt: Quyidagi kod namunasi orqali tushunish osonroq bo‘ladi. **for-in** ifodasi ichidagi kod jami 4 marta takrorlanadi va har bir takrorlash davrida ro‘yxat ichidagi qiymat (bu “item” deb ataladi) larni biz belgilagan o‘zgaruvchi nomi orqali birma-bir avtomatik tarzda olib, takrorlash bajariladi. Copy for item in [0, 1, 2, 3]: print(item) # Takrorlashning har bir aylanishida [0, 1, 2, 3] ro‘yxatidagi # element qiymatlari ketma-ket olinadi output: 0 1 2 3 **Yuqoridagi misolda keltirilgan** _**for item in \[0, 1, 2, 3\]**_ **ifodasi aslida** _**for item in range(4)**_ **kodi bilan bir xil deb qaralishi mumkin.** Shu joygacha tushungan bo‘lsangiz, endi 11-qatordagi **for block\_row in range(4):** ifodasini ham tushuna olasiz. U jami 4 marta takrorlanadi va har bir takrorlash davrida **block\_row** o‘zgaruvchi qiymati ketma-ket 0 dan 3 gacha bo‘ladi, shuningdek 12-qatordagi **for block\_col in range(8):** ifodasi esa jami 8 marta takrorlanib, har bir takrorlash davrida **block\_col** o‘zgaruvchisi qiymati 0 dan 7 gacha bo‘lishini kutish mumkin. Aynan mana shu qiymatlardan foydalanib, 15-qatorida **block\_row** va **block\_col** o‘zgaruvchilari orqali Actor obyektini yaratishda ularning joylashuv koordinatalarini hisoblab chiqish mumkin bo‘ladi. 🔢 Blok obyektini yaratishda ishlatiladigan parametrlar orasida ilgari o‘rganilmagan bitta parametr hali qolgan, u esa 16-qatorda berilgan **anchor** parametri hisoblanadi. **anchor — bu biz ilgari Entry blokli kodlashda foydalanib ko‘rgan obyektning markaz nuqtasi bo‘lib, Pygameda bu nuqta anchor deb ataladi.** Entry blokli kodlashda ba’zida shu markaz nuqtani o‘zgartirish zarur bo‘lganidek, matnli kodlashda ham aynan shunday holat yuz berishi mumkin, va hozir aynan shunday holat sodir bo‘lmoqda. Entryda bo‘lganidek, **Actor obyektining standart anchor qiymati rasmning markaziy nuqtasi (center) hisoblanadi.** Biz esa uni pastdagi ko‘rsatilgandek chap yuqori burchakka (**topleft** yoki **lefttop**) ko‘chirmoqchimiz va bu holatda 16-qatorda ko‘rsatilganidek **anchor=('left', 'top')** degan parametr qiymatini berish kifoya qiladi. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252Fm4e7QUS7fgtcH5H4YTEI%252Fimage.png%3Falt%3Dmedia%26token%3D3aa40281-6771-4731-8c29-f63c8e7e0094&width=768&dpr=3&quality=100&sign=4ed69752&sv=2) Nega **anchor**ni ko‘chirish kerak, deb so‘rasangiz — bu blok obyektlar to‘plamini o‘yinning ekranining chap chetiga mahkam yopishtirib, aynan o‘sha joydan boshlab ekran bo‘ylab chizishni istaganimiz uchun. Agar **anchor**ni ko‘chirmay blok obyektlar to‘plamini chizishga harakat qilsak, bu gapning ma’nosini darhol tushunib olasiz, chunki **anchor**ning standart qiymati rasmning markazi bo‘ladi. Shuning uchun, **anchor**ni o‘zgartirmay chizilsa, quyidagi rasmda ko‘rsatilganidek, blokning yarmi kesilgan holda chiziladi. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FsZCIuLdDhEUwEuIwKrxz%252Fimage.png%3Falt%3Dmedia%26token%3D62971b97-637f-4fc7-90c3-483466cbc431&width=768&dpr=3&quality=100&sign=6aa49ce4&sv=2) 🔢 Endi oxirgi bosqichda **draw** funksiyasi ichida bloklar to‘plamini chizish bilan bog‘liq bo‘lgan 24~25-qatorlardagi kodni ko‘rib chiqamiz. Bu yerda biz allaqachon o‘rgangan **for-in** takrorlash operatori ishlatilgan bo‘lib, **blocks** deb nomlangan, mustaqil blok obyektlarini o‘z ichiga olgan ro‘yxatdagi har bir blok obyektini bittalab olib, ekranga chizish amali, ro‘yxat ichidagi barcha obyektlar chiqarilguncha takrorlanayotganini ko‘rish mumkin. Ushbu bobning 1-bo‘limida ilgari o‘rganilmagan bir nechta yangi tushunchalar paydo bo‘lgani sababli, kutganimizdan ko‘ra tushuntirishlar ko‘payib, bo‘lim cho‘zildi. Keyingi 2-bo‘limda esa sahnadagi aktyorlarning harakat algoritmlari bilan bog‘liq qiziqarli jihatlarni o‘rganamiz. [Previous6\. Breakout o‘yinini yaratishchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/breakout) [Next6.2 Aktyorlarning harakatlarini amalga oshirishchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.2_actors_movement) Last updated 7 days ago --- # 10.3 Tarmoqli o‘yinga aylantirish 1 | Python-Pygame Zero Faqat bitta kompyuterda ishlaydigan o‘yin(bunday turdagi o‘yinlarga **standalone** o‘yin deyiladi)ni tarmoqli o‘yinga aylantirish uchun mavjud Pong o‘yinini tashkil etuvchi obyektlar (hisob, reflektor, to‘p) kodiga biroz o‘zgartirish kiritish lozim bo‘ladi. Biz o‘yinni boshidan tarmoqli o‘yin sifatida yaratmoqchi bo‘lmaganimiz sababli, obyektlar dizayni tarmoq uchun yetarli darajada moslashtirilmagan va ushbu bo‘limda aynan shu kamchiliklarni to‘ldiramiz. Avvalo, hisob(Score) obyektidan boshlaymiz. Eslatib o‘tamiz, biz har bir obyektning butun kodini emas, faqat qo‘shilgan yoki o‘zgartirilgan qismlarini alohida ko‘rib chiqamiz. **reinit** deb nomlangan yangi a’zo funksiyasi zarur bo‘ladi, bu funksiyaning maqsadi o‘yinni to‘liq boshlang‘ich holatga qaytarishdir. Bunday holat faqat tarmoqli o‘yinda yuzaga kelishi mumkin. U qachon kerak bo‘lishi mumkin? O‘yin davomida kutilmaganda tarmoqdagi uzilishlar yoki raqibning o‘yinni to‘xtatishi kabi holatlarda zarur bo‘ladi. Copy class Score(): ... def reinit(self): self._b1_score = -1 self._b2_score = -1 ... def update(): global num_peers ... # raqib bilan aloqa uzildi num_peers = len(net.get_peers()) if num_peers < MAX_PEERS: if is_host: score.reinit() ball.reset() else: # Player2 print("The host is disconnected.") exit() # host o'chganda xonani yopish ... Rele serveri usulidagi o‘yinning xususiyati shundan iboratki, ilgari ko‘rib chiqqanimizdek, guruh xonasida **host** muhim rol o‘ynaydi va host o‘yinning umumiy holatini boshqarish orqali o‘yinni davom ettirish vazifasini bajaradi. Agar ushbu host har qanday holatda o‘yin davomida guruh xonasidan chiqib ketsa, albatta o‘yinni davom etishning iloji qolmaydi. Bunday vaziyatni qanday hal qilish mumkinligi borasida turli senariylar ishlab chiqish mumkin, lekin eng oddiy yechim tanish bo‘lgan “xonani portlatish" deb ataluvchi usul bo‘lib, bunda guruh ichidagi barcha mijozlar guruhdan chiqariladi, ya’ni barcha mijozlarning server bilan mavjud tarmoqdagi aloqasi majburan uziladi (19~21-qatorlar). Bunga teskari holatda, agar host bo‘lmagan oddiy foydalanuvchi to‘satdan guruh xonasidan chiqib ketsa, bunday vaziyatni qanday hal qilish kerak? Bu holat aynan **reinit** funksiyasini chaqirish orqali o‘yinni to‘liq boshlang‘ich holatga qaytarish va hostning guruhda yolg‘iz qolib yangi o‘yinchi ulanishini kutadigan boshlang‘ich holatga o‘tish vaziyatidir (16~18-qatorlar). Unda o‘yin davomida qaysi mijoz guruhdan chiqib ketganini qanday aniqlash mumkin? Buning javobi **update** funksiyasining 14-qatorida bo‘lib, unda **NetNode** obyektining **get\_peers** deb nomlangan a’zo funksiyasi mavjud bo‘lib, u hozirgi vaqtda guruh ichida mavjud bo‘lgan mijozlarning id ro‘yxatini qaytaradi va ushbu funksiyani **update** funksiyasi ichiga joylashtirib, bu o‘zgaruvchanlikni real vaqtda kuzatish orqali o‘yin davomida qaysi mijoz guruhdan chiqib ketganini bilish mumkin bo‘ladi. Endi esa har bir mijozning reflektorini boshqarish va harakat bilan shug‘ullanadigan tartiblarni ko‘rib chiqaylik. Copy class Bar(Rect): ... def collide_ball(self, sound_only=False): if self.colliderect(self.ball): if not sound_only: # avval 10 piksel oldinga o'tish if self.ball.vx < 0: # bar1 holatida self.ball.x += 10 else: # bar2 holatida self.ball.x -= 10 self.ball.vx = -self.ball.vx * SPEED_UP # Tezlikning x yo'nalishini teskari o'zgartirish ''' To‘p yuqori tomondan kirib, reflektorning yuqori qismiga urilganda yoki to‘p pastki tomondan kirib, reflektorning pastki qismiga urilganda, kirish yo‘nalishi o‘zgarmay aks etadi ''' if (self.ball.vy > 0 and self.ball.centery < self.centery) or \ (self.ball.vy < 0 and self.ball.centery > self.centery): self.ball.vy = -self.ball.vy * SPEED_UP sounds.bar.play() ... def update(): ... # qaytargich if keyboard.a or keyboard.up: my_bar.up() if keyboard.z or keyboard.down: my_bar.down() net.send_msg(peer_id, 'bar_pos', my_bar.center) for bar in bars: if is_host: bar.collide_ball() else: # Player2 bar.collide_ball(sound_only=True) ... # xabar yuborish net.process_send() Reflektorni boshqarish host yoki oddiy foydalanuvchi bo‘lishidan qat’iy nazar, har ikkisi uchun ham bir xil bo‘lib, foydalanuvchi o‘zi xohlagan usulda klaviaturadagi "**a**" tugmasi yoki "**yuqori ko‘satkich**" tugmasi orqali yuqoriga, hamda "**z**" tugmasi yoki "**pasgi ko‘satkich**" tugmasi orqali pastga harakatlantirishi mumkin (24~27-qatorlar). Eslatib o‘tamiz, **my\_bar** o‘zgaruvchisi qiymati avvalgi bo‘limdagi **connect\_server** funksiyasida ko‘rib chiqqanimizdek, guruhga kirish tartibiga qarab **bar1** yoki **bar2** qiymatlaridan biri oldindan belgilanib qo‘yilganini bilish mumkin. **Shu yerga qadar UI darajasida o‘z ekranida harakatni amalga oshirgach, endi esa raqibga ham o‘z harakatidagi o‘zgarishlarni tarmoq orqali yetkazishi kerakki, shu tarzda har bir foydalanuvchi ekranida o‘zaro harakatlar real vaqtda ko‘rinadi. Ana shu maqsadda ishlatiladigan a’zo funksiyasi esa keyingi 28-qatorida qo‘llanilgan** _send\_msg_ **funksiyasidir.** Bu funksiya 3 ta parametr qiymatiga ega. Birinchisi, bu (axborot)xabarni oluvchining guruh ichidagi **id** qiymatidir, bu yerda **peer\_id** argument sifatida uzatiladi, xuddi avvalgi bo‘limdagi **connect\_server** funksiyasida bu qiymat oldindan belgilanganidek. Ya’ni, host bo‘lgan o‘yin foydalanuvchisi raqib oddiy foydalanuvchiga/oddiy foydalanuvchi hostga xabar yuboradi. Ikkinchi qiymat, bu xabarni oluvchi tomonidan bir nechta xabarlar ichidan ushbu xabarni ajratib olish uchun xizmat qiladigan xabar identifikatori (xuddi id kabi). Uchinchi qiymat esa real xabar mazmuni bo‘lib, bu yerda reflektor obyektining markaz koordinatasi **my\_bar.center** yuboriladi va qabul qiluvchi tomon bu qiymatni UI darajasida ekranga aks ettirib raqib reflektorining harakatini tasvirlaydi. Biroq, **send\_msg** **funksiyasi xabarni darhol raqibga yubormaydi, balki xabarni yuborish buferi(buffer) deb ataluvchi vaqtincha saqlash joyiga joylab qo‘yadi. Xabarlarning haqiqiy yuborilishi esa 38-qatoridagi** _**NetNode**_ **obyektining** _process\_send_ **a’zo funksiyasi orqali amalga oshadi va bu funksiya buferga vaqtincha yig‘ilgan xabarlarni vaqti-vaqti bilan birgalikda yuboradi. Shuning uchun bu funksiyani update funksiyasining oxiriga doim joylashtirish zarurligini unutmang.** Hozirgacha xabar yuborish jarayonini to‘liq tushunib oldik, va agar xabar yuborish bo‘lsa, albatta, ularni qabul qilib qayta ishlash tartibi ham mavjud bo‘ladi. Bu haqda keyingi bo‘limda batafsil ko‘rib chiqamiz. Oxirida reflektorni boshqarish orqali yangi qo‘shilgan qismlarni yana ko‘rib chiqadigan bo‘lsak (31~34-qatorlar), bu yerda o‘yin hosti va oddiy foydalanuvchining qanday ishlashi ajratilganini ko‘ramiz. Host holatida bu yakka(standalone) o‘yindagi holatdan farq qilmaydi, oddiy foydalanuvchi holatida esa **collide\_ball** funksiyasi chaqirilmoqda va ilgari ko‘rmagan yangi argument — **sound\_only** uzatilmoqda. Bu nomidan ma’lum, to‘pning urilishi aniqlanganda to‘g‘ridan-to‘g‘ri aks ettirish emas, balki faqat tovush effektini chiqarish uchun mo‘ljallangan (5-qator). Nega bunday ishlov zarur bo‘ladi? _Chunki tarmoqli o‘yinning xususiyatiga ko‘ra, masofadan turib qatnashayotgan barcha o‘yinchilarning real vaqt rejimidagi sinxronligi (sync) uchun ba’zi jarayonlarni har bir mijoz mustaqil ravishda bajarishi kerak bo‘ladi, boshqa qismlar esa host tomonidan umumiy tarzda bajarilishi lozim bo‘ladi. Shuning uchun bu jihatlarni inobatga olib, rollarni to‘g‘ri taqsimlab kod yozish kerak bo‘ladi. Ammo bunday rol taqsimotini oldindan to‘liq aniqlash har doim ham oson emas, ko‘pincha bu holatlar o‘yinni ishlab chiqish davomida haqiqiy tarmoq muhitida sinovdan o‘tkazish jarayonida aniqlanadi._ Unda keyingi bo‘limda davom etib, o‘yin ishlab chiqishning qolgan qismlari — o‘yinning boshlanishini boshqarish, to‘pning harakatini qayta ishlash hamda yuborilgan xabarlarni qabul qilish va ularni qayta ishlash haqida bilib olamiz. [Previous10.2 Rele serverini ishga tushurish va mijozning ulanishichevron-left](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.2_server_connection) [Next10.4 Tarmoqli o‘yinga aylantirish 2chevron-right](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.4_dev_net_2) Last updated 6 days ago --- # 9.6 Obyektga yo‘naltirilgan dasturlash 3 | Python-Pygame Zero Obyektga yo‘naltirilgan dasturlashda obyektni kim yaratishi muhim ahamiyatga ega bo‘ladi, ba’zida, ayniqsa o‘yin ishlab chiqishda obyektning yo‘q bo‘lish vaqti ham birga ko‘rib chiqilishi kerak bo‘ladi, bu holatga misol sifatida o‘q obyektini keltirish mumkin. O‘q obyektini tank (asosiy qahramon tank yoki dushman tank) yaratishi tabiiy hol bo‘lib, qahramon tank foydalanuvchi tomonidan boshqariladi, ya’ni o‘q faqat foydalanuvchi bo‘sh joy(spacebar) tugmasini bosganda yaratiladi, dushman tank esa kompyuter tomonidan avtomatik ravishda tasodifiy o‘q otadi. Bunga qo‘shimcha ravishda, _o‘qning yo‘q bo‘lish holati 3 xil vaziyatda yuz berishi mumkin: birinchisi, o‘q uchib borayotganida devorga urilishi; ikkinchisi, dushman tank bilan to‘qnashuvi; uchinchisi, hech narsaga urilmasdan ekran tashqarisiga chiqib ketishi._ Avvalo, mavjud o‘q obyektida o‘qning uchish funksiyasi mavjud emas, shuning uchun **move** nomli metod qo‘shiladi, bu metodda o‘qning qaysi yo‘nalishda uchishini **angle** xususiyati belgilab beradi. Tank obyekti foydalanuvchiga o‘q otish xizmatini ko‘rsatishi kerak va bu uchun **fire** nomli metod yaratiladi. O‘q obyektining yaratilish vaqti aynan shu metod chaqirilgan payt deb hisoblanadi. actors.py Copy class Bullet(Actor, CheckOutOfScreen): def __init__(self, img_name, pos, angle, screen): Actor.__init__(self, img_name, pos) CheckOutOfScreen.__init__(self, screen) self.angle = angle def is_out_of_screen(self): if self.x > self.s_width or self.x < 0 or \ self.y > self.s_height or self.y < 0: return True else: return False def move(self): if self.angle == 0: self.x += 5 elif self.angle == 90: self.y -= 5 elif self.angle == 180: self.x -= 5 elif self.angle == 270: self.y += 5 # ekran chegaralarini tekshirish if self.is_out_of_screen(): self.pos = self._original_pos # devor bloklarini tekshirish if self.collidelist(self._walls) != -1: self.pos = self._original_pos class Tank(Actor, CheckOutOfScreen): def __init__(self, img_name, pos, angle, walls, screen): Actor.__init__(self, img_name, pos) CheckOutOfScreen.__init__(self, screen) self._original_pos = 0 self.angle = angle self._walls = walls self._bullets = [] def is_out_of_screen(self): if self.right > self.s_width or self.left < 0 or \ self.bottom > self.s_height or self.top < 0: return True else: return False def move(self): self._original_pos = self.pos if self.angle == 180: self.x -= 2 elif self.angle == 0: self.x += 2 elif self.angle == 90: self.y -= 2 elif self.angle == 270: self.y += 2 # ekran chegaralarini tekshirish if self.is_out_of_screen(): self.pos = self._original_pos # devor bloklarini tekshirish if self.collidelist(self._walls) != -1: self.pos = self._original_pos def fire(self, image, sound_obj=None): bullet = Bullet(image, self.pos, self.angle, (self.s_width, self.s_height)) self._bullets.append(bullet) if sound_obj: sound_obj.play() def draw(self): super().draw() for bullet in self._bullets: bullet.draw() 🔢 52-qatorda o‘q obyektini yaratarkanmiz, o‘q obyektining birinchi joylashuvi tankning markazida bo‘lishi kerakligi sababli **self.pos** koordinata qiymatini parametr sifatida uzatganimizni eslab qo‘yaylik. Shuningdek, ekran chegaralari uchun **tuple** qiymati (**self.s\_width, self.s\_height**) avvalgi bobda **CheckOutOfScreen** ota obyektining (interfeys) boshlang‘ich sozlanishi paytida allaqachon belgilab qo‘yilgani uchun, ota obyektga tegishli ushbu xususiyatni farzand obyekt xuddi o‘z xususiyatidek ishlata oladi. battle\_city\_oop.py Copy # qahramon tank o'q otishini kechiktirish bullet_delay_cnt = 0 BULLET_DELAY = 50 def update(): global enemy_move_cnt, bullet_delay_cnt # tank qahramoni if keyboard.left: tank.angle = 180 tank.move() elif keyboard.right: tank.angle = 0 tank.move() elif keyboard.up: tank.angle = 90 tank.move() elif keyboard.down: tank.angle = 270 tank.move() if bullet_delay_cnt == 0: # o'q otish mumkin if keyboard.space: tank.fire("bulletblue2", sounds.sfx_exp_medium12) bullet_delay_cnt = BULLET_DELAY else: bullet_delay_cnt -= 1 # dushman tanklari for enemy in enemies: choice = random.randint(0, 3) if enemy_move_cnt > 0: enemy_move_cnt -= 1 enemy.move() elif choice == 0: # harakatni kechiktirish vaqtini boshlash??? enemy_move_cnt = ENEMY_MOVE_DELAY elif choice == 1: # tasodifiy yo'nalishni aniqlash enemy.angle = random.randint(0, 3) * 90 else: enemy.fire("bulletred2") 🔢 **battle\_city\_oop.py** kodi ichidagi **update** funksiyasida bosh qahramon tankining o‘q qayta yuklash tezligini sekinlashtirish uchun yozilgan kod bo‘limi protseduraviy yondashuvdagi algoritm bilan bir xil bo‘lib, tushunishda katta qiyinchilik tug‘dirmaydi. Protseduraviy usulda o‘q otish tovushi to‘g‘ridan-to‘g‘ri ijro etilgan bo‘lsa, obyektga yo‘naltirilgan yondashuvda esa tovush ijrosini ham obyektga topshirilmoqda. Hozirgacha yozilgan kodni ishga tushirib ko‘rsak, dushman tanklari avtomatik tarzda o‘q otishni boshlaydi va bosh qahramon tanki ham bo‘sh joy tugmasi bosilgan paytda o‘q otish ovozi bilan birga o‘q yaratilishi to‘g‘ri ishlashini ko‘ramiz. Biroq yaratilgan o‘q harakatlanmaydi, ya’ni ucha olmaydi, sababi biz hali o‘qning haqiqiy harakatlanishini ta’minlovchi va to‘qnashuvni tekshiruvchi kod qismini qo‘shmadik. Endi esa shu qismni ham kodga qo‘shib chiqamiz. actors.py Copy class Tank(Actor, CheckOutOfScreen): ... qisqartirildi def collidelist_bullets(self, tanks):battle_city_oop.py tank_index = -1 for bullet in self.bullets: bullet.move() # ekran chegaralarini tekshirish if bullet.is_out_of_screen(): self.bullets.remove(bullet) # devorga urilish holatini qayta ishlash wall_index = bullet.collidelist(self.walls) if wall_index != -1: del self.walls[wall_index] self.bullets.remove(bullet) # dushman tankini tekshirish tank_index = bullet.collidelist(tanks) if tank_index != -1: self.bullets.remove(bullet) return tank_index battle\_city\_oop.py Copy def update(): global enemy_move_cnt, bullet_delay_cnt # tank qahramoni ... qisqartirildi enemy_idx = tank.collidelist_bullets(enemies) if enemy_idx != -1: del enemies[enemy_idx] if len(enemies) == 0: winner = "You" # dushman tanklari for enemy in enemies: ... qisqartirildi tank_idx = enemy.collidelist_bullets([tank]) if tank_idx != -1: winner = "Enemy" 🔢 Biz tankning ota obyekti ichida **collidelist\_bullets** nomli a’zo funksiyasini amalga oshirdik. Bu funksiyaning vazifasi, agar o‘q bo‘lsa, o‘qning harakatini yaratish (8-qator), va o‘q uchayotganda devorlar to‘plamiga yoki dushman tankiga to‘qnashsa yoki hech qanday to‘qnashuvsiz ekran tashqarisiga chiqib ketsa, o‘q obyektini olib tashlashdir (12, 18, 23-qatorlar). Va qaytish qiymati sifatida tankga o‘q tegganmi yoki yo‘qmi degan holat muhim bo‘lgani sababli, unga mos natija qaytariladi. Aksincha, **battle\_city\_oop.py** ichidagi **update** funksiyasi ichida esa bu a’zo funksiyasi takroran chaqiriladi, va funksiyaning qaytgan qiymati orqali o‘q nishonga tekkan-tekmaganini aniqlab, masalan, dushman tankiga o‘q tegsa, urilgan tankni olib tashlash kabi (9-qator) natijalarni o‘yinga aks ettiruvchi kodlar qo‘shiladi. Bu yerda **winner** degan o‘zgaruvchi protseduraviy yondashuvda ham ishlatilgan bo‘lib, o‘yinda g‘olibni aniqlash maqsadida ishlatiladi va **winner** o‘zgaruvchisida saqlangan qiymatga qarab, o‘yinning yakuniy natijasi ekranning markazida katta matn shaklida aks ettiriladi. Nihoyat, o‘yinimizning deyarli barcha qismini yakunladik va oxirgi qolgan qism — bu o‘q tekkan tankning portlash animatsiyasini qo‘shishdir. Qolgan qismini va yakuniy to‘liq bajarilishini keyingi bo‘limga qoldirib davom etamiz. [Previous9.5 Obyektga yo‘naltirilgan dasturlash 2chevron-left](https://roboticsware.gitbook.io/python-pygame_zero/battle_city/9.5_oop_dev2) [Next9.7 Obyektga yo‘naltirilgan dasturlash 4chevron-right](https://roboticsware.gitbook.io/python-pygame_zero/battle_city/9.7_oop_dev4) Last updated 6 days ago --- # 8.7 (Bonus) Pygame Zero misoli versiyasi 1 | Python-Pygame Zero [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/pong/8.7_bonus_dev1#oyinning-dizayn-tuzilishini-tushunish) O‘yinning dizayn tuzilishini tushunish ------------------------------------------------------------------------------------------------------------------------------------------------------------------- Ushbu bonus bo‘limda ham Pong o‘yini ko‘rib chiqiladi, [biroq bu safar Pygame Zero kutubxonasining muallifi tomonidan to‘g‘ridan-to‘g‘ri yaratilgan va kutubxona foydalanishiga misol sifatida birga tarqatilgan kodarrow-up-right](https://github.com/lordmauve/pgzero/tree/main/examples/pong) dan foydalanamiz. Bu kodni misol qilib olib, birgalikda tahlil qilib chiqamiz va obyektga yo‘naltirilgan kodni bu tarzda ham yozish mumkin ekan degan yondashuvni o‘rganish tarzida davom etamiz. Ma’lumot uchun, ushbu misol kodi ushbu bob boshida ko‘rib o‘tilgan video namoyishdagi haqiqiy o‘yin qurilmasida bo‘lgani kabi ikki foydalanuvchi qarama-qarshi o‘ynaydigan ikki kishilik o‘yin emas, balki kompyuter virtual raqib bo‘lib ishtirok etadigan bitta o‘yinchilik o‘yinni yaratishga qaratilgan. Ma’lumot uchun, avval ham tilga olinganidek, odatda barcha manba kodlarini faqat bitta faylda yozish usuli ma’qul ko‘rilmaydi, ammo taxmin qilish mumkinki, muallif aynan shunday maqsadda (minimal soddalashtirilgan kod orqali o‘rganish) barcha manba kodlarini **pong.py** deb nomlangan bitta faylga yozganini eslab qolaylik. Bundan tashqari, o‘yinni yanada soddalashtirish maqsadida hattoki tovush effektlari ham chiqarib tashlangan bo‘lib, o‘yinda hech qanday qo‘shimcha media ishlatilmagan va grafik elementlar ham faqat kod orqali amalga oshirilgan. Quyidagi ekranda biz yaratadigan o‘yinning yakuniy natijasini avval ko‘rib chiqsak, keyinchalik kodni tushunish ancha osonlashadi. Endi esa, haqiqiy kodni birma-bir ko‘rib chiqamiz. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FsUMQUgOLtnz6h2CQzfEQ%252Fimage.png%3Falt%3Dmedia%26token%3D7344b48a-145b-44d1-990e-62f02753106f&width=768&dpr=3&quality=100&sign=2d14c4a5&sv=2) Umumiy tuzilmani tezda tushunib olish uchun, o‘yinning asosiy qismlarini, **draw**, **update** funksiyalari va boshqalarni, avval ko‘rib chiqamiz. Copy # computer-controlled opponent or another player controlling a second # paddle on the opposing side. Players use the paddles to hit a ball # back and forth. The aim is for each player to reach eleven points # before the opponent; points are earned when one fails to return # the ball to the other. import pgzrun import random WIDTH = 800 HEIGHT = 600 TITLE = 'pong' # a color used to draw things MAIN_COLOR = 'yellow' # width and height of a player paddle PADDLE_WIDTH = 15 PADDLE_HEIGHT = 100 # radius of the tennis ball TENNIS_BALL_RADIUS = 10 LEFT_PLAYER = "left" RIGHT_PLAYER = "right" player = LEFT_PLAYER # first player is chosen game = Game(player) def draw(): game.draw() def update(): if keyboard.up: game.right_paddle.up() elif keyboard.down: game.right_paddle.down() # move the computer controlled paddle game.computer_act() # set the position of the ball to be in the middle of the paddle if not game.in_progress: game.position_ball() if game.in_progress: game.proceed() def on_key_down(key): # pressing SPACE launches the ball if key == keys.SPACE: if game.score_left == 11 or game.score_right == 11: game.score_left = game.score_right = 0 if not game.in_progress and game.active_player == RIGHT_PLAYER: game.in_progress = True Ushbu o‘yin muallifi tomonidan yozilgan kodning eng katta farqi shundaki, dastlabki ikki qatorda **Game** deb nomlangan butun o‘yinni boshqaruvchi super obyekt mavjud bo‘lib, oxir-oqibatda butun o‘yin aynan shu asosiy obyekt orqali qurilgan va u tarkibiy qismlar bo‘lgan alohida obyektlar (to‘p, raketka(biz ilgari reflektor deb ataganmiz))ni boshqarish usulini qabul qilgan. Sizlar bu kabi obyektga yo‘naltirilgan kodlashda o‘yin yaratish uslubini yana bir mumkin bo‘lgan texnika sifatida tushunib olsangiz yaxshi bo‘ladi. Bundan tashqari, ushbu o‘yin muallifi hisob uchun alohida obyekt yaratmagan — bu ham farqli jihat hisoblanadi. O‘yin asosiy qismi (**draw**, **update** funksiyalari va boshqalar) **Game** obyekti ichidagi a’zo o‘zgaruvchilar va funksiyalarni boshqarish orqali maksimal darajada soddalashtirilganligi sababli, kodni tushunishda katta qiyinchilik yo‘q. Chap tomondagi raketka kompyuter tomonidan avtomatik boshqariladi, o‘ng tomondagi raketka esa foydalanuvchi tomonidan boshqariladi. Bu yerda to‘p obyekti avtomatik ravishda markaziy chiziqdan chap-o‘ngga otish tarzida ishlamaydi, balki stol tennisi o‘yiniga o‘xshab har bir foydalanuvchi o‘ziga tegishli to‘pni raqib tomon otish (launch) uchun space tugmasini bosishi kerak bo‘ladi. Yakuniy o‘yin natijasi ikki tomondan biri 11 ballga erishganida aniqlanadi. Endi esa keyingi bo‘limdan boshlab o‘yin obyektini tashkil qiluvchi 3 ta alohida obyekt (to‘p, raketka, o‘yin(Game)) ichki tuzilmasini birma-bir ko‘rib chiqamiz. [Previous8.6 Obyektga yo‘naltirilgan dasturlash 2chevron-left](https://roboticsware.gitbook.io/python-pygame_zero/pong/8.6_oop_dev2) [Next8.8 (Bonus) Pygame Zero misoli versiyasi 2chevron-right](https://roboticsware.gitbook.io/python-pygame_zero/pong/8.8_bonus_dev2) Last updated 6 days ago --- # 5.3 Flappy Bird(obyekt)ning ekrandagi tabiiy harakatini yaratish | Python-Pygame Zero Ko‘zimizga flappy birdning harakati tabiiy ko‘rinmaganining sababi — bu harakatni tabiatda mavjud bo‘lgan haqiqiy fizik qonunlar, ya’ni tortishish kuchiga o‘xshatib tuzmaganimizdir, deb aytishimiz mumkin. Shuning uchun endi harakatni haqiqiy tortish kuchiga o‘xshash tarzda amalga oshirib ko‘raylik. Bizga ma’lum bo‘lgan umumiy tushunchaga ko‘ra, tortish kuchi — bu doimiy va o‘zgarmas kuch bo‘lib, u ta’sir qilganda jismlar tushayotganda doimiy tezlikda emas, balki **tezlanish** bilan, ya’ni tobora tezroq qulaydi. Shuning uchun biz ham bu ikki elementni (tortishish kuchi va tushish tezligini) ikkita alohida o‘zgaruvchi orqali ajratib ko‘rsatamiz. Copy TITLE = 'Flappy Bird' WIDTH = 400 HEIGHT = 708 GRAVITY = 0.3 drop_speed = 0 flappy_bird = Actor('bird1', (75, 350)) def draw(): screen.blit('background', (0, 0)) flappy_bird.draw() def update(): global drop_speed drop_speed += GRAVITY flappy_bird.y += drop_speed def on_mouse_down(): global drop_speed drop_speed = -6.5 🔢 Yuqorida tilga olinganidek, tabiiy ko‘rinadigan harakatni amalga oshirish uchun qo‘shimcha bir nechta o‘zgaruvchilarni kiritish zarur. Flappy Bird o‘yinidagi qushning tabiiy tushishini ta’minlovchi pastga tortuvchi kuch – ya’ni gravitatsiya – o‘zgarmaydigan, doimiy kuch bo‘lib, bu kuch 5-chi qatorda **GRAVITY** degan o‘zgaruvchi nomi bilan ifodalanib, uning qiymati **0.3** deb belgilangan. _Bu yerda e’tibor qilish kerak bo‘lgan jihat – gravitatsiya kuchining qiymati ataylab o‘zgaruvchiga joylashtirilgan. Bunday qilishdan maqsad – bu qiymatni keyinchalik o‘zgaruvchi nomi orqali chaqirishdir. Bunday texnik yondashuvni qo‘llashning ikki asosiy maqsadi mavjud._ Birinchidan, agar tortish kuchi qiymatini o‘zgaruvchi nomi bilan emas, balki bevosita son qiymati orqali ishlatganimizda, hozircha bu muammo tug‘dirmasligi mumkin, ammo vaqt o‘tib, bu kodni o‘zimiz yoki boshqa hamkasblarimiz o‘qiganda, kodning o‘qilishi (anglashiluvchanligi) pasayadi. Kodni tushunish uchun qatorlarni birma-bir ko‘zdan kechirayotgan paytda, to‘satdan paydo bo‘lgan son (masalan, 0.3) ko‘zga tashlanadi va bu son aslida nimani bildirayotganini bir muddat o‘ylab ko‘rishga to‘g‘ri keladi. Aynan shunday nuqtalar — kodni uzluksiz va tez o‘qib chiqishga xalaqit beradi va shu orqali kodning o‘qilish qulayligini pasaytiradi. Biroq, agar biz bu son qiymatini tortish kuchi (GRAVITY) degan o‘zgaruvchi bilan bog‘lab qo‘ygan bo‘lsak, unda biz faqat o‘zgaruvchi nomiga qarab ([avvalgi boblarda aytib o‘tilgan — o‘zgaruvchilarga ma’noli nom berish juda muhim!arrow-up-right](https://roboticsware.gitbook.io/entry-python/boshlash/uzgaruvchi) ) bu sonning ma’nosini darhol anglab yetishimiz mumkin bo‘ladi. **Shuningdek, o‘zgaruvchi nomini ataylab katta harflar bilan yozganimiz ham alohida jihatdir. Albatta, o‘zgaruvchi degani o‘zgaruvchan qiymatni saqlash uchun ishlatiladi, lekin bu holatda u o‘zgaruvchan qiymatni saqlashdan ko‘ra, ma’lum bir qat’iy qiymatni ifodalash uchun ishlatilmoqda, shuning uchun unga maxsus ma’no berish uchun katta harflar bilan yozildi. Ma’lumot uchun, bu dasturchilar orasida qabul qilingan kodlash odatlaridan (**[**Coding conventions**arrow-up-right](https://en.wikipedia.org/wiki/Coding_conventions) **) biri bo‘lib, uni faol qo‘llash foydali bo‘ladi.** Ikkinchidan, bunday yondashuvning yana qanday afzalligi bo‘lishi mumkin? Keyinchalik qandaydir sabablarga ko‘ra ([avvalgi kitobarrow-up-right](https://roboticsware.gitbook.io/entry-python/boshlash/hello_world) da aytib o‘tilgandek, dasturiy ta’minot xususiyatiga ko‘ra kodda o‘zgarishlar kutilgandan ko‘ra ko‘ptoq sodir bo‘ladi) o‘yinimizga yangi talablar qo‘yilib, o‘yin murakkablik darajasini oshirish maqsadida kuchliroq tortish kuchi kerak bo‘ldi, deylik. Va biz bunga mos ravishda butun kod bo‘ylab tortish kuchi soniga o‘zgartirish kiritishimiz kerak bo‘ladi. Lekin biz bunday ehtimolga oldindan aqlli tarzda tayyor bo‘lib, bu qiymatni o‘zgaruvchi nomi orqali yozib qo‘ygan edik, shunday emasmi? Demak, bu qiymat(GRAVITY)ning joriy qiymati 0.3 ni, masalan 0.5 ga o‘zgartirish bilan, kodni tezda va oson yangilash imkoniyatiga ega bo‘lamiz. 🔢 6-qatorga kiritilgan **drop\_speed** o‘zgaruvchisi — nomidan ham ko‘rinib turibdiki, **qiymati doimiy o‘zgarib boradigan o‘zgaruvchi bo‘lib, aynan shu maqsadda ishlatiladi. Shuning uchun bu o‘zgaruvchining nomi ataylab kichik harflar bilan yozilganini eslab qolaylik. Katta va kichik harf orqali yozilgan nomlar orqali ularning vazifasini osongina ajratish mumkin bo‘ladi.** drop\_speed nomidan ham ko‘rinib turibdiki, qulashni yuzaga keltiradigan kuch — ya’ni tortish kuchi (gravitatsiya) doimiy bo‘lsada, haqiqiy qulash vaqtida tezlik vaqt o‘tishi bilan ortadi, ya’ni tezlanadi. Ushbu o‘zgaruvchi aynan shu tezlanayotgan harakatni ifodalash uchun ishlatiladi. Endi biz bu o‘zgaruvchining maqsadi va vazifasini tushundik. Xo‘sh, endi esa _bu o‘zgaruvchi butun kod bo‘yicha qayerda aniqlangani (definition) masalasiga e’tibor qaratamiz. Nega u funksiyaning ichi(scope)da emas, tashqarisida aniqlangan?_ **Buni tushunish uchun o‘zgaruvchi yaratish qoidalarini bilish kerak: agar biror o‘zgaruvchi faqat bitta funksiya ichida ishlatilsa, uni funksiyaning ichida aniqlaymiz. Ammo, agar o‘zgaruvchi bir nechta funksiyada umumiy foydalaniladigan bo‘lsa, u holda uni funksiyalar tashqarisida aniqlash kerak bo‘ladi — xuddi bu yerda bo‘lgani kabi.** Xuddi shu tarzda, **drop\_speed** qiymati **update** funksiyasi va **on\_mouse\_down** funksiyasi — ya’ni ikkita joyda birgalikda ishlatilayotganini ko‘rish mumkin. Aynan shu sabab tufayli bu o‘zgaruvchi funksiyalar tashqarisida aniqlangan. Agar bu o‘zgaruvchidan foydalanilayotgan funksiyalar ichidagi ishlatilishiga diqqat bilan qarasak, **u funksiyalardan tashqarida joylashgan bo‘lsa ham, ichkarida uning qiymatini o‘zgartirish kerak bo‘lsa, Python sintaksisiga ko‘ra o‘zgaruvchi nomi oldiga** _**global**_ **degan kalit so‘z(keyword)ni yozib, funksiyaning kirish qismida bu o‘zgaruvchini e’lon qilish talab qilinishini ko‘rish mumkin. To‘g‘ri, Python sintaksisida funksiyadan tashqarida mavjud bo‘lgan o‘zgaruvchidan foydalanayotganimizni aniq bildirish uchun, o‘zgaruvchi nomi oldiga** _**global**_ **(ya’ni, butun kod bo‘yicha foydalanilishi mumkin bo‘lgan o‘zgaruvchi degan ma’noda) deb yozishimiz kerakligini eslab qolaylik. Shuningdek, bunday o‘zgaruvchilarni ifodalovchi atama ham mavjud bo‘lib, ular “global o‘zgaruvchilar” deb ataladi — buni ham yodda saqlaylik.** circle-info _Aytgancha, bu yerda ehtiyot bo‘lish kerak —_ _**Python dasturlash tilining qat’iy sintaksisga unchalik bog‘liq bo‘lmagan moslashuvchanligi ba’zan afzallik bo‘lsada**__, ba’zida esa kamchilikka ham aylanadi. Ba’zida_ _**global**_ _degan kalit so‘zni aniq yozmasak ham, dastur hech qanday xato (error) chiqarmay to‘g‘ri ishlayotgandek tuyuladi. Bunday holatlarda esa, dastur xohlaganimizdek ishlamayotganining mantiqiy xatosini aniqlash juda qiyin bo‘lishi mumkin. Shu sababli, ehtiyotkorlik bilan yondashish lozim._ 🔢 _21-qatorda_ foydalanuvchi sichqoncha tugmasini bosib flappy birdni havoga ko‘tarishga harakat qilganda, qulash tezligini ataylab manfiy qiymatga qaytarish orqali flappy birdning yuqoriga ko‘tarilish effektini hosil qilmoqdamiz. Hozirgacha flappy birdning tabiiy harakatini hosil qilish uchun qo‘llangan texnikalar haqida ko‘rib chiqdik va bu orqali yangi narsalarni (masalan, Python sintaksisi, kodlash odatlari va hokazo) o‘rgandik. Endi keyingi bobda o‘yin sahnamizdagi ikkinchi Actor(aktyor) — quvur obyektlarini yaratish va ularni sahnaga chiqarishni ko‘rib chiqamiz. [Previous5.2 Flappy Bird(obyekt)ni ekranga chiqarish va harakatlantirishchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.2_flying) [Next5.4 Quvur(obyekt)ni ekranga chiqarish va harakatlantirishchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.4_pipes) Last updated 7 days ago sun-brightdesktopmoon sun-brightdesktopmoon --- # 6. Breakout o‘yinini yaratish | Python-Pygame Zero Blok sindirish o‘yini — bu deyarli hamma biladigan darajada mashhur bo‘lgan, 1972-yilda tashkil etilgan dunyodagi birinchi video o‘yin kompaniyasi Atari tomonidan 1976-yilda ishlab chiqilgan juda klassik o‘yindir. Vaqt o‘tishi bilan turli xil o‘zgartirilgan versiyalari chiqarilgan bo‘lsada, biz klassik blok sindirish o‘yini (g‘isht sindirish o‘yini deb ham atalgan, ingliz tilidagi asl nomi esa [_Breakout_arrow-up-right](https://en.wikipedia.org/wiki/Breakout_(video_game)) ) birinchi versiyasining asosiy o‘yin qoidalariga amal qilishni maqsad qilamiz. Ya’ni, biz o‘yinning klonini yaratamiz, bu yerda maqsad barcha bloklarni (yoki g‘ishtlarni) sindirish (buzish) va to‘pni, o‘yin oynasi pastki qismidan tashqari, o‘yin oynasida to‘qnashadigan hamma narsalardan doimiy ravishda aks ettirish. Blok sindirish (g‘isht sindirish) o‘yinini yaratishning 2 xil asosiy usuli mavjud. Siz o‘yindagi aktyorlar(bloklar, to‘p, aks ettiruvchi plastina(reflektor))ni butunlay kod bilan chizib yasash yoki avvalgidek tayyor tasvirlardan foydalanib yaratishingiz mumkin. Birinchisi aslida ushbu o‘yinning original versiyasida qo‘llanilgan usul bo‘lib, ikkinchisini esa hozirgi davrga mos grafikani ta’kidlaydigan o‘yin deyish mumkin. Shunday qilib, agar ikkita o‘yin ishlab chiqarish usulidan qaysi biri kamroq kodlashni talab qilishini va tushunish osonroq ekanligini ko‘rib chiqsak, ikkinchisi yaxshiroqdir. Ammo agar biz yakka dasturchi bo‘lib, o‘yinga kerakli tasvirlarni o‘zimiz grafik tahrirlash vositalari yordamida yaratishimiz kerak bo‘lsa, kod yozilishi kamaygan taqdirda ham, bu ishda vaqt va kuch ko‘p ketishi mumkinligi sababli, umumiy jihatdan dasturchi nuqtai nazaridan qaysi biri qulayroq degan savolning javobi boshqacha bo‘lishi mumkin. 6-bobda biz quyidagicha ish tutamiz. Avval osonroq usul bo‘lgan tayyor tasvirlardan foydalangan holda o‘yinni yaratamiz, so‘ngra qo‘shimcha variant sifatida hech qanday tasvirdan foydalanmay, o‘yindagi barcha elementlarni to‘liq kod yordamida chizib, original o‘yin klonini (clone) qo‘shimcha ravishda yaratib ko‘ramiz. [Previous5.8 Flappy Bird o‘yini uchun qo‘shimcha funksiyalar (Flappy Bird animatsiyasi)chevron-left](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.8_animation) [Next6.1 O‘yin sahnasiga fon va aktyorlarni qo'shishchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.1_bg_actors) Last updated 6 months ago sun-brightdesktopmoon sun-brightdesktopmoon --- # 9.4 Obektga yo‘naltirilgan dasturlash nazariyasi (interfeys) | Python-Pygame Zero Biz o‘tgan safar obyektga yo‘naltirilgan dasturlash nazariyasida **meros olish** tushunchasini o‘rgangan edik. Ushbu bo‘limda esa, tushuncha jihatidan meros olishning bir ko‘rinishi bo‘lsada, maqsadi biroz boshqacha bo‘lgan **interfeys**(Interface) tushunchasini o‘rganishimiz zarur. Meros olish juda foydali tushuncha bo‘lishiga qaramay, barcha muammolarni faqat meros olish orqali hal etib bo‘lmaydigan cheklovlarga ega, va bu holatni quyidagi misol orqali tushunish mumkin. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FvHF1db1nzCxNYezKyovW%252Fimage.png%3Falt%3Dmedia%26token%3Daaf8612d-db8d-40c2-86f1-f648826e563b&width=768&dpr=3&quality=100&sign=9c76ad4&sv=2) Rasmda ko‘rsatilgandek, biz yashayotgan ekotizimda masalan, pingvinlar qush bo‘lsada ucha olmaydi, uchishi mumkin bo‘lsada qushlar guruhiga kirmaydigan ko‘rshapalaklar mavjud, yoki sut emizuvchi bo‘lsada yerda yurmay, baliq kabi suzib yuradigan kit kabi bir nechta toifaga kiruvchi gibrid tirik mavjudotlar ham uchraydi. Xuddi shunday, ayrim obyektlargina muayyan funksiyaga ega bo‘lishi mumkin, masalan, suza olish (Swimmable) yoki ucha olish (Flyable) funksiyasi. Agar bu funksiyalar yuqori darajadagi ota obyektlar (Bird, Mammal, Fish) ichida amalga oshirilsa, ular aslida bu funksiyaga ehtiyoji bo‘lmagan barcha farzand obyektlarda ham mavjud bo‘lib qoladi va natijada barcha farzand obyektlarning hajmi bir xil kattalashib, keraksiz xotira egallashiga olib keladi. Shu sababli, bunday funksiyalar uchun mustaqil **abstrakt obyekt** yaratiladi va ushbu funksiya kerak bo‘lgan har bir obyekt ushbu abstrakt obyektni meros qilib, uni bevosita amalga oshirishga majbur qilinadi. Mana shu turdagi abstrakt obyektlar **interfeys** deb ataladi. Bu yerda _“abstrakt” so‘zining ma’nosi “aniq” (concrete) tushunchasiga qarama-qarshi bo‘lib, ya’ni, bu obyekt ichida aniq implementatsiya mavjud emas, deganidir. Shuning uchun,_ _**interfeys bu faqat metodning sarlavhasi(ya’ni, nomi, argumentlari, qaytarib berish turi)ni aniqlab(define) beruvchi, lekin ularning qanday ishlashini o‘z ichiga olmaydigan abstrakt tur(type) hisoblanadi.**_ _Obyekt bir yoki undan ortiq interfeysdan meros olishi mumkin, va ushbu interfeysdan meros olgan har qanday klass interfeysda aniqlangan barcha metodlarni_ _**majburiy**_ _tarzda implementatsiya qilishi kerak (aks holda dastur ishga tushayotganda xatolik yuz beradi). Bu “majburiy implementatsiya” deganidir._ Yuqoridagi rasmdagi holatlarning bir qismini, interfeysni hisobga olgan holda, kod ko‘rinishida quyidagicha ifodalash mumkin bo‘ladi. Copy from abc import ABC, abstractmethod class Animal(ABC): @abstractmethod def has_organ(self): pass class Bird(Animal, ABC): def has_organ(self): print("I have wings") @abstractmethod def has_feather(self): pass class Flyable(ABC): @abstractmethod def fly(self): pass class Eagle(Bird, Flyable): def has_feather(self): print("I have 718 feathers.") def fly(self): print("I can fly.") class Penguin(Bird): def has_feather(self): print("I have short and waterproof feathers.") Eslatma sifatida, bu kodlar tushuntirish uchun yozilgan **misol** kodlar bo‘lib, soddalashtirilgan holda ko‘rsatish maqsadida \_\_init\_\_ funksiyalari ataylab chiqarib tashlanganini inobatga olishingizni so‘rayman. Copy # foydalanish misoli eagle = Eagle() eagle.has_organ() eagle.fly() eagle.has_feather() penguin = Penguin() penguin.has_feather() bajarish natijasi: I have wings I can fly. I have 718 feathers. I have short and waterproof feathers. [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/battle_city/oop_interface#abstrakt-obyektni-aniqlash-define-grammatikasi) Abstrakt obyektni aniqlash(define) grammatikasi ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- > from abc import ABC, abstractmethod > > **class** abstrakt klass nomi(ABC): > > _**def**_ _\_\_init\_\_(self, parametrlar):_ > > xususiyatlar > > **@abstractmethod** > > **def** abstrakt metod nomi(self): > > pass Abstrakt obyektlarni yaratish sintaksisi birinchi marta uchrayotgani sababli, diqqat bilan ko‘rib chiqamiz. Avvalo, **abc** nomli ichki modulni import qilamiz va **ABC** ([Abstract Base Classarrow-up-right](https://docs.python.org/3.13/library/abc.html) ) deb ataladigan abstrakt klassni yaratish uchun bazaviy klassdan meros olamiz. So‘ng, abstrakt klass ichida bo‘ladigan abstrakt metod ustiga **@abstractmethod** deb nomlangan dekorator(decorator) qo‘yib metodni e’lon qilamiz. _Abstrakt bo‘lgani uchun, tabiiyki, bu funksiyada batafsil amalga oshirish bo‘lmaydi, shunchaki hech nima bajarmaydigan_ _**pass**_ _operatorini yozib qo‘yish bilan tugaydi. Dekorator sintaksisi ham yangi tushunchalardan biri bo‘lib, mavjud funksiyani o‘zgartirmasdan uning funksionalligini kengaytirish imkonini beruvchi usuldir._ Bu yerda esa oddiy qilib tushunsak “bu funksiya oddiy metod emas, balki abstrakt metod” sifatida tanilsin degan maqsadda ishlatilgan. Endi esa Flyable interfeysini meros olgan Eagle klassini ko‘rib chiqaylik. Flyable interfeysidan meros olganligi sababli, u interfeysda aniqlangan **abstrakt metod** bo‘lgan fly funksiyasini majburiy tarzda **implementatsiya qilishi kerak** (avvalgi darsda o‘rgangan funksiyani qayta yozish, ya’ni **overriding** usuli bilan). Demak, agar faqatgina meros olib, lekin **fly** funksiyasini implementatsiya qilmasak nima bo‘ladi? Buni to‘g‘ridan-to‘g‘ri bajarib ko‘rsangiz, quyidagidek xatolik yuz beradi: **abstrakt metod bo‘lgan fly funksiyasi implementatsiya qilinmadi**, degan mazmunda xato chiqib, dastur to‘xtaydi. Bu ham mantiqan to‘g‘ri: foydalanuvchi nuqtai nazaridan qaralganda, amalda ishi yo‘q bo‘lgan (ya’ni, implementatsiyasi yo‘q) biror funksiyadan qanday qilib ma’lum bir funksional ishni kutish mumkin bo‘lsin? Copy File "test.py", line 64, in eagle = Eagle() TypeError: Can't instantiate abstract class Eagle with abstract methods fly Yana bir bor umumlashtirib aytadigan bo‘lsak, bu yerda _**interfeys (abstrakt obyekt) merosining tushunchasi ota sinfning barcha funksiyalarini meros qilib olish maqsadidagi merosdan ko‘ra, interfeysni meros qilgan obyekt ushbu funksiyaga albatta ega bo‘lishini kafolatlaydigan kelishuv va uning implementatsiyasini majburlash orqali obyektga yo‘naltirilgan dizayn muallifi qo‘ygan qoidalarga rioya qildirishga xizmat qiladi,**_ degan ma’no ko‘zda tutiladi. Oxir-oqibat, bu qoidalarga rioya qilish qanday ustunliklar berishi qiziq tuyulishi mumkin. Bu masala obyektga yo‘naltirishning katta mavzularidan biri bo‘lgan **polimorfizm(Polymorphism)** bilan chambarchas bog‘liq. Mavzu juda keng bo‘lgani sababli bu safar batafsil yoritmaymiz; keyinroq ushbu tushunchani bilib, ishlatish zarur bo‘lgan paytda yana bir bor tushuntiramiz. Endi interfeys konsepsiyasidan foydalanib, ushbu bo‘limning maqsadi bo‘lgan Battle City o‘yinini obyektga yo‘naltirilgan usulda dasturlashni davom ettiramiz. [Previous9.3 Obyektga yo‘naltirilgan dasturlash 1chevron-left](https://roboticsware.gitbook.io/python-pygame_zero/battle_city/9.3_oop_dev1) [Next9.5 Obyektga yo‘naltirilgan dasturlash 2chevron-right](https://roboticsware.gitbook.io/python-pygame_zero/battle_city/9.5_oop_dev2) Last updated 6 days ago --- # 10.1 Tarmoqli o‘yinlarni tushunish va kutubxonani o‘rnatish | Python-Pygame Zero Hozirgi davrda har doim internetga ulanadigan (Always-on) mobil telefonlarning ommalashuvi tufayli ko‘pchilik o‘yinlar asosiy tarzda tarmoqda boshqa foydalanuvchilar bilan birga zavqlaniladigan tarmoqli o‘yinlariga aylangan. Barchamiz shunday o‘yinlardan birini yaratib ko‘rishni xohlashimiz tabiiy. Shuning uchun, tijorat darajasidagi o‘yin bo‘lmasa ham, shunday o‘yin tayyorlash prinsiplarini tushunish uchun yetarli darajadagi o‘yinni yaratib ko‘ramiz. Tarmoqli o‘yinini tayyorlashni tushuntirishga yetarli vaqt bo‘lmagani sababli butunlay yangi o‘yinni yaratishga vaqt sarflamasdan, ilgari mahally/local (local) o‘ynash uchun yaratib ko‘rgan o‘yinimizni tarmoq o‘yiniga aylantirish yo‘li bilan davom etish maqsadga muvofiq bo‘ladi. Tarmoq o‘yinini yaratish uchun avvalo mavjud tarmoqli o‘yinlar o‘yin foydalanuvchilari (user) o‘rtasida tarmoqdagi ulanishni qanday yaratib va qanday boshqarishini tushunish zarur. Ulanish uchun asosiy yechim sifatida **o‘yin foydalanuvchilarini bog‘laydigan** _**hosting**_ **yechimlari, quyidagi rasmda ko‘rsatilgandek, o‘yin talablarga qarab Rele(Relay) server yoki maxsus(Dedicated) o‘yin serveri usuliga bo‘linadi.** Ikkalasini ham, asosan, o‘yin ishtirokchilari soniga qarab ajratish mumkin: taxminan 2–10 nafar ishtirokchi bir vaqtda o‘ynaydigan holatmi yoki kamida o‘nlab va undan ko‘p kishi birga o‘ynashni ko‘zlayaptimi, shunga qarab tanlanadi. Shulardan _biz kichik ko‘lamli, og‘ir bo‘lmagan o‘yinlar uchun qulay bo‘lgan_ _**Rele server**_ _usulidagi ulanish yechimidan foydalanib o‘yinni amalga oshiramiz._ ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FlhAUsC9UJBDa2BWjGen8%252Fimage.png%3Falt%3Dmedia%26token%3Dfb663daf-bc2d-4c9e-aaac-da171204fbb5&width=768&dpr=3&quality=100&sign=d8cd88aa&sv=2) Manba: Unity veb-sayti **Rele server** **faqat o‘yinchilar o‘rtasidagi ulanish va xabarlarni uzatishni bajaradi,** **o‘yin mantiqi esa har bir o‘yinchining klientida qayta ishlanadi**. Shuning uchun o‘yinchilar orasidagi ulanish holatiga qarab o‘yin unumdorligi o‘zgarishi mumkin, beqaror ulanish esa kechikish yoki uzilishlarni keltirib chiqarishi mumkin. Biroq afzalligi shundaki, xavfsizlik devori (firewall) mavjud bo‘lgan tarmoqlarda ham o‘yin o‘ynash mumkin. Biz o‘sha kutubxona modulini olib, dasturlashda foydalanamiz. Hozirda [maxsus Mu Editoriarrow-up-right](https://github.com/roboticsware/mu/releases) ning **1.2.9 versiya yoki undan yuqori**sida kod yozayotgan bo‘lsangiz, u modul muharrir ichiga allaqachon kiritilgan, shuning uchun yuqorida tilga olingan qo‘shimcha modul o‘rnatish jarayonlarisiz darhol kod yozishni boshlashingiz mumkin! Ammo boshqa muharrir yoki **IDE**dan foydalanayotgan bo‘lsangiz, modulni o‘zingiz yuklab olib o‘rnatishingiz kerak bo‘ladi. Yuklab olish uchun [shu yerniarrow-up-right](https://raw.githubusercontent.com/QuirkyCort/nethelper/refs/heads/main/nethelper.py) bosing. Veb-brauzerda (menda **Chrome** veb-brauzeri) ochilib, modulning manba kodi ko‘rinadi. So‘ng **\[Fayl\]** menyusidan **\[Sahifani boshqa nom bilan saqlash\]**(Save Page As) ni tanlab, saqlash joyi sifatida bizninging manba kodlarimiz joylashgan Mu Editorining standart papkasini tanlang (o‘z hisobingiz ostidagi **mu\_code** nomli papka) va o‘sha yerga saqlang. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FpUknGmb8wHTGFjyBK1SY%252Ftg_image_2701385179.png%3Falt%3Dmedia%26token%3Dfd40e23e-a50f-4ea1-94b8-d8456446e4ad&width=768&dpr=3&quality=100&sign=95fb0ba&sv=2) ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FtVUJtwQ1Gm0y3IrxQqql%252Fimage.png%3Falt%3Dmedia%26token%3D455c7c79-9fbf-4cf9-84f1-c44b29d3dd22&width=768&dpr=3&quality=100&sign=8d8d2c43&sv=2) Kodlashga tayyorgarlik tugadi, endi amalda kodlashni boshlaylik. Agar esingizda bo‘lsa, kutubxona yoki modul bo‘lishidan qat’iy nazar, yaratuvchi niyatiga muvofiq foydalanuvchilar ishlatishi uchun odatda foydalanuvchi qo‘llanmasi taqdim etiladi, degan edik. Albatta, ushbu modul uchun ham [GitHubdagi manba kodi repozitoriyasiarrow-up-right](https://github.com/QuirkyCort/nethelper) da foydalanish yo‘riqnomasi mavjud va [u yerarrow-up-right](https://github.com/QuirkyCort/nethelper/wiki) da har bir API (Application Programming Interface) bo‘yicha batafsil ma’lumotni ko‘rish mumkin. Qo‘llanma berilgan ekan, har kim uni o‘qib, o‘zi mustaqil kodlashni boshlashi ham mumkin; biroq bizning kitob boshlovchilarni inobatga olgan soddalashtirilgan “yumshoq ta’mli” versiya bo‘lgani uchun keyingi bo‘limda birga kodlashni boshlaymiz. [Previous10\. Pongni tarmoq o‘yiniga aylantirishchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/pong_network) [Next10.2 Rele serverini ishga tushurish va mijozning ulanishichevron-right](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.2_server_connection) Last updated 6 days ago --- # 7. TwinBee otishma o‘yinini yaratish | Python-Pygame Zero Bu o‘yin 1985-yilda yaratilgan TwinBee nomli klassik otishma o‘yinidir. Mana o‘yindan olingan videoni ko‘ring: Garchi bu juda mashhur o‘yin bo‘lmasada, u vertikal aylantiruvchi otish o‘yini sifatida juda muvaffaqiyatli ekanligi ma’lum. Agar biz ushbu o‘yinni to‘liq klonlash va uni deyarli bir xil qilishimiz kerak bo‘lsa, kodlash miqdorini sezilarli darajada oshirishimiz kerak bo’lar, va siz uchun kodlash zavqi kamayishi mumkin edi. Shunday qilib, biz turli uslublarda o‘yinlar yaratish orqali kodlashni o‘rganishdan zavq olishdek asl maqsadimizdan chetga chiqmaslik uchun qiyinlik darajasini moslashtirishni rejalashtirmoqdamiz. Biroq, orangizida irodali va qiziquvchan o‘quvchilar bo‘lishi mumkinligini hisobga olib, qo‘shimcha kodlashni sizga topshiriq sifatida qoldiraman va o‘zingiz o‘rganishingiz mumkin bo‘lgan veb-sayt havolasini ulashaman. Mayli, keling, birga o‘yinni yaratishni boshlaylik. [Previous6.5 (Bonus) Original o‘yin kabi yaratib ko‘rishchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.5_make_original) [Next7.1 Skrol fon obyektini yaratish, fon musiqasi, aktyorlar (dushman, qahramon) ni tanishtirishchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/twinbee/7.1_scroll_backgrounds) Last updated 6 days ago sun-brightdesktopmoon sun-brightdesktopmoon --- # 7.1 Skrol fon obyektini yaratish, fon musiqasi, aktyorlar (dushman, qahramon) ni tanishtirish | Python-Pygame Zero Quyidagi ekranda biz yaratadigan o‘yinning yakuniy natijasini avval ko‘rib chiqsak, kodni tushunish ancha oson bo‘ladi. Faqat, bu darsning boshida aytib o‘tilganidek, murakkablikni nazorat qilish maqsadida barcha funksiyalarni to‘liq amalga oshirmaymiz, ammo quyidagi yakuniy natijani to‘liq yaratmoqchi bo‘lganlar uchun alohida o‘rganish mumkin bo‘lgan havolalarni taqdim etamiz. To‘liq o‘yinni yaratishga kirishishdan oldin, ushbu o‘yin uchun kerakli bo‘lgan rasm, ovoz kabi resurslarni bu [havolaarrow-up-right](https://github.com/roboticsware/python-pygame_zero-samples/tree/main/breakout) dan yuklab olishingiz mumkin va o‘yinga kerakli rasm fayllari kodda ishlatilgan nomlar bilan **images** papkasiga allaqachon saqlangan, effekt ovozlari esa **sounds**, fon musiqalari esa **music** papkasiga saqlangan deb hisoblab boshlaymiz. Yoki agar [maxsus Mu Editordanarrow-up-right](https://github.com/roboticsware/mu/releases) foydalanayotgan bo‘lsangiz, Mu Editorining ishchi katalogi bo‘lgan (foydalanuvchi\_nomi)\\mu\_code\\examples\\pygame\_zero ichidan ularni nusxalab oliishingiz mumkin. Bu o‘yin bosqichining avvalgilaridan farqi shundaki, u harakatsiz fon emas, balki harakatlanuvchi fon (obyekt)dir. Agar siz Entry blokini kodlash bilan tanish bo‘lsangiz, fon obyekt bo‘lishi mumkinligi va uni kodlashi mumkinligi notanish bo‘lmaydi. Oldingi misollardan bilamizki, fonni oddiy tasvir sifatida ishlatganda kodlash quyidagi tarzda ishlatilishi mumkin. Biroq, endi biz qilmoqchi bo‘lgan ish — fonni obyekt sifatida yaratib, cheksiz takrorlanuvchi vertikal aylanadigan(skrol) fonni amalga oshirishdir. Skrol qilinadigan ekranni yaratish uchun, jismoniy jihatdan bir-biridan ajratilgan bo'lsa-da, uni bitta panoramik tasvir kabi ko'rinadigan kamida **2 ta rasm** kerak bo‘ladi. Bu yerda biz "background1" va "background2" deb nomlangan 2 ta rasmni alohida aktyor obyektlari sifatida yaratamiz. Birinchi fon obyekti uchun **Anchor (markaziy koordinata)** — ekran kengligi va balandligi teng ikkiga bo‘lingan qiymatlar bo‘lishi kerak (WIDTH / 2, HEIGHT / 2), shunda u to‘liq ekran o‘lchamiga mos ravishda chiziladi. Bu fon obyekti va uning yuqorisida joylashgan fon obyektining markaziy koordinatasi dastlab ko‘zimizga ko‘rinmasada, uni ekranning tashqi yuqori qismiga joylashtirish uchun ekran balandligi qiymatini ayirib ((HEIGHT / 2) - HEIGHT) holatdagi Anchor qiymatini (ya’ni -300 qiymatini) qo‘llashga to‘g‘ri keladi. Buni tushunishingizga yordam berish uchun quyidagi diagramma: ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FOsABR1LxsEValzd8SXMf%252Fimage.png%3Falt%3Dmedia%26token%3De0f81c0f-986b-4155-a028-cde3a10bbbfa&width=768&dpr=3&quality=100&sign=a9b0fd42&sv=2) Fonni obyektga aylantirdik va **draw** kolbek(callback) funksiyasida ekranga chizdik. Shundan so‘ng, bu fonni skroll qilish orqali cheksiz aylanish (rotation) holatiga keltirish uchun kerakli kod ya’ni, obyektga harakat beruvchi kod — **update** kolbek funksiyasida yozilishi kerak bo‘ladi. Ekran harakat tezligi 3 piksel pastga siljiydi va har bir fon obyekti harakatlanib, agar hozirgi ko‘rinadigan ekran hududidan chiqib ketsa, ekran yuqorisidagi ko‘rinmaydigan joyga darhol qaytariladi, shu orqali **cheksiz aylanish(infinite scroll)** amalga oshiriladi. _Bunday algoritm esa ilgari blokli dasturlashda tez-tez ishlatilgan va sizga notanish emas._ Shu vaqtgacha tushuntirilgan narsalarni kod shaklida ifodalaydigan bo‘lsak quyidagicha bo‘ladi. Endi ushbu bo‘limning qolgan qismida o‘yin sahnasining bosh qahramonlari (dushman samolyoti, mening samolyotim)ni sahnaga chiqarish navbati, shuningdek, **ularni boshqarishda zarur bo‘ladigan funksional kodlar haqida oldindan o‘ylab ko‘rish va bu funksiyalarni ma’noli kod bo‘laklari, ya’ni funksiyalash(functionalize) – yaxshi dasturchi bo‘lish uchun zarur bo‘lgan fazilatlardan biridir**. Bu haqda o‘ylayotganda, quyidagidek zarur bo‘ladigan funksiyalarning nomlarini (naming) o‘z ichiga olgan ro‘yxatni oldindan tuzib chiqish orqali umumiy tuzilmaning konturini shakllantirishda yordam olish mumkin. **Funksiyalash jarayonida biz birinchi navbatda e**’**tiborga olishimiz kerak bo**‘**lgan ustuvor vazifa** — **bu funksiya yaratilishining asosiy maqsadi** — **takroriy kodni kamaytirishdir.** _Biroq, biz yaratmoqchi bo‘lgan yakuniy dastur qanday bo‘lishiga qarab, ba’zida kutilganidek takrorlanuvchi kodlar mavjud bo‘lmasligi ham mumkin._ Bu o‘yinda shunday holat kuzatiladi, masalan, bu 1 kishilik otishma o‘yini bo‘lgani uchun, klaviatura orqali boshqariladigan harakatlar faqat bosh qahramon samolyot uchun kerak bo‘ladi va boshqa obyektlar bilan umumiy foydalanilmaydi. Shuningdek, o‘q otish metodlari ham bosh qahramon otadigan o‘qlar va dushman samolyoti otadigan o‘qlar turiga va metodiga ko‘ra deyarli umumiylikka ega emas, shu sababli ularni umumiy funksiyaga aylantirish foyda keltirmaydi. Shu sababli, quyidagi kodni ko‘zdan kechiradigan bo‘lsak, bizning _dasturdagi funksiyalardan foydalanish maqsadi — takrorlanuvchi kodlarni kamaytirishdan ko‘ra, kodni o‘qish qulayligini oshirish uchun ma’no birliklariga ko‘ra funksiyalash ekanligini ko‘rish mumkin._ Men jami 5 ta bo‘sh funksiya (**move\_player, shoot\_bullets, create\_endemies, check\_collision**) yaratdim va har bir funksiyada vaqtinchalik **pass** ni qoldirdim. Bu shuni anglatadiki, hozir bajariladigan hech narsa yo‘q va bu vaqtinchalik ifoda sintaksisi bo‘lib, batafsil amalga oshirishni keyinroq kechiktirishdir. Bu yerda nima uchun funksiyalar 5 ga bo‘lingan, nega 4 yoki 6 emas, degan savollar tug‘ilishi mumkin, lekin yangi boshlovchilar uchun qaysi funksiyalar kerakligi va funksiyalarni necha qismga bo‘lish kerakligi haqida oldindan o‘ylay olmasligi odatiy holdir va aslida kodlash sohasida aynan shunday bo‘lishi kerak bo‘lgan 100% to‘g‘ri javob yo‘q. **Kodlash aslida bir nechta mumkin bo**‘**lgan yechimlar orasidan eng samarali usulni topish jarayonidir.** Shuning uchun, bu qism muammosiz o‘tishi uchun juda ko‘p tajriba to‘planishi kerak deb taxmin qilish kerak. Muhimi, boshidanoq o‘zingizni juda og‘ir his qilmaslik, bu haqda ko‘p o‘ylamaslik kerak, birdan mukammal funksiyani yaratish mumkin emas. Har xil usullarni sinab ko‘rib, takror-takror tuzatib borish orqali asta-sekin rivojlantirish tabiiy jarayondir. (Kodlashda bu jarayon [refaktoringarrow-up-right](https://en.wikipedia.org/wiki/Code_refactoring) deb ataladi.) Shu tarzda, **o‘yin dasturlarini tilga olsak, biz** [**oldingi kitob**arrow-up-right](https://roboticsware.gitbook.io/entry-python) **da o‘rgangan funksiyalar orqali** [**protsessual dasturlash paradigmasi**arrow-up-right](https://roboticsware.gitbook.io/entry-python) **dan ko‘ra, aslida** [**obyektga yo‘naltirilgan dasturlash paradigmasi**arrow-up-right](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/oop) **ko‘proq mos keladi.** Biroq, shu paytgacha biz faqat tayyorlangan obyektlardan boshqalar tomonidan yaratilgan sinflar orqali foydalanganmiz va o‘z ehtiyojlarimizga ko‘ra o‘z obyektlarimizni yaratish va ishlatishni hali o‘rganmaganmiz. Aslida, men sizni foydalanuvchi tomonidan belgilangan funksiyalar(User defined function)ni yaratish va ulardan foydalanish bilan biroz tanish bo‘lishingizni kutgan edim va quyidagi 8-misoldan boshlab biz o‘z sinflarimiz va obyektlarimiz yordamida kodlashni o‘rganamiz. Nihoyat, bu bobni 21-qatorda o‘yin davomida fon musiqasini qanday ijro etishni aytib o‘tish bilan yakunlayman. Ovoz effektlari va fon tovushlari o‘rtasidagi farq shundaki, tovush effektlari qisqa va bir martalik, fon tovushlari esa uzoq va cheksiz takrorlanish xususiyatiga ega. Biz tovush effektlarini qanday ishlatishni bilamiz va fon tovushlari aslida tovush effektlari sifatida ijro etilishi mumkin va agar biz tovushni cheksiz takrorlashni istasak, argument sifatida -1 ni kiritishimiz mumkin. Biroq, kutubxona [fon musiqasi uchun maxsus APIarrow-up-right](https://pygame-zero.readthedocs.io/en/stable/builtins.html#music) taqdim etganligi sababli, undan foydalanish maqsadga muvofiq bo‘ladi. Fon musiqa fayli turi **mp3** yoki **ogg** fayli bo‘lishi mumkin, o‘ynatish funksiyasi esa kutubxona tomonidan taqdim etilgan **music.play** bo‘lishi mumkin. [Previous7\. TwinBee otishma o‘yinini yaratishchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/twinbee) [Next7.2 Aktyorlarning harakati va o‘q otish hujumini amalga oshirishchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/twinbee/7.2_bullet_attack) Last updated 6 days ago sun-brightdesktopmoon Copy def draw(): screen.blit('background', (0, 0)) Copy WIDTH = 800 HEIGHT = 600 backgrounds = [] background1 = Actor("background1", (400, 300)) backgrounds.append(background1) background2 = Actor("background2", (400, -300)) backgrounds.append(background2) def draw(): for background in backgrounds: background.draw() def update(): for background in backgrounds: background.y += 3 if background.top > HEIGHT: background.y = -300 Copy WIDTH = 800 HEIGHT = 600 backgrounds = [] background1 = Actor("background1", (400, 300)) backgrounds.append(background1) background2 = Actor("background2", (400, -300)) backgrounds.append(background2) player = Actor("player", (400, 500)) MAX_BULLETS = 3 bullets = [] enemies = [] enemy_bullets = [] explosions = [] score = 0 game_over = False music.play(main_theme) def move_player(): pass def shoot_bullets(): pass def create_enemies(): pass def check_collision(): pass def draw_text(): pass def draw(): for background in backgrounds: # Fon rasmini chizish background.draw() player.draw() # Bosh qahramonning samolyotini chizish for enemy in enemies: # Dushman samolyotlarini chizish enemy.draw() for bullet in bullets: # Bosh qahramon o'qini chizish bullet.draw() for explosion in explosions: # Dushman samolyotining portlashini chizish explosion.draw() for bullet in enemy_bullets: # Dushman o'qlarini chizish bullet.draw() draw_text() # Hisob va o'yin yakuni matnini chizish def update(): for background in backgrounds: background.y += 3 if background.top > HEIGHT: background.y = -300 move_player() # Bosh qahramon samolyotini klaviatura orqali boshqarish shoot_bullets() # Dushmanga qarata o‘q otish create_enemies() # Harakatlanadigan va o'q otadigan dushman samolyotlarini yaratish check_collision() # To'qnashuvga oid barcha jarayonlar Copy sounds.main_theme.play(-1) sun-brightdesktopmoon --- # 5.8 Flappy Bird o‘yini uchun qo‘shimcha funksiyalar (Flappy Bird animatsiyasi) | Python-Pygame Zero Hozirgi Flappy Bird tasviri uchayotgan holatda bo‘lishiga qaramay, u qanot qoqmay, xuddi harakatsiz holda uchayotgandek ko‘rinadi. Bu g‘ayritabiiy tuyuladi. Agar qanot qoqish animatsiyasi ifodalansa, o‘yin ancha mukammal bo‘lishi mumkin. Endi ushbu qismini birgalikda amalga oshirib ko‘raylik. Agar siz ilgari Entry blokli dasturlash bilan tanish bo‘lgan bo‘lsangiz, nima qilish kerakligini tezda anglab olasiz. Entryda bir nechta obyektlar orasida ayrim obyektlar uchun \[Shakl\] nomli yorliqni bossangiz, ular animatsiyada ishlatilishi mumkin bo‘lgan bir nechta tasvirlardan iborat ekanini ko‘rgansiz. Va o‘sha tasvirlarni muayyan vaqt oralig‘ida ketma-ket aylantirish orqali animatsiya yaratilganini eslab qolgan bo‘lsangiz kerak. Agar Pygame Zeroda ham shunday usulda kod yozish imkoni bo‘lsa, juda qulay bo‘lardi. Afsuski, original Pygame Zero bu tarzda kodlash uchun yetarlicha tayyorlangan emas. [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.8_animation#pgzhelper-kutubxonasini-ornatish) pgzhelper kutubxonasini o‘rnatish --------------------------------------------------------------------------------------------------------------------------------------------------------------- Biroq, **ochiq kodli dunyoning afzalligi nimada?** **Agar biror jihat yetarli bo‘lmasa, istalgan kishi ochiq manbadagi mavjud kodni o‘zgartirib, funksiyalarini yaxshilagan holda qayta ommaga taqdim etishi mumkin.** Singapurda yashovchi bir dasturchi esa aynan biz Entryda qilgan uslubga o‘xshash tarzda obyekt animatsiyalarini yaratish imkonini beruvchi, [Pygame Zero asosidagi qo‘shimcha Python modulini ishlab chiqib, ochiq manbada taqdim qilmoqdaarrow-up-right](https://github.com/QuirkyCort/pgzhelper) . circle-info **pgzhelper** dastlab Singapurlik **Cort** ismli dasturchi tomonidan Scratch blokli kodlashdan Pygame Zero ga port(porting) qilish (ya’ni xuddi o‘sha funksiyalarni amalga oshirish) jarayonida Pygame Zero ning o‘ziga xos cheklovlari sababli yuzaga kelgan qiyinchiliklarni bartaraf etish maqsadida yaratilgan. [RoboticsWarearrow-up-right](https://roboticsware.uz/) ham xuddi shunga o‘xshash sabablarga ko‘ra, Entry blokli kodlashni Pygame Zero ga oson port qilish uchun ushbu kutubxonaga qo‘shimcha funksiyalar qo‘shib, uni takomillashtirgan va ochiq kodli sayt bo‘lgan GitHubda ([https://github.com/roboticsware/pgzhelperarrow-up-right](https://github.com/roboticsware/pgzhelper) ) e’lon qilgan. Bu bo‘limda biz o‘sha moduldan foydalanamiz. Agar siz hozirda **1.2.6 yoki undan yuqori versiya**dagi [Maxsus Mu Editorarrow-up-right](https://github.com/roboticsware/mu/releases) dan foydalanayotgan bo‘lsangiz, bu modul allaqachon uning ichiga o‘rnatilgan bo‘ladi, shuning uchun yuqorida tilga olingan qo‘shimcha modul o‘rnatish jarayonlarisiz bevosita kod yozishni boshlashingiz mumkin! Biroq, agar siz boshqa editor yoki IDEdan foydalanayotgan bo‘lsangiz, o‘rnatishning ikkita asosiy usuli mavjud: [PIP (Python Package Index)arrow-up-right](https://pypi.org/project/pgzhelper-rw/) orqali o‘rnatish yoki GitHub saytida modullarni o‘zingiz to‘g‘ridan-to‘g‘ri yuklab olishishingiz mumkin. Avvalo, agar siz PIP orqali o‘rnatmoqchi bo‘lsangiz, Windows foydalanuvchilari Buyruqlar Satri(Command Prompt) oynasida, Mac foydalanuvchilari esa Terminal oynasida quyidagi buyruqni kiritishlari kerak bo‘ladi. Copy pip install pgzhelper-rw Ikkinchi qo‘lda yuklab olib o‘rnatish usuli uchun ushbu [havolaarrow-up-right](https://raw.githubusercontent.com/QuirkyCort/pgzhelper/main/pgzhelper.py) ni bossangiz, veb-brauzeringiz (muallif holatida, Chrome brauzeri) ochiladi va modulning manba kodi ko‘rinadi. \[Fayl\] menyusidan \[Saxifani boshqa nom bilan saqlash\] menyusini tanlab, saqlash joyini bizning o‘yinimiz manba kodi joylashgan Mu Editorining asosiy papkasi (foydalanuvchi hisobingiz(user account) ostidagi _mu\_code_ nomli papka) qilib belgilang. Saqlash usuli va yakuniy saqlangan ko‘rinish quyida tasvirlab berilgan. Biz ishlab chiqayotgan o‘yin manba kodi va foydalanmoqchi bo‘lgan modul bir xil joyda joylashgan bo‘lishi kerak, chunki shundagina biz modulni oddiy **import** operatori orqali kodga qo‘shishimiz mumkin bo‘ladi. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FpUknGmb8wHTGFjyBK1SY%252Ftg_image_2701385179.png%3Falt%3Dmedia%26token%3Dfd40e23e-a50f-4ea1-94b8-d8456446e4ad&width=768&dpr=3&quality=100&sign=95fb0ba&sv=2) ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FPS27d7hKnaov61KHW8vw%252Fimage.png%3Falt%3Dmedia%26token%3Dfc9ed07e-0c8f-4080-b35b-ae1e61766b17&width=768&dpr=3&quality=100&sign=9b6fd5ad&sv=2) Endi biz kodlashga tayyormiz, keling, boshlaylik. Agar kutubxona yoki modul yaratuvchisining niyatiga ko‘ra foydalanuvchilar undan qanday foydalanishini bilishlari uchun foydalanuvchi qo‘llanmasi taqdim etilishi odatiy hol ekanligini eslasangiz, bu modul ham albatta foydalanish bo‘yicha ko‘rsatmaga ega va uni [bu yerarrow-up-right](https://www.aposteriori.com.sg/pygame-zero-helper/) da ko‘rish mumkin. Foydalanish tartibi mavjud bo‘lganidan so‘ng, har kim uni o‘qib chiqib, mustaqil ravishda kod yozishi mumkin, biroq bizning kitobimiz yangi boshlovchilarni hisobga olgan "yengil darajali" versiya bo‘lganligi sababli, biz birgalikda kod yozib ko‘ramiz. Avvalo, hujjatda eslatib o‘tilgan animatsiya qilish usulining nihoyatda soddalashtirilgan kodi quyidagicha bo‘lib, avvalgi kodlarni vaqtincha izoh(kommentariya)qilib qo‘yib, quyidagi 11 qatordan iborat kodni ishga tushirsangiz, animatsiyalangan Flappy Birdni ko‘rishingiz mumkin bo‘ladi. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FskGsLAoZqAx0FLbd6kLs%252Fimage%2520%281%29.gif%3Falt%3Dmedia%26token%3D2ec1e2bb-97c5-4249-b195-c5697f649c6d&width=768&dpr=3&quality=100&sign=1e1d9595&sv=2) Oxirida, biz qilishimiz kerak bo‘lgan yagona narsa yuqoridagi animatsiya kodini mavjud kodimizga moslashtirishdir va biz quyida ko‘rsatilgandek yakuniy kod bilan yakunlashimiz mumkin. Endi kodni tarkibini birma-bir tushunib olaylik. 🔢 Biz alohida yuklab olgan qo‘shimcha modul (**pgzhelper**)ni o‘z kodimiz ichida ishlatish uchun, albatta, 2-qatorda kabi avvalo ushbu modulni **import** qilishimiz kerak bo‘ladi. Endi **import** iborasi bilan ishlashga ko‘nikib qolgan bo‘lsangiz kerak. Bu yerda esa biz **import** sintaksisining yangi shaklini: _**from-import \***_ **ni birinchi marta ishlatyapmiz. Shunchaki import qilish va** _**from-import \***_ **qilish o‘rtasida qanday farq bor?** Aslida **import** buyruq orqali olib kelgan kutubxona (yoki paket) yoki modul ichida ma’lum bir klass yoki funksiyani ishlatmoqchi bo‘lsak, biz allaqachon bilamizki, u holda funksiyaning tarkibiy joylashuvi haqidagi ma’lumotlarni o‘z ichiga olgan (shu funksiyani o‘z ichiga olgan) kutubxona (yoki paket, modul) nomi shaklida chaqirishimiz kerak. Misol uchun, 37-qatordagi **randint** funksiyasining chaqiruvi misolida ham, uni ishlatish uchun **random.** deb nomlangan modul kerak bo‘ldi va yakuniy natijada **random.randint** shaklida chaqirdik. Lekin, agar random modulini **from-import \*** orqali **from random import \*** deb import qilgan bo‘lsak, unda qanday farq bo‘ladi? Bu holatda endi funksiyaning tarkibiy joylashuvi haqidagi ma’lumotlarsiz, to‘g‘ridan-to‘g‘ri funksiyaning nomi bo‘lgan **randint** bilan chaqirishimiz mumkin bo‘ladi. Qanday, qulayroq emasmi? **from-import \*** buyruqning umumiy maqsadi shunday va **bu yerda pgzhelper modulini from-import \* orqali chaqirishimiz kerak bo‘lishining sababi, keyinchalik bayon etiladigan Actor klassining qo’shimcha atributlari bo’lgan images, fps va hokazo hamda uning harakatlari, ya’ni animate funksiyasi(metodi) yoki Actor klassini kengaytirish uchun qulay kodlash maqsadida ishlatiladi deb tushunish mumkin.** 🔢 Keyinroq biz modulni ishlatish usuli misolida talab qilinayotganidek, biz animatsiyada ishlatiladigan har bir rasmning bosqichma-bosqich tasvirlari(frame)ning **ketma-ket** to‘plamini 17-qatordagi kabi ro‘yxat sifatida yaratishimiz kerak. Flappy Birdning osmonda uchish harakati jami 3 ta rasm bilan tashkil etilgan va bu rasmlar biz [5.1-bo‘limarrow-up-right](https://jjlee.gitbook.io/python-pygame_zero/flappy_bird/5.1_background) da **images** papkasiga oldindan nusxalab qo‘yganimizni eslaymiz. Endi 18-qatordagi fps degani nima? Oddiy qilib aytganda, bu animatsiyaning tezligi, ya’ni FPS (Frame Per Second) degani, 1 soniya ichida nechta bosqichma-bosqich rasm (frame) ko‘rsatilishi haqida. Agar batafsil bilishni istasangiz, bu kitobning keyingi versiyasida tekshirib ko‘rishingiz mumkin. Bu yerda esa faqat fps qiymati katta bo‘lsa, animatsiya tezlashadi, kichik bo‘lsa, sekinlashadi, deb bilsangiz bo‘ladi va bir necha marta ishga tushirib, to‘g‘ri qiymatni topishingiz kerak bo‘ladi. 🔢 Endi qolgan narsa **update** funksiyasi ichida **animate** funksiyasini chaqirish, lekin hisobga olinishi kerak bo‘lgan bitta istisno holati bor: agar joriy kodni o‘zgartirmasdan qoldirsak, Flappy Bird uchib ketayotganda quvurga tegib o‘lib qolgan holatda ham darhol yana tirilib(?) ketma-ket uchib ketayotgan animatsiyasini ko‘rish mumkin bo‘ladi. Albatta, bu holatga yo‘l qo‘yilmasligi kerak, shuning uchun 47~48-qatorlardagiday animatsiya faqat Flappy Bird tirik bo‘lsa amalga oshirilishi mumkin degan shart ichida animatsiyani ishga tushirish kodini joylashtirish kerak bo‘ladi. Shu bilan Flappy Bird o‘yini uchun 3 ta qo‘shimcha funksiyani amalga oshirish ham tugallandi. 3 ta funksiyani qo‘shish orqali jami 25 ta qo‘shimcha kod qatori yozilib, umumiy manba kodi 76 qatordan iborat bo‘ldi. O‘yin sifatini oshirish uchun yana ko‘plab qo‘shimcha funksiyalarni qo‘shish mumkin. Masalan, ekranning burchagida hozirgacha olingan eng yuqori hisoblarni(ballarni) ko‘rsatish orqali o‘yindagi raqobat ruhini oshirish mumkin, quvurning balandligi faqatgina tasodifiy (random) bo‘lishi emas, balki o‘yin davomida murakkablikni oshirish uchun quvur harakatining tezligini ham o‘zgartirish mumkin bo‘ladi, shuningdek o‘yin davomida eshitiladigan tovushlar (fon musiqasi, Flappy Bird o‘lganda yoki parvoz qilgandagi effektlar) orqali o‘yinga audiovizual zavq qo‘shish mumkin. Flappy Bird o‘yini aslida faqatgina tanishuv darajasidagi ilk loyiha bo‘lganligi sababli, hozircha bundan ortiq maqsad qilinmaydi. Yuqorida tilga olingan funksiyalarni keyinchalik boshqa o‘yin loyihalarida ko‘rib chiqamiz. Shunga qaramay, ayni paytda o‘zingiz mustaqil ravishda [Pygame Zero kutubxonasi hujjatlariarrow-up-right](https://pygame-zero.readthedocs.io/) ni ko‘rib chiqib, bu funksiyalarni qo‘shishga urinmoqchi bo‘lsangiz, albatta bu jasoratli urinishingizni olqishlayman. Chunki aynan shunday urinishlar sizni yanada yaxshi dasturchiga aylantirishi aniq. [Previous5.7 Flappy Bird o'yini uchun qo'shimcha funksiyalar (quvur pozitsiyalarini tasodiylashtirish)chevron-left](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.7_pipe_random) [Next6\. Breakout o‘yinini yaratishchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/breakout) Last updated 7 days ago sun-brightdesktopmoon Copy from pgzhelper import * flappy_bird = Actor('bird1') flappy_bird.images = ['bird0', 'bird1', 'bird2'] flappy_bird.fps = 10 def update(): flappy_bird.animate() def draw(): flappy_bird.draw() flappy\_bird.py Copy import random from pgzhelper import * TITLE = 'Flappy Bird' WIDTH = 400 HEIGHT = 708 GRAVITY = 0.3 drop_speed = 0 GAP = 140 PIPE_SPEED = -3 bird_alive = True score = 0 # Actor obyekti flappy_bird = Actor('bird1', (75, 350)) flappy_bird.images = ['bird0', 'bird1', 'bird2'] flappy_bird.fps = 10 top_pipe = Actor('top', (350,0)) bottom_pipe = Actor('bottom', (350, top_pipe.height + GAP)) def draw(): screen.blit('background', (0, 0)) flappy_bird.draw() top_pipe.draw() bottom_pipe.draw() screen.draw.text( str(score), color = 'white', midtop = (WIDTH/2, 10), fontsize = 70, shadow = (1, 1) ) def reset_pipes(): random_y = random.randint(-100, 100) top_pipe.y = random_y bottom_pipe.y = top_pipe.height + GAP + random_y top_pipe.x = WIDTH bottom_pipe.x = WIDTH def update(): global drop_speed, bird_alive, score drop_speed += GRAVITY flappy_bird.y += drop_speed if bird_alive == True: flappy_bird.animate() top_pipe.x += PIPE_SPEED bottom_pipe.x += PIPE_SPEED # cheksiz quvurlar sikli if top_pipe.right < 0 or bottom_pipe.right < 0: reset_pipes() if bird_alive == True: score += 1 # quvurlar bilan to'qnashuv if flappy_bird.colliderect(top_pipe) or flappy_bird.colliderect(bottom_pipe): flappy_bird.image = "birddead" bird_alive = False # o'yinni qayta boshlash if flappy_bird.y > HEIGHT or flappy_bird.y < 0: flappy_bird.image = "bird1" bird_alive = True flappy_bird.center = (75, 350) drop_speed = 0 reset_pipes() score = 0 def on_mouse_down(): global drop_speed if bird_alive == True: drop_speed = -6.5 sun-brightdesktopmoon --- # 6.3 To‘pni aks ettirish va bloklarni sindirishni amalga oshirish | Python-Pygame Zero Ushbu bo‘limda endi to‘pning aks ettirilishini amalga oshirish navbati keldi. To‘p aks ettiriladigan holatlar — chap va o‘ng devorlar, yuqori devor, to‘pning aks ettiruvchi panelga(reflektor) urilgan vaqti, hamda blok singan payt bo‘lib, blok singani bilan birga aks ettirish ham sodir bo‘ladi. Copy TITLE = 'Breakout' WIDTH = 800 HEIGHT = 600 GAP_FROM_SCREEN = 50 ball = Actor('ball', (WIDTH / 2, HEIGHT / 2)) bar = Actor('bar', (WIDTH / 2, HEIGHT - GAP_FROM_SCREEN)) # 4-qator*8-ustundan iborat bloklar to'plamini yaratish blocks = [] for block_row in range(4): for block_col in range(8): block = Actor( 'block', (block_col * 100, block_row * 32 + GAP_FROM_SCREEN), anchor=('left', 'top') ) blocks.append(block) # to'pning boshlang'ich (yo'nalish) tezligi vx = 5 vy = -5 def draw(): screen.blit('space', (0, 0)) ball.draw() bar.draw() for block in blocks: block.draw() def update(): global vx, vy # ekran ichida reflektorning harakatini cheklash if bar.left < 0: bar.left = 0 if bar.right > WIDTH: bar.right = WIDTH # to'pni x va y yo'nalishlarida vx va vy masofaga mos ravishda harakatlantirish ball.move_ip(vx, vy) # to'p chap yoki o'ng devorga tegsa, x yo'nalishini teskari tomonga o'zgartirish if ball.left < 0 or ball.right > WIDTH: vx = -vx sounds.wall.play() # to'p yuqori devorga yoki reflektorga tegsa, y yo'nalishi teskari bo'ladi if ball.top < 0 or ball.colliderect(bar) == True: vy = -vy sounds.wall.play() # to'p blokga tegsa b_index = ball.collidelist(blocks) if b_index != -1: vy = -vy sounds.block.play() blocks.pop(b_index) # o'yin tugash holati if ball.bottom > HEIGHT: sounds.die.play() game.exit() if not blocks: sounds.win.play() vx = 0 vy = 0 def on_mouse_move(pos): x, y = pos bar.centerx = x 🔢 Birinchida, jami 4 ta joy bo‘yicha aks ettirishni amalga oshiramiz: chap (devor)/ o‘ng (devor)/yuqori (devor)/reflektor (bar). O‘xshash joylarni 2 tadan juftlab kod yozilsa, kod hajmi kamayadi. Avvalo, 45-qatordagi kod orqali to‘p chap/o‘ng devorga tegganligini **if** shart operatori bilan doimiy ravishda tekshirib, aks ettirishni bajarish mumkin. Aks ettirish kodi murakkab emas. 46-qatorda **vx = -vx** degani, _tezlik qiymatidagi x o‘qi yo‘nalishini (direction) faqat qarama-qarshi tomonga o‘zgartirishni bildiradi, ya’ni qarama-qarshi tomonga o‘zgartirish bu +(musbat)ni –(manfiy)ga, –(manfiy)ni +(musbat)ga aylantirish bo‘lib, qiymatning faqat ishorasini o‘zgartirish demakdir, shuning uchun asl qiymatning qarama-qarshi ishorali shakli_ _**\-vx**_ _ni o‘ziga qayta tayinlab qo‘ydik._ Bu o‘yindan boshlab ilk bor o‘yin ichidagi qandaydir vaziyatlarga (to‘pning aks etish paytida, blok buzilish paytida, o‘yin tugash paytida) tovushlar effektlarini qo‘shish orqali o‘yin jarayonini kuchaytirib, foydalanuvchiga yanada qiziqarli o‘yin tajribasini taqdim etamiz. Jarayon oddiy, avvalgi o‘yinlarda tasvirlarni **images** deb nomlangan belgilangan papkaga joylashtirganimiz kabi, **o‘yinda ishlatiladigan oldindan tayyorlangan tovush effektlarini** _**sounds**_ **deb nomlangan papkaga saqlab qo‘yish kifoya. Saqlashning eng oson yo‘li bu Mu Editorida** _**Effektlar**_**(Sounds) deb nomlangan belgisini bosib, shu papkani ochish (agar ilgari mavjud bo‘lmasa, avtomatik ravishda yaratiladi), va shu papkaga joylashtirishdan iborat.** Ma’lumot uchun, ushbu o‘yinda ishlatiladigan tovush effektlari [shu yerarrow-up-right](https://github.com/roboticsware/python-pygame_zero-samples/tree/main/breakout/sounds) da. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FPm0SdE1VEjf59CEU2zTW%252Fimage.png%3Falt%3Dmedia%26token%3Dd8354e02-6c2c-49cf-bd6b-c5b935f7a37f&width=768&dpr=3&quality=100&sign=5c0eb2ec&sv=2) Tovushli effektni ijro etish usuli oddiy bo‘lib, 47-qatorda ko‘rib turganingizdek _**sounds.ijro qilinadigan tovushli effekt fayli nomi.play()**_ **degan sintaksis** orqali ijro etish mumkin. Batafsil foydalanish usullari haqida ma’lumot [Pygame Zero kutubxonasi hujjatlaridaarrow-up-right](https://pygame-zero.readthedocs.io/en/stable/builtins.html?highlight=colliderect#sounds) . Qolgan narsa bu — to‘p yuqori devorga to‘qnashgan holat yoki biz boshqarayotgan reflektorga to‘qnashgan holat bo‘lib, bu ikkisini ham birga shart operatori bilan birlashtirib kod yozish mumkin, sababi — tezlik qiymatidan faqat **y** o‘qi yo‘nalishini qarama-qarshi tomonga o‘zgartirish orqali to‘pni aks ettirish mumkin bo‘ladi. To‘p o‘yin ekranining yuqori qismiga tekkanligini tekshirish (ball.y < 0) qiyin emas, va to‘p aks ettiruvchi panelga to‘qnashganmi (tekkan) degan holatni esa o‘tgan 5.5-bobda ko‘rgan edik. 🔢 Endi to‘p blok bilan to‘qnashgan holatga o‘tamiz. To‘qnashuvni tekshirish kerak bo‘ladi, bu borada sizning xayolingizga qanday g‘oya keladi? Balki shunday g‘oya bo‘lishi mumkin: **for** sikl operatoridan foydalanib bloklar to‘plami ro‘yxatidan har bir blokni bittalab olib, ulardan qaysi biri bilan to‘qnashganligini **colliderect** funksiyasi yordamida birma-bir tekshirib chiqish mumkin bo‘ladi. Buni kod orqali ifodalash quyidagicha bo‘ladi. Ha, bu yaxshi fikr va yaxshi o‘ylangan. Agar o‘ylaganingizdek kodlasangiz, u ham to‘g‘ri ishlaydi. Biroq, o‘sha ikki qatorlik kod bo‘yicha Pygameda allaqachon bitta funksiya tayyorlab qo‘yilgan, ya’ni 55-qatordagi [collidelist funksiyasiarrow-up-right](https://www.pygame.org/docs/ref/rect.html#pygame.Rect.collidelist) orqali buni bajarish mumkin. _Bu funksiya parametr sifatida ro‘yxatni kirish qiymati qilib oladi va agar ro‘yxat ichidagi qandaydir obyekt (element) bilan to‘qnashuv aniqlansa, to‘qnashgan element ro‘yxatda nechinchi o‘rinda joylashganini indeks qiymati sifatida qaytaradi. Agar ro‘yxat ichidagi hech bir element bilan to‘qnashuv aniqlanmasa, u holda -1 manfiy qiymatini qaytaradi. (Eslatma sifatida: indeks qiymati hech qachon manfiy bo‘la olmaydi, shuning uchun bu qiymat ataylab foydalaniladi.)_ Shu sababli, 56-qatordagi shart operatorida indeks qiymati -1 ga teng bo‘lmagan holatdagina (ya’ni **!= operatori “teng emas”** degani) — ya’ni faqat to‘qnashuv yuz bergan holatdagina — shartli blok ichiga kiriladi va bu yerda to‘pni aks ettirish uchun tezlik yo‘nalishini o‘zgartirish, to‘qnashuv effekt tovushini chiqarish hamda **blocks** nomli blok obyektlari ro‘yxatidan **pop metodi** orqali to‘qnashgan blokni o‘chirish kabi harakatlar bajariladi. 🔢 Oxirgisi esa to‘pning aks etishi emas, balki o‘yin tugash holati. Birinchidan, foydalanuvchi to‘pni qaytarish vazifasini bajara olmagan holatda, ya’ni to‘p to‘g‘ridan-to‘g‘ri o‘yin ekranining pastki qismiga qulab tushgan holatda, bu — vazifa muvaffaqiyatsiz bajarilgan va o‘yin tugagan holat hisoblanadi, shuning uchun qisqacha kod bilan buni qayd etish kerak. 62~64-qatorlarda bo‘lgani kabi, o‘yin tugagan holatga mos tovush effektini ijro etamiz va **game.exit** metodini chaqirib dasturni yopamiz. Aksincha, agar vazifa to‘liq bajarilib, barcha bloklar to‘liq yo‘q qilingan bo‘lsa, bu ham o‘yinning g‘alaba bilan tugagan holatidir. 66~69-qatorlardagi kodda ko‘rsatilganidek, o‘yin g‘alabasiga oid tovush effekti ijro etilib, to‘p joyida to‘xtatiladi. Shu bilan Breakout o‘yinining asosiy qismi to‘liq bajarildi. Yuqoridagi kodlar asosida o‘yinni o‘ynab ko‘rsangiz, ehtimol ba’zi kamchiliklar yoki biror o‘ziga xos xatolikni topishingiz mumkin. Keyingi bo‘limda aynan o‘sha muammolarni hal qilib, o‘yinimizni yakunlaymiz. [Previous6.2 Aktyorlarning harakatlarini amalga oshirishchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.2_actors_movement) [Next6.4 To‘qnashuv testini o‘tkazishda e’tiborga olish kerak bo‘lgan narsalarchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.4_consider_collisions) Last updated 7 days ago sun-brightdesktopmoon Copy for block in blocks: if ball.colliderect(block): sun-brightdesktopmoon --- # 7.4 Qo‘shimcha vazifalar | Python-Pygame Zero Hozirgacha yaratgan ko‘rgan TwinBee o‘yini kloni bizning o‘rganish darajamizni inobatga olib, juda sodda asosiy funksiyalar darajasida amalga oshirilganini tushungan bo‘lsangiz kerak. Biroq, sizlarning orangizda yetarlicha qobiliyatli va yana o‘zini sinab ko‘rishga ishtiyoqi bor kishilar borligini ham bilaman. Ular uchun bajarib ko‘rish mumkin bo‘lgan vazifalarni sanab o‘tamiz va u funksiyalarning ba'zilarini qanday amalga oshirish haqida o‘rganish mumkin bo‘lgan saytlarni ko‘rsatish orqali ushbu bo‘limni yakunlaymiz. [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/twinbee/7.4_additional_challenge#sinov-vazifalari) Sinov vazifalari ------------------------------------------------------------------------------------------------------------------------------------- Quyidagilarni ketma-ket bajarib ko‘ring. ### [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/twinbee/7.4_additional_challenge#boshlangich-oyna-va-qiyinchilik-bosqichi-level) Boshlang‘ich oyna va qiyinchilik bosqichi (level) * O‘yin boshlanganda kirish oynasi(Intro) yaratib, o‘yin faqat "Boshlash" belgisi bosilganda ishga tushishini ta’minlang * O‘yinda bir nechda bosqichlar yaratib, har bir bosqichga qarab fon va dushman turlarini qo‘shing ### [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/twinbee/7.4_additional_challenge#koproq-hayotlar) Ko‘proq hayotlar * Bosh qahramonga 3 ta hayot berib, o‘yin faqat barcha hayotlar tugaganda yakunlansin ### [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/twinbee/7.4_additional_challenge#fon-grafik-effektlari) Fon grafik effektlari * Parvoz qiluvchi bulutlar qo‘shing * Fonga animatsiyon rasmlar qo‘shing, masalan, shamol tegirmonlari ### [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/twinbee/7.4_additional_challenge#kuchni-oshiruvchi-buyumlar-qoshish) Kuchni oshiruvchi buyumlar qo‘shish * Qalqon(shield) buyumi: buyum olingandan keyin qahramon atrofida qalqon hosil bo‘ladi. Dushman o‘qidan bir marta himoya qilgach, qalqon yo‘qoladi * Bomba buyumi: ekrandagi barcha dushmanlarni yo‘q qiluvchi bomba * Dron: qahramon bilan yonma-yon uchib yordam beruvchi dron buyumi (original o‘yindan ilhomlangan) ### [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/twinbee/7.4_additional_challenge#turli-dushmanlarni-qoshish) Turli dushmanlarni qo‘shish * Kuchli dushman: bir nechta o‘q bilan buzish kerak bo‘lgan dushman * Otishmachi(Shooter) dushman: barcha yo‘nalishda doimiy o‘q otuvchi dushman * Boss dushman: har bir bosqich oxirida paydo bo‘ladigan bosh dushman Yuqorida tilga olingan funksiyalarni qo‘shishni avvalo o‘zingiz mustaqil tarzda amalga oshirishga harakat qiling. Biroq, o‘ylagandek oson bo‘lmasa, [ushbu saytarrow-up-right](https://trinket.io/aposteriori/courses/intermediate-game-development-with-pygame-zero) ga murojaat qilib mustaqil o‘rganishni davom ettirishingiz mumkin. [Previous7.3 To‘qnashuvni boshqarish va boshqa ma‘lumotlar(hisob va o‘yin yakuni)ni ko‘rsatishchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/twinbee/7.3_collision_detection) [Next8\. Pong o‘yinini yaratishchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/pong) Last updated 8 months ago * [Sinov vazifalari](https://roboticsware.gitbook.io/python-pygame_zero/twinbee/7.4_additional_challenge#sinov-vazifalari) * [Boshlang‘ich oyna va qiyinchilik bosqichi (level)](https://roboticsware.gitbook.io/python-pygame_zero/twinbee/7.4_additional_challenge#boshlangich-oyna-va-qiyinchilik-bosqichi-level) * [Ko‘proq hayotlar](https://roboticsware.gitbook.io/python-pygame_zero/twinbee/7.4_additional_challenge#koproq-hayotlar) * [Fon grafik effektlari](https://roboticsware.gitbook.io/python-pygame_zero/twinbee/7.4_additional_challenge#fon-grafik-effektlari) * [Kuchni oshiruvchi buyumlar qo‘shish](https://roboticsware.gitbook.io/python-pygame_zero/twinbee/7.4_additional_challenge#kuchni-oshiruvchi-buyumlar-qoshish) * [Turli dushmanlarni qo‘shish](https://roboticsware.gitbook.io/python-pygame_zero/twinbee/7.4_additional_challenge#turli-dushmanlarni-qoshish) sun-brightdesktopmoon sun-brightdesktopmoon --- # 6.5 (Bonus) Original o‘yin kabi yaratib ko‘rish | Python-Pygame Zero Ushbu bo‘lim sizning keyingi o‘rganishingiz uchun bonusdir. Maqsad - mavjud o‘yinlarni asl o‘yin kabi hech qanday tasviriy elementlarisiz faqat kodlash orqali grafik elementlarni ifodalovchi o‘yinga aylantirish. Siz sezganingizdek, o‘zgarishlarning aksariyati UI elementlariga tegishli, shuning uchun o‘yin algoritmining o‘zida o‘zgartirish uchun ko‘p narsa yo‘q. Mavjud o‘yin sahnasi foni yo‘qoldi va o‘zgartirilishi kerak bo‘lgan yagona narsa bu o‘yin aktyorlari, masalan, to‘p, reflektor va blok to‘plami to‘g‘ridan-to‘g‘ri kod orqali yaratilgan va chizilgan qismdir. Shunday qilib, keling, har birini kodda qanday chizish mumkinligini ko‘rib chiqaylik. Birinchidan, kodlashni tushunishingizga yordam berish uchun, keling, biz yaratadigan o‘yinning yakuniy natijasini ko‘rib chiqaylik. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FZ14zNRsEOdiiO4H0k5tq%252Fimage.png%3Falt%3Dmedia%26token%3D2ab09207-007d-488d-a49a-ea39322a0027&width=768&dpr=3&quality=100&sign=bc58ce0f&sv=2) [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.5_make_original#reflektorni-chizish) Reflektorni chizish ------------------------------------------------------------------------------------------------------------------------------------- Keling, chizish uchun eng osonidan boshlaylik. Reflektor oddiygina to‘rtburchakdir(Rectangle). Mana Pygameda to‘rtburchaklar yaratish va uning ichki qismini ma’lum bir rang bilan to‘ldirish uchun kod (bu holda, qizil): circle-info To‘rtburchak Rect klassi (class) Rect(ekranda joylashadigan x-koordinata, ekranda joylashadigan y-koordinata, kenglik, balandlik) yoki Rect((ekranda joylashadigan x-koordinata, ekranda joylashadigan y-koordinata), (kenglik, balandlik)) Bu yerda Rect (to‘rtburchak) klassi yordamida yaratilgan Rect obyekti Pygame Zeroda ichki obyekt sifatida ishlatilishi mumkinligi sababli, hech qanday qo‘shimcha modul yoki kutubxonani **import** qilmasdan foydalanish mumkinligi ko‘rsatilgan. Yaratilgan to‘rtburchak (rect) obyekt ichini ma’lum bir rang bilan to‘ldirish uchun **filled\_rect** metodi ishlatiladi. Ushbu metod parametr sifatida ichini bo‘yash uchun rangni belgilaydi. **Rang qiymatlari yorug‘likning uch asosiy rangining (qizil, yashil, ko‘k) intensivligi (eng kam 0 ~ eng ko‘p 255) kombinatsiyasi orqali ifodalanadi. Har bir asosiy rangning yorug‘lik qiymatlari (Red qiymat, Green qiymat, Blue qiymat) shaklidagi** [**tuple**arrow-up-right](https://jjlee.gitbook.io/python-pygame/boilerplate#tuple) **(to‘plam) ma’lumot turi sifatida berilishi kerak. Rang ifodalash usullari haqida** [**avvalgi bob**arrow-up-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/kuchuk-mushuk_1#rgb-rang-qiymatlarining-onlik-korinishida-oq-rangni-kodlash) **da batafsil tushuntirilgan, shuning uchun o‘sha qismga murojaat qilish yoki internetdagi ko‘plab manbalar orasidan** [**ushbu blog**arrow-up-right](https://phominator.tistory.com/42) **ni ham ko‘rib chiqish mumkin.** [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.5_make_original#topni-chizish) To‘pni chizish -------------------------------------------------------------------------------------------------------------------------- Biz [oldingi bo‘lim](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.4_consider_collisions) da bilib oldikki, to‘pning mohiyati oddiy to‘rtburchak, ya’ni to‘g‘ridan-to‘g‘ri, shuning uchun to‘p ham xuddi yuqorida yaratilgan reflektor kabi Rect obyekti sifatida yaratilishi kerak. Agar buni tushunsangiz, to‘pni yasashda hech qanday qiyinchilik yo‘q. U quyidagi kod yordamida yaratilishi mumkin. Yaxshiyamki, Rect to‘rtburchak shaklida bo‘lsada, ko‘zimizga doira kabi ko‘rinadigan tarzda chizib beruvchi funksiya mavjud. **screen.draw.filled\_circle** metodiga doiraning markaz koordinatalari (to‘pning **rect** obyekti yaratilgan zahoti **center** qiymati avtomatik tarzda yaratiladi), radiusi va doirani to‘ldiruvchi rang qiymatini uzatish kifoya. Ammo, to‘pni Rect shaklida yaratganda bir qo‘shimcha muammo bor: to‘p va reflektor o‘rtasidagi to‘qnashuvni faqat Rectlar o‘rtasida tekshirish mumkin bo‘ladi. Bu holatda, oldin aytilganidek, to‘p va reflektor aslida tegmagan bo‘lsa ham, to‘qnashuv sodir bo‘lgan deb noto‘g‘ri aniqlanib, to‘p aks bilan bog‘liq xatolik (bug) yuzaga keladi. Buni qanday hal qilish mumkin? Albatta, pgzhelper modulini eslash mumkin, ammo to‘p endi rasm(image) emas, balki Rect bo‘lgani uchun, uni Actor sifatida yaratib bo‘lmaydi va shu bois bu modul yordamidan foyda olish qiyin. Bunday holda, _biz to_‘_pning to_‘_qnashuvini aniqlash uchun standart bo_‘_ladigan Rect va biz ko_‘_zimiz bilan ko_‘_radigan to_‘_pning dumaloq ko_‘_rinishi o_‘_rtasidagi munosabatni o_‘_rnatish orqali yechimni ishlab chiqishimiz mumkin. Ilgari biz faqat to_‘_pni tashqi tomondan o_‘_rab turgan Rects haqida o_‘_ylagandik, ammo Rects ham to_‘_p ichida bo_‘_lishi mumkin._ ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252Fa98IonEeex810INECkTq%252Fimage.png%3Falt%3Dmedia%26token%3Dabfd3e41-84af-4b25-bbed-bcc303f12641&width=768&dpr=3&quality=100&sign=bf5a3989&sv=2) ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FbEqWXB3HN9pGYW49Oc39%252Fimage.png%3Falt%3Dmedia%26token%3D29ca5a6b-1f4f-4cd4-9b91-6644f5a59c64&width=768&dpr=3&quality=100&sign=27d60569&sv=2) To‘p ichiga joylashtirilgan kichik Rect yordamida reflektor bilan to‘qnashuv tekshiruvini amalga oshirsak, kamida ko‘zimizga shar tegmagan bo‘lsa ham to‘qnashuv sodir bo‘layotgandek ko‘rinadigan xato(bug)ni tuzatish mumkin bo‘ladi. Ushbu fikrni inobatga olib, kod quyidagicha o‘zgartiriladi. Eslatma: _**sqrt**_ _— matematik kvadrat ildiz degani, buni kodda ifodalash uchun_ _**math**_ _kutubxonasini import qilib,_ _**sqrt**_ _funksiyasidan foydalanish kerak bo‘ladi._ [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.5_make_original#bloklar-toplamini-chizish) Bloklar to‘plamini chizish -------------------------------------------------------------------------------------------------------------------------------------------------- Bloklar to‘plami kodi ham qiyin emas. Oddiy qilib aytganda, har bir blokni mavjud kodda obyekt sifatida yaratishda siz ushbu blokni Rect sifatida yaratishingiz mumkin. Agar biz buni kodda amalga oshirsak, u quyidagicha bo‘ladi: Bu yerda blokning kengligi oldingi rasmda chizilganidek 100 piksel emas, balki 96 piksel bo‘lishining sababi shundaki, yonma-yon joylashgan bloklarni bir-biridan bo‘shliq qoldirmay ketma-ket joylashtirsak, bloklar alohida ajralib ko‘rinmay qoladi (o‘yinning yuqori qismidagi yakuniy ekran natijasiga qarang). Shu sababli, har bir blokning chap va o‘ng tomonlariga 2 piksellik bo‘sh joy qoldiriladi. Bu holat bloklarning chizilish joyini belgilashda ham hisobga olinishi kerak, shuning uchun **block\_col \* 100 + 2** deb yozilganida, qo‘shimcha 2 piksel bo‘shliq uchun qo‘shilgan. Agar buni yaxshi tushunsangiz, blokning vertikal uzunligi 25 piksel emas, balki 23 piksel bo‘lishining ham aynan shu sababga bog‘liq ekanini bilasiz. Bloklar orasidagi vertikal bo‘shliq ham 2 pikselga teng. [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.5_make_original#fon-rasmi-orniga-bosh-ekran) Fon rasmi o‘rniga bo‘sh ekran ------------------------------------------------------------------------------------------------------------------------------------------------------- Asl o‘yinda mavjud bo‘lmagan rasmli sahna(ekran) fonini ifodalovchi kodni olib tashlab, uning o‘rniga sahnaga chiqadigan aktyorlar chizilishidan avval, avvalgi chizilgan tasvirlarni tozalab, ularning ustiga yangi tasvirlar chizilishi uchun, sahna fonini quyidagi kod bilan almashtirish kerak bo‘ladi. Bu esa avvalgi tasvir izlari bilan ustma-ust chiqib ketmasligi uchun muhimdir. [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.5_make_original#barcha-kodlarni-birlashtish) Barcha kodlarni birlashtish ----------------------------------------------------------------------------------------------------------------------------------------------------- Keling, yuqorida chizilgan barcha o‘yin aktyorlarini birlashtirgan butun kodni ko‘rib chiqaylik. Boshida aytib o‘tilganidek, o‘yinning ishlash algoritmining o‘zi o‘zgarmadi. O‘zgargan yagona narsa - bu sahna fonini yo‘q qilish va o‘yin aktyorlarini to‘g‘ridan-to‘g‘ri kodlab chizish - to‘p, reflektor va bloklar to‘plami. [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.5_make_original#qoshimcha-vazifalar) Qo‘shimcha vazifalar -------------------------------------------------------------------------------------------------------------------------------------- Bu bloklarni buzadigan o‘yinni yaratish yakunlandi. Biroq, o‘yinni yanada yaxshilash uchun qo‘shilishi mumkin bo‘lgan ko‘plab xususiyatlar mavjud. Masalan, o‘yin boshidan oxirigacha to‘p tezligida o‘zgarish yo‘qligi sababli o‘yin oson va qiyinchiliksiz bo‘lib qolmasligi uchun, bloklar singanida yoki to‘pni reflektor qaytarishi soni ortishi bilan ma’lum bir vaqtga qarab to‘p tezligini bosqichma-bosqich oshiruvchi usul mavjud. O‘yin foydalanuvchiga faqat to‘pni qabul qilish imkonini berilganligi sababli, foydalanuvchiga unchalik katta erkinlik bermagani uchun unga kamroq qiziq bo‘lishi mumkin, shuning uchun foydalanuvchi to‘pni reflektorning chap yoki o‘ng tomonidagi ma’lum bir qismga ataylab tegishiga qarab to‘pni aks ettirish burchagini o‘zgartirish usulini qo‘shish o‘yin qiziqarliligini oshirish uchun yaxshi fikr bo‘ladi. Men qo‘shimcha funksiyalarni amalga oshirish vazifasini sizga qoldiraman, ammo shu paytgacha o‘qishdagi mashaqqatli mehnatingiz uchun rahmat. _Kelgusida yana bir nechta o‘yinlar yaratish orqali dasturlash jarayonida duch keladigan muammoli vaziyatlarga qanday algoritmlar bilan yondashish mumkinligini javobni ko‘rmasdan oldin o‘zingiz mustaqil o‘ylab ko‘ring._ So‘ng, **o‘sha algoritmlarni matnli kodlash uslublari ichida qanday hal qilish mumkinligini o‘zlashtirib bora olsangiz, matnli kodlash degan narsa hayotingizda duch keladigan turli muammolarni qo‘rqmasdan hal qilish uchun ishlata oladigan o‘ziga xos vosita yoki ko‘nikmalar (skillset) to‘plamiga aylanishi aniq.** Endi o‘sha kun haqida o‘ylab va uni intiqlik bilan kutib, navbatdagi o‘yinga o‘taylik! [Previous6.4 To‘qnashuv testini o‘tkazishda e’tiborga olish kerak bo‘lgan narsalarchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.4_consider_collisions) [Next7\. TwinBee otishma o‘yinini yaratishchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/twinbee) Last updated 7 days ago * [Reflektorni chizish](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.5_make_original#reflektorni-chizish) * [To‘pni chizish](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.5_make_original#topni-chizish) * [Bloklar to‘plamini chizish](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.5_make_original#bloklar-toplamini-chizish) * [Fon rasmi o‘rniga bo‘sh ekran](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.5_make_original#fon-rasmi-orniga-bosh-ekran) * [Barcha kodlarni birlashtish](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.5_make_original#barcha-kodlarni-birlashtish) * [Qo‘shimcha vazifalar](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.5_make_original#qoshimcha-vazifalar) sun-brightdesktopmoon Copy TITLE = 'Breakout' WIDTH = 800 HEIGHT = 600 RED = (200, 0, 0) GAP_FROM_SCREEN = 50 bar = Rect(WIDTH / 2, HEIGHT - GAP_FROM_SCREEN, 100, 15) draw(): screen.draw.filled_rect(bar, RED) Copy HEIGHT = 600 WHITE = (200, 200, 200) BALL_RADIUS = 10 ball = Rect(WIDTH / 2, HEIGHT / 2, BALL_RADIUS * 2, BALL_RADIUS * 2) def draw(): screen.draw.filled_circle(ball.center, BALL_RADIUS, WHITE) Copy import math HEIGHT = 600 WHITE = (200, 200, 200) BALL_RADIUS = 10 ball = Rect(WIDTH / 2, HEIGHT / 2, BALL_RADIUS * math.sqrt(2), BALL_RADIUS * math.sqrt(2)) def draw(): screen.draw.filled_circle(ball.center, BALL_RADIUS, WHITE) Copy GAP_FROM_SCREEN = 50 GOLD = (205, 145, 0) blocks = [] for block_row in range(4): for block_col in range(8): block = Rect( block_col * 100 + 2, block_row * 25 + GAP_FROM_SCREEN, 96, # blok kengligi 23 # blok balandligi ) blocks.append(block) def draw(): for block in blocks: screen.draw.filled_rect(block, GOLD) Copy screen.clear() Copy import math TITLE = 'Breakout' WIDTH = 800 HEIGHT = 600 WHITE = (200, 200, 200) RED = (200, 0, 0) GOLD = (205, 145, 0) GAP_FROM_SCREEN = 50 bar = Rect(WIDTH / 2, HEIGHT - GAP_FROM_SCREEN, 100, 15) BALL_RADIUS = 10 ball = Rect(WIDTH / 2, HEIGHT / 2, BALL_RADIUS * math.sqrt(2), BALL_RADIUS * math.sqrt(2)) # 4-qator*8-ustundan iborat bloklar to'plamini yaratish blocks = [] for block_row in range(4): for block_col in range(8): block = Rect( block_col * 100 + 2, block_row * 25 + GAP_FROM_SCREEN, 96, # blok kengligi 23 # blok balandligi ) blocks.append(block) # to'pning boshlang'ich (yo'nalish) tezligi vx = 5 vy = -5 def draw(): screen.clear() screen.draw.filled_rect(bar, RED) screen.draw.filled_circle(ball.center, BALL_RADIUS, WHITE) for block in blocks: screen.draw.filled_rect(block, GOLD) def update(): global vx, vy # ekran ichida reflektorning harakatini cheklash if bar.left < 0: bar.left = 0 if bar.right > WIDTH: bar.right = WIDTH # to'pni x va y yo'nalishlarida vx va vy masofaga mos ravishda harakatlantirish ball.move_ip(vx, vy) # to'p chap yoki o'ng devorga tegsa, x yo'nalishini teskari tomonga o'zgartirish if ball.left < 0 or ball.right > WIDTH: vx = -vx # Tezlikning x yo'nalishini teskari tomonga o'zgartirish sounds.wall.play() # to'p yuqori devorga tegsa if ball.top < 0: vy = -vy # Tezlikning y yo'nalishini teskari tomonga o'zgartirish sounds.wall.play() # to'p reflektorga tegsa if ball.colliderect(bar) == True: ball.y -= 10 # Avval vertikal ravishda 10 pikselni siljitish vy = -vy # Tezlikning y yo'nalishini teskari tomonga o'zgartirish sounds.bar.play() # to'p blokga tegsa b_index = ball.collidelist(blocks) if b_index != -1: vy = -vy # Tezlikning y yo'nalishini teskari tomonga o'zgartirish sounds.block.play() blocks.pop(b_index) # o'yin tugashi holati if ball.bottom > HEIGHT: sounds.die.play() exit() if not blocks: sounds.win.play() vx = 0 vy = 0 def on_mouse_move(pos): x, y = pos bar.centerx = x sun-brightdesktopmoon --- # 5.7 Flappy Bird o'yini uchun qo'shimcha funksiyalar (quvur pozitsiyalarini tasodiylashtirish) | Python-Pygame Zero Agar siz [Entry-Pythonarrow-up-right](https://roboticsware.gitbook.io/entry-python) kitobidan beri kuzatib borgan bo‘lsangiz, tasodifiylashtirish sizga notanish emas. Chunki u allaqachon Entry-Python kitobining [tasodifiy sonlar bobiarrow-up-right](https://roboticsware.gitbook.io/entry-python/boshlash/tasodifiy_son) da yoritilgan. Men Entry-Python va asl Python o‘rtasida ozgina farq borligini aytib o‘tgan edim. Ya'ni, tasodifiy funksiyani kodlash uchun, haqiqiy Python holatida, birinchi navbatda tasodifiy deb nomlangan modul import qilinishi kerak edi. Keling, shu qismdan boshlaylik. Shunday qilib, **biz** **original Python-da bo**‘**lganimiz sababli, tasodifiy moduldan foydalanish uchun kodimizning birinchi qatoriga tasodifiy modulni import qilishdan boshlaylik.** Bizning kodimizda quvurlarning joylashuvi qachon tasodifiy bo‘lishi kerak? Bu kamida ikkita holatda kerak bo‘ladi: birinchidan, quvur ekranning chap tomoniga chiqqanda va ekranning o‘ng tomonidan yana paydo bo‘lishi kerak bo‘lsa, ikkinchidan, o‘yin boshidan qayta boshlanganda, quvurning joylashuvi tasodifiy bo‘lsa yaxshi bo‘lardi. _**Xuddi shu kod kamida ikki marta ishlatilishi kutilayotganligi sababli, bu holda ushbu qismni funksionallashtirish haqida o‘ylash yaxshi bo‘lar edi.**_ Copy import random TITLE = 'Flappy Bird' WIDTH = 400 HEIGHT = 708 GRAVITY = 0.3 drop_speed = 0 GAP = 140 PIPE_SPEED = -3 bird_alive = True score = 0 # Actor obyekti flappy_bird = Actor('bird1', (75, 350)) top_pipe = Actor('top', (350,0)) bottom_pipe = Actor('bottom', (350, top_pipe.height + GAP)) def draw(): screen.blit('background', (0, 0)) flappy_bird.draw() top_pipe.draw() bottom_pipe.draw() screen.draw.text( str(score), color = 'white', midtop = (WIDTH/2, 10), fontsize = 70, shadow = (1, 1) ) def reset_pipes(): random_y = random.randint(-100, 100) top_pipe.y = random_y bottom_pipe.y = top_pipe.height + GAP + random_y top_pipe.x = WIDTH bottom_pipe.x = WIDTH def update(): global drop_speed, bird_alive, score drop_speed += GRAVITY flappy_bird.y += drop_speed top_pipe.x += PIPE_SPEED bottom_pipe.x += PIPE_SPEED # cheksiz quvurlar sikli if top_pipe.right < 0 or bottom_pipe.right < 0: reset_pipes() if bird_alive == True: score += 1 # quvurlar bilan to'qnashuv if flappy_bird.colliderect(top_pipe) or flappy_bird.colliderect(bottom_pipe): flappy_bird.image = "birddead" bird_alive = False # o'yinni qayta boshlash if flappy_bird.y > HEIGHT or flappy_bird.y < 0: flappy_bird.image = "bird1" bird_alive = True flappy_bird.center = (75, 350) drop_speed = 0 reset_pipes() score = 0 def on_mouse_down(): global drop_speed if bird_alive == True: drop_speed = -6.5 🔢 Yuqorida tilga olinganidek, 33~38-qatorlarda bu qism **reset\_pipes** nomi bilan funksiyaga aylantirilgan. Va bu funksiya aynan yuqorida eslatilgan ikki vaziyatda (o‘yinni qayta boshlash, quvurlarni cheksiz aylantirish) chaqirilmoqda. Endi ushbu funksiyani diqqat bilan tushunib chiqamiz. Avvalo, tasodifiy qiymatni olish uchun **random** modulidagi [**randint**arrow-up-right](https://docs.python.org/3/library/random.html#random.randint) funksiyasi chaqiriladi, bu funksiya nomidan ham ko‘rinib turibdiki, u tasodifiy butun son(integer)ni yaratadi va bu sonning eng kichik hamda eng katta qiymatlari parametr sifatida uzatiladi. Biz **randint(-100, 100)** deb yozdik, bu esa -100 dan 100 gacha bo‘lgan oraliqdagi tasodifiy butun sonni olishni anglatadi. Asosiy maqsad esa — quvurlar joylashuvini shu oraliq ichida yuqoriga yoki pastga tasodifiy (random) siljitishdir. 35~36-qatorlarda ko‘rish mumkinki, mavjud **top\_pipe.y** va **bottom\_pipe.y** qiymatlariga **random\_y** qiymatini qo‘shish orqali har ikkala quvur tasodifiy qiymat bilan yangilangan yakuniy joylashuvga ega bo‘ladi. Natijada, agar **random\_y** manfiy bo‘lsa, quvur avvalgi joyidan yuqoriga, musbat bo‘lsa — pastga siljiydi. Endi oxirida o‘yinning qiziqarliligini oshirish uchun amalga oshiriladigan narsa — Flappy Bird osmonda uchayotganida qanot qoqishini aks ettiruvchi animatsiyani qo‘shish orqali o‘yin grafik sifati darajasini oshirish qolmoqda. [Previous5.6 Flappy Bird o‘yiniga qo‘shimcha funksiyalarni joriy qilish (ball funksiyasi)chevron-left](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.6_score) [Next5.8 Flappy Bird o‘yini uchun qo‘shimcha funksiyalar (Flappy Bird animatsiyasi)chevron-right](https://roboticsware.gitbook.io/python-pygame_zero/flappy_bird/5.8_animation) Last updated 7 days ago sun-brightdesktopmoon sun-brightdesktopmoon --- # 8. Pong o‘yinini yaratish | Python-Pygame Zero Bu bobda biz birgalikda yaratib ko‘radigan o‘yin — bu 1972-yilda tashkil topgan, dunyodagi birinchi video-o‘yin kompaniyasi bo‘lish bilan birga, butun o‘yin sanoatini boshlab bergan tarixiy kompaniya — [**Atari**arrow-up-right](https://en.wikipedia.org/wiki/Atari) tomonidan tashkil topgan yili, ya’ni 1972-yilda chiqarilgan juda klassik bir o‘yindir. Bu o‘yin — tijoriy jihatdan ham muvaffaqiyatga erishgan birinchi **arkad video o‘yini** hisoblanadi. Arkad video o‘yinlari degani — hozirgi kunda kompyuter klublari (Internet Cafe) bilan almashtirilgan bo‘lsada, ilgari har mahallada uchraydigan "o‘yin avtomatlari"da, tangani solib, bir partiya o‘yin o‘ynaladigan davrdagi o‘yinlar tushuniladi. Shu o‘yin avtomatlariga o‘rnatilgan o‘yinlar arkad o‘yinlari deb ataladi. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FiSIHT61xw7fndYhMZdSG%252Fimage.png%3Falt%3Dmedia%26token%3D9c638a5a-c8b9-4978-a4c0-8a1932c7770c&width=768&dpr=3&quality=100&sign=e1963b30&sv=2) Manba: Wikipedia Biz birgalikda [Pongarrow-up-right](https://en.wikipedia.org/wiki/Pong) o‘yinining chiqarilgan paytdagi ilk versiyasining klonini (pastdagi YouTube videosiga qarang) yaratib ko‘ramiz. Qiziq bir ma’lumot sifatida, bu o‘yinga “Pong” nomi berilganining sababi — bu o‘yin “ping-pong” deb ataladigan stol tennisi o‘yinini taqlid qilib yaratilgani uchundir. Aytgancha, [6-bob](https://roboticsware.gitbook.io/python-pygame_zero/breakout) da yaratgan Breakout nomli bloklarni sindirish o‘yini Pong o‘yinining faqat ikki kishilik o‘yin bo‘lishi kamchiligini bartaraf etish uchun yaratilgan bir kishilik o‘yin versiyasidir. [Previous7.4 Qo‘shimcha vazifalarchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/twinbee/7.4_additional_challenge) [Next8.1 Protseduraviy dasturlash 1chevron-right](https://roboticsware.gitbook.io/python-pygame_zero/pong/8.1_procedural_dev1) Last updated 6 days ago sun-brightdesktopmoon sun-brightdesktopmoon --- # 7.3 To‘qnashuvni boshqarish va boshqa ma‘lumotlar(hisob va o‘yin yakuni)ni ko‘rsatish | Python-Pygame Zero Endi qolgan ikkita funksiyani yaratishni boshlaylik. Birinchi navbatda, to‘qnashuvni aniqlash(**check\_collision**) funksiyasi haqida gaplashamiz. Bu yerda aytilayotgan to‘qnashuv deganda, bosh qahramon otgan o‘q dushman samolyotiga tegishi, yoki aksincha dushman samolyotining o‘qi bosh qahramonga tegishi, va nihoyat dushman samolyoti va asosiy qahramonning bevosita to‘qnashuvi bo‘lishi mumkin, ya’ni jami uchta holat mavjud. Har bir to‘qnashuv holatiga tegishli kodni ko‘rib chiqamiz. Dushman otgan o‘q bitta emasligi sababli, ularning obyektlari ro‘yxat shaklida saqlanadi. Shuning uchun **for** operatori yordamida ro‘yxatdagi har bir o‘q bilan alohida to‘qnashuv tekshiruvi amalga oshiriladi. Agar to‘qnashuv aniqlansa, o‘q obyektining o‘zi (8-qator) va dushman samolyoti (15-qator) xotiradan olib tashlanadi. Lekin shunchaki yo‘qolib ketsa, o‘yin jozibadorligi pasayadi. Shu bois, bu holatda portlash animatsiyasi orqali o‘yinga yanada ko‘proq dinamika qo‘shiladi. E’tibor bering, dushman samolyotini yo‘q qilish usuli sifatida **del** buyrug‘i yangi sintaksisi paydo bo‘ldi, bu obyektni o‘chirish(xotiradan bo‘shatish)ning bir usulidir. Biz **enemies** ro‘yxatida **enemy** obyektlari borligini bilamiz va **enemy\_index** orqali biz o‘chirishni xohlagan obyektning joyini aniq belgilab o‘chiramiz. Avval ro‘yxatdan ma’lum qiymatni o‘chirish uchun **pop** va **remove** ichki metodlarini ishlatgan edik, bu metodlar yordamida ham o‘chirish mumkin, ammo yangi va qulay sintaksisni o‘rganish uchun bu imkoniyatdan foydalanishimiz mumkin. Portlash sahnasi 2 ta tasvirini obyektga aylantirilgan holda animatsiya ishlovidan o‘tkazildi, bunda diqqat qilish kerak bo‘lgan qism — portlash sahnasi animatsiyasini vaqt kutish yordamida yetarlicha ko‘rsatish zarur edi (13-qator, 21~23-qatorlar). Bu qism nima uchun kerakligini tushunish uchun ushbu kodni olib tashlab ishga tushirsangiz darhol tushunasiz — [avvalgi bo‘limarrow-up-right](https://roboticsware.gitbook.io/python-pygame_zero/twinbee/7.2_bullet_attack) da aytilganidek, **update** callback funksiyasining tez-tez chaqirilishi sababli animatsiyani yetarlicha ko‘rsatmasdan turib portlash obyektining o‘zini o‘chirib yuborishni oldini olish maqsadida shunday qilingan. Bundan tashqari, **score** va **game\_over** nomli ikki global o‘zgaruvchiga kelsak, dushman samolyoti yo‘q qilinib, hisob oshadigan holat (16-qator) hamda qahramon halok bo‘lib o‘yin tugaydigan holatda (27-qator) o‘zgaruvchi qiymatlari yangilanishi qo‘llanilmoqda. Copy def check_collision(): global score, game_over # Dushmanga o'q tegsa for bullet in bullets: enemy_index = bullet.collidelist(enemies) if enemy_index != -1: bullets.remove(bullet) explosion = Actor("explosion1") explosion.pos = enemies[enemy_index].pos explosion.images = ["explosion1", "explosion2"] explosion.fps = 8 explosion.duration = 15 explosions.append(explosion) del enemies[enemy_index] score += 1 # Dushman samolyoti portlash animatsiyasi for explosion in explosions: explosion.animate() explosion.duration -= 1 if explosion.duration == 0: explosions.remove(explosion) # Qahramon dushman o'qiga tegsa yoki dushman bilan to'qnashsa if player.collidelist(enemy_bullets) != -1 or player.collidelist(enemies) != -1: game_over = True Endi ekranda ma’lumot ko‘rsatish uchun **draw\_text** funksiyasini amalga oshirish bilan barcha foydalanuvchi funksiyalari tayyor bo‘ladi. **draw\_text** funksiyasi oddiy bo‘lib, quyida ko‘rsatilgandek, faqat hisob va o‘yin tugash holatini ekranda sodda ko‘rinishda aks ettiradi. Oxirgi bir narsani hal qilish kerak: o‘yin tugagandan keyin ham o‘yin davom etishiga yo‘l qo‘ymaslikdir. Bu qiyin ish emas, quyida ko‘rsatilgandek, **update** kolbek(callback) funksiyasida faqat o‘yin tugamagan paytda qahramonni boshqarish mumkin bo‘lishi uchun shart operatorini qo‘shish kifoya (8-qator). Shu bilan TwinBee o‘yini uchun mo‘ljallangan barcha funksiyalarni to‘liq amalga oshirish yakuniga yetdi. Endi esa yakuniy bosqich sifatida butun kodni to‘liq birlashtirib, ushbu bo‘limni yakunlaymiz. [Previous7.2 Aktyorlarning harakati va o‘q otish hujumini amalga oshirishchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/twinbee/7.2_bullet_attack) [Next7.4 Qo‘shimcha vazifalarchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/twinbee/7.4_additional_challenge) Last updated 6 months ago sun-brightdesktopmoon Copy def draw_text(): screen.draw.text("Score " + str(score), (50, 0), color="black", fontsize=30) if game_over: screen.draw.text( "Game over", midbottom=(WIDTH / 2, HEIGHT / 2), color="blue", fontsize=100 ) Copy def update(): for background in backgrounds: background.y += 3 if background.top > HEIGHT: background.y = (HEIGHT / 2) - HEIGHT create_enemies() if game_over == False: move_player() shoot_bullets() check_collision() Copy from pgzhelper import * import random WIDTH = 800 HEIGHT = 600 backgrounds = [] background1 = Actor("background1", (WIDTH / 2, HEIGHT / 2)) backgrounds.append(background1) background2 = Actor("background2", (WIDTH / 2, (HEIGHT / 2) - HEIGHT)) backgrounds.append(background2) player = Actor("player", (400, 500)) MAX_BULLETS = 3 bullets = [] enemies = [] enemy_bullets = [] explosions = [] score = 0 game_over = False music.play('main_theme') def move_player(): if keyboard.right: player.x += 5 if keyboard.left: player.x -= 5 if keyboard.up: player.y -= 5 if keyboard.down: player.y += 5 if player.right > WIDTH: player.right = WIDTH if player.left < 0: player.left = 0 if player.bottom > HEIGHT: player.bottom = HEIGHT if player.top < 0: player.top = 0 def shoot_bullets(): if keyboard.space and len(bullets) < MAX_BULLETS: sounds.sfx_sounds_interaction25.play() bullet_delay = 5 bullet = Actor("player_bullet") bullet.pos = player.pos bullet.angle = 90 bullets.append(bullet) for bullet in bullets: bullet.move_forward(15) if bullet.y < 0: bullets.remove(bullet) def create_enemies(): if random.randint(0, 1000) > 980: enemy = Actor("enemy1_1") enemy.images = ["enemy1_1", "enemy1_2"] enemy.fps = 5 enemy.y = -50 enemy.x = random.randint(100, WIDTH - 100) enemy.direction = random.randint(-100, -80) enemies.append(enemy) for enemy in enemies: enemy.move_in_direction(4) enemy.animate() if enemy.top > HEIGHT: enemies.remove(enemy) if random.randint(0, 1000) > 990: bullet = Actor("enemy_bullet") bullet.pos = enemy.pos bullet.angle = random.randint(0, 359) enemy_bullets.append(bullet) for bullet in enemy_bullets: bullet.move_forward(5) if bullet.x < 0 or bullet.x > WIDTH or bullet.y < 0 or bullet.y > HEIGHT: enemy_bullets.remove(bullet) def check_collision(): global score, game_over for bullet in bullets: enemy_index = bullet.collidelist(enemies) if enemy_index != -1: bullets.remove(bullet) explosion = Actor("explosion1") explosion.pos = enemies[enemy_index].pos explosion.images = ["explosion1", "explosion2"] explosion.fps = 8 explosion.duration = 15 explosions.append(explosion) del enemies[enemy_index] score += 1 for explosion in explosions: explosion.animate() explosion.duration -= 1 if explosion.duration == 0: explosions.remove(explosion) if player.collidelist(enemy_bullets) != -1 or player.collidelist(enemies) != -1: game_over = True def draw_text(): screen.draw.text("Score " + str(score), (50, 0), color="black", fontsize=30) if game_over: screen.draw.text( "Game over", midbottom=(WIDTH / 2, HEIGHT / 2), color="blue", fontsize=100 ) def draw(): for background in backgrounds: background.draw() player.draw() for enemy in enemies: enemy.draw() for bullet in bullets: bullet.draw() for explosion in explosions: explosion.draw() for bullet in enemy_bullets: bullet.draw() draw_text() def update(): for background in backgrounds: background.y += 3 if background.top > HEIGHT: background.y = (HEIGHT / 2) - HEIGHT create_enemies() if game_over == False: move_player() shoot_bullets() check_collision() sun-brightdesktopmoon --- # 9. Battle city o‘yinini yaratish | Python-Pygame Zero Ushbu bo‘limda bolalikdagi(?) o‘yin avtomatlarida ko‘p o‘ynalgan Battle City o‘yinining klonini birga yaratib ko‘ramiz. Agar hali Battle City o‘yini qanday o‘yin ekanligini yaxshi bilmaydigan yosh(?)lar bo‘lsa, YouTubega joylangan ushbu o‘yin qanday ekanligini ko‘rib chiqamiz. Bu murakkab o‘yin emas, shunchaki kompyuterga qarshi to‘p otib jang qilishga asoslangan oddiy jangari o‘yin deb tushunsa bo‘ladi. Faqat shuni aytib o‘tish kerakki, bu kursda o‘yin soddalashtirilgan versiyada bo‘ladi, chunki asl o‘yinni to‘liq nusxalash ko‘p mehnat va juda katta hajmdagi kod yozishni talab qiladi, shu sababli imkon qadar kamroq kod bilan asosiy funksiyalarni taqlid qilishni ko‘zlaymiz. Unda, keyingi bo‘limdan boshlab o‘yinni yaratishni boshlaymiz! [Previous8.8 (Bonus) Pygame Zero misoli versiyasi 2chevron-left](https://roboticsware.gitbook.io/python-pygame_zero/pong/8.8_bonus_dev2) [Next9.1 Protseduraviy dasturlash 1chevron-right](https://roboticsware.gitbook.io/python-pygame_zero/battle_city/9.1_procedural_dev1) Last updated 6 months ago sun-brightdesktopmoon sun-brightdesktopmoon --- # 8.3 Obyektga Yo‘naltirilgan Dasturlash nazariyasi (Obyektga Yo‘naltirilgan dizayn nima) | Python-Pygame Zero Endi nihoyat biz Battle City o‘ynining [obyektga yo‘naltirilganarrow-up-right](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/oop) versiyasini yaratishga urinib ko‘ramiz. Ammo Battle City o‘ynining obyektga yo‘naltirilgan versiyasini yaratishdan oldin, [protsessualarrow-up-right](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/procedural) va obyektga yo‘naltirilgan paradigmalarning farqini rasm orqali ifodalangan holda ko‘rib chiqaylik va shunday qilib, bizning yakuniy maqsadimiz bo‘lgan ikkala yondashuvning asosiy tuzulish farqini avval tushunib olaylik. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FRLEulP4wQKmLzRmuGlGu%252Fimage.png%3Falt%3Dmedia%26token%3D4889da9f-0f8a-4148-aeab-f8606b9f84b7&width=768&dpr=3&quality=100&sign=5ac9ad8&sv=2) Rasm manbasi: [https://www.altexsoft.com/blog/pros-and-cons-of-java-programming/arrow-up-right](https://www.altexsoft.com/blog/pros-and-cons-of-java-programming/) ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FNRBRmaFMKcsSTkkWBCSK%252Fimage.png%3Falt%3Dmedia%26token%3D6882fb84-e00b-43b6-8c08-6171bff717d3&width=768&dpr=3&quality=100&sign=93aff598&sv=2) Rasm manbasi: [https://en.wikipedia.org/wiki/Coupling\_(computer\_programming)arrow-up-right](https://en.wikipedia.org/wiki/Coupling_(computer_programming)) Protsedurali paradigma funksiyalar orasidagi ko‘pga-ko‘p (many-to-many) munosabatlarga asoslanadi, bu munosabatlar bir-biriga qattiq bog‘langan bo‘ladi (buni yuqori darajadagi [bog‘lanish(coupling)arrow-up-right](https://en.wikipedia.org/wiki/Coupling_(computer_programming)) deb atashadi, yuqoridagi bog‘lanish haqidagi rasmga qarang). Bu usulda funksiyalar bir-birini ogohlantirmay chaqiradi va o‘zaro bog‘liqlik (dependency) hosil qiladi. Kichik hajmdagi dasturlarda bunday yondashuv ma’lum darajada boshqarilishi mumkin, lekin dasturiy ta’minot bir marotaba yaratilib tugamaydi, balki doimiy ravishda rivojlanadi. Vaqt o‘tishi bilan yangi funksiyalar qo‘shiladi, mavjud funksiyalar yaxshilanadi, tuzatishlar va qo‘shimchalar kiritiladi, shu sababli hajmi va murakkabligi tez sur’atlarda oshadi va boshqarib bo‘lmas darajaga yetishi mumkin. Yuqori bog‘lanish qanday muammo tug‘diradi? Funksiyani yaxshilash yoki qo‘shimcha qilish uchun mavjud kodni o‘zgartirish zarur bo‘ladi, agar bog‘lanish darajasi yuqori bo‘lsa, bitta o‘zgartirish ko‘p boshqa kod qismlariga ta’sir ko‘rsatadi, natijada boshqa kod qismlarini qayta o‘zgartirish kerak bo‘ladi va bu o‘z navbatida yana boshqa kod qismlariga ta’sir qilib, [kapalak effektiarrow-up-right](https://en.wikipedia.org/wiki/Butterfly_effect) kabi tarqaladi. Yuqori murakkablik esa dasturiy ta’minotda yashirin xatoliklar (bag - ing. "bug") paydo bo‘lishiga olib keladi va kodni texnik xizmat ko‘rsatishni (maintenance) qiyinlashtiradi. Natijada, shunday aniq chegaralari bo‘lgan yondashuvni davom ettirib bo‘lmaydi va boshidan shu cheklovlarni yengib o‘tish imkonini beruvchi yangi paradigma asosidagi dasturlash dizayni zarur bo‘lib qoldi. Avvalgi funksiyalar orasidagi ko‘plab to‘g‘ridan-to‘g‘ri murojaatlar katta murakkablikning asosiy sababidir, shuning uchun butun dasturiy ta’minot tuzilishida har birining roli va mas’uliyati bo‘yicha mustaqil kod bloklariga ajratilishi mumkin bo‘lgan obyekt tushunchasi joriy qilindi. Bu yondashuvda bir obyekt boshqa obyektga to‘g‘ridan-to‘g‘ri murojaat qilmasdan, kerak bo‘lgan paytda o‘sha obyektning roli va mas’uliyatini bajarishni so‘raydi va shu tarzda mustaqil obyektlar o‘rtasidagi hamkorlik strukturasiga asoslanib butun dastur bajariladi. Bunday yondashuv o‘rtadagi bog‘lanish darajasini sezilarli darajada kamaytiradi (yuqoridagi bog‘lanish haqidagi rasmga qarang), natijada har bir obyekt kodi faqat o‘zi ichida o‘zgarishlarni amalga oshiradi va boshqa obyektlarga ta’siri minimal bo‘ladi. Bunday obyektga yo‘naltirilgan paradigma yanada rivojlantirilsa, obyektlar to‘plami mustaqil komponent ([componentarrow-up-right](https://en.wikipedia.org/wiki/Software_component) ) shaklida tashkil qilinishi mumkin va ushbu mustaqil komponentlar yig‘ilib, katta yakuniy dasturiy mahsulot yaratish darajasiga yetishi mumkin. Bunday dastur ishlab chiqish usuli Komponentga Asoslangan Dasturiy Ta’minot Ishlab Chiqish (CBD([Component-Based Developmentarrow-up-right](https://en.wikipedia.org/wiki/Component-based_software_engineering) )) deb ataladi. Ushbu yondashuvning afzalligi shundaki, yaxshi yaratilgan mustaqil komponentlarni boshqa dasturiy ta’minotlarda qayta ishlatish mumkin bo‘lib, kodning qayta foydalanish imkoniyatini ([reusabilityarrow-up-right](https://en.wikipedia.org/wiki/Reusability) ) oshiradi. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FB1MAry3S49DXPLpS2vBb%252Fimage.png%3Falt%3Dmedia%26token%3D019e5a29-3a11-422c-958e-991bd9c273a3&width=768&dpr=3&quality=100&sign=b591373a&sv=2) CBD rivojlanishiga muvofiq dasturiy ta'minot tuzilmasi (Rasm manbasi: [https://ars.els-cdn.com/content/image/3-s2.0-B978155860900650004X-f01-08-9781558609006.gifarrow-up-right](https://ars.els-cdn.com/content/image/3-s2.0-B978155860900650004X-f01-08-9781558609006.gif) ) _Obyektga yo‘naltirilgan dasturlash yuqorida aytilganidek faqatgina afzalliklarga egami? Dunyo hech narsa shunday bo‘lmaydi, albatta obyektga yo‘naltirilgan yondashuvning ham kamchiliklari bor. Eng avvalo, kod yozishni boshlashdan oldin har bir obyektni yaxshi loyihalash (dizayn qilish) uchun ko‘p vaqt va kuch sarflash talab etiladi. Loyiha uchun oldindan bilish kerak bo‘lgan ko‘plab tushunchalar mavjud va ushbu tushunchalarni mohirona qo‘llay olish, yaxshi dizaynga erishish uchun tajriba va xatolardan o‘rganish orqali sezilarli vaqt va mehnat talab qilinadi._ Shunga qaramay, biz yuqori darajadagi(?) dasturchi bo‘lishimiz uchun buni chetlab o‘tib bo‘lmaydi va albatta o‘rganishimiz kerak, shuning uchun avvaliga biroz qiyin tuyulsada, ko‘nikmaguningizcha taslim bo‘lmasdan sabr bilan oxirigacha harakat qilishingizni kutaman. Obyektga yo‘naltirilgan dizayn([OOD: Object-Oriented Designarrow-up-right](https://simple.wikipedia.org/wiki/Object-oriented_design) )ni boshlashdan oldin, avvalgi protsedurali yondashuvdan farqli tarzda fikrlashni o‘zgartirish zarur. Biz yaratmoqchi bo‘lgan dastur uchun tuzilish va dizayn qilayotganda, endi biz obyekt markazida fikrlashimiz kerak. Bu degani, dasturimizda obyekt bo‘lishi kerak bo‘lgan narsalarni aniqlab, ularning o‘zaro hamkorlik tuzilmasini qanday yaratishni o‘ylash jarayonidir. Ammo, yaxshiyamki, biz Entry blokli kodlashdan boshlab bilib-bilmay bunday yondashuvga allaqachon o‘rganib qolganmiz. Ayniqsa, yaratayotgan o‘yin dasturimizda obyektlarni aniqlash oson, chunki o‘yin sahnasida ishtirok etuvchi qahramonlar (aktyorlar) asosida obyektga yo‘naltirilgan tuzilmani tashkil qilish mumkin. Obyektlar aniqlangach, har bir obyektning bajarishi kerak bo‘lgan roli (Role) va mas’uliyati (Responsibility), shuningdek, obyektlar o‘rtasida hamkorlik uchun yuborilishi kerak bo‘lgan xabarlar (Message) haqida o‘ylashni boshlash kerak. Qo‘shimcha ma’lumot uchun, mas’uliyat — bu obyektning tashqi, ya’ni obyekt foydalanuvchilariga taqdim eta oladigan xizmatlar ro‘yxatidir (obyektga yo‘naltirilgan dasturlashda buni ommaviy interfeysi(public interface) deb atashadi). Avvalo esda tutish kerak bo‘lgan narsa, _funksiyalashtirish jarayonida bo‘lgani kabi, kodning qaysi qismini qayergacha funksiyalashtirish masalasida aniq javob yo‘qligi singari, OOD da ham “mana bunday qilish to‘g‘ri” degan 100% to‘g‘ri javob mavjud emas. Dizayn tuzishda “bunday mezonlar asosida ishlash kerak” deb qabul qilingan prinsiplar (masalan,_ [_SOLID printsiplari_arrow-up-right](https://simple.wikipedia.org/wiki/SOLID_(object-oriented_design)) _) mavjud, xolos._ Aslida dizayn haqidagi bilimlarni chuqur o‘rganmoqchi bo‘lsangiz, bu universitetda kamida bir semestr davomida o‘tiladigan hajmdagi mavzu bo‘lib, ushbu kitob darajasida bu qadar chuqur borish ortiqcha bo‘ladi. Shu sababli, murakkablik darajasini muvofiqlashtirish maqsadida barcha dizayn prinsiplarini oldindan batafsil o‘rganib chiqib, ularni birma-bir qo‘llab tushuntirishdan ko‘ra, sizning tushunishingizga katta qiyinchilik tug‘dirmaydigan darajada murosaviy chegarada obyektga yo‘naltirilgan dizaynni qo‘llash rejalashtirilgan, va yanada chuqurroq o‘rganish bilan birga o‘rganilgan dizaynni har xil shakllarda o‘zgartirib qo‘llab ko‘rish esa har biringizning shaxsiy vazifangiz bo‘lib qolishini oldindan tushunishingizni so‘rayman. [Previous8.2 Protseduraviy dasturlash 2chevron-left](https://roboticsware.gitbook.io/python-pygame_zero/pong/8.2_procedural_dev2) [Next8.4 Obyektga Yo‘naltirilgan Dasturlash nazariyasi (foydalanuvchi aniqlagan obyekt yaratish, meros)chevron-right](https://roboticsware.gitbook.io/python-pygame_zero/pong/oop_inheritance) Last updated 6 months ago sun-brightdesktopmoon sun-brightdesktopmoon --- # Mu editorining tezkor tugmalari | Python-Pygame Zero Qo'shimcha ma'lumot uchun [shu yerarrow-up-right](https://codewith.mu/en/tutorials/1.2/shortcuts) ga kiring. [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/appendix/shortcuts#windows-uchun) Windows uchun ----------------------------------------------------------------------------------------------------------------- Funksiya Tezkor tugma Muning qaysi versiyalarda Indentatsiya darajasini sozlash Tab, Shift + Tab Tanlangan qatorni izoh qilish Ctrl + K Joriy qatorni tozalash Ctrl + L Izlash (so'zni) Ctrl + F Oldinga izlash F3 Orqaga izlash Shift + F3 Kodlash oynasini kattalashtirish/kichraytirish Ctrl + Shift + = , Ctrl + - Kodni boslash va to'xtatish F5 Kodni tekshirish F2 Kodlash rejimini o'zgartirish Ctrl + Shift + M Sozlamalar oynasini ochish Ctrl + Shift + D Kodlash ekranini suratga olish (skrinshot) Ctrl + Alt + S Kodlash ekranini suratga olish (skrinshot) Ctrl + Shift + S Joriy tab (oyna) ni yopish Ctrl + W Maxsus 1.2.5 va keyingi Tablar orasida chapga/o'ngga ko'chirish Ctrl + , yoki Ctrl + . Maxsus 1.2.6 va keyingi ### [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/appendix/shortcuts#mac-uchun) [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/appendix/shortcuts#mac-uchun-1) Mac uchun ----------------------------------------------------------------------------------------------------------- Windows tezkor tugmalariga o'xshash, faqat Ctrl tugmasi o'rniga Command tugmasidan foydalanish kerak. [PreviousO'yinimizni EXE fayliga aylantirishchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/appendix/packaging) Last updated 9 months ago * [Windows uchun](https://roboticsware.gitbook.io/python-pygame_zero/appendix/shortcuts#windows-uchun) * [Mac uchun](https://roboticsware.gitbook.io/python-pygame_zero/appendix/shortcuts#mac-uchun-1) sun-brightdesktopmoon sun-brightdesktopmoon --- # 8.6 Obyektga yo‘naltirilgan dasturlash 2 | Python-Pygame Zero Endi qolgan to‘p(Ball) obyektiga va reflektor(Bar) obyektiga nazar tashlaymiz. Avvalo, Ball obyektidan boshlaymiz. U Rect obyektidan meros olgan bo‘lib, **Rect**ning o‘zi esa Pygame Zero kutubxonasining asosi bo‘lgan [Pygame ichida mavjud obyektarrow-up-right](https://www.pygame.org/docs/ref/rect.html) hisoblanadi. Asosiy vazifasi shundaki, biz Actor obyektida quyidagidek ichki o‘rnatilgan joylashuv ma’lumotlaridan foydalanishimiz mumkinligini o‘rgangan edik, aslida esa bu joylashuv ma’lumotlarining o‘zi Rect obyektida joylashgan. Actor obyektining Rect obyektini meros qilib ishlatishi sababli, Actor obyekti ham aslida ota obyektga tegishli bo‘lgan ushbu joylashuv xususiyatlarini xuddi o‘zida azaldan mavjud bo‘lgandek ishlata oladi. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FmWcGn33yWgSYN5jtycqS%252Fimage.png%3Falt%3Dmedia%26token%3D8ba7d20d-f0e2-409d-8fb3-44af7e534a05&width=768&dpr=3&quality=100&sign=4c061d3&sv=2) 🔢 7-qatorda Rect ota obyektini yaratishda uzatilishi kerak bo‘lgan 4 ta boshlang‘ich qiymat (x koordinata, y koordinata, kenglik, balandlik) yuborilib, ota obyekt inisializatsiya qilinmoqda. Bu yerda (x, y) koordinatalari (0, 0) sifatida berilgan, lekin aslida nima qiymat bershingiz katta ahamiyatga ega emas. Sababi 8-qatorning o‘zida ushbu obyektning markaz koordinatasi darhol **start\_pos** parametri qiymatiga almashtiriladi. To‘p obyektini yaratishda uzatilishi kerak bo‘lgan parametrlar orasida hisob (**score**) obyekti ham bo‘lishi shart. Bu, to‘p obyekti ichida hisob obyektiga nisbatan bog‘liqlik (dependency) paydo bo‘lishini anglatadi: to‘p obyekti hisob obyektidan qandaydir harakatni so‘rashi yoki u tashqaridan o‘zgartirishga ruxsat bergan xususiyatlarni bevosita o‘zgartirishi mumkin. Bu yerda birinchi holat ishlatiladi: **collide\_wall** funksiyasida to‘pning chap/ong (ekran) devorlari bilan to‘qnashuvi — har bir o‘yindagi g‘alaba–mag‘lubiyatning aniqlanishi — ro‘y beradi va shu paytda g‘olib tomonga ball qo‘shish uchun hisob obyektining add **ochiq metod**ini chaqirib, qiymat oshiriladi. circle-info **Ochiq funksiyalar yoki ochiq metodlar(public method) degani nima?** Boshqa obyekt bilan o‘zaro ta’sir qilish maqsadida, boshqa obyekt uni chaqirib, ma’lum bir harakatni bajarishga undashi uchun tashqi tomonga ochiq qilingan a’zo funksiyani shunday atashadi. Uning aksi esa yopiq(private) metod deb yuritiladi. 🔢 26-qatordagi **move** funksiyasi ichida ishlatilgan **move\_ip** funksiyasini chaqirish usuliga diqqat bilan qarasak, u **self** orqali chaqirilayotganini ko‘ramiz. Bu ham meros olish natijasidir: **move\_ip** funksiyasi **Ball** obyekti ichida aniqlangan a’zo funksiya bo‘lmasa ham, go‘yo unda mavjuddek chaqirilmoqda. Ya’ni, **move\_ip** funksiyasi aslida ota bo‘lgan Rect obyekti ichida mavjud va farzand bo‘lgan Ball obyekti uni xuddi o‘zining bir qismi kabi ishlata oladi. Keyingi, reflektor obyektini ko‘rib chiqamiz. Reflektor obyektiga ham Rect obyekti ota sifatida meros qilingan. A’zo funksiyalar tarkibiga e’tibor bilan qarasak, obyektni yuqoriga va pastga harakatlantirish harakatini bajarishga mo‘ljallangan alohida funksiyalarga ega. Bu harakatlar davomida funksiya ichida reflektorning ekrandan chiqib ketmasligini ta’minlovchi cheklovlar mavjud. Xuddi shuningdek, bu obyekt ham tashqi obyekt bo‘lgan to‘p (Ball) obyektini **ball** parametri sifatida qabul qiladi va shu orqali to‘p obyektiga bog‘liqlik hosil qiladi. Bu bog‘liqlikning maqsadi ham avvalgi to‘p obyektining hisob obyektiga bo‘lgan bog‘liqligiga o‘xshaydi: reflektor to‘p bilan to‘qnashuvni tekshirib, to‘pning qaytarish harakatini yaratish uchun uning harakat yo‘nalishini qarama-qarshi tomonga o‘zgartirish jarayonini bajaradi. Shu bilan biz yaratmoqchi bo‘lgan Pong o‘yinining obyektga yo‘naltirilgan versiyasining yakuniy variantini tugatdik. Boshqalar yaratib bergan obyektlardan foydalanish bilangina cheklanmay, qanday o‘zingizning foydalanuvchi obyektlaringizni yaratib, ular o‘rtasidagi hamkorlik orqali obyektga yo‘naltirilgan paradigma asosida ishlab ko‘rish yangicha tajriba bo‘lgandek tuyuldimi? Shunday bo‘lsa kerak deb o‘ylayman. Biroq hali ham obyektga yo‘naltirish murakkabdek, katta afzalligi sezilmagandek his qilishingiz mumkin. Aslida bu o‘yin tuzilmasi juda sodda bo‘lgani uchun obyektga yo‘naltirishning yirik afzalliklari to‘liq namoyon bo‘lmadi. Shunga qaramay, agar Entry blokli kodlashda obyekt tushunchasi bilan o‘ylab, kod yozganingizdagi qulaylik(?) hissi biroz bo‘lsa ham qayta esga tushgan bo‘lsa, shu o‘ziyoq obyektga yo‘naltirilgan paradigmaga muvaffaqiyatli kirib kelganingizdan darak beradi. Hali birinchi qadamdanoq “to‘ygandek” bo‘lish qiyin. Keyingi o‘yinlardan boshlab doim obyektga yo‘naltirilgan usulda o‘yin yasab, asta-sekin bu tushunchalarga yanada ko‘proq ko‘nikib borasiz. Endi esa, hozirgacha yozgan kodlarimizning to‘liq manbasini joylashtirish bilan ushbu bo‘limni yakunlaymiz. O‘yinning boshida aytilganidek, barcha manba kod bitta fayl ichida jamlanganini yodda tuting. [Previous8.5 Obyektga yo‘naltirilgan dasturlash 1chevron-left](https://roboticsware.gitbook.io/python-pygame_zero/pong/8.5_oop_dev1) [Next8.7 (Bonus) Pygame Zero misoli versiyasi 1chevron-right](https://roboticsware.gitbook.io/python-pygame_zero/pong/8.7_bonus_dev1) Last updated 6 months ago sun-brightdesktopmoon Copy class Ball(Rect): ''' To'pning harakati (joylashuvi, harakalanishi) va to'qnashuvni tekshirish ''' def __init__(self, start_pos, velocity, score): super().__init__(0, 0, BALL_RADIUS * math.sqrt(2), BALL_RADIUS * math.sqrt(2)) self.center = start_pos self._velocity = velocity self.vx = self.vy = self._velocity self._score = score def reset(self): if self._score.is_game_over(): self.vx = self.vy = 0 else: self.vx = self.vy = self._velocity self.vx *= random.choice([-1, 1]) # Markaziy chiziqdan tasodifiy chapga va o'ngga tashlash self.center = (WIDTH/2 , random.randint(BALL_RADIUS*2, \ HEIGHT - BALL_RADIUS*2)) def move(self): # To'pni vx va vy tezliklari bilan harakatlantirish self.move_ip(self.vx, self.vy) def collide_wall(self): # Yuqori yoki pastki devor if self.top < 0 or self.bottom > HEIGHT: self.vy = -self.vy # Tezlikning y yo'nalishini teskari o'zgartirish sounds.wall.play() # chap devor if self.left < 0: self._score.add('b2') += 1 sounds.die.play() self.reset() # o'ng devor if self.right > WIDTH: self._score.add('b1') += 1 sounds.die.play() self.reset() def draw(self): screen.draw.filled_circle(self.center, BALL_RADIUS, 'white') Copy class Bar(Rect): def __init__(self, x, y, ball): super().__init__(x, y, BAR_W, BAR_H) self.ball = ball def up(self): if self.y > 0: self.y -= 7 def down(self): if self.y + self.height < HEIGHT: self.y += 7 def collide_ball(self): if self.colliderect(self.ball): # Avval 10 piksel oldinga o'tish if self.ball.vx < 0: # bar1 holatida self.ball.x += 10 else: # bar2 holatida self.ball.x -= 10 self.ball.vx = -self.ball.vx * SPEED_UP # Tezlikning x yo'nalishini teskari o'zgartirish ''' To‘p yuqori tomondan kirib, reflektorning yuqori qismiga urilganda yoki to‘p pastki tomondan kirib, reflektorning pastki qismiga urilganda, kirish yo‘nalishi o‘zgarmay aks etadi ''' if (self.ball.vy > 0 and self.ball.centery < self.centery) or \ (self.ball.vy < 0 and self.ball.centery > self.centery): self.ball.vy = -self.ball.vy * SPEED_UP sounds.bar.play() def draw(self): screen.draw.filled_rect(self, 'white') pong\_oop.py Copy import random import math # o'yin oynasi TITLE = 'pong' WIDTH = 800 HEIGHT = 600 # qaytargich BAR_H = 100 BAR_W = 15 GAP_FROM_SCR = 20 # to'p BALL_RADIUS = 10 VELOCITY = 5 SPEED_UP = 1.08 # hisob FINAL_SCORE = 11 class Score(): ''' Ekranda hisob va g'alaba/mag'lubiyat UI ni ifodalash ''' def __init__(self, final_score): self._final_score = final_score self._b1_score = -1 self._b2_score = -1 def _gameover_draw(self): if self._b1_score == self._final_score: winner = 'Player1' elif self._b2_score == self._final_score: winner = 'Player2' if winner: screen.draw.text(winner + ' Win!!', (WIDTH/3, HEIGHT/2 - 50), color='blue', fontsize=70) screen.draw.text('Press Space to play again', (WIDTH/4, HEIGHT/2 + 50), color='skyblue', fontsize=50) def is_game_over(self): if (self._b1_score == self._final_score or self._b2_score == self._final_score) \ or (self._b1_score == -1 and self._b2_score == -1): return True else: return False def add(self, who): if who == 'b1': self._b1_score += 1 elif who == 'b2': self._b2_score += 1 def reset(self): self._b1_score = 0 self._b2_score = 0 def draw(self): screen.draw.text(str(self._b1_score), (WIDTH/4, GAP_FROM_SCR), color='yellow', fontsize=60) screen.draw.text(str(self._b2_score), ((WIDTH/4)*3, GAP_FROM_SCR), color='yellow', fontsize=60) if self.is_game_over(): self._gameover_draw() class Ball(Rect): ''' To'p harakati va joylashuvi, va to'qnashuvni aniqlash ''' def __init__(self, start_pos, velocity, score): super().__init__(0, 0, BALL_RADIUS * math.sqrt(2), BALL_RADIUS * math.sqrt(2)) self.center = start_pos self._velocity = velocity self.vx = self.vy = self._velocity self._score = score def reset(self): if self._score.is_game_over(): self.vx = self.vy = 0 else: self.vx = self.vy = self._velocity self.vx *= random.choice([-1, 1]) # Markaziy chiziqdan tasodifiy chapga va o'ngga tashlash self.center = (WIDTH/2 , random.randint(BALL_RADIUS*2, \ HEIGHT - BALL_RADIUS*2)) def move(self): # To'pni vx va vy tezliklari bilan harakatlantirish self.move_ip(self.vx, self.vy) def collide_wall(self): # Yuqori yoki pastki devor if self.top < 0 or self.bottom > HEIGHT: self.vy = -self.vy # tezlikning y o'qini teskari tomonga o'zgartirish sounds.wall.play() # chap devor if self.left < 0: self._score.add('b2') sounds.die.play() self.reset() # o'ng devor if self.right > WIDTH: self._score.add('b1') sounds.die.play() self.reset() def draw(self): screen.draw.filled_circle(self.center, BALL_RADIUS, 'white') class Bar(Rect): def __init__(self, x, y, ball): super().__init__(x, y, BAR_W, BAR_H) self.ball = ball def up(self): if self.y > 0: self.y -= 7 def down(self): if self.y + self.height < HEIGHT: self.y += 7 def collide_ball(self): if self.colliderect(self.ball): # Avval 10 piksel oldinga o'tish if self.ball.vx < 0: # bar1 holatida self.ball.x += 10 else: # bar2 holatida self.ball.x -= 10 self.ball.vx = -self.ball.vx * SPEED_UP # Tezlikning x yo'nalishini teskari o'zgartirish ''' To‘p yuqori tomondan kirib, reflektorning yuqori qismiga urilganda yoki to‘p pastki tomondan kirib, reflektorning pastki qismiga urilganda, kirish yo‘nalishi o‘zgarmay aks etadi ''' if (self.ball.vy > 0 and self.ball.centery < self.centery) or \ (self.ball.vy < 0 and self.ball.centery > self.centery): self.ball.vy = -self.ball.vy * SPEED_UP sounds.bar.play() def draw(self): screen.draw.filled_rect(self, 'white') # qahramon obyektlarini yaratish score = Score(FINAL_SCORE) ball = Ball((WIDTH/2, HEIGHT/2), VELOCITY, score) bar1 = Bar(GAP_FROM_SCR, HEIGHT/2 - BAR_H/2, ball) bar2 = Bar(WIDTH - BAR_W - GAP_FROM_SCR, HEIGHT/2 - BAR_H/2, ball) bars = [bar1, bar2] def draw(): screen.clear() screen.draw.line((WIDTH/2, GAP_FROM_SCR), (WIDTH/2, HEIGHT - GAP_FROM_SCR), \ color='grey') if not score.is_game_over(): ball.draw() bar1.draw() bar2.draw() score.draw() def update(): # qaytargich if keyboard.a: bar1.up() if keyboard.z: bar1.down() if keyboard.up: bar2.up() if keyboard.down: bar2.down() for bar in bars: bar.collide_ball() # o'yin boshlanish shartlari if score.is_game_over(): if keyboard.space: score.reset() ball.reset() else: # to'p ball.move() ball.collide_wall() sun-brightdesktopmoon --- # 8.1 Protseduraviy dasturlash 1 | Python-Pygame Zero Quyida ko‘rsatilgan o‘yin yakuniy natijasini avval ko‘rib chiqadigan bo‘lsak, kodni tushunish ancha osonlashadi. Biz ushbu o‘yinni ikkita dasturlash paradigmasi ([protsessualarrow-up-right](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/procedural) va [obyektga yo‘naltirilganarrow-up-right](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/oop) ) yordamida ikki xil versiyada yaratib ko‘ramiz. Avvalgi bobda aytib o‘tilganidek, o‘z obyektimizni yaratish va undan foydalanishni o‘rganish orqali hozirda keng qo‘llanilayotgan obyektga yo‘naltirilgan dasturlashning ilgari qo‘llanilgan protsessual usuldan qanday jiddiy farqlari borligini tushunib olish va obyektga yo‘naltirilgan paradigmaga kirishish shu bobning vazifasi hisoblanadi. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FgMyr77ffQ7Anto9rIdBR%252Fimage.png%3Falt%3Dmedia%26token%3Dd6ddaf41-105d-4d2d-98c6-198f4f4bf94f&width=768&dpr=3&quality=100&sign=70cb1ed&sv=2) Biz allaqachon 5~7-boblar davomida 3 ta o‘yin muvaffaqiyatli yaratdik, shuning uchun endi o‘zimizni boshlang‘ich bosqichidan o‘tgan deb hisoblashimiz mumkin. Shu sababli, ushbu bobdan boshlab ilgari batafsil tushuntirilgan asosiy tushunchalarni qayta-qayta takrorlash o‘rniga, kodning asosiy va muhim qismlarini tezkor va mazmunli tarzda tushuntirib borish sizga nisbatan hurmat(?) bo‘ladi deb o‘ylayman. Ma’lumot uchun, ushbu o‘yinni yaratish uchun kerakli ovoz va boshqa resurslarni [**bu yerdan**arrow-up-right](https://github.com/roboticsware/python-pygame_zero-samples/tree/main/breakout/images) yuklab olishingiz mumkin. Shuningdek, o‘yinda kerak bo‘ladigan effekt ovozlar allaqachon **sounds** papkasida saqlangan deb hisoblab ishni boshlaymiz. Yoki agar siz [**maxsus Mu Editor**arrow-up-right](https://github.com/roboticsware/mu/releases) dasturidan foydalanayotgan bo‘lsangiz, uning ishchi katalogi bo‘lgan (foydalanuvchi\_nomi)\\mu\_code\\examples\\pygame\_zero ichidan kerakli resurslarni nusxalab olishingiz mumkin. Avvalo protsessual(procedural) uslubda dasturlashni boshlaymiz. Ushbu o‘yin ikki foydalanuvchi bir-biriga to‘pni qaytarib o‘ynaydigan tennis ga o‘xshash o‘yindir. Tuzilishi jihatidan esa, to‘p va uni qaytaruvchi - reflektor ishlatiladi, bu esa ilgari yaratgan [original Breakout](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.5_make_original) o‘yinining biroz kengaytirilgan shakli deb qaralishi mumkin. Breakout o‘yinida reflektor (yoki “raketka” deb ataladi) bitta edi, bu o‘yinda esa har bir foydalanuvchi alohida boshqaradigan ikkita reflektor mavjud bo‘ladi — bu esa asosiy farqlardan biridir. 🔢 Bundan tashqari, 6-bobda yaratgan **Breakout** o‘yinidan farqli jihati shundaki, bu 2 kishilik o‘yin bo‘lishiga qaramay, 1 kishilik kabi darhol boshlanib ketsa chalkashlik tug‘dirishi mumkin. Shu sababli, ikki o‘yinchi tayyor bo‘lganda **bo‘sh joy (space) tugmasi** bosilishi orqali o‘yin boshlanadi. Yakuniy g‘alaba yoki mag‘lubiyat aniqlangach ham, yana bo‘sh joy tugmasi orqali o‘yinni qayta boshlash imkoniyati taqdim etiladi. Bu bilan bog‘liq kodda, 22~23-qatorlarda hisobning boshlang‘ich qiymatini -1 deb belgilash orqali o‘yin hali boshlanmagan holatda ekanligi ajratib ko‘rsatilgan. Space tugmasi bosilgach, 72-qatordan pastdagi kodlar ishga tushadi va o‘yin boshlanadi. 🔢 Yuqoridagi **30-qatorgacha bo‘lgan kod** — bu o‘yin sahnasidagi aktyor obyektlarini yaratish uchun mo‘ljallangan. Bu yerda **to‘p (ball)** va **2 ta reflektor (bar)** yaratiladi. Har bir obyektni yaratish qismi avvalgi **Breakout** o‘yinidagisidan unchalik farq qilmaydi. E’tibor berish kerak bo‘lgan jihat — bu yerda aktyor obyektlari **Actor** klassi orqali emas, [**Rect**](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.5_make_original) klassi orqali yaratilgan obyektlar ekanligidir. Hozirda protseesual(procedural) usulda ishlab chiqishga qaror qilganimiz sababli, kerakli funksiyalarni funksiyalashtirish (functionalize) kerakligini o‘rgandik. Ushbu o‘yinda ham funksiyalashtirishni amalga oshiraylik. **Kod yozishda doimo yodda tutish kerak bo‘lgan narsa – bu siz va boshqalar uchun oson o‘qiladigan bo‘lishi va keyinchalik o‘zgartirishlarga tayyor bo‘lishi, ya’ni texnik xizmat (maintenance) nuqtai nazaridan hisobga olinishi kerak.** Aslida, funksiyalar aynan shunday ehtiyojlar sababli paydo bo‘lgan deb aytish mumkin. Funksiyaning asosiy maqsadi — koddagi takrorlanishlarni kamaytirish. Biroq, ushbu o‘yinda bir nechta obyektlar tomonidan umumiy foydalaniladigan funksiyalarga bog‘lash mumkin bo‘lgan holatlar ko‘p emas. Shunga qaramay, bir xil maqsad va funksiyaga ega bo‘lgan ikkita qaytargich (reflektor) obyekt mavjud bo‘lib, ular uchun umumiy funksional maqsadga mos keladigan **bar\_move\_collide** funksiyasini qo‘shamiz. Qolgan funksiyalar (**reset\_ball**, **ball\_move\_collide**, **gameover\_draw**) esa umumiy foydalanish uchun emas, balki funksional jihatdan ajratilgan funksiyalar hisoblanadi. 🔢 Keyingi bo‘limdan boshlab yuqorida tilga olingan funksiyalarning amalga oshirilishini ko‘rib chiqamiz, hozir esa o‘sha funksiyalarni hisobga olmagan holda qolgan kodlarni yanada chuqurroq ko‘rib chiqaylik. Hozirgacha barcha jarayonlarni birgalikda o‘rganib kelgan sizlarning darajangizdan kelib chiqib aytadigan bo‘lsak, bu joylarning aksariyati ilgari allaqachon o‘rgangan narsalarning biroz o‘zgartirilgan shakli bo‘lib, mulohaza bilan qaralsa deyarli hammasini tushunish mumkinligiga ishonaman. Sizlar ilgari blok sindirish (block breaker) o‘yinini yakunlaganingizda taklif qilingan [qo‘shimcha sinov vazifalarini](https://roboticsware.gitbook.io/python-pygame_zero/breakout/6.5_make_original) eslaysizmi? O‘sha vazifalarni o‘zingiz mustaqil tarzda qo‘shimcha funksiyalar sifatida amalga oshirib ko‘rganmisiz, bilmayman. Bu safargi Pong o‘yinida esa o‘sha qo‘shimcha vazifalarda taklif etilgan funksiyalarni ham o‘z ichiga olgan holda amalga oshiramiz. Shuning uchun, o‘yinga ko‘proq qiziqish qo‘shish maqsadida ikki o‘yinchi tezda g‘oliblikka erisha olmay, ketma-ket zarbalar uzoq davom etsa, to‘pning harakat tezligini asta-sekin oshirish uchun 18-qatorga **SPEED\_UP** qiymati miqdorida tezlikni oshiruvchi algoritm qo‘shilishi rejalashtirilgan va aynan shu maqsadda ishlatish uchun [makroarrow-up-right](https://en.wikipedia.org/wiki/Macro_(computer_science)) (Macro) oldindan e’lon qilib qo‘yilgan. Endi esa, keyingi bo‘limdan boshlab foydalanuvchi funksiyalarimizning amalga oshirilishini aniq va batafsil tarzda to‘ldirib chiqamiz. [Previous8\. Pong o‘yinini yaratishchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/pong) [Next8.2 Protseduraviy dasturlash 2chevron-right](https://roboticsware.gitbook.io/python-pygame_zero/pong/8.2_procedural_dev2) Last updated 6 days ago sun-brightdesktopmoon Copy import math import random # o'yin oynasi TITLE = 'pong' WIDTH = 800 HEIGHT = 600 GAP_FROM_SCR = 20 # reflektor BAR_H = 100 BAR_W = 15 # to'p vx = 5 vy = 5 BALL_RADIUS = 10 SPEED_UP = 1.05 # hisob FINAL_SCORE = 11 b1_score = -1 b2_score = -1 # aktyor obyektlari ball = Rect(WIDTH/2, HEIGHT/2, \ BALL_RADIUS * math.sqrt(2), BALL_RADIUS * math.sqrt(2)) bar1 = Rect(GAP_FROM_SCR, HEIGHT/2 - BAR_H/2, BAR_W, BAR_H) bar2 = Rect(WIDTH - BAR_W - GAP_FROM_SCR, HEIGHT/2 - BAR_H/2, BAR_W, BAR_H) bars = [bar1, bar2] def reset_ball(): pass def ball_move_collide(): pass def gameover_draw(): pass def bar_move_collide(player): pass def draw(): screen.clear() # o'rta chiziq screen.draw.line((WIDTH/2, GAP_FROM_SCR), (WIDTH/2, HEIGHT - GAP_FROM_SCR), color='grey') # aktyor screen.draw.filled_circle(ball.center, BALL_RADIUS, 'white') for bar in bars: screen.draw.filled_rect(bar, 'white') # hisob screen.draw.text(str(b1_score), (WIDTH/4, GAP_FROM_SCR), color='yellow', fontsize=60) screen.draw.text(str(b2_score), ((WIDTH/4)*3, GAP_FROM_SCR), color='yellow', fontsize=60) if b1_score == FINAL_SCORE or b2_score == FINAL_SCORE: gameover_draw() def update(): global b1_score, b2_score # to'p ball_move_collide() # reflektor for bar in bars: bar_move_collide(player) # o'yin boshlanish shartlari if (b1_score == FINAL_SCORE or b2_score == FINAL_SCORE) or \ (b1_score == -1 and b2_score == -1): if keyboard.space: b1_score = 0 b2_score = 0 reset_ball() else: # to'p ball_move_collide() sun-brightdesktopmoon --- # 8.4 Obyektga Yo‘naltirilgan Dasturlash nazariyasi (foydalanuvchi aniqlagan obyekt yaratish, meros) | Python-Pygame Zero Biz aynan obyektga yo‘naltirilgan dizaynga kirishishdan oldin obyektning o‘zini chuqurroq o‘rganishimiz kerak, chunki hozirgacha faqat boshqalar tomonidan yaratilgan obyektlardan foydalanadigan kod yozdik, endi esa o‘zimizga obyekt (foydalanuvchi tomonidan aniqlangan obyekt: User Defined Object) yaratib, undan foydalanish orqali obyektni yanada chuqurroq tushunib chiqamiz. Bizga tanish bo‘lgan real hayotdagi obyektdan birini misol qilib olib, uni dasturlash olamiga moslashtirib obyektlashtirib ko‘raylik. Real avtomobilni dasturlash olamidagi avtomobil obyektiga aylantirib ko‘raylik. Obyektlashtirishda avvalo obyekt ichida mavjud bo‘lgan **xususiyat (attribute)/xatti-harakat (behavior)** nuqtai nazaridan qaralishi kerak. Xususiyat degani — avtomobilning o‘ziga xos belgilari bo‘lib, masalan, barcha avtomobillarda uchrashi mumkin bo‘lgan umumiy belgilar sifatida korpus shakli (body), dvigatel turi (engine), g‘ildiraklar turi (wheels) keltirilishi mumkin va **bular obyekt ichida o‘zgaruvchi qiymatlar orqali ifodalanadi.** _Aslida avtomobilga xos belgilar bundan ham ko‘p, lekin ularning barchasini ifodalash shart emas, faqat dasturimiz maqsadini amalga oshirish uchun kerakli jihatlarigina olinadi._ Endi avtomobil bajarishi mumkin bo‘lgan harakatlar haqida o‘ylab ko‘raylik. Avtomobilning **bajarishi mumkin bo‘lgan harakatlar**i, masalan: harakatlanish (drive), to‘xtash (brake), burilish (turn) kabi xatti-harakatlar bo‘lib, bular **dasturlash tilida obyekt ichidagi metodlar (ya’ni obyekt ichida joylashgan funksiyalar) orqali ifodalanadi**. _Xuddi atributlar (xususiyatlar) kabi, avtomobilning bajarishi mumkin bo‘lgan harakatlari ham aslida juda ko‘p bo‘lishi mumkin. Biroq, ularning barchasini ifodalash shart emas, faqat bizning dasturimizning maqsadiga xizmat qiladigan zarur metodlargina yetarli bo‘ladi._ Harakatlanish, to‘xtash yoki burilish harakatlari natijasida hozirgi avtomobil holatini (state) ifodalash uchun qo‘shimcha ravishda (hozirgi) tezlik (speed), (hozirgi) yo‘nalish (direction) kabi xususiyat qiymatlari ham kerak bo‘ladi. _Shunday tarzda, dastlab avtomobilning xususiyatlari orqali atributlar ajratib olinganida atribut sifatida qaralmagan narsalar, harakatlar ajratib olinadigan bosqichda, ma’lum bir harakat natijasidagi hozirgi avtomobil holatini aniqlash maqsadida qo‘shimcha atributlar sifatida paydo bo‘lishi — tabiiy holat hisoblanadi._ Endi buni kod orqali ifodalab ko‘raylik. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FJter7ys2T7fTPUzpTtWO%252Fimage.png%3Falt%3Dmedia%26token%3Dd81a2719-e724-4ef4-8068-cf75e3613d45&width=768&dpr=3&quality=100&sign=2b5ba56f&sv=2) [https://www.youtube.com/watch?v=X3cFiJnxUBYarrow-up-right](https://www.youtube.com/watch?v=X3cFiJnxUBY) [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/pong/oop_inheritance#obyektni-aniqlash-define-grammatikasi) Obyektni aniqlash(define) grammatikasi -------------------------------------------------------------------------------------------------------------------------------------------------------------------- > class klass nomi_(meros uchun sinf nomlari)_: > > _super().\_\_init\_\_(parametrlar)_ > > **def** \_\_init\_\_(self, parametrlar): > > xususiyatlar > > metodlar Biz funksiyani yaratganimizda **def** degan kalit so‘z orqali aniqlagan bo‘lsak, obyektni yaratishda esa **class** degan kalit so‘z orqali aniqlashimiz kerak. Sintaksisda yashil kursiv bilan ifodalangan qism bu obyektning meros olish(Inheritance)ga oid sintaksis bo‘lib, bu haqida keyinroq batafsil ko‘rib chiqamiz, hozircha esa e’tibor bermasangiz ham bo‘ladi. Obyekt aniqlash sintaksisiga muvofiq **Car** degan obyektni aniqladik(yaratdik), va yuqorida tilga olingan 5 ta xususiyat 3~7-satrlar oralig‘ida o‘zgaruvchi shaklida mavjud ekanligini payqagan bo‘lsangiz kerak. Shuningdek, yuqorida aytilgan 3 ta harakat (behavior) esa funksiya shaklida mavjudligini ham ko‘rgan bo‘lasiz. Aytgancha, **\_\_init\_\_ deb nomlangan metod — ilgari ko‘rinmagan notanish ko‘rinishdagi funksiya bo‘lib, bu nima ekanligi qiziq tuyulishi mumkin. Bu Python tiliga xos ichki funksiyalardan biri bo‘lib, obyektning xususiyat qiymatlarini boshlang‘ich holatga keltirish uchun mo‘ljallangan. Aynan shu maqsadda klass ichida ishlatiladi. Keyinchalik ushbu obyektdan foydalanilayotgan vaqtda,** _obyekt yaratilishi bilan Python tizimi ichida avtomatik tarzda chaqiriladigan kolbek(callback) metod hisoblanadi._ Unda, **self** degani nima? **self** ning vazifasi keyinchalik obyekt yaratilgan vaqtda, ya’ni dastur ishga tushganda xotirada real yaratilgan obyektga (bunga **instansiya (instance)** deyiladi) o‘zini ko‘rsatishdir. Hozircha bu gaplar birdaniga to‘liq tushunilmasligi mumkin, ammo murakkab deb o‘ylamasdan, **oddiy ajratib turuvchi belgi (identifikator)** deb o‘ylasangiz ham bo‘ladi. Ya’ni, self bo‘lsa — u obyektning o‘z ichidagi **xususiyatlar (attributes)** va **metodlar (methods)** ni bildiradi. Agar self bo‘lmasa — bu **oddiy o‘zgaruvchilar** va **oddiy funksiyalar** deb ajratib turish mumkin. Keling, **sifatlar** bo‘limini yana bir oz chuqurroq ko‘rib chiqamiz. **Tezlik** (speed) va **yo‘nalish** (direction) sifatlarini ifodalovchi o‘zgaruvchilarga **\_** (pastki chiziq, “underbar” yoki “underscore” deb o‘qiladi) qo‘shilganini ko‘rishimiz mumkin. Bu haqida ilgari ham bir necha marta aytilgan, ammo kod yozishda **bir nuqta yoki bir bo‘sh joy ham ma’noga ega**, shuning uchun bu yerda ham biror maqsad bor deb taxmin qilish mumkin. Albatta, bu **atayin** (ya’ni, o‘ylab) qilingan, va **Python tilida obyektga yo‘naltirilgan dasturlash** (object-oriented programming) amalga oshirilganda **odat tarzidagi kelishuv** sifatida bu xildagi sifatlar **faqat obyektning ichki ishlari** uchun ishlatiladi, deb tushuniladi. Ya’ni, bu qiymatlarni **obyektdan foydalanuvchi tashqi odamlar bilishi shart emas**, degan ma’noni bildiradi. Shuning uchun bu yerda **underscore** ishlatiladi. (Obyektga yo‘naltirilgan dasturlash nazariyasida bu xususiyatlar **private** — “yashirin” sifatlar deb ataladi.) **\_\_init\_\_** metodining ichida bu sifat qiymatlari qanday **boshlang‘ich qiymatlar bilan to‘ldirilishini** (ya’ni, “initialization”) yana bir bor ko‘rib chiqadigan bo‘lsak, \_\_**init\_\_** metodi **body**, **engine**, **wheels** degan parametrlar orqali qiymatlarni olib, ularni obyekt ichida self yordamida saqlayotganini ko‘ramiz. Bu shuni anglatadiki: kimdir yangi **Car** obyektini yaratmoqchi bo‘lsa, kerakli qiymatlarni **init** ga **argument sifatida** beradi, va bu qiymatlar self orqali obyektning ichki sifatlariga aylantiriladi. _Qolgan metodlar esa juda tushunarli:_ _**drive**_ _metodini qayta-qayta chaqirsangiz, tezlik_ _**+2 ga oshadi**__; aksincha,_ _**brake**_ _ni chaqirsangiz, tezlik_ _**\-1 ga kamayadi**__;_ _**turn**_ _metodini chaqirsangiz,_ _**yo‘nalish o‘zgaradi**__._ [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/pong/oop_inheritance#undefined) Obyektlardan foydalanish -------------------------------------------------------------------------------------------------------------------------- Endi biz obyektni yaratdik, demak, undan foydalanib ko‘rish vaqti keldi. Quyida avtomobilni tezlashtirib, so‘ngra tezligini kamaytirib, chapga burilib, yana qayta tezlashtiradigan kod berilgan. Obyektni yaratish siz uchun yangi tajriba bo‘lishi mumkin, lekin undan foydalanish — buni siz allaqachon ko‘p marta qilgansiz, shuning uchun bu joyda katta qiyinchilik bo‘lmasligi kerak. 1-qatorda dastlabki obyektni yaratishda hech qanday argument qiymati uzatilmagan holda yaratilgan. Shunga qaramay, uni ishga tushirib ko‘rilsa, hech qanday xatolik yuz bermaydi va obyekt ichidagi \_\_init\_\_ metodida atribut qiymatlari muammosiz tarzda boshlang‘ich holatga keltirilgan. Bu qanday bo‘ldi? Uning siri shundaki, \_\_init\_\_ metodini aniqlashda parametrlar uchun standart qiymatlar (default qiymatlar) oldindan belgilanadigan sintaksis mavjud va aynan shu usuldan foydalanilgan. Aynan shu qismda esa 3 ta parametr qiymatlariga (body, engine, wheels) har biriga standart qiymat sifatida 'general' belgilangani sababli, agar foydalanuvchi tomonidan maxsus argument qiymatlari uzatilmasa, bu qiymatlar avtomatik tarzda ishlatiladi. [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/pong/oop_inheritance#obyeklarni-meroslash) Obyeklarni meroslash --------------------------------------------------------------------------------------------------------------------------------- Keling, obyekt tushunchasini biroz chuqurroq o‘rganib chiqamiz. Endi obyektga yo‘naltirilgan dasturlashning hayratlanarli imkoniyatlari jiddiy ravishda namoyon bo‘la boshlaydi. Hozirgacha biz oddiy, umumiy avtomobil obyektini yaratib ko‘rdik. Endi esa shu asosiy avtomobilni tayanch(base) qilib, undan kelib chiqqan holda quyidagidek turli xil avtomobil turlarini yaratish mumkin bo‘lsa, juda yaxshi bo‘lmasmidi degan fikr tug‘ila boshlaydi. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FftKca5gD9u0k92ijSEig%252Fimage.png%3Falt%3Dmedia%26token%3Dd80ad030-3f8c-464b-802f-2e22ce9da3ec&width=768&dpr=3&quality=100&sign=e9dd05d3&sv=2) [https://www.youtube.com/watch?v=X3cFiJnxUBYarrow-up-right](https://www.youtube.com/watch?v=X3cFiJnxUBY) Bu mumkinmi, deysizmi? Ha, albatta, mumkin. Obyektga yo‘naltirilgan dasturlashning paydo bo‘lish sababi ham aynan an’anaviy protseduraviy dasturlashning cheklovlarini yengib o‘tish va dasturiy ta’minot ishlab chiqish jarayonining samaradorligi hamda kengaytirilish imkoniyatini oshirish edi. Buni qo‘llash uchun esa **obyektlar orasidagi meros olish(Inheritance) tushunchasini tushunish kerak bo‘ladi. Bu juda murakkab tushuncha emas. Bu, xuddi ota-onadan bolaga DNKning o‘tishi kabi — bola ota-onaning DNKsini meros qilib oladi, lekin shu bilan birga o‘ziga xos xususiyatlarga ham ega bo‘ladi. Xuddi shunday, ota-obyektdan (Parent yoki Super obyekt deb ataladi) meros olgan bola-obyekt (Children yoki Sub obyekt deb ataladi) ota-obyektning barcha xususiyatlari va harakatlarini o‘ziniki kabi ishlata oladi va shu bilan birga o‘ziga xos atributlar va funksiyalarga ham ega bo‘ladi.** Keling, asosiy tayanch avtomobildan kelib chiqadigan turli avtomobillar ichidan biz tezlanish kuchi yuqori bo‘lgan sariq sport avtomobilini va tomi ochiladigan funksiyaga ega qizil kabrioletni yaratmoqchimiz, deb faraz qilaylik. Unday bo‘lsa, bunday tayanchga asoslangan meros olish munosabatini kodda qanday ifodalash mumkin? ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FRNac9bpcVwcpnZzHnJNO%252Fimage.png%3Falt%3Dmedia%26token%3Dfcc281bd-2bea-44db-8381-9c59903e4290&width=768&dpr=3&quality=100&sign=7db8c9ed&sv=2) [https://www.youtube.com/watch?v=X3cFiJnxUBYarrow-up-right](https://www.youtube.com/watch?v=X3cFiJnxUBY) Buni kodlash uchun yuqoridagi sintaksis ifodasida, oldinroq keyinga qoldirilgan obyekt yaratish qoidalariga meros olish qoidasi(yashil kursiv qism) qo‘shilganini eslab olaylik. 1 va 17-qatorlarda hosila obyekt (meros olgan obyektni bildiradigan atama) yaratilganda, ota (bu yerda Car) kim ekani qavs ichida ko‘rsatiladi. So‘ng, obyekt xususiyatlarini boshlang‘ich qiymatlarga o‘rnatadigan **\_\_init\_\_** metodida eng avval **super().\_\_init\_\_() metodidan foydalanib, body, engine, wheels kabi parametrlarni ota tomonga “uzatish” usuli bilan ota obyektning xususiyat qiymatlari tayyorlanadi**. _Tartib bo‘yicha avval ota tomoni tayyorlanadi (boshlang‘ich qiymatlar beriladi), so‘ng hammasini meros qilib olib foydalanadigan bizning tomon keyin tayyorlanadi; bu mantiqan ham to‘g‘ri._ Bu yerda **super() ning vazifasini ham ko‘rdik: u ilgari tilga olingan** _**self**_**ga o‘xshash maqsadda obyekt ichida ishlatiladigan Python ichki funksiyasi bo‘lib, o‘zining ota klassi(Parent)ning obyektini qaytarib beruvchi maxsus metod** hisoblanadi. Sportcar asosan ota obyekt bo‘lgan bazaviy avtomobilining barcha narsasini meros qilib oladi, bundan tashqari, o‘ziga xos deb aytiladigan qanday xususiyatlarga ega bo‘lishi mumkin? Agar biz yasamoqchi bo‘lgan avtomobil sariq sportcar ekanini eslasak, bu sportcar alohida **rang** (color) xususiyatiga ega bo‘lishi kerakligini taxmin qilish mumkin (4-qatorga qarang). Yana ota bilan farqi nimada? _Ota bilan bir xil tarzda harakatlana oladi(drive), burila oladi(turn), sekinlasha oladi(brake), ammo farqi shundaki, poyga kabi dinamik haydash tajribasini ta’minlash uchun tezroq yurish(drive) va tezroq sekinlashish(brake) imkoniyatiga ega._ Shuning uchun, **ota obyektida allaqachon mavjud bo‘lgan harakatlar bo‘lsada va ularni meros qilib olish mumkin bo‘lsada, ota obyektida mavjud bo‘lgan drive va brake metodlarini farzand — sportcar klassi ichida qaytadan funksionalligini amalga oshirgan**. Bu shuni anglatadiki, farzand nuqtai nazaridan otanikini o‘z holicha ishlatish mos kelmaydi va “ota metodini emas, o‘zimning metodimni ishlataman” degan niyat mavjud. Obyektga yo‘naltirilgan dasturlashda buni **qayta belgilash**(overriding) atamasi bilan ifodalaydi, buning ma’nosi ham mavjud narsani qaytadan yozib chiqish deganidir. **drive** va **brake** metodlari ichidagi amalga oshirilgan qismlarga diqqat bilan qarash foydali bo‘ladi. 7 va 11-qatorlarda uchraydigan **self.speed** xususiyati qayerdan kelgan bo‘lishi mumkin? **\_\_init\_\_** metodida bu xususiyat biror marta ham yaratilmagan, ammo xuddi o‘ziga tegishli bo‘lgandek ishlatilmoqda. Ha, _bu xususiyat aslida otaga tegishli bo‘lib, otaning hamma narsasini meros qilib olgan farzand nuqtai nazaridan qaraganda, o‘zida bo‘lmasa ham xuddi o‘zida allaqachon mavjud bo‘lgandek ishlatilmoqda._ Agar **sportcar**ning ota–farzand meros munosabatini yaxshi tushungan bo‘lsangiz, **kabriolet** holati juda oson. Xuddi shunday, u ham otaning hamma narsasini meros qilib oladi. Unda o‘ziga xos qanday xususiyatlar bo‘lishi mumkin? Biz uni qizil kabriolet deb aytganimiz uchun, xuddi shunday tarzda kuzov rangi(color) xususiyatiga ega bo‘lishi kerak. Shuningdek, “kabriolet” deb atalishining sababi bo‘ladigan o‘ziga xos xususiyati — tomni ochib/yopa olish (**move\_roof**) harakatini bajarishidir. Buni batafsil amalga oshirish quyidagicha: avvalo, 17-qatorda **ConvertibleCar(Car)** sintaksisi orqali **Car** dan meros olinadi va yuqorida jamlagan sifat va harakatlar nuqtai nazaridan **ota**dan farq qiladigan faqat o‘ziga xos jihatlarigagina qo‘shimcha kod yozish kifoya. Kabriolet avtomobilning haqiqatan ham otadan hamma narsani to‘liq meros olganini qayerdan bilish mumkin? Quyidagi klass funksiyalarini tekshirishga mo‘ljallangan test kodida 15, 17, 18, 20-qatorlarda **drive**, **brake**, **turn** metodlari **kabriolet** klassi ichida hech qachon aniqlanmagan bo‘lsa ham, xuddi o‘zida allaqachon mavjuddek ishlatilmoqda. Shu yergacha, biz obyektni qanday yaratishni va obyektning foydaliligini oshiradigan eng asosiy xususiyatlardan biri bo‘lgan meros olishni tushundik. Shunga qaramay, agar siz uchun obyektga yo‘naltirilgan dasturlash birinchi marta bo‘lsa, tushunish oson bo‘lmasligi mumkin. Lekin xavotirga o‘rin yo‘q, chunki har kimga ham bunga o‘rganish uchun vaqt kerak bo‘ladi. Aslida, obyektga yo‘naltirilgan dasturlash dunyosi juda keng va katta. Ammo, ataylab sizlarni boshidan boshlab juda katta hajmdagi bilimlar bilan charchatib qo‘ymaslik uchun, hozircha zarur bo‘lgan darajada tushuntirish bilan cheklanmoqchimiz. Keyinchalik, xuddi hozirgacha qilganimizdek, yana yangi tushunchalar zarur bo‘ladigan joylarda, o‘sha o‘rinda navbatdagi bilimlarni tushuntirib boramiz. Xo‘sh, unda keyingi bo‘limdan boshlab, mavjud protsessual uslubda yaratilgan Pong o‘yinini misol qilib olib, uni obyektga yo‘naltirilgan uslubda amalga oshirishni boshlaymiz. [Previous8.3 Obyektga Yo‘naltirilgan Dasturlash nazariyasi (Obyektga Yo‘naltirilgan dizayn nima)chevron-left](https://roboticsware.gitbook.io/python-pygame_zero/pong/ood) [Next8.5 Obyektga yo‘naltirilgan dasturlash 1chevron-right](https://roboticsware.gitbook.io/python-pygame_zero/pong/8.5_oop_dev1) Last updated 6 days ago * [Obyektni aniqlash(define) grammatikasi](https://roboticsware.gitbook.io/python-pygame_zero/pong/oop_inheritance#obyektni-aniqlash-define-grammatikasi) * [Obyektlardan foydalanish](https://roboticsware.gitbook.io/python-pygame_zero/pong/oop_inheritance#undefined) * [Obyeklarni meroslash](https://roboticsware.gitbook.io/python-pygame_zero/pong/oop_inheritance#obyeklarni-meroslash) sun-brightdesktopmoon Copy class Car: def __init__(self, body='general', engine='general', wheels='general'): self._speed = 0 self._direction = 'forward' self._body = body self._engine = engine self._wheels = wheels def drive(self): self._speed += 2 print("Current speed is " + str(self._speed)) def brake(self): self._speed -= 1 if self._speed < 0: self._speed = 0 print("Current speed is " + str(self._speed)) def turn(self, direction): self._direction = direction print("Changed direction to " + str(self._direction)) Copy car = Car() for _ in range(3): car.drive() for _ in range(2): car.brake() car.turn('left') for _ in range(2): car.drive() Copy Bajarish natijalari: Current speed is 2 Current speed is 4 Current speed is 6 Current speed is 5 Current speed is 4 Changed direction to left Current speed is 6 Current speed is 8 Copy def __init__(self, body='general', engine='general', wheels='general'): Copy class SportsCar(Car): def __init__(self, color): super().__init__('sports', 'strong', 'big') self._color = color def drive(self): self._speed += 4 print("Current speed is " + str(self._speed)) def brake(self): self._speed -= 2 if self._speed < 0: self._speed = 0 print("Current speed is " + str(self._speed)) class ConvertableCar(Car): def __init__(self, color): super().__init__('convertable') self._color = color self._opened = False def move_roof(self): self._opened = not self._opened if self._opened: print("Current roof is opned") else: print("Current roof is closed") Copy # Sport avtomobil sinovi s_car = SportsCar('yellow') for _ in range(3): s_car.drive() for _ in range(2): s_car.brake() s_car.turn('left') for _ in range(2): s_car.drive() # Qoplanadigan avtomobil sinovi c_car = ConvertableCar('red') c_car.move_roof() for _ in range(2): c_car.drive() for _ in range(2): c_car.brake() s_car.turn('right') for _ in range(2): c_car.brake() c_car.move_roof() Copy Bajarish natijalari: Current speed is 4 Current speed is 8 Current speed is 12 Current speed is 10 Current speed is 8 Changed direction to left Current speed is 12 Current speed is 16 Current roof is opned Current speed is 2 Current speed is 4 Current speed is 3 Current speed is 2 Changed direction to right Current speed is 1 Current speed is 0 Current roof is closed sun-brightdesktopmoon --- # 7.2 Aktyorlarning harakati va o‘q otish hujumini amalga oshirish | Python-Pygame Zero Ushbu bo‘limdan boshlab biz oldingi bo‘limda bo‘sh funksiya sifatida yaratilgan har bir funktsiyaning amalga oshirilishini umumiy tuzilmaviy konturni o‘rnatgan holda to‘ldiramiz. Birinchisi **move\_player** funktsiyasidir. Oldingi o‘yinlar faqat sichqoncha bilan boshqariladigan, endi esa birinchi marta klaviatura boshqaruvi joriy etildi. _Pygame Zeroning qulay tomoni shundaki, klaviatura operatsiyalari uchun on\_key\_down kolbek(callback) funksiyasidan foydalanish shart emas,_ _**update**_ _funksiyasidagi maxsus klaviatura tugmalari (masalan, ko‘rsatkich tugmalari) uchun oldindan belgilangan o‘zgaruvchilar (masalan,_ _**keyboard.up/down/left/right**_ _va h.k.) yordamida bosish mavjudligini tekshirishingiz mumkin._ Har bir bosilgan ko‘rsatkich tugmasi uchun 5 pikselli harakat hosil qiladi. Bosh qahramonning samolyoti barcha yo‘nalishlarda oldinga, orqaga, chapga va o‘ngga harakatlanishi mumkin, ammo uning berilgan ekrandan tashqariga chiqishiga yo‘l qo‘ymaslik uchun chegaralarni belgilash kerak (10~17-qatorlar). Endi, biz oldingi ko‘plab o‘yinlarda bu darajadagi kodlashni amalga oshirganimiz sababli, uni tushunish yoki amalga oshirishda unchalik qiyin bo‘lmaydi. Copy def move_player(): if keyboard.right: player.x += 5 if keyboard.left: player.x -= 5 if keyboard.up: player.y -= 5 if keyboard.down: player.y += 5 if player.right > WIDTH: player.right = WIDTH if player.left < 0: player.left = 0 if player.bottom > HEIGHT: player.bottom = HEIGHT if player.top < 0: player.top = 0 Keyin, asosiy qahramonning o‘q otish qismini ifodalovchi **shoot\_bullets** funksiyasini amalga oshiraylik. Avvalo, esda tutish kerak bo‘lgan narsa, o‘q kichik va ahamiyatsiz ko‘rinsa ham, har bir o‘q alohida obyektdir. Foydalanuvchi bo‘sh joy tugmasini bosib o‘qni chiqarishda yuzaga keladigan barcha amallar ketma-ketligini o‘ylab ko‘rsak, avvalo, o‘q otishning ovozi chiqariladi (3-qator), o‘q obyekti yaratiladi (4-qator), ammo o‘qning boshlang‘ich joyi asosiy qahramonning samolyotidan boshlanishi kerak (5-qator), o‘qning uchish yo‘nalishi yuqori oldinga qarab bo‘ladi (6-qator). O‘q 15 piksel harakatlanib uchib boradi (9~10-qator), agar uchayotgan o‘q ekraning yuqori qismidan chiqib ketgan bo‘lsa, bu o‘qning mavjudligi endi ma'nosiz bo‘lib, xotirani to‘ldirmasligi uchun (e'tibor bering, agar xotira to‘lsa, dastur to‘satdan majburiy ravishda yopilishi mumkin) o‘q obyekti xotiradan o‘chiriladi (11~12-qator). Xotiradan o‘chirilishi demak, bu o‘q obyekti **bullets** ro‘yxatidagi mos o‘qni o‘chirishni anglatadi, buni amalga oshirish uchun ro‘yxatning **remove** metodidan foydalanish qulay (12-qator). Nima uchun bir vaqtning o‘zida otilgan o‘qlar soni MAX\_BULLETS bilan cheklanganiga hayron bo‘lishingiz mumkin, lekin agar siz o‘qlarning maksimal sonini tekshiradigan kodni olib tashlasangiz va o‘yinni ishga tushirsangiz, nima uchun bu zarurligini darhol tushunasiz. Biz bo‘sh joy tugmachasini bir marta bosamiz deb o‘ylaymiz, lekin aslida **update** kolbek(callback) funksiyasi sekundiga 60 marta (60 FPS) - nihoyatda yuqori tezlikda qayta-qayta chaqiriladi, shuning uchun bo‘sh joy doimiy bosilganday bo‘ladi va hosil bo‘lgan o‘qlar soni tez o‘sib boradi, shuning uchun biz bir vaqtning o‘zida juda ko‘p o‘qlarning uchayotganini ko‘rishimiz mumkin. Bu hodisa bizni dushmanlarimizga nisbatan haddan tashqari ustunlikka ega bo‘lishimizga olib keladi, bu o‘yinni juda oson qiladi va o‘yin qiziqarliligini kamaytiradi, shuning uchun o‘yin uchun bir vaqtning o‘zida otilgan o‘qlar sonini ma‘lum darajada cheklash kerak. 6-qatordagi angle xususiyati qiymati biz [oldingi kitobarrow-up-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/gul_yasash) da allaqachon bilib olgan narsadir. Qiymatni 90 darajaga o‘rnatishdan maqsad o‘qni ekranning yuqori qismiga qarab harakatlantirishdir. Agar [oldingi kitobarrow-up-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic) ni o‘qimagan o‘quvchilar bo‘lsa, burchak qiymatlarining ma‘nosini tushuntirish uchun men quyidagi rasmni qo‘shdim. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252F6zQHnniFS4xGFCItF8gt%252Fimage.png%3Falt%3Dmedia%26token%3D9ed17391-1944-432d-bc4e-605b15e2124a&width=768&dpr=3&quality=100&sign=fa8512&sv=2) Endi, dushman samolyotlarini paydo bo‘lishini ta’minlovchi **create\_enemies** funksiyasini yaratamiz. Dushman samolyoti paydo bo‘lishi va undan keyin hujum qilish uchun o‘q otish jarayonini ko‘rib chiqsak, birinchi navbatda, dushman samolyotlari ko‘rinmaydigan ekran yuqori qismida (6-qatorda) tasodifiy tarzda hosil bo‘lib (7-qatorda), ekranning pastki qismiga tasodifiy ravishda (8-qatorda) uchib tushishi kerak bo‘ladi (12-qator). 8-qatorda biz [ilgari o‘rganganarrow-up-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/gul_yasash) angle(burchak) ga juda o‘xshash, lekin bir oz farqli tushunchaga ega **direction**(yo‘nalish) degan xususiyat paydo bo‘ladi. Agar siz Entry blokli kodlash muhitidan kelgan bo‘lsangiz, sizga bu allaqachon tanish: Entryda “aylanish” va “harakat yo‘nalishi” degan ikki xil qiymat mavjud edi. Bu ikki qiymatning farqi shundaki, biri obyektning o‘zini aylantiradi, ikkinchisi esa obyektni aylantirmasdan faqat uning harakat yo‘nalishini o‘zgartiradi. Bu yerda **direction** ikkinchi holatni bildiradi. Pygame Zeroda Actor obyektining angle (burchak, aylanish) xususiyati va direction (yo‘nalish) xususiyati uchun belgilangan burchak bir xil ma’noga ega bo‘lgani sababli, koddagi **random.randint(-100, -80)** ifodasi ekranning pastki yo‘nalishi (-90 daraja) atrofida 10 daraja tasodifiy harakat berishni ko‘zda tutadi. Dushman samolyoti uchayotganida unga animatsiya qo‘shilganini (4- va 13-qatorda) eslab qolish kerak, bu esa o‘yinga ko‘proq dinamika bag‘ishlaydi. Pygame Zeroda Actor obyektiga qanday qilib animatsiya berilishi haqida biz [oldingi kitobarrow-up-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/sakrashni_sanash) da allaqachon o‘rganganmiz, shuning uchun bu yerda batafsil tushuntirish berilmaydi. Qo‘shimcha o‘rganishga ehtiyoji borlar avvalgi bo‘limlarga murojaat qilishlari mumkin. Dushman samolyoti oddiygina uchib o‘tmaydi, u uchayotganda o‘q otadi, shuning uchun bu qismini ham kodlash kerak. Otgan o‘qlari 360 daraja bo‘ylab istalgan yo‘nalishda tasodifiy tarzda uchadi (19-qator) va ularning uchish tezligi 5 piksel qilib belgilangan (23-qator). Bundan tashqari, dushman samolyoti bo‘lsin yoki o‘q bo‘lsin, agar ular ekran tashqarisiga chiqib ketsa, ularni xotiradan o‘chirish kodi har doim zarur bo‘ladi (14~15-qatorlar, 24~25-qatorlar). Qolgan ikkita funksiya (check\_collision va draw\_text) haqidagi tushuntirishlarni keyingi bo‘limda davom ettiriladi. Agar o‘rganish jarayonida kod bo‘yicha qo‘shimcha savollar paydo bo‘lsa, [aloqada bo‘lishimiz uchun kanalarrow-up-right](https://t.me/entry_uz) tayyorlab qo‘yilganini va har doim shu kanal orqali savollarga birgalikda javob topish mumkinligini unutmang. [Previous7.1 Skrol fon obyektini yaratish, fon musiqasi, aktyorlar (dushman, qahramon) ni tanishtirishchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/twinbee/7.1_scroll_backgrounds) [Next7.3 To‘qnashuvni boshqarish va boshqa ma‘lumotlar(hisob va o‘yin yakuni)ni ko‘rsatishchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/twinbee/7.3_collision_detection) Last updated 6 days ago sun-brightdesktopmoon Copy def shoot_bullets(): if keyboard.space and len(bullets) < MAX_BULLETS: sounds.sfx_sounds_interaction25.play() bullet = Actor("player_bullet") bullet.pos = player.pos bullet.angle = 90 bullets.append(bullet) for bullet in bullets: bullet.move_forward(15) if bullet.y < 0: bullets.remove(bullet) Copy def create_enemies(): if random.randint(0, 1000) > 980: enemy = Actor("enemy1_1") enemy.images = ["enemy1_1", "enemy1_2"] enemy.fps = 5 enemy.y = -50 enemy.x = random.randint(100, WIDTH - 100) enemy.direction = random.randint(-100, -80) enemies.append(enemy) for enemy in enemies: enemy.move_in_direction(4) enemy.animate() if enemy.top > HEIGHT: enemies.remove(enemy) if random.randint(0, 1000) > 990: bullet = Actor("enemy_bullet") bullet.pos = enemy.pos bullet.angle = random.randint(0, 359) enemy_bullets.append(bullet) for bullet in enemy_bullets: bullet.move_forward(5) if bullet.x < 0 or bullet.x > WIDTH or bullet.y < 0 or bullet.y > HEIGHT: enemy_bullets.remove(bullet) sun-brightdesktopmoon --- # 10.2 Rele serverini ishga tushurish va mijozning ulanishi | Python-Pygame Zero Pong o‘yinining **OOP (Object Oriented Programming)** versiyasini asos qilib, uni tarmoqli o‘yinga aylantirish jarayonida qo‘shiladigan va kengaytiriladigan qismlarinigina qo‘shimcha tushuntirib borish usulini tanlaymiz. Biroq sizlarning yangi boshlovchi ekaningizni inobatga olib, tarmoq bo‘yicha eng asosiy bilimlar hamda qo‘shimcha ravishda **nethelper**ning asosiy foydalanish usullarini oldindan o‘zlashtirib olish zarur. Shu bois, avval shu qismni tushuntirib o‘tamiz, so‘ng davom etamiz. Avvalo tarmoq (Network) bilan bog‘liq asosiy atamalarni aniqlab olaylik. Biz tarmoq deganda kompyuterlar o‘rtasidagi simli yoki simsiz (Wired/Wireless) aloqalarni yaratib, kerakli ma’lumotlarni o‘zaro almashish uchun xizmat qiladigan kompyuter tarmog‘i(Computer Network)ni nazarda tutamiz. [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.2_server_connection#lan-vs-internet) LAN vs Internet -------------------------------------------------------------------------------------------------------------------------------------- Har bir atamaning farqlanishi tarmoqning ko‘lami bilan bog‘liq. Eng asosiy birlik bo‘lgan **LAN (Local Area Network)** cheklangan hudud ichida kompyuterlarni ulaydigan tarmoqni bildiradi. Bu yerda cheklangan hudud odatda bitta uy, sinfxona, ofis yoki bino darajasidagi ko‘lamni anglatadi. Atrofda eng oson uchraydigan misol bu uy yoki ofisda simsiz **WiFi routeri (WiFi Router)** dan foydalanib, aloqa qurilmasi o‘rnatilgan elektron qurilmalar (kompyuterlar ham) o‘rtasida tarmoq tuzishdir. Internet esa shunday tarmoqlarning asosiy birligi bo‘lgan **LAN** lar o‘rtasidagi ulanishni bosqichma-bosqich kengaytirib, tarmoq ko‘lamini butun dunyo miqyosiga yoygan tizimdir. [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.2_server_connection#ip-protokoli-protocol-va-ip-manzili-address) IP protokoli(Protocol) va IP manzili(Address) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Shunday ekan, tarmoqda bir-biriga ulangan qurilmalar o‘rtasida ma’lumot yuborish uchun nimalar zarur? Ma’lumotni yuborish va qabul qilish uchun, uni qaysi shaklga keltirish va qanday usulda almashish bo‘yicha qurilmalar o‘rtasida oldindan o‘zaro kelishuv bo‘lishi shart. Bunday o‘zaro aloqa qoidalari **protokol (Protocol)** deb ataladi. **IP (Internet Protocol, internet protokoli)** deb ataluvchi aloqa qoidasi nomidan ko‘rinib turibdiki, internetni tashkil etishga xizmat qiladi va internetning asosiy birligi bo‘lgan **LAN** darajasidan boshlab aynan shu qoidalarga rioya qilib aloqa qilinadi. _Ushbu aloqa qoidasi ichida tarmoqdagi muloqot qilinadigan qarshi tomonni aniqlash va farqlash uchun identifikatsiya tizimi mavjud bo‘lib, u biz kundalik hayotda keng qo‘llaydigan manzil(__**Address**__)ga asoslanadi._ Masalan, uy manzili yoki email manzilini bilsak, o‘sha tomonni aniq ko‘rsatib, bizga kerakli ma’lumotni (xabar yoki xat va hokazo) yuborishimiz mumkin. Shu sabab, **IP** manzil **IP** protokol qoidalari orqali muloqot qilish uchun internetda joylashgan har bir aloqa qurilmasiga beriladigan vaqtinchalik manzildir. Bu yerda vaqtincha beriladi degani, manzil barcha qurilmalarga oldindan doimiy biriktirilmaydi, balki qurilma internet tarmog‘iga ulangan paytda, aloqa jarayoni davomida vaqtincha taqdim etiladi. Kompyuteringiz hozirda tarmoqqa ulanganmi? Agar shunday bo‘lsa, siz albatta IP manzilga ega bo‘lasiz. Endi, o‘sha ajratilgan IP manzilingizni qanday aniqlash mumkin? Quyidagi usullar orqali bilib olish mumkin. ### [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.2_server_connection#windows) **Windows** **Buyruqlar Qatori(Command Prompt)dan foydalanish:** * Windows tugmasi + R ni bosib bajarish oynasini oching. * `cmd` deb yozing va Enter tugmasini bosing. * Buyruqlar Qatori oynasi paydo bo‘lgach, `ipconfig` deb yozing va Enter tugmasini bosing. * IPv4 manzili kompyuteringizning IP manzilidir. ### [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.2_server_connection#macos) **macOS** **Terminaldan foydalanish:** * Finder > Ilovalar > Utilitalar > Terminalni ishga tushiring. * `ifconfig` deb yozing va Enter tugmasini bosing. * en0 yoki en1 (Wi-Fi uchun) bo‘limidagi inet dan keyingi manzil sizning IP manzilingizdir. [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.2_server_connection#mijoz-client-va-server) Mijoz(Client) va Server ----------------------------------------------------------------------------------------------------------------------------------------------------- Ikki atamaning inglizcha ma’nosidan kelib chiqib, mijoz(Client) — bu xizmatni so‘rovchi tomon bo‘lsa, Server esa mijozning so‘roviga javob berib xizmat ko‘rsatuvchidir. Biroq, _tarmoqda mijoz yoki server deganda butun kompyuter emas, balki kompyuterda ishlayotgan dastur sifatida tushunish osonroq._ Biz ilgari rele server haqida ko‘rib chiqqanmiz. Serverni dastur deb aytgan edik, ya’ni rele server deganda dasturni ishga tushirib qo‘ysak, u server dasturi sifatida endi xabarlarni uzatuvchi vositachi rolini bajarib, tarmoqli o‘yin ishtirokchilarining mijoz dasturlari orasida ma’lumot(xabar)larni bu tomondan u tomonga yetkazib berish xizmatini, ya’ni “xizmat qilish(Serving)”ni boshlaydi. Endi biz tarmoq orqali noaniq sonli foydalanuvchilar bilan birga tarmoqli o‘yin o‘ynashni istasak, bu rele server joylashgan kompyuterni jismonan qayerga joylashtirish eng ma’qul bo‘ladi? Agar siz haqiqiy tijorat o‘yin xizmatini taklif qilmoqchi bo‘lsangiz, albatta barcha foydalanuvchilarga tarmoq orqali eng oson ulanish imkonini beruvchi, shu bilan birga barcha o‘yin ishtirokchilariga tezkor tarmoq tezligini ta’minlay oladigan joyni tanlaysiz. Bunday joy qayer bo‘lishi mumkin? To‘g‘ri, siz hech bo‘lmaganda bir marta eshitgan bo‘lishingiz mumkin bo‘lgan atamalar bunday joy uchun ishlatiladi: bular ma’lumot markazi (Data center) yoki [kloud (Cloud)arrow-up-right](https://en.wikipedia.org/wiki/Cloud_computing) deb ataladi. Albatta, bunday jismoniy joyni ijaraga olish katta xarajatlarni talab qiladi. [hashtag](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.2_server_connection#rele-serverini-ishga-tushirish-va-mijozlarni-ulash) Rele serverini ishga tushirish va mijozlarni ulash ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Biz endigina tarmoqli o‘yin yasashni o‘rganayotgan bosqichdamiz, shunday joylar hozir bizga kerakmi? Albatta, kerak emas. Biroq, ehtimol keyinroq siz uzoqda yashovchi do‘stingiz bilan o‘zingiz yaratgan tarmoqli o‘yinni birgalikda o‘ynashni xohlab qolasiz, shunda kloudda virtual kompyuterni ijaraga olish haqida o‘ylab ko‘rsangiz bo‘ladi. Lekin hozircha bu rele server dasturini shunchaki o‘z kompyuteringizda ishga tushirib, hozircha sizning kompyuteringiz rele server vazifasini bajarsin. Rele server dasturi **nethelper** kutubxonasi ichida taqdim etiladi, va har biringiz ushbu dasturini quyidagicha buyruqlar qatori yoki terminal orqali o‘z kompyuteringizda ishga tushirishingiz mumkin. Bu yerda guruh nomi tarmoqli o‘yinga ishtirokchilar yig‘iladigan makon bo‘ladigan guruh (group) nomini anglatadi. O‘yin ishtirokchilari aynan shu guruh nomi identifikatori orqali ushbu joyga qo‘shila olishlari uchun guruh nomi oldindan belgilab qo‘yilishi kerak bo‘ladi. Biz tarmoqda birgalikda Pong o‘yinini o‘ynashni rejalashtirganimiz sababli, xona nomini **pong\_game** deb belgilaymiz. Guruh nomi bilan birga ishga tushirsangiz, quyidagidek ishga tushirish natijasini ko‘rishingiz mumkin. Agar server to‘g‘ri ishga tushgan bo‘lsa, mijozlarning ulanishini kutayotganligini bildiruvchi **listening** degan xabarni ko‘rishingiz mumkin bo‘ladi. Server tarmoqli o‘yin davomida doimiy ishlaydigan holatda(alive) bo‘lishi kerak bo‘lgani sababli, ishga tushgan oynani o‘zgartirmang yoki yopmang, aynan shunday holatda qoldiring. Keyin, mijozlar rele serverida yaratilgan guruh xonasiga ulanib, haqiqiy o‘yinni o‘ynasa bo‘ladigan tamoqli o‘yin dasturini yaratamiz. Aniqroq aytganda, rele serveridagi **pong\_game** deb ataluvchi guruh xonasiga ulanadigan qismini avval kodlab chiqamiz. **nethelper** kutubxonasidan **NetNode** nomli tarmoqli o‘yin foydalanuvchisi sifatida bir a’zo (node) bo‘ladigan obyekt **import** qilinadi va 10-qatorda ushbu obyekt yaratilmoqda. **NetNode** obyektida **connect** deb nomlangan a’zo funksiyasi mavjud bo‘lib, u to‘rtta parametr qiymatini argument sifatida oladi. Birinchi parametr rele serverining IP manzili, ikkinchisi foydalanuvchining guruh xonasidagi id, uchinchisi guruh xonasi nomi, to‘rtinchisi esa server bilan ulanish yakunlanguncha kutishni bildiradi. Endi bu argumentlarning har birini batafsil ko‘rib chiqaylik. Birinchidan, **rele serveri** manzili bu '**localhost**'. Odatda IP manzil nuqtalar bilan ajratilgan to‘rtta raqamdan iborat bo‘lishini bilsangiz kerak, biroq, _istisno tariqasida, o‘z kompyuteringizning o‘zini bildiruvchi IP manzil sifatida oldindan kelishilgan '__**127.0.0.1**__' manzili o‘rniga, aynan shu ma’noni qulay ifodalovchi ‘localhost’ dan foydalanish_ mumkin. Demak, agar 'localhost' qiymatini ishlatishni xohlamasangiz, uning o‘rniga '127.0.0.1' qiymatini ko‘rsatishingiz mumkin. **Shuni ham yodda tuting: hozircha rele serveri bizning kompyuterimiz o‘zida ishlamoqda, ammo keyinchalik biz ushbu tarmoqli o‘yinni internet orqali masofadagi foydalanuvchilarga taqdim etsak, o‘shanda rele serveri manzili sifatida server ishlaydigan internetdagi haqiqiy, yagona IP manzilni kiritishimiz kerak bo‘ladi.** Ikkinchidan, guruh xonasiga ulanishda o‘z **id**\-ingizni **Player1** qilib belgilaysiz, ya’ni guruh xonasiga eng birinchi kirgan kishi o‘yin boshqaruvchisi(host) vazifasini bajaradi (17-qator). _Rele serveri usulidagi o‘yinlarda guruh xonasida bir kishi albatta_ _**host**_ _rolini bajarishi shart._ Bizning o‘yinda guruh xonasiga birinchi ulangan kishi host bo‘ladi. Bu o‘yin faqat 2 kishi o‘ynaydigan, bir-biriga qarshi duel turidagi o‘yin; agar siz host bo‘lsangiz, sizning raqibingiz bo‘ladigan o‘yinchining **id**\-si tabiiy ravishda **Player2** bo‘ladi (18-qator). 19-qatordagi **my\_bar** nomli global o‘zgaruvchi keyinchalik men boshqaradigan reflektor chap/o‘ng tomondan qaysi biri ekanini ajratish uchun xizmat qiladi; bizning o‘yinda **host** doimo chap tomondagisini (bar1) boshqaradi, raqib esa o‘ng tomondagisini (bar2) boshqaradi. _Eslatma: ushbu kodni ishga tushirsangiz, hozircha o‘zgaruvchi(bar1 yoki bar2) yo‘q degan xato chiqadi, shuning uchun vaqtincha u qatorlarni kommentariyga olib ishga tushiring._ Ikkinchi bo‘lib guruh xonasiga ulanadigan kishi darhol 21-qatorga o‘tadi, buning sababi shundaki, **connect** nomli a’zo funksiyasi chaqirilganida unga argument sifatida uzatilgan **id** qiymati allaqachon guruh ichida boshqa foydalanuvchi tomonidan ishlatilayotgan bo‘lsa, u holda funksiyadan darhol **False** qiymati qaytariladi. Shuning uchun ikkinchi ulanadigan foydalanuvchi host rolini emas, balki host tomonidan yuboriladigan boshqaruv buyruqlari va o‘yin holati haqidagi ma’lumotlarni qabul qilib, ularni qayta ishlaydigan oddiy foydalanuvchi sifatida o‘yinda ishtirok etadi. E’tiborga molik jihat — **bizning Pong tarmoqli o‘yinimiz** _**host**_ **uchun alohida, oddiy foydalanuvchi uchun alohida ishlab chiqilmaydi, balki bitta dasturda ikkala rolni ham bajara oladigan shaklda ishlab chiqiladi. Shunga ko‘ra, yuqorida tarmoq (rele serveri) bilan ulanadigan kod ham har ikkala rolni (host/oddiy foydalanuvchi) bajarishga mo‘ljallangan bo‘ladi.** Shu boisdan, **pong\_net.py** nomli ushbu dasturni sinab ko‘rish uchun yangi ikkita buyruq satri (yoki terminal) oynasini ochib, har bir oynada **pong\_net.py** dasturni alohida ishga tushirib ko‘ring. Ushbu ikki oynadan qaysi birida dastur birinchi bo‘lib ishga tushirilsa (yoki ulanadigan bo‘lsa), u holda o‘sha foydalanuvchi **pong\_game** guruh xonasida **host** (Player1) bo‘lganini ko‘rishingiz mumkin. ![](https://roboticsware.gitbook.io/python-pygame_zero/~gitbook/image?url=https%3A%2F%2F958093619-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FowRqKin3ADhKX90PsZfd%252Fuploads%252FdCemB6DCYRocf05vhwrs%252Fimage.png%3Falt%3Dmedia%26token%3D43db694b-7dec-4a8e-8db2-05e4bf00c8aa&width=768&dpr=3&quality=100&sign=3a1940cb&sv=2) Ma’lumot uchun, guruhda ikki nafar o‘yinchi to‘liq yig‘ilgandagina o‘yin boshlash sharti bajariladi. Avval guruhga kirib, raqibning kirishini kutayotgan holat uchun ekranda ifodalish kerak bo‘ladi va buni quyidagi kod orqali amalga oshirish mumkin. Bu yerda **num\_peers** deb ataladigan global o‘zgaruvchi joriy guruh ishtirokchilarining umumiy sonini real vaqtda ko‘rsatadi. Hozircha tarmoq o‘yinini boshlash uchun rele serveri orqali o‘yinchilar o‘rtasidagi asosiy ulanish yakunlandi. Endi keyingi bo‘limdan boshlab, tarmoqli o‘yinni to‘liq olib borish uchun zarur kodlarni qo‘shamiz. [Previous10.1 Tarmoqli o‘yinlarni tushunish va kutubxonani o‘rnatishchevron-left](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.1_nethelper_install) [Next10.3 Tarmoqli o‘yinga aylantirish 1chevron-right](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.3_dev_net_1) Last updated 6 days ago * [LAN vs Internet](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.2_server_connection#lan-vs-internet) * [IP protokoli(Protocol) va IP manzili(Address)](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.2_server_connection#ip-protokoli-protocol-va-ip-manzili-address) * [Windows](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.2_server_connection#windows) * [macOS](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.2_server_connection#macos) * [Mijoz(Client) va Server](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.2_server_connection#mijoz-client-va-server) * [Rele serverini ishga tushirish va mijozlarni ulash](https://roboticsware.gitbook.io/python-pygame_zero/pong_network/10.2_server_connection#rele-serverini-ishga-tushirish-va-mijozlarni-ulash) sun-brightdesktopmoon Copy python nethelper -g Copy python nethelper.py -g pong_game Starting Server Interface: ALL Port: 65042 Groups: pong_game Server listening pong\_net.py Copy from nethelper import NetNode SERVER_IP = 'localhost' # rele server IP manzili is_host = False # host sifatida zimat qiladimi peer_id = '' # aloqadagi sherikdin 'id'si MAX_PEERS = 2 # o'yinchilar maksimal soni num_peers = 0 # o'yinchilarning hozirgi soni my_bar = '' net = NetNode() def connect_server(): global is_host, peer_id, my_bar # birinchi ulangan o'yinchi (Player1) host rolini oladi if net.connect(SERVER_IP, "Player1", "pong_game", wait=True): is_host = True peer_id = "Player2" my_bar = bar1 print("Connected as host (Player 1)") else: # agar host mavjud bo'lsa, peer (Player2) rolini ishlatilsin if net.connect(SERVER_IP, "Player2", "pong_game", wait=True): is_host = False peer_id = "Player1" my_bar = bar2 print("Connected as peer (Player 2)") else: print("Failed to connect. The group is full.") exit() # o'yinni boshlashdan oldin rele serveriga ulaning connect_server() Copy def draw(): ... if num_peers < MAX_PEERS: screen.draw.text('Waiting for a peer connection...', (WIDTH/6, HEIGHT/2), color='blue', fontsize=50) sun-brightdesktopmoon --- # 9.2 Protseduraviy dasturlash 2 | Python-Pygame Zero Ushbu bo‘limdan boshlab bizning 3 ta foydalanuvchi funksiyamizning implementatsiyasi(amalga oshirilishi)ni aniq yozib chiqamiz. Avvalambor, **move\_player** funksiyasidan boshlaymiz. Bu bizga allaqachon juda tanish bo‘lgan funksiya. Faqat bu yerda bosh qahramon tankining foydalanuvchi klaviatura orqali boshqarilishi va dushman tankining kompyuter tomonidan avtomatik boshqarilishi holatlari parametr qiymati(player) orqali ajratilib qo‘llanilmoqda. Tank harakatida cheklovlar mavjud, ya’ni u ekrandan tashqariga chiqolmaydi (35~39-qatorlar) va devor ichidan o‘ta olmaydi (30~32-qatorlar). Bunday harakatga urinish bo‘lganda esa, tank hozirgi holatida, ya’ni **origin\_x**, **origin\_y** koordinatalarida qoldiriladi. Copy def move_player(player): # tankning boshlang'ich joylashuvini saqlab qo'yish original_x = player.x original_y = player.y if player == tank: # tank qahramoni if keyboard.right: player.angle = 0 player.x += 2 elif keyboard.left: player.angle = 180 player.x -= 2 elif keyboard.up: player.angle = 90 player.y -= 2 elif keyboard.down: player.angle = 270 player.y += 2 else: # dushman tanki if player.angle == 0: player.x += 2 elif player.angle == 90: player.y -= 2 elif player.angle == 180: player.x -= 2 elif player.angle == 270: player.y += 2 # devordan o'tib keta olmaslik va eski joyida qolish if player.collidelist(walls) != -1: player.x = original_x player.y = original_y # o'yin oynasidan chiqib ketmaslik if player.left < 0 or player.right > WIDTH \ or player.top < 0 or player.bottom > HEIGHT: player.x = original_x player.y = original_y Keyingisi, **fire\_bullets** funksiyasi. Bu ham juda sodda implementatsiyaga ega bo‘lib, ilgari TwinBee o‘yinida yozilgan funksiyaga o‘xshash bo‘lgani sababli tushunishda qiyinchilik tug‘dirmaydi. Faqatgina farqi shundaki, bu safar funksiyada parametr qiymatlari mavjud, ular orqali bosh qahramon tanki va dushman tankining o‘q(yoki to‘p) tasvirlarini farqlab, har biriga mos ravishda o‘q yaratish mumkin bo‘ladi. Oxirgisi, **collide\_bullets** funksiyasidir. Nomidan ham ko‘rinib turibdiki, bu funksiya o‘q uchib borayotganda boshqa obyektlar (devor yoki dushman tanki) bilan to‘qnashuv sodir bo‘lgan holatlarni qayta ishlashga javobgar. Biroq, o‘q hech narsaga tegmasdan shunchaki ekrandan chiqib ketishi ham mumkin, bunday hollarda shunchaki o‘qni yo‘q qilish kifoya (21~23-qatorlar). Bundan tashqari, e’tibor berish kerak bo‘lgan narsa bu o‘q devor yoki dushman tank bilan to‘qnashganda, faqat devor yoki tankni emas, balki ular bilan to‘qnashgan o‘qning o‘zini ham birga yo‘q qilish zarurligidir (18, 29-qatorlar). Biz o‘yinning yakuniy g‘alaba yoki mag‘lubiyat holatini qayerda aniqlaymiz deb o‘ylaganimizda, bu to‘qnashuvni qayta ishlash funksiyasi ichida buni aniqlash joy nuqtai nazaridan yomon emas. Dushman tanklari bironta ham qolmagan holat (37~38-qatorlar), yoki bosh qahramon tankiga o‘q teggan holat (40~41-qatorlar) bo‘lishi mumkin. 3 ta foydalanuvchi funksiyasining implementatsiyasi va tushuntirilishi yakunlandi. Avval ham aytib o‘tilgandek, ushbu o‘yin ilgari yaratgan ikki o‘yin(Breakout va TwinBee)ning xususiyatlariga oid oldindan bilim bo‘lgani sababli, bu o‘yinni yaratish va tushunish o‘ylagandan ko‘ra ko‘proq vaqt talab qilmagandek ko‘rinadi. Nihoyat, barcha kodni to‘liq ulashish bilan protseduraviy dasturlash yordamida ishlab chiqilgan Battle City o‘yinini yakunlaymiz, va keyingi bo‘limdan boshlab esa foydalanuvchi tomonidan yaratilgan obyektlarni qanday tuzishdan boshlaymiz hamda aynan shu o‘yinni obyektga yo‘naltirilgan paradigma asosida yaratishni boshlaymiz. [Previous9.1 Protseduraviy dasturlash 1chevron-left](https://roboticsware.gitbook.io/python-pygame_zero/battle_city/9.1_procedural_dev1) [Next9.3 Obyektga yo‘naltirilgan dasturlash 1chevron-right](https://roboticsware.gitbook.io/python-pygame_zero/battle_city/9.3_oop_dev1) Last updated 6 months ago sun-brightdesktopmoon Copy def fire_bullets(player, bullets): if player == tank: bullet = Actor("bulletblue2") else: bullet = Actor("bulletred2") bullet.angle = player.angle bullet.pos = player.pos bullets.append(bullet) Copy def collide_bullets(bullets): global winner for bullet in bullets: if bullet.angle == 0: bullet.x += 5 elif bullet.angle == 90: bullet.y -= 5 elif bullet.angle == 180: bullet.x -= 5 elif bullet.angle == 270: bullet.y += 5 # devorga urilish holatini qayta ishlash wall_index = bullet.collidelist(walls) if wall_index != -1: del walls[wall_index] bullets.remove(bullet) # ekrandan chiqib ketish holatini qayta ishlash if bullet.x < 0 or bullet.x > WIDTH \ or bullet.y < 0 or bullet.y > HEIGHT: bullets.remove(bullet) # tanklar bilan to'qnashuvni qayta ishlash if bullets != enemy_bullets: # dushman tanki enemy_index = bullet.collidelist(enemies) if enemy_index != -1: bullets.remove(bullet) explosion = Actor("explosion3") explosion.pos = enemies[enemy_index].pos explosion.images = ["explosion3", "explosion4"] explosion.fps = 8 explosion.duration = 15 explosions.append(explosion) del enemies[enemy_index] if len(enemies) == 0: winner = "You" else: # qahramon tank if bullet.colliderect(tank): winner = "Enemy" # tank portlash animatsiyasi for explosion in explosions: explosion.animate() explosion.duration -= 1 if explosion.duration == 0: explosions.remove(explosion) Copy from pgzhelper import * import random WIDTH = 800 HEIGHT = 600 bullets = [] bullet_delay_cnt = 0 BULLET_DELAY = 50 enemy_bullets = [] explosions = [] winner = '' tank = Actor("tank_blue", (400, 575)) tank.angle = 90 ENEMY_MOVE_DELAY = 20 MAX_ENEMIES = 3 enemies = [] for i in range(MAX_ENEMIES): enemy = Actor("tank_red") enemy.angle = 270 enemy.x = (i + 1) * WIDTH / (MAX_ENEMIES + 1) enemy.y = 25 enemy.move_cnt = 0 enemies.append(enemy) # 50x50 devor maketini yarating walls = [] WALL_SIZE = 50 for x in range(int(WIDTH / WALL_SIZE)): for y in range(int(HEIGHT / WALL_SIZE - 2)): # yuqori/pastki qismini bo'sh qoldiring # tasodifiy devorsiz bo'sh joy yaratish if random.randint(0, 100) < 50: wall = Actor("wall", anchor=("left", "top")) wall.x = x * WALL_SIZE wall.y = y * WALL_SIZE + WALL_SIZE # yuqori qismini bo'shating walls.append(wall) def move_player(player): # tankning boshlang'ich joylashuvini saqlab qo'yish original_x = player.x original_y = player.y if player == tank: # tank qahramoni if keyboard.right: player.angle = 0 player.x += 2 elif keyboard.left: player.angle = 180 player.x -= 2 elif keyboard.up: player.angle = 90 player.y -= 2 elif keyboard.down: player.angle = 270 player.y += 2 else: # dushman tanki if player.angle == 0: player.x += 2 elif player.angle == 90: player.y -= 2 elif player.angle == 180: player.x -= 2 elif player.angle == 270: player.y += 2 # devordan o'tib keta olmaslik va eski joyida qolish if player.collidelist(walls) != -1: player.x = original_x player.y = original_y # o'yin oynasidan chiqib ketmaslik if player.left < 0 or player.right > WIDTH \ or player.top < 0 or player.bottom > HEIGHT: player.x = original_x player.y = original_y def fire_bullets(player, bullets): if player == tank: bullet = Actor("bulletblue2") else: bullet = Actor("bulletred2") bullet.angle = player.angle bullet.pos = player.pos bullets.append(bullet) def collide_bullets(bullets): global winner for bullet in bullets: if bullet.angle == 0: bullet.x += 5 elif bullet.angle == 90: bullet.y -= 5 elif bullet.angle == 180: bullet.x -= 5 elif bullet.angle == 270: bullet.y += 5 # devorga urilish holatini qayta ishlash wall_index = bullet.collidelist(walls) if wall_index != -1: del walls[wall_index] bullets.remove(bullet) # ekrandan chiqib ketish holatini qayta ishlash if bullet.x < 0 or bullet.x > WIDTH \ or bullet.y < 0 or bullet.y > HEIGHT: bullets.remove(bullet) # tanklar bilan to'qnashuvni qayta ishlash if bullets != enemy_bullets: # dushman tanki enemy_index = bullet.collidelist(enemies) if enemy_index != -1: bullets.remove(bullet) explosion = Actor("explosion3") explosion.pos = enemies[enemy_index].pos explosion.images = ["explosion3", "explosion4"] explosion.fps = 8 explosion.duration = 15 explosions.append(explosion) del enemies[enemy_index] if len(enemies) == 0: winner = "You" else: # qahramon tank if bullet.colliderect(tank): winner = "Enemy" # tank portlash animatsiyasi for explosion in explosions: explosion.animate() explosion.duration -= 1 if explosion.duration == 0: explosions.remove(explosion) def draw(): screen.blit('grass', (0, 0)) tank.draw() for enemy in enemies: enemy.draw() for wall in walls: wall.draw() for bullet in bullets: bullet.draw() for bullet in enemy_bullets: bullet.draw() for explosion in explosions: explosion.draw() if winner: screen.draw.text(winner + " Win!", \ midbottom=(WIDTH / 2, HEIGHT / 2), fontsize=100) def update(): global bullet_delay_cnt, enemy_move_cnt # tank qahramoni if winner == '': move_player(tank) if bullet_delay_cnt == 0: # kechikish vaqti tugagach qayta o‘q otish mumkin if keyboard.space: sounds.sfx_exp_medium12.play() fire_bullets(tank, bullets) bullet_delay_cnt = BULLET_DELAY else: bullet_delay_cnt -= 1 collide_bullets(bullets) # dushman tanklari for enemy in enemies: choice = random.randint(0, 2) if enemy.move_cnt > 0: # tankni harakatlantirish enemy.move_cnt -= 1 move_player(enemy) elif choice == 0: # harakatni kechiktirish vaqtini boshlash enemy.move_cnt = ENEMY_MOVE_DELAY elif choice == 1: # tankni yo'nalishini o'zgartirish enemy.angle = random.randint(0, 3) * 90 else: # o'q otish fire_bullets(enemy, enemy_bullets) collide_bullets(enemy_bullets) sun-brightdesktopmoon --- # 8.8 (Bonus) Pygame Zero misoli versiyasi 2 | Python-Pygame Zero Avvalo, raketka(Paddle) va tennis to‘pi(TennisBall) obyektlarini ko‘rib chiqamiz. Bu ikkala obyekt ham ilgari yaratilgan reflektor(Bar) va to‘p(Ball) obyektlaridan unchalik farq qilmagani uchun tushunishda katta qiyinchilik tug‘dirmaydi. Muallif yozgan kod bilan asosiy farq shundaki, reflektor va to‘p obyektlarining o‘zida to‘qnashuvni aniqlash funksiyasi mavjud emas, aksincha bu ishlar asosiy obyekt bo‘lgan o‘yin(Game) obyektida bajariladi. Copy class Paddle(Rect): """ Paddle represents one player on the screen. It is drawn like a long rectangle and positioned either left or right on the screen. Two helper methods move the paddle up or down. """ def __init__(self, start_x, start_y): super().__init__(start_x, start_y, PADDLE_WIDTH, PADDLE_HEIGHT) def up(self): if self.y - 5 > 40: self.y -= 5 def down(self): if self.y + self.height + 5 < HEIGHT - 40: self.y += 5 def draw(self): screen.draw.filled_rect(self, MAIN_COLOR) class TennisBall(): """ Represents a tennis ball on the screen """ def __init__(self, start_pos, dt): """ Initialize the tennis ball position and set the movement rate """ self.x, self.y = start_pos self.dx = self.dy = dt @property def pos(self): return (self.x, self.y) def move(self): self.x += self.dx self.y += self.dy def draw(self): screen.draw.filled_circle(self.pos, TENNIS_BALL_RADIUS, MAIN_COLOR) Boshqa farqi shundaki, TennisBall obyekti **Rect**dan meros olmaydi, shu sababli obyekt o‘zining joylashuv ma’lumotlarini mustaqil ravishda boshqarishi kerak bo‘ladi. Shuning uchun 38~40-qatorlarda ko‘rganimizdek, u o‘zining joriy joylashuvini bildiruvchi **pos** nomli alohida xususiyatga ega. Shuningdek, _bu yerda birinchi marta Pythondagi_ _**property**_ _deb ataladigan dekorator(__**decorator**__) ishlatilganini ko‘rasiz, bu sizga biroz begona tuyulishi mumkin. Oddiy tushuntirsak,_ _**ma’lum bir dekoratorni funksiya nomi ustiga @ belgisi bilan yozsangiz**__,_ _**mavjud funksiyani o‘zgartirmasdan uning imkoniyatini kengaytirish usulini taqdim etadigan sintaksis**_ _bo‘ladi. Bu yerda_ _**pos**_ _endi obyektning metodi emas, balki oddiy xususiyati(property) sifatida ko‘rilishini ta’minlash maqsadida yaratilgan_ deb hisoblaylik_._ Boshqacha aytganda, 38~40-qatorlardagi kod quyidagi 5-qator kod bilan 100% bir xil ma’noga ega. Xo‘sh, shunchaki shunday kodlasak bo‘lar ekan, nega aynan dekorator qo‘shib alohida ajratib yozdik degan savolga, o‘yinni yaratgan muallif **pos** degan xususiyatni muhim deb bilgani uchun uni alohida ko‘zga tashlanadigan qilib ta’kidlash maqsadi deb tushunsa bo‘ladi. Endi navbat o‘yin obyekti(Game)ni ko‘rishga keladi, u yerda property dekoratori yana bir bor ishlatiladi va shunda bu dekoratorning asl maqsadi yanada ravshan bo‘ladi. Demak, endi eng asosiy, eng katta va og‘ir bo‘lgan o‘yin obyektini batafsil ko‘rib chiqamiz. O‘yin obyekti o‘ziga kerak bo‘lgan tarkibiy qismlarni, ya’ni alohida obyektlarni, bevosita yaratishdan tortib ularni yo‘q qilishgacha boshqaradi. 13~14-qatorlarda reflektor obyektlari to‘g‘ridan-to‘g‘ri yaratilib, ichki xususiyat sifatida tayinlanmoqda. Va darhol ortidan, 16-qatorda **set\_ball** a’zo funksiyasi orqali tennis to‘pi obyekti yaratiladi. Bu yerda **set\_ball** funksiyasining argumenti sifatida **ball\_pos** xususiyat qiymati uzatilayotganini ko‘rish mumkin. 18~23-qatorlardagi **ball\_pos** funksiyasida yuqorida tilga olingan o‘sha dekorator yana paydo bo‘ladi; **property** dekoratori yordamida, aslida funksiya bo‘lgan narsa o‘zgaruvchi (xususiyat qiymati) kabi ishlatiladigan shaklga o‘zgartirilgan. Shuning uchun endi **ball\_pos** funksiyamas, **self.ball\_pos** tarzida chaqirilib, xuddi o‘zgaruvchidek qo‘llanmoqda. _**ball\_pos**_ _funksiyasini ko‘zdan kechiradigan bo‘lsak, u avvalgidek_ _**tennis to‘pi**__ning '__**pos'**__i singari oddiygina joriy koordinatani qaytarmaydi; balki qaytarishdan avval to‘pning holatini joriy reflektorning holatiga muvofiq, reflektorning markaziga “yopishgan” to‘p koordinatasiga bog‘laydi va shundan keyin natijani beradi. To‘g‘ri,_ _**property**_ _dekoratorining asl qo‘llanish maqsadi ham shunday — xususiyat qiymatini qaytarishda qo‘shimcha ishlov berish kerak bo‘lganda undan foydalanishdir._ Endi qolgan a’zo funksiyalarning amalga oshirilishini birma-bir ko‘rib chiqib, algoritmik jihatlarini tushunsak bo‘ladi. Va nihoyat, 51 va 61-qatorlarda ishlatilgan **collidepoint** funksiyasi haqida qo‘shimcha tushuntirish kerak. Nomidan ko‘rinib turibdiki, bu ham to‘qnashuv tekshiruvini bajaradi, lekin avvalgidek **Rect** asosida, ya’ni to‘rtburchakga tayangan tekshiruv o‘rniga, endi **Point** asosida, ya’ni piksellar darajasida tekshiradi. Piksellar darajasida tekshirilgani uchun to‘qnashuvni yanada aniqroq aniqlash mumkin deb kutamiz. Biroq hamma narsa faqat yaxshi bo‘lavermaydi — bunday nozik tekshiruv ko‘proq hisob-kitob talab qiladi, kompyuter resurslari ko‘proq sarflanadi va eng yomon holatda o‘yinning umumiy bajarilish tezligi sekinlashishi mumkinligini yodda tutish kerak. Shu bois biz doimo ma’lum bir murosa(tradeoff) bilan kod yozamiz. Malumot uchun, bu funksiya Pygame Zeroning asosi bo‘lgan [Pygame kutubxonasidagi Rect obyekti a’zo funksiyasiarrow-up-right](https://www.pygame.org/docs/ref/rect.html#pygame.Rect.collidepoint) dir. Shu bilan Pong o‘yiniga oid qismlarni yakunlaymiz. Bu bonus bo‘limdagi mazmunni, sizlarning darajangizda, tushunish biroz qiyin bo‘lishi mumkin degan fikrdaman. Biroq, bu asl ma’noda bonus bo‘lib, barchangiz tushunishingiz shart degan maqsadda emas, balki orangizda bu darajadan biroz murakkabroq bilimdan foyda ko‘radiganlar ham bo‘lishi mumkinligi uchun qo‘shimcha qilindi. Agar hozircha hammasini to‘liq tushunmagan bo‘lsangiz ham xavotir olmang, chunki bu tabiiy holat. Keyinchalik turli yo‘nalishlarda bilimlaringiz kengayganida, ushbu mavzuga bir necha bor qaytib kelsangiz, bir kun kelib barchasini "mukammal tushunib" olishingiz shubhasiz. Keling, shu yerda yakunlaymiz va keyingi bobda obyektga yo‘naltirilgan dasturlashni o‘rganishni davom etamiz. [Previous8.7 (Bonus) Pygame Zero misoli versiyasi 1chevron-left](https://roboticsware.gitbook.io/python-pygame_zero/pong/8.7_bonus_dev1) [Next9\. Battle city o‘yinini yaratishchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/battle_city) Last updated 6 days ago sun-brightdesktopmoon Copy class TennisBall(): def __init__(self, start_pos, dt): self.x, self.y = start_pos self.dx = self.dy = dt self.pos = (self.x, self.y) Copy class Game(): def __init__(self, player): self.active_player = player self.score_left = 0 self.score_right = 0 self.in_progress = False self.computer_acting = False # position paddles in the middle of the screen middle = HEIGHT/2 - PADDLE_HEIGHT/2 self.left_paddle = Paddle(20, middle) self.right_paddle = Paddle(WIDTH-40, middle) self.set_ball(self.ball_pos) @property def ball_pos(self): if self.active_player == LEFT_PLAYER: return (20 + PADDLE_WIDTH + 10, self.left_paddle.centery) else: return (WIDTH - 35 - PADDLE_WIDTH, self.right_paddle.centery) def set_ball(self, pos): # a ball is set on the paddle of last player that got a point dt = 5 if self.active_player == LEFT_PLAYER else -5 self.tennis_ball = TennisBall(pos, dt) def position_ball(self): # used when the player moves tha paddle and # game is not in progress self.tennis_ball.x, self.tennis_ball.y = self.ball_pos def score_for_left(self): self.in_progress = False self.active_player = LEFT_PLAYER self.score_left += 1 self.set_ball(self.ball_pos) def score_for_right(self): self.in_progress = False self.active_player = RIGHT_PLAYER self.score_right += 1 self.set_ball(self.ball_pos) def proceed(self): self.tennis_ball.move() # bounce from the walls if self.tennis_ball.y <= 40: self.tennis_ball.dy = -self.tennis_ball.dy if self.tennis_ball.y >= HEIGHT - 40: self.tennis_ball.dy = -self.tennis_ball.dy # bounce from the paddles if self.left_paddle.collidepoint(self.tennis_ball.pos): self.tennis_ball.dx = -self.tennis_ball.dx if self.right_paddle.collidepoint(self.tennis_ball.pos): self.tennis_ball.dx = -self.tennis_ball.dx # if we didn't bounce, then that is a score if self.tennis_ball.x <= 0: self.score_for_right() if self.tennis_ball.x >= WIDTH: self.score_for_left() if self.score_left == 11 or self.score_right == 11: self.in_progress = False # computer movement def computer_launch(self): self.in_progress = True self.computer_acting = False def computer_stop_acting(self): self.computer_acting = False def computer_move(self): # move towards the center of the screen when the ball is # travelling toward the enemy if self.tennis_ball.dx > 0: target_y = HEIGHT / 2 else: # when the ball is on other side of screen, just move # in general direction if self.tennis_ball.x > WIDTH / 2: delta = int(WIDTH * 0.25) if self.tennis_ball.dy < 0: target_y = self.tennis_ball.y - delta else: target_y = self.tennis_ball.y + delta else: # the ball is on our side, move with it rnd = random.randint(40, 200) if self.tennis_ball.dy < 0: target_y = self.tennis_ball.y - rnd else: target_y = self.tennis_ball.y + rnd target_y = max(40, min(target_y, HEIGHT - 80)) animate( self.left_paddle, y=target_y, duration=.50, on_finished=self.computer_stop_acting ) def computer_move_randomly(self): # move the paddle randomly during one second before launching the ball target_y = random.randint(40, HEIGHT - PADDLE_HEIGHT - 80) distance = abs(self.left_paddle.y - target_y) duration = max(0.1, distance / 200.0) self.computer_total_duration += duration if self.computer_total_duration + duration < 1.0: on_finished = self.computer_move_randomly else: on_finished = self.computer_launch animate( self.left_paddle, y=target_y, duration=duration, on_finished=on_finished ) def computer_act(self): if self.in_progress: # predict where the ball will move and move towards it self.computer_move() elif self.active_player == LEFT_PLAYER: # move randomly for a bit, then shoot the ball out if not self.computer_acting: self.computer_acting = True self.computer_total_duration = 0.0 self.computer_move_randomly() def draw(self): # slightly gray background screen.fill((64, 64, 64)) # show the score for the left player screen.draw.text( 'Computer: {}'.format(self.score_left), color=MAIN_COLOR, center=(WIDTH/4 - 20, 20), fontsize=48 ) # show the score for the right player screen.draw.text( 'Player: {}'.format(self.score_right), color=MAIN_COLOR, center=(WIDTH/2 + WIDTH/4 - 20, 20), fontsize=48 ) # a dividing line screen.draw.line( (WIDTH/2, 40), (WIDTH/2, HEIGHT-40), color=MAIN_COLOR) if self.score_left == 11: screen.draw.text( 'COMPUTER WINS!!!', color=MAIN_COLOR, center=(WIDTH/2, HEIGHT/2), fontsize=96 ) elif self.score_right == 11: screen.draw.text( 'PLAYER WINS!!!', color=MAIN_COLOR, center=(WIDTH/2, HEIGHT/2), fontsize=96 ) else: self.left_paddle.draw() self.right_paddle.draw() self.tennis_ball.draw() sun-brightdesktopmoon --- # 9.7 Obyektga yo‘naltirilgan dasturlash 4 | Python-Pygame Zero Nihoyat uzoq yo‘lni bosib o‘tib, amalga oshirishning yakuniy bosqichigacha yetib kelganingiz bilan tabriklayman. Bu bo‘limda o‘tgan bo‘limdagi yozgan kodimizning ayrim qismlarini tahrirlaymiz va hali amalga oshirilmagan qismlarni ham to‘liq amalga oshirib, umumiy kodlashni yakunlamoqchimiz. Avvalo, hali amalga oshirilmagan qism sifatida o‘q tekkan tankning portlashini qo‘shmoqchimiz. Biz allaqachon protseduraviy dasturlashda ko‘rib chiqqanimizdek, "portlash" ham aslida bitta Actor obyekti va u portlash obyektini animatsiya qilish orqali amalga oshirilgan. Demak, obyektga yo‘naltirilgan versiyada bu portlash obyektini Actor dan meros olgan mustaqil obyekt (bu yerda uning nomi **Explosion**) sifatida yaratamiz, uni yaratish va undan foydalanish esa tank obyekti o‘ziga tegishli bo‘lishi mumkin. Shu sabab, buni quyidagicha kodlash mumkin. actors.py Copy class Explosion(Actor): def __init__(self, img_names, pos): super().__init__(img_names[0], pos) self.images = img_names self.fps = 8 self.duration = 15 def update(self): self.animate() self.duration -= 1 class Tank(Actor, CheckOutOfScreen): def __init__(self, img_name, pos, angle, walls, screen): Actor.__init__(self, img_name, pos) CheckOutOfScreen.__init__(self, screen) self._original_pos = None self.angle = angle self.walls = walls self.bullets = [] self.explosions = [] ... qisqartirildi def draw(self): super().draw() for bullet in self.bullets: bullet.draw() for explosion in self.explosions: explosion.draw() def collidelist_bullets(self, tanks): tank_index = -1 for bullet in self.bullets: bullet.move() # ekran chegaralarini tekshirish if bullet.is_out_of_screen(): self.bullets.remove(bullet) # devorga urilish holatini qayta ishlash wall_index = bullet.collidelist(self.walls) if wall_index != -1: del self.walls[wall_index] self.bullets.remove(bullet) # dushman tankini tekshirish tank_index = bullet.collidelist(tanks) if tank_index != -1: self.bullets.remove(bullet) explosion = Explosion(["explosion3", "explosion4"], \ tanks[tank_index].pos) self.explosions.append(explosion) # portlash animatsiyasi for explosion in self.explosions: explosion.update() if explosion.duration == 0: self.explosions.remove(explosion) return tank_index 🔢 Portlash bilan bog‘liq ishlov uchun qo‘shilgan kod 1~10, 21, 29~30 va 52~59-qatorlardagi kodlardir. Yuqoridagi kodni ishga tushirsangiz, o‘q tekkan tank biz maqsad qilganimizdek portlash animatsiyasini namoyon qiladi. Shu tariqa biz yaratmoqchi bo‘lgan Battle City o‘yinining obyektga yo‘naltirilgan versiyasining yakuniy variantini tugalladik. O‘zingizning klasslaringizni belgilab, o‘z obyektlaringizni yaratib va ularning hamkorligi orqali obyektga yo‘naltirilgan paradigma asosida dasturlash qiziqarli tajriba bo‘ldi, deb o‘ylayman. Biroq, hali ham obyektga yo‘naltirilgan dasturlash murakkabdek tuyulishi va katta ustunliklari aniq ko‘rinmasligi mumkin; ammo ushbu mavzuning kirish qismida quyidagicha ta’kidlaganimizdek, > _Masalan, dushman sifatida faqat tank emas, boshqa turdagi dushmanlar ham qo‘shilishini, yoki mening ishlatadigan qurolim ham faqat to‘p emas, boshqa turdagi hujum vositalarini ham o‘z ichiga olishini, hozircha faqat devor to‘siqlari mavjud bo‘lsada, boshqa turdagi to‘siqlarni ham o‘ylayotganimizni nazarda tutamizmi? Chunki aynan shunday qarorlarga qarab, hozirdan boshlab qanday chuqurlikda meros olish kerakligi va obyektga yo‘naltirilgan dizayn ko‘lami aniqlanadi._ Aslida bu o‘yin hajmi kattalashib, murakkablashgan sari uning afzalliklari to‘liq namoyon bo‘ladi. Albatta, bunday jihatlarni ham inobatga olib ishlab chiqish uchun dastlabki bosqichda obyektga yo‘naltirilgan dizaynning murakkabligi ortadi va qo‘shimcha o‘rganilishi kerak bo‘lgan bilimlar ham paydo bo‘ladi. _Birinchi qoshiqda to‘ymaslik_ tabiiy, shuning uchun obyektga yo‘naltirilgan paradigmaga asoslangan bu ikkinchi ishlanma shu darajada qoniqarli. Keyingi nashrni yangilash imkoni bo‘lsa, chuqurlashtirilgan implementatsiyani ilova sifatida qo‘shaman. Endi esa yakunda, hozirgacha bo‘lgan kodlash mazmunining to‘liq manba kodlarini ulashish qilish bilan ushbu bo‘limni yakunlayman. [Previous9.6 Obyektga yo‘naltirilgan dasturlash 3chevron-left](https://roboticsware.gitbook.io/python-pygame_zero/battle_city/9.6_oop_dev3) [Next10\. Pongni tarmoq o‘yiniga aylantirishchevron-right](https://roboticsware.gitbook.io/python-pygame_zero/pong_network) Last updated 6 days ago sun-brightdesktopmoon actors.py Copy from pgzhelper import * from abc import ABC, abstractmethod class CheckOutOfScreen(ABC): def __init__(self, screen): self.s_width, self.s_height = screen @abstractmethod def is_out_of_screen(self): pass class Bullet(Actor, CheckOutOfScreen): def __init__(self, img_name, pos, angle, walls, screen): Actor.__init__(self, img_name, pos) CheckOutOfScreen.__init__(self, screen) self.angle = angle self.walls = walls def is_out_of_screen(self): if self.x > self.s_width or self.x < 0 or \ self.y > self.s_height or self.y < 0: return True else: return False def move(self): if self.angle == 0: self.x += 5 elif self.angle == 90: self.y -= 5 elif self.angle == 180: self.x -= 5 elif self.angle == 270: self.y += 5 class Explosion(Actor): def __init__(self, img_names, pos): super().__init__(img_names[0], pos) self.images = img_names self.fps = 8 self.duration = 15 def update(self): self.animate() self.duration -= 1 class Tank(Actor, CheckOutOfScreen): def __init__(self, img_name, pos, angle, walls, screen): Actor.__init__(self, img_name, pos) CheckOutOfScreen.__init__(self, screen) self._original_pos = None self.angle = angle self.walls = walls self.bullets = [] self.explosions = [] def is_out_of_screen(self): if self.right > self.s_width or self.left < 0 or \ self.bottom > self.s_height or self.top < 0: return True else: return False def move(self): self._original_pos = self.pos if self.angle == 180: self.x -= 2 elif self.angle == 0: self.x += 2 elif self.angle == 90: self.y -= 2 elif self.angle == 270: self.y += 2 # ekran chegaralarini tekshirish if self.is_out_of_screen(): self.pos = self._original_pos # devor bloklarini tekshirish if self.collidelist(self.walls) != -1: self.pos = self._original_pos def fire(self, image, sound_obj=None): bullet = Bullet(image, self.pos, self.angle, self.walls, (self.s_width, self.s_height)) self.bullets.append(bullet) if sound_obj: sound_obj.play() def collidelist_bullets(self, tanks): tank_index = -1 for bullet in self.bullets: bullet.move() # ekran chegaralarini tekshirish if bullet.is_out_of_screen(): self.bullets.remove(bullet) # devorga urilish holatini qayta ishlash wall_index = bullet.collidelist(self.walls) if wall_index != -1: del self.walls[wall_index] self.bullets.remove(bullet) # dushman tankini tekshirish tank_index = bullet.collidelist(tanks) if tank_index != -1: self.bullets.remove(bullet) explosion = Explosion(["explosion3", "explosion4"], \ tanks[tank_index].pos) self.explosions.append(explosion) # portlash animatsiyasi for explosion in self.explosions: explosion.update() if explosion.duration == 0: self.explosions.remove(explosion) return tank_index def draw(self): super().draw() for bullet in self.bullets: bullet.draw() for explosion in self.explosions: explosion.draw() battle\_city\_oop.py Copy import random from actors import Tank WIDTH = 800 HEIGHT = 600 winner = "" # dushman tankining harakatidagi kutish vaqti enemy_move_cnt = 0 ENEMY_MOVE_DELAY = 20 # qahramon tank o'qi qayta yuklash kutish vaqti bullet_delay_cnt = 0 BULLET_DELAY = 50 # 50x50 50x50 devor blokini yaratish walls = [] WALL_SIZE = 50 for x in range(int(WIDTH / WALL_SIZE)): # tank joylashadigan birinchi va oxirgi qatordan iborat jami 2 qatorni bo'sh qoldirish uchun -2 qilib yaratilgan for y in range(int(HEIGHT / WALL_SIZE - 2)): if random.randint(0, 100) < 50: # kerakli miqdordagi devorlarni yaratish wall = Actor("wall", anchor=("left", "top")) wall.x = x * WALL_SIZE wall.y = y * WALL_SIZE + WALL_SIZE # birinchi qatorni bo'shatish uchun oxirigacha pastga surish walls.append(wall) # tank qahramonini yaratish tank = Tank("tank_blue", (400, 575), 90, walls, (WIDTH, HEIGHT)) # dushman tanklarini yaratish enemies = [] MAX_ENEMIES = 3 for i in range(MAX_ENEMIES): enemies.append(Tank("tank_red", (400, 25), 270, walls, (WIDTH, HEIGHT))) def draw(): screen.blit("grass", (0, 0)) # fon rasmini shizish tank.draw() for enemy in enemies: enemy.draw() for wall in walls: wall.draw() if winner: screen.draw.text( winner + " Win!", midbottom=(WIDTH / 2, HEIGHT / 2), fontsize=100 ) def update(): global enemy_move_cnt, bullet_delay_cnt, winner # tank qahramoni if winner == "": if keyboard.left: tank.angle = 180 tank.move() elif keyboard.right: tank.angle = 0 tank.move() elif keyboard.up: tank.angle = 90 tank.move() elif keyboard.down: tank.angle = 270 tank.move() if bullet_delay_cnt == 0: # o'q otish mumkin if keyboard.space: tank.fire("bulletblue2", sounds.sfx_exp_medium12) bullet_delay_cnt = BULLET_DELAY else: bullet_delay_cnt -= 1 enemy_idx = tank.collidelist_bullets(enemies) if enemy_idx != -1: del enemies[enemy_idx] if len(enemies) == 0: winner = "You" # dushman yanklari for enemy in enemies: choice = random.randint(0, 3) if enemy_move_cnt > 0: enemy_move_cnt -= 1 enemy.move() elif choice == 0: # harakatni kechiktirish vaqtini boshlash enemy_move_cnt = ENEMY_MOVE_DELAY elif choice == 1: # tankni yo'nalishini o'zgartirish enemy.angle = random.randint(0, 3) * 90 else: enemy.fire("bulletred2") tank_idx = enemy.collidelist_bullets([tank]) if tank_idx != -1: winner = "Enemy" sun-brightdesktopmoon --- # 9.5 Obyektga yo‘naltirilgan dasturlash 2 | Python-Pygame Zero Biz o‘tgan [4-bo‘lim](https://roboticsware.gitbook.io/python-pygame_zero/battle_city/oop_interface) da barcha obyektlarga emas, balki faqat tank va o‘q obyektlariga kerak bo‘ladigan ekran chegarasi cheklovini obyektga yo‘naltirilgan nuqtai nazardan qanday amalga oshirish mumkinligini o‘ylab tugatgan edik. Buni amalga oshirish uchun **interfeys** tushunchasi kerak edi, va o‘tgan bobda bu qismni yaxshi tushunib oldik. Endi esa uni amalda qo‘llaymiz. Quyidagi **CheckOutOfScreen** nomli abstrakt klassni ta’riflab(define), uning ichiga haqiqatan ham ekran chegarasidan chiqib ketganini tekshiradigan **is\_out\_of\_screen** abstrakt metodini qo‘shdik. Bu interfeysni meros olgan tomon esa ushbu metodni bevosita o‘zi amalga oshiradi. Chunki ekran chegarasidan chiqib ketganlik mezoni obyektning turiga qarab farq qilishi mumkin. Copy from abc import ABC, abstractmethod class CheckOutOfScreen(ABC): def __init__(self, screen): self.s_width, self.s_height = screen @abstractmethod def is_out_of_screen(self): pass circle-info Eslatma sifatida aytib o‘tish lozim - **ekran chegarasini tekshiradigan o‘lchamni oldindan qat’iy belgilab qo‘ymasdan**, har bir obyekt ushbu interfeysni meros olayotgan vaqtda **o‘zi istagan ekran o‘lchamini** belgilab, shunga muvofiq chegarani tekshirishi kerak bo‘ladi. 5-satrda uchraydigan **self.s\_width, self.s\_height = screen** degan ifoda sizga yangi ko‘rinishi mumkin. Bu kodning ma’nosi **screen** nomli o‘zgaruvchi bitta bo‘lsada, uning ichidagi qiymatlar bir nechta bo‘lishi mumkin (masalan, **ro‘yxat (list)** yoki **juftlik (tuple)** shaklida). Shuning uchun, bu kod ichidagi qiymatlarni tartib bilan bittadan olib, **self.s\_width** va **self.s\_height** degan yangi o‘zgaruvchilarga **mos ravishda ajratib joylashtiradi** deb tushunsa bo‘ladi. Python tilida bu jarayon **unpack** (ya’ni, “ochib ajratish”) deb ataladi. Masalan, har bir obyekt tomonidan amalga oshirilgan quyidagi implementatsiya tafsilotlarini ko‘rib chiqadigan bo‘lsak, **o‘q** obyektining holatida, uning ekran chegarasidan chiqmaganini aniqlash uchun o‘qning markaziy koordinatalari (**self.x, self.y**) asos qilib olinadi. Ammo tank obyektining holatida esa, tank tasvirining chap, o‘ng, yuqori va pastki chetlari (self.left, self.right, self.top, self.bottom) mezon sifatida olinadi (7~12-satrlar). Ya’ni, har bir obyekt o‘ziga xos holda chegarani aniqlash mezoniga ega bo‘lishi mumkin (22~27-satrlar). Copy class Bullet(Actor, CheckOutOfScreen): def __init__(self, img_name, pos, angle, screen): Actor.__init__(self, img_name, pos) CheckOutOfScreen.__init__(self, screen) self.angle = angle def is_out_of_screen(self): if self.x > self.s_width or self.x < 0 or \ self.y > self.s_height or self.y < 0: return True else: return False class Tank(Actor, CheckOutOfScreen): def __init__(self, img_name, pos, angle, screen): Actor.__init__(self, img_name, pos) CheckOutOfScreen.__init__(self, screen) self._original_pos = 0 self.angle = angle def is_out_of_screen(self): if self.right > self.s_width or self.left < 0 or \ self.bottom > self.s_height or self.top < 0: return True else: return False def move(self): self._original_pos = self.pos if self.angle == 180: self.x -= 2 elif self.angle == 0: self.x += 2 elif self.angle == 90: self.y -= 2 elif self.angle == 270: self.y += 2 # ekran chegaralarini tekshirish if self.is_out_of_screen(): self.pos = self._original_pos circle-info Eslatma sifatida aytish joizki, 17-qatoridagi ota obyektni ishga tayyorlash qismi ilgari **super().init** metodi orqali yozilgan edi, ammo endi aniq obyekt nomi bilan chaqirilmoqda. Buning sababi shundaki, klass endi ikki yoki undan ortiq ota obyektlardan meros olyapti, shuning uchun qaysi ota obyektni ishga tayyorlash kerakligini nom orqali ochiq-oydin ko‘rsatish zarur bo‘ladi. 🔢 Tank obyektining **move** metodida ham o‘zgarishlar mavjudligini sezish mumkin. 30-qatorida joriy holat eslab olinadi va 40~42-qatorlar orqali harakatlangan nuqtada ekran chegarasidan chiqib ketgan-ketmaganligini obyektning o‘zidagi **is\_out\_of\_screen** metodi orqali tekshiriladi. Agar chiqib ketsa, u tomonga harakat qilishga ruxsat berilmaydi va obyekt yana avvalgi joyiga qaytariladi. Bu bilan ekran chegarasidan tashqariga chiqib ketishni cheklash maqsadiga erishilmoqda. Bu allaqachon tank harakatining cheklanishi bilan bog‘liq tarzda muhokama qilingan bo‘lib, devordan o‘tib keta olmaslik kabi devor bilan bog‘liq cheklovlar haqida edi. Bu holatda ikki obyekt (tank va devor) to‘qnashuvini aniqlagandan so‘ng harakatga cheklov qo‘yiladi. Ushbu funksiya ham **move** metodiga qo‘shilishi kerak bo‘ladi. Shu mazmundagi barcha hozirgacha bajarilgan kodni birgalikda ko‘rsatadigan bo‘lsak, quyidagicha bo‘ladi. 🔢 59~60 qatordagi tankning devorlar to‘plami bilan to‘qnashuvi mavjudligini aniqlash **collidelist** metodidan foydalanish orqali tekshirilishi mumkin, ammo bu yerda to‘qnashuv obyektlari bo‘lgan devorlar to‘plamining ma’lumotlari (aniqrog‘i, yaratilgan obyektning xotiradagi joylashuvi) 29 va 34-qatorlardagi kabi tank obyektini yaratishda parametr sifatida uzatiladi va shu orqali foydalaniladi. Tank obyektlarining harakatga oid funksiyalari tayyor bo‘lgani uchun, ularni haqiqiy foydalanish joyi (**battle\_city\_oop.py** faylidagi **update** funksiyasi)dagi kod bilan birgalikda ko‘rib chiqsak, bizning yozgan kodimiz qanday ishlashini yanada aniqroq tushunishimiz mumkin bo‘ladi. Kodda diqqat bilan ko‘rish kerak bo‘lgan yangi element bu **update** funksiyasining paydo bo‘lganidir. Bu yerda bosh qahramon tank foydalanuvchining klaviatura orqali boshqarilishi, dushman tank esa avtomatik boshqarilishi uchun yozilgan kod qismlari avvalgi protsedurali uslubdagi algoritmlar bilan bir xil bo‘lib, tushunishda katta qiyinchilik tug‘dirmaydi. Asosiy farq shundaki, ilgari global funksiyalar chaqirilib bajarilgan funksiyalar endi obyekt chaqiruvi orqali bajarilmoqda, va bu holat bizning obyektga yo‘naltirilgan dasturlashga o‘tish maqsadimizga muvofiqdir. Endi esa, keyingi bo‘limda tanklarning o‘q otishi funksiyasini qanday loyihalash va amalga oshirishni ko‘rib chiqamiz. [Previous9.4 Obektga yo‘naltirilgan dasturlash nazariyasi (interfeys)chevron-left](https://roboticsware.gitbook.io/python-pygame_zero/battle_city/oop_interface) [Next9.6 Obyektga yo‘naltirilgan dasturlash 3chevron-right](https://roboticsware.gitbook.io/python-pygame_zero/battle_city/9.6_oop_dev3) Last updated 6 months ago sun-brightdesktopmoon actors.py Copy from pgzhelper import * from abc import ABC, abstractmethod class CheckOutOfScreen(ABC): def __init__(self, screen): self.s_width, self.s_height = screen @abstractmethod def is_out_of_screen(self): pass class Bullet(Actor, CheckOutOfScreen): def __init__(self, img_name, pos, angle, screen): Actor.__init__(self, img_name, pos) CheckOutOfScreen.__init__(self, screen) self.angle = angle def is_out_of_screen(self): if self.x > self.s_width or self.x < 0 or \ self.y > self.s_height or self.y < 0: return True else: return False class Tank(Actor, CheckOutOfScreen): def __init__(self, img_name, pos, angle, walls, screen): Actor.__init__(self, img_name, pos) CheckOutOfScreen.__init__(self, screen) self._original_pos = 0 self.angle = angle self._walls = walls def is_out_of_screen(self): if self.right > self.s_width or self.left < 0 or \ self.bottom > self.s_height or self.top < 0: return True else: return False def move(self): self._original_pos = self.pos if self.angle == 180: self.x -= 2 elif self.angle == 0: self.x += 2 elif self.angle == 90: self.y -= 2 elif self.angle == 270: self.y += 2 # ekran chegaralarini tekshirish if self.is_out_of_screen(): self.pos = self._original_pos # devor bloklarini tekshirish if self.collidelist(self._walls) != -1: self.pos = self._original_pos battle\_city\_oop.py Copy import random from actors import Tank WIDTH = 800 HEIGHT = 600 enemy_move_cnt = 0 ENEMY_MOVE_DELAY = 20 # 50x50 devor maketini yarating walls = [] WALL_SIZE = 50 for x in range(int(WIDTH / WALL_SIZE)): # tank joylashadigan birinchi va oxirgi qatordan iborat jami 2 qatorni bo'sh qoldirish uchun -2 qilib yaratilgan for y in range(int(HEIGHT / WALL_SIZE - 2)): if random.randint(0, 100) < 50: # kerakli miqdordagi devorlarni yaratish wall = Actor("wall", anchor=("left", "top")) wall.x = x * WALL_SIZE wall.y = y * WALL_SIZE + WALL_SIZE # birinchi qatorni bo'shatish uchun oxirigacha pastga surish walls.append(wall) # tank qahramonini yaratish tank = Tank("tank_blue", (400, 575), 90, walls, (WIDTH, HEIGHT)) # dushman tanklarini yaratish enemies = [] MAX_ENEMIES = 3 for i in range(MAX_ENEMIES): enemies.append(Tank("tank_red", (400, 25), 270, walls, (WIDTH, HEIGHT))) def draw(): screen.blit("grass", (0, 0)) # fon rasmini chizish tank.draw() for enemy in enemies: enemy.draw() for wall in walls: wall.draw() def update(): global enemy_move_cnt # tank qahramoni if keyboard.left: tank.angle = 180 tank.move() elif keyboard.right: tank.angle = 0 tank.move() elif keyboard.up: tank.angle = 90 tank.move() elif keyboard.down: tank.angle = 270 tank.move() # dushman tanklari for enemy in enemies: choice = random.randint(0, 3) if enemy_move_cnt > 0: enemy_move_cnt -= 1 enemy.move() elif choice == 0: # harakatni kechiktirish vaqtini boshlash??? enemy_move_cnt = ENEMY_MOVE_DELAY elif choice == 1: # tasodifiy yo'nalishni aniqlash enemy.angle = random.randint(0, 3) sun-brightdesktopmoon --- # Dasturimizni EXE fayliga aylantirish | Pygame Zero boshlang'ich **Avvalo shuni ma'lum qilmoqchimanki, bu xususiyat umumiy rasmiy Mu editorida mavjud emas va faqat** [**muallif tomonidan ishlab chiqilayotgan Mu editorining maxsus versiyasi**arrow-up-right](https://github.com/roboticsware/mu/releases) **da mavjud.** Foydalanish usuli oddiy. Birinchidan, _agar siz yaratgan o'yin boshqalarga tarqatilishi uchun yetarli darajada to'liq deb hisoblasangiz, barcha manbalarni to'plash orqali o'yinni avtomatik ravishda bitta bajariladigan fayl (Windows platformasi uchun exe fayli) sifatida yaratish uchun editor o'ziga o'rnatilgan funksiyadan foydalanishingiz mumkin. Bu funksiya manba kodi fayllarni, qo'shimcha modullarni va o'yin dasturlari chiqarish uchun zarur bo'lgan resurslarni (rasmlar, ovozlar, fontlar va boshqalar) bitta faylga aylantiradi. Bu sizning o'yiningizni boshqalarga tarqatishni osonlashtiradi va o'yin foydalanuvchilari uchun bitta bajariladigan faylni ikki marta bosish orqali o'yindan zavq olishlari ham qulay._ Misol uchun, keling, [keyingi darajali kitobiarrow-up-right](https://roboticsware.gitbook.io/python-pygame_zero) da 4-bobda birgalikda yaratgan "Flappy Bird" o'yinini qadoqlab ko'raylik. Birinchi, siz qadoqlamoqchi bo'lgan o'yin manba kodi faylining joylashuvini ko'rib chiqaik. Editorni o'rnatishda u Pygame Zero uchun editor o'zi tomonidan o'rnatilgan standart papka bo'lgan "akkauntingiz nomi/mu\_code" da joylashgan bo'lishi mumkin va albatta, siz uni bu holatda bo'lgani kabi qadoqlab ko'rishingiz mumkin. Biroq, **o'yin bilan bir-biriga bog'liq bo'lmagan fayllarni qadoqlashdan boshqa foyda yo'qligi sababli, bu faqat keraksiz hajmni oshiradi, iloji bo'lsa, faqat o'yin uchun zarur bo'lgan fayllar va resurslarni qadoqlash eng tejamkor usuli bo'ladi.** _Agar siz o'yinni yasashdan boshidanoq tegishli fayllarni alohida papkaga joylashtirgan bo'lsangiz va o'sha joyida dasturlashni boshlagan bo'lsangiz, uni oson qadoqlashga urinib ko'rishingiz mumkin, bo'lmasa, ularni hozir alohida tashkil qilishingiz mumkin._ Quyidagi misol faqat Flappy Bird o'yinida ishlatiladigan manba kodi fayllari va resurslarini alohida papkada tashkil qiladi. ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252F8WO8tZwOQj1UTWawCpbW%252Fimage.png%3Falt%3Dmedia%26token%3D65640e8f-cdc7-4c3c-930b-1878abc9d968&width=768&dpr=3&quality=100&sign=59c18629&sv=2) Papkalarni tartibga solishda yodda tutish kerak bo'lgan narsa shundaki, [5.1.1-bo'lim](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/kuchuk-mushuk_1#pygame-zeroda-resurlarni-boshqarish) da o'rganib olgandek resurslarni (rasmlar, fontlar, ovozli effektlari, fon musiqasi) o'z ichiga olgan pastki papkalar nomlari Pygame Zeroning asosiy cheklovlariga muvofiq yaratilishi kerak. Bu ular faqat oldindan belgilangan nomlar (images, fonts, sounds, music) bilan yaratilishi kerakligini bildiradi. Endi siz tayyor bo'lsangiz, jarayon juda oddiy. _Agar sizda editor ichida bir nechta fayllar ochiq bo‘lsa, qadoqlamoqchi bo'lgan o'yinning manba kodi fayl yorlig'ini bosib kiring va quyidagi rasmda ko'rsatilganidek, "__**Exe fayliga**__" deb nomlangan menyu belgisini bosing._ ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FLXFnqfnEq1lJd4Aamuck%252FScreenshot%25202024-07-08%2520at%252011.39.20.png%3Falt%3Dmedia%26token%3Da05dca9d-efef-40c9-b23c-15c25e4a7188&width=768&dpr=3&quality=100&sign=1bb65cb8&sv=2) Tugmani bosganingizdan qadoqlash jarayoni boshlanadi va rasmda ko'rsatilgandek, qadoqlash **"... completed successfully"** xabari bilan muvaffaqiyatli tamomlansa, manba fayllari saqlangan joyda **dist** nomli papka yaratilganini ko'rasiz. Uning ichida Flappy Bird o'yini bitta bajariladigan **flappy\_bird.exe** fayliga qadoqlanganini ko'rasiz. ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FKqwRsORV2QD18aEocqSK%252FScreenshot%25202024-07-08%2520at%252011.44.23.png%3Falt%3Dmedia%26token%3D91e64bec-2707-43de-bd6d-82b381cf3f5c&width=768&dpr=3&quality=100&sign=5b6ef9b5&sv=2) ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252F4dZkxpR0DocOIOGVtSkW%252Fimage.png%3Falt%3Dmedia%26token%3D76e447a9-33cf-47dd-982e-65637b0d6682&width=768&dpr=3&quality=100&sign=f79dc611&sv=2) [PreviousIlovachevron-left](https://roboticsware.gitbook.io/pygame_zero-entry_basic/ilova) [NextMu editorining tezkor tugmalarichevron-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/ilova/mu_tezkor_tugmalar) Last updated 7 days ago sun-brightdesktopmoon sun-brightdesktopmoon --- # 4.3 Hodisaga asoslangan (Event-Driven) | Entry-Python Keling, **hodisaga asoslangan**(Event-Based) **yoki hodisaga yo‘naltirilgan dasturlash paradigma**si haqida gaplashamiz. Ushbu paradigma keng qo‘llanila boshlagan davr operatsion tizimlar(OS: Operating System) interfeyslari **konsol**(Console) matnli buyruqlari orqali ishlashdan **grafik foydalanuvchi interfeysi**(GUI: Graphic User Interface)ga o‘tish davriga to‘g‘ri keladi. Boshqacha aytganda, GUI muhitiga mos dasturlar kerak bo‘ldi, va dastur ishlab chiqish usullari ham shu ehtiyojlarga mos ravishda rivojlandi. **GUI muhiti** deganda grafik asosida ishlaydigan tizim tushuniladi. Masalan, kompyuter yoki smartfonlarda biz bosish yoki teginish orqali tanlovlar va boshqaruvlar amalga oshiramiz. Bugungi kunda bu kompyuterni boshqarishning keng tarqalgan usuli bo‘lib, ushbu paradigmadan foydalanishni tushunish qiyinchilik tug‘dirmaydi. Shunga qaramay, hodisaga yo‘naltirilgan dasturlash konsepsiyasini quyidagi rasm yordamida yaxshiroq tushunishga harakat qilaylik. ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FPupqDbM3wwMXvapOvknu%252Feventdriven.png%3Falt%3Dmedia%26token%3Dbdfeb404-945d-4986-9756-d733b49ebb35&width=768&dpr=3&quality=100&sign=54f57b44&sv=2) Manba: [Kamang's IT Blogarrow-up-right](https://kamang-it.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EA%B8%B0%EB%B0%98-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8DEvent-based-programming) **Hozir ekranda ko‘rinib turgan dasturimda biror harakatni qo‘zg‘atuvchi(trigger) barcha holatlar hodisa(event) deb ataladi. Masalan, foydalanuvchi ekranda ma'lum bir rasmli tugmani yoki belgini bosgan payt, klaviaturada ma'lum bir tugmacha(harf, maxsus belgi, yo‘nalish tugmalari va boshqalar)ni bosgan payt, sichqonchaning ma'lum bir tugmachasi(chap, o‘rta, o‘ng)ni bosgan payt, belgilangan vaqtga yetgan payt yoki boshqa bir dastur mening dasturimni chaqirgan payt va shunga o‘xshash holatlar.** Ya'ni, dasturchi bunday hodisalar sodir bo‘lishini oldindan taxmin qilib, har bir hodisa sodir bo‘lganda qaysi vazifani bajarish kerakligini ko‘rsatadigan tarzda kod yozishni **hodisaga asoslangan dasturlash paradigam**si deb atash mumkin. Biz allaqachon Entry platformasida shu usulda kod yozish tajribasiga egamiz, shuning uchun ushbu tushunchani anglash yoki amalda qo‘llashda qiyinchilik bo‘lmaydi, deb o‘ylayman. Faqatgina, Entry-Pythonda bu kabi hodisalar uchun qanday funksiyalardan foydalanish kerakligini bilishimiz kifoya. Quyidagi jadvalda Entryda mavjud bo‘lgan hodisalar turlari va ushbu hodislarga mos keladigan, oldindan aniqlangan(kelishilgan) **kolbek(callback) funksiyalar** ([3.1-bo‘limdagi kolbek funksiyalarga qarang](https://roboticsware.gitbook.io/entry-python/boshlash/hello_world#kolbek-callback-funksiyasi-nima) ) ro‘yxatini ko‘rishingiz mumkin. Hodisa turi Blokli kodlashdagi bloklar Matnli kodlash uchun kolbek funksiyasi Ekrandagi boshlash tugmasini bosganda ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FdbNW70eAOD6p4AQaaMQu%252Fbosh.png%3Falt%3Dmedia%26token%3Dec0f2ec6-d9ba-4fd0-acf7-fbc67c2efb30&width=300&dpr=3&quality=100&sign=a5c4d821&sv=2) def when\_start(): Klaviaturadagi tugmacha bosilganda ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FEwjJtEx5TUQgnryWOKlS%252Fklav.png%3Falt%3Dmedia%26token%3Db6c46494-d230-45cb-9715-0990d0ce56c7&width=300&dpr=3&quality=100&sign=5942cfef&sv=2) def when\_press\_key("q"): Sichqoncha bosilganda ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252F9ON4ehWf7A75gQLv23Pv%252Fsich.png%3Falt%3Dmedia%26token%3D83885886-9c34-4884-8f60-87434f42800b&width=300&dpr=3&quality=100&sign=d81ee3c8&sv=2) def when\_click\_mouse\_on(): Sichqonchani bosishni qo‘yib yuborganda ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FOaFSXJYJebhDYH9t6aP4%252Fsichq.png%3Falt%3Dmedia%26token%3De985b0d7-5037-43ce-9c0c-520b5f64c63b&width=300&dpr=3&quality=100&sign=97535482&sv=2) def when\_click\_mouse\_off(): Obyektni bosganda ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FQwmBrwDiMWScxLjEwMey%252Fobb.png%3Falt%3Dmedia%26token%3D192063b8-fad8-4517-b84f-4b3d8b33d3f1&width=300&dpr=3&quality=100&sign=b8dcdaa8&sv=2) def when\_click\_object\_on(): Obyektni bosishni qo‘yib yuborganda ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252Fm3sQLf3PiExeyLvB2abD%252Fobbq.png%3Falt%3Dmedia%26token%3D5dee544e-fb16-4bb5-9824-ed35473cd84b&width=300&dpr=3&quality=100&sign=4b79e6db&sv=2) def when\_click\_object\_off(): Yangi sahna boshlanganda ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FJK5HH0rcY9ktjyMQuAw8%252Fsb.png%3Falt%3Dmedia%26token%3D25637404-ae77-48dd-a988-9ce0e22832d3&width=300&dpr=3&quality=100&sign=540e6691&sv=2) def when\_start\_scene(): [Previous4.2 Protsessual (Procedural)chevron-left](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/procedural) [Next4.4 Obyektga yo‘naltirilgan (Object-Oriented)chevron-right](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/oop) Last updated 10 months ago sun-brightdesktopmoon sun-brightdesktopmoon --- # 3.2 Kiritish/Chiqarish (Input/Output) | Entry-Python Dasturda kiritish/chiqarish nima? Bu foydalanuvchidan kerakli ma'lumotlarni olish yoki aksincha, ko'rsatish orqali foydalanuvchi bilan interaktiv aloqa vositasi. Entry blokli kodlashda biz quyidagi ikkita blok (![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252Fx9MiGP7MnXGNBVfThZdT%252Fentry%2520blocki.png%3Falt%3Dmedia%26token%3Dd8553adc-a2f5-48d0-abfc-b9b60e022474&width=309&dpr=3&quality=100&sign=b2f4e819&sv=2)![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FRre7PI3UGafSQQHZ4RSV%252Fentry%2520blocko.png%3Falt%3Dmedia%26token%3D4be1b9ab-41c4-40ee-8513-23252339da5a&width=198&dpr=3&quality=100&sign=2657a436&sv=2)) yordamida kirish va chiqishni kodlagan edik. Endi buni matnli dasturlash orqali amalga oshiraylik. Kiritish/chiqarish funksiyalarini biz avvalgi bo‘limda o‘rgangan **Entry** kutubxonasidagi ikki turdagi funksiyani (print, input) chaqirish orqali bajarish mumkin. Funksiya nomlari juda intuitiv bo‘lib, ularning vazifasi darhol tushunarli. Mazkur funksiyalar **Entry-Python** dasturida asl Pythondan bir oz farq bilan ishlaydi (_**asl Pythonda bu funksiyalarni kutubxonani chaqirmasdan, to‘g‘ridan-to‘g‘ri ishlatish mumkin; bunday funksiyalar tilning o‘ziga xos bo‘lgan ichki funksiyalari bo‘lib, "ichki funksiyalar" deb ataladi**_). Ammo **Entry**da ular alohida kutubxona tarkibiga kiradi. Bu funksiyalarni qanday chaqirishni avvalgi bo‘limlarda ko‘rib chiqqanmiz: **KutubxonaNomi.FunksiyaNomi** ko‘rinishidagi sintaksis yordamida chaqiriladi. Shunday ekan, **Entry.print()** va **Entry.input()** funksiyalarini chaqirish mumkin. Biroq, funksiyaning to‘g‘ri ishlashi uchun chaqiruvchi tomonidan uzatilishi lozim bo‘lgan majburiy qiymatlar (parametrlar) qanday ekanini aniq bilish kerak. Aslida, buni intuitiv tarzda taxmin qilish mumkin: **print** (chiqarish) funksiyasida foydalanuvchiga ko‘rsatmoqchi bo‘lgan xabarni uzatish kerak, **input** (kiritish) funksiyasida esa foydalanuvchidan olishni xohlagan ma’lumotni tushuntiruvchi xabarni uzatish kerak. Ushbu xabarlar odatda istalgan matn bo‘lib, kodlash dunyosida bu ma’lumot turi **string** (satrli qiymatlar) deb ataladi. Shu sababli, xabarni ifodalash uchun matnni _**" "(qo‘shtirnoqlar)**_ orasiga yozish kifoya. (Bittalik qo'shtirnoqdan(' ') foydalanish ham mumkin, lekin **Entry-Python** avtomatik ravishda uni ikkitalik qo'shtirnoqqa o‘zgartiradi.) Bundan tashqari, chiqarilmoqchi bo‘lgan xabarni bir nechta qismga ajratib, ularni birlashtirib chiqarish ham qiziqarli usuldir. Bir nechta matn qismlarini birlashtirish uchun foydalaniladigan operator **+** bo‘lib, u "matnlarni birlashtirish" degan mantiqiy ma’noni beradi. Keling, hozirgacha nazariy jihatdan o'rgangan barcha narsalarni birlashtiramiz va foydalanuvchining yoshini kiritish va uni chiqaradigan matnli dasturlash yordamida juda oddiy dasturni kodlaymiz. Ijro natijasi Blokli kodlash Entry-Python ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252Fev3hbwNK5A0kmhVprdkJ%252F2we22%2520copy.png%3Falt%3Dmedia%26token%3D7004f238-1973-4bb6-820d-7a0f75351fff&width=768&dpr=3&quality=100&sign=bebdf023&sv=2) ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FOIDlbJvUWYEMB3fypNRK%252Finout.png%3Falt%3Dmedia%26token%3D3c15df2d-0053-433b-9c0e-af8ca67595db&width=768&dpr=3&quality=100&sign=f17ddd6e&sv=2) Kodlarni tushunish qiyin emasmi? Biroz notanish bo‘lgan joy **Entry.answer()** deb yozilgan qismidir. Bu funksiya nima uchun kerak? _Aslida, bu funksiya faqat_ _**Entry-Python**_ _uchun zarur (haqiqiy Pythonda foydalanuvchi kiritgan qiymatni dasturchi o‘zi aniqlagan o‘zgaruvchiga saqlab ishlatadi, shuning uchun bunday maqsadga mo‘ljallangan funksiya kerak emas). Ushbu funksiyaning vazifasi foydalanuvchi tomonidan kiritilgan qiymatni bilib olishdir. Bu yerda_ _**Entry.print**_ _funksiyasi ichida chiqarish xabarini tuzishda, foydalanuvchi kiritgan qiymatni olib uni natija sifatida ko‘rsatishda foydalanilgan._ Ichki ishlash jarayonini biroz batafsilroq tushuntirsak, foydalanuvchi qandaydir qiymat kiritganida, bu qiymatini kodning boshqa qismida qayta ishlatish uchun uni qandaydir joyga vaqtinchalik saqlash kerak bo‘ladi (odatda bunday saqlash joyi **o‘zgaruvchi** deb ataladi). Keyin shu o‘zgaruvchi orqali kiritilgan qiymati kodning boshqa qismlarida ishlatiladi. Ammo bizning kodimizda o‘zimiz yaratgan birorta o‘zgaruvchi bo‘lmasada, kerakli natijani amalga oshirdi. Bu qanday sodir bo‘ldi? Haqiqatda, **Entry** ichki tizimida foydalanuvchi kiritgan qiymati vaqtinchalik yashirin o‘zgaruvchida saqlanadi. Bizga esa faqat ushbu qiymatini o‘qib olish uchun **answer()** funksiyasi taqdim etiladi. Yuqorida aytib o‘tilganidek, haqiqiy Python dasturlashida bunday usul ishlatilmaydi. Ammo **Entry** blokli kodlashda foydalanuvchilar uchun maksimal qulaylikni ta'minlash maqsadida bu zarurat tug‘ilgan. **Entry-Python** ham blokli kodlashni to‘liq davom ettiruvchi va foydalanuvchilarni matnli dasturlashga o‘tishga o‘rgatuvchi oraliq ko‘prik sifatida xizmat qiladi. Shuning uchun ham, **Entry-Python** Pythonni mukammal o‘rganish vositasi emas, balki blokli kodlashdan matnli dasturlashga o‘tishda yordam beruvchi vosita ekanligini ushbu misoldan ham bilib olishimiz mumkin. [Previous3.1 "Hello World" namuna kodini tushunishchevron-left](https://roboticsware.gitbook.io/entry-python/boshlash/hello_world) [Next3.3 O‘zgaruvchi (Variable)chevron-right](https://roboticsware.gitbook.io/entry-python/boshlash/uzgaruvchi) Last updated 10 months ago sun-brightdesktopmoon Copy # (1)Entrybot's Python code import Entry def when_start(): Entry.input("Iltimos, yoshingizni kiriting.") Entry.print("Siz " + Entry.answer() + " yoshdasiz.") sun-brightdesktopmoon --- # 5.1.2 Kuchuk va mushuk Salom aytadi2 (Ketma-ketlik) | Pygame Zero boshlang'ich Oxirgi bo'limgacha biz o'yin sahnasini (orqa fon) tayyorlashni yakunladik. Endi biz sahnada aktyor sifatida ishlaydigan ikkita obyektni, kuchuk va mushukni yaratishdan boshlashimiz kerak. Entryda biz obyektlarni o'zimiz yaratishimiz shart emas edi, chunki Entry ularni biz bilmasdan biz uchun yaratdi. Bunday aktyor obyektlarini yaratish uchun Pygame Zero Actor nomli **klass(class)** tayyorlagan. Klass atamasi birinchi marta paydo bo'ldi, lekin sodda qilib aytganda, keling, uni obyektlarni e'lon qilish uchun ishlatiladigan grammatika deb hisoblaylik. Bu biz funtsiyalarni e'lon qilish uchun ishlatgan [def grammatikasiarrow-up-right](https://roboticsware.gitbook.io/entry-python/boshlash/hello_world#funksiyani-qanday-yaratish-elon-qilish) ga o'xshaydi. **Funksiyani yaratish va undan foydalanish turli tushunchalar** ekanligini allaqachon tushunib yetdik. Funksiyani e'lon qilish, ya'ni funksiya yaratish degani, boshqacha qilib aytganda, funksiya chaqirilganda va foydalanilganda nima qilishini bildiruvchi ish tavsifi bilan funksiya yaratishni anglatadi. Shundan so'ng, ushbu e'lon qilingan (yaratilgan) funksiyadan foydalanish uchun funksiya o'zining nomi bilan (va ba'zan funksiya talab qiladigan argumentlar bilan) chaqiriladi va funtsiya chaqirilgan paytda u kompyuterning xotirasiga yuklanadi va funksiyada ko'rsatilgan ishni haqiqatda bajaradigan kichik, mujassamlangan dastur sifatida ishlaydi. ### [hashtag](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/kuchuk-mushuk_2#klass-va-obyekt-orasidagi-farq) Klass va obyekt orasidagi farq Klass va obyekt o‘rtasidagi munosabat bir xil. **Obyektni e'lon qilganda foydalaniladigan narsa — bu klass bo‘lib, haqiqiy foydalanish maqsadida chaqirilgan va xotirada yaratilgan holati(bu holatga “Instansiya” (Instance) deb nom beriladi) esa obyekt deb ataladi.** Ya’ni, klass nomi orqali chaqirib (xuddi funksiya nomi bilan funksiyani chaqirgandek) obyekt yaratish mumkin. Endi esa haqiqiy kodga qarab, buni batafsil tushunib olaylik. Copy from pgzhelper import * TITLE = 'Kuchuk va Mushuk salom aytadi' WIDTH = 480 HEIGHT = 270 dog = Actor('dog', (100, 150)) def draw(): screen.fill('white') Yangi qo‘shilgan kod quyidagicha. U kutubxonada oldindan belgilangan Actor class (o‘yin sahnasida faol bo‘lgan aktyor degani uchun shunday nomlangan)ni chaqirish orqali obyektni kompyuter xotirasida shakillantiradi va o’sha obyektni **dog** deb nomlangan o‘zgaruvchida saqlash orqali boshqaradi. Copy dog = Actor('dog', (100, 150)) **Agar siz bu yerda Actorga diqqat bilan qarasangiz, bu funksiya chaqiruvi emas, balki klass chaqiruvi ekanligini darhol ko'rishingiz mumkin.** Buni darhol payqashingiz sababi shundaki, **biz Python grammatikasidagi (nafaqat Python, balki boshqa dasturlash tillari) funksiya nomlari kichik harf bilan va klass nomlari katta harf bilan boshlanishi qoidasiga amal qilganmiz.** _Xuddi funksiya chaqiruvi kabi, klass chaqiruvida unga uzatilishi kerak bo'lgan argumentlar bo'lishi yoki bo'lmasligi mumkin_. Biroq, Actor ikkita argument talab qiladi. Birinchi qiymat ('dog') Actor obyekti tashqi ko‘rinishi uchun foydalanadigan rasm fayli nomi (dog.png), ikkinchi qiymat (100, 150) esa rasmning qayerda chizilishi haqidagi ma’lumotdir (aniqrog'i, ekrandagi tasvir markazining joylashuvi haqidagi ma'lumot). Agar siz Actor klassi haqida ko'proq bilmoqchi bo'lsangiz, [PygameZero kutubxonasi qo'llanmasiga (dokumentatsiyaga) arrow-up-right](https://pygame-zero.readthedocs.io/en/latest/builtins.html#actors) murojaat qilishingiz mumkin. Kutubxona muallifining o'zi har bir klassning maqsadi va ishlatilishini batafsil tushuntiradi. Bu yerga qadar obyekt muvaffaqiyatli yaratilgan bo‘lsa, endi ushbu obyektni ekranda aks ettirish (chizish) kerak. O‘tgan darsda ekranni butunlay oq rang bilan to‘ldirgan edik, endi shu fon ustiga obyektni chizamiz (12-qator). Shu sababli, _7-qatorida yaratilgan "kuchuk" obyektini ifodalovchi (uni ko‘rsatib turgan)_ _**dog**_ _o‘zgaruvchisi_ orqali obyekt ichidagi **draw** funksiyasini chaqirish kifoya. Kod shaklida bu quyidagicha yoziladi: **dog.draw()**. Bu yerda biz avvaldan kutubxona ichidagi funksiyalar yoki o‘zgaruvchilarni chaqirish uchun tez-tez ishlatgan **" . " (nuqta operatori)** yordamida, "kuchuk" obyekti ichidagi **draw** funksiyasini chaqirayapmiz. Endi savol tug‘iladi, 8-qatoridagi kod nima uchun kerak? **dog.scale = 0.5** degan kodning ma'nosi shuki, bu orqali "kuchuk" obyekti ichidagi **scale** o‘zgaruvchisiga 0.5 qiymati tayinlanmoqda. Agar bu kodni qo‘shmasdan, hozirgi kodni ishga tushirsangiz, "kuchuk" obyektining tasviri ekranda yaxshi chizilishini ko‘rasiz. Ammo bir muammo mavjud: "kuchuk" obyektining tasviri juda katta bo‘ladi. Shuning uchun, bu muammoni hal qilish, ya’ni tasvir hajmini yarmiga qisqartirish uchun ushbu kod kerak edi. Ushbu kodni qo‘shib, dasturni qaytadan ishga tushirsangiz, obyekt tasviri mos hajmda ko‘rinadi. ### [hashtag](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/kuchuk-mushuk_2#obyekt-nima) **Obyekt nima?** Dastlab obyektni yaratib va foydalanib ko‘rganingizda, yangi paydo bo‘lgan ushbu obyekt tushunchasi aslida nima ekanligi haqida qanday fikrga keldingiz? _Obyekt ichida funksiyalar va o‘zgaruvchilar mavjud bo‘lib, ulardan foydalanish uchun_ `_**"."**_` _(nuqta operatori) ishlatiladi, degan fikrga ko‘ra, ehtimol siz obyektni kutubxonaga juda o‘xshash va balki kichraytirilgan kutubxona,_ deb o‘ylashingiz mumkin. **Foydalanish jihatidan kutubxonaga juda o‘xshash bo‘lsada, yaratilish maqsadi va obyektni bevosita loyihalash hamda yaratish jarayoni o‘rtasida katta farq bor.** Tez-tez takrorlanadigan funksiyalarni biror joyga (kutubxonaga) to‘plab, undan foydalanish kodning qayta ishlatilishi jihatidan qulay bo‘lishi uchun yaratilgani kutubxona deb hisoblanadi. Obyekt ham oxir-oqibatda kodning qayta ishlatilishini oshirish maqsadini ko‘zlaydi, ammo shunga qo‘shimcha ravishda, dasturiy ta’minot ishlab chiqishning murakkabligini kamaytirish maqsadidan kelib chiqadi, deyish mumkin. Agar bu mavzuni batafsilroq bilishni istasangiz, avvalgi kitobda keltirilgan [obyektga yo‘naltirilgan dasturlash (OOP: Object-Oriented Programming) paradigmasiarrow-up-right](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/oop) haqida yana bir bor o‘qib chiqishingiz foydali bo‘ladi. Endi esa dasturlashda obyekt deganda nimani anglatishi haqida tushuntirish kerak. **Obyekt — bu uning nomidan ham tushunish mumkin bo‘lganidek, haqiqiy dunyoda (real world) mavjud bo‘lgan obyektlar(masalan, chashka, stol, stul, gulvazo, televizor, avtomobil va hokazo)ni dasturlash olami (programming world)ga olib kirish uchun ularning xususiyatlari(attribute) va harakatlari(behavior)ni modellashtirish orqali yaratilgan kod tuzilmasidir.** _Shuni yodda tutingki, obyektning xususiyatlari va harakatlarini kod orqali ifodalashda_ _**xususiyatlar o‘zgaruvchilar yordamida, harakatlar esa funksiyalar orqali (ularni metodr(method)lar deb ham atashadi) ifodalanadi.**_ Bizning birinchi obyektimiz sifatida foydalanilgan Actor(Aktyor) obyekti aslida nimani modellashtiradi? Aslida, ushbu obyekt haqiqiy dunyoda mavjud emas, balki dasturlash olamidagi o‘yin sahnasida aktyor sifatida bir rolni bajarish uchun yaratilgan. Agar siz ushbu obyektni ilk bor dizayn qilayotgan bo‘lsangiz, uni qanday loyihalashtirgan bo‘lar edingiz? **Ushbu obyektning o‘yin sahnasi ichida bajarishi kerak bo‘lgan rollari va mas'uliyatlari nima? U qanday xususiyatlar(o‘zgaruvchilar)ga ega bo‘lishi va qanday harakatlar(funksiyalar)ni bajarishi kerakligini o‘ylab ko‘rish kerak.** Birinchi navbatda kerakli xususiyatlarni ko‘rib chiqaylik: aktyor obyektining tashqi ko‘rinishi tasvir(rasm) orqali bo‘lgani sababli, tashqi ko‘rinishni qanday tasvir faylidan yaratishni belgilash uchun **rasm nomi (image name) xususiyati** kerak bo‘lishi mumkin. Ba'zan ushbu tasvirning o‘lchami o‘yin sahnasiga mos kelishi uchun uni belgilash imkonini beruvchi **o‘lcham(scale)** **xususiyati** foydali bo‘lishi mumkin. Bundan tashqari, tasvirni qaysi joyga joylashtirishni belgilash uchun **joylashuv(position)** **xususiyati** kerak bo‘ladi. Agar ushbu tasvirni aylantirib ko‘rsatishni xohlasak, burchakni belgilash uchun **burchak(angle) xususiyati** ham bo‘lishi mumkin. Endi esa Actor obyektining bajarishi kerak bo‘lgan harakatlar haqida o‘ylab ko‘raylik. Aktyor asosiy harakat sifatida ekranda **ko‘rinishi(chizilishi) kerak**. U **harakatlanishi lozim** va o‘yin sahnasi xususiyatlari sababli **boshqa obyektlar bilan to‘qnashuv** **yoki ularga tegishni aniqlaydigan vazifalarni bajarishi kerak** bo‘ladi. Actor obyekti biz yuqorida taxmin qilgan darajadagi xususiyatlar va harakatlarni o‘z ichiga olish bilan birga, aslida undan ham ko‘p xususiyatlar va harakatlarga ega. Agar hozirning o‘zida Actor obyektining qanday xususiyatlarga ega ekanligi va nimalarni qila olishini bilmoqchi bo‘lsangiz, bu obyektning yaratuvchisi tomonidan yozilgan [qo‘llanmaarrow-up-right](https://pygame-zero.readthedocs.io/en/stable/builtins.html#actors) ni ko‘rib chiqishingiz mumkin. Ammo, bu kitobning misollarini bosqichma-bosqich o‘rganib borar ekansiz, tabiiy ravishda bularni tushunib olasiz, shuning uchun shoshilishga hojat yo‘q. Ushbu bo‘limda siz zamonaviy dasturlash tushunchalari ichida eng muhim bo‘lgan obyekt tushunchasini o‘rgandingiz. Bu yutuq bilan sizni tabriklaymiz! Obyekt haqida hozircha shu darajadagi tushuncha yetarli, va yanada chuqurroq mavzularni keyinchalik ko‘rib chiqamiz. Endi esa qolgan kodlarni davom ettiraylik! [Previous5.1.1 Kuchuk va mushuk Salom aytadi1 (Ketma-ketlik)chevron-left](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/kuchuk-mushuk_1) [Next5.1.3 Kuchuk va mushuk Salom aytadi3 (Ketma-ketlik)chevron-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/kuchuk-mushuk_3) Last updated 7 days ago * [Klass va obyekt orasidagi farq](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/kuchuk-mushuk_2#klass-va-obyekt-orasidagi-farq) * [Obyekt nima?](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/kuchuk-mushuk_2#obyekt-nima) sun-brightdesktopmoon Copy from pgzhelper import * TITLE = 'Kuchuk va Mushuk salom aytadi' WIDTH = 480 HEIGHT = 270 dog = Actor('dog', (100, 150)) dog.scale = 0.5 def draw(): screen.fill('white') dog.draw() sun-brightdesktopmoon --- # 2. Entry-Python bilan ishlashni boshlash | Entry-Python [hashtag](https://roboticsware.gitbook.io/entry-python/mantli_dasturlash_qiyinchlik#entry-blokli-kodlash-less-than-greater-than-pyhton-matnli-kodlash-ga-aylantirish) Entry (blokli kodlash) <--> Pyhton(matnli kodlash)ga aylantirish ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Agar siz allaqachon Entry foydalanuvchisi bo'lsangiz, Entry haqida oldindan ma'lumotga ega bo'lganingiz yoki Entry qanday ishlashini o'rganayotganda tasodifan bu menyuga duch kelgan bo'lishingiz mumkin. Ikki xil kod o'rtasida almashish uchun Entryning yuqori menyu satridagi kodni o'zgartirish belgisini bosish kifoya. ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FUu1pPzpJ3hHORWgwlRP6%252Fimage%2520%283%29%2520copy.png%3Falt%3Dmedia%26token%3Db9fbf5d8-2c12-4cad-9df6-a2060a063ad4&width=768&dpr=3&quality=100&sign=d335950c&sv=2) Shu tarzda Entry nafaqat blokli kodlashni matnli kodlash tili (Python) sifatida qanday o‘zgarishini kod konvertatsiyasi orqali ko‘rish imkonini beradi, balki Entry-Python kodlash muharriri oynasi orqali to‘g‘ridan-to‘g‘ri matnli kod yozish va uni ishga tushirish funksiyasini ham taqdim etadi. Bunday Entry-Python o‘quvchilar yoki o‘qituvchilar uchun Entryda "blokli kodlashdan boshlab, matnli kodlashni o‘zlashtirish" maqsadiga erishishda o‘rtada bog‘lovchi ko‘prik vazifasini bajaradi, deb aytish mumkin. [hashtag](https://roboticsware.gitbook.io/entry-python/mantli_dasturlash_qiyinchlik#blokli-kodlashdan-matnli-kodlashga-otish-tajribasi) Blokli kodlashdan matnli kodlashga o'tish tajribasi ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Odatda, blok dasturlash dunyosidan matnli dasturlash dunyosiga o'tishda qiynaladigan sababi oldindek bloklarni endi bloklarning bo'limidan muharrir(kodni yig'ish) maydoniga sudrab olib tashlashning intuitiv va qulay usulidan foydalanib dasturlash imkoniyat yo'q bo'lib qoladi. O'riniga endi siz matnning har bir belgisini qo'lda kiritib, so'zma-so'z "uzun insho yozishingiz" kerak. Ushbu jarayonda biz blokli dasturlashga xos bo'lmagan xatolarga duch kelamiz va ba'zida bu kichik ko'rinadigan xatolar (yoki errorlar) dasturning umuman ishga tushmasligiga olib keladi, bu esa biroz chalkashliklarni keltirib chiqaradi. Blokli dasturlashda, agar kod noto'g'ri yozilgan bo'lsa ham, dastur shunchaki noto'g'ri ishlaydi, lekin to'liq ishlashni to'xtatmaydi. Matnli dasturlashdagi xatolar matn terish xatolaridan kelib chiqishi mumkin, bu juda tushunarli, lekin ba'zida muammo faqat katta va kichik harflar orasidagi farq yoki nuqta mavjudligi/yo'qligi bilan bog'liq. Dasturni ishga tushirishga urinayotganda, hatto bunday mayda narsa ham xato deb hisoblanishi mumkin va dastur ishga tushirishni rad etadi. Matnli dasturlash kodni juda ehtiyotkorlik bilan va aniq yozishni, shuningdek tanlangan dasturlash tili uchun belgilangan sintaktik qoidalarga rioya qilishni talab qiladi. Shu sababli, matnli dasturlashdagi birinchi qiyinchiliklar har bir kishi uchun tabiiydir va, albatta, ushbu dasturlash uslubiga ko'nikish uchun vaqt kerak bo'ladi. [hashtag](https://roboticsware.gitbook.io/entry-python/mantli_dasturlash_qiyinchlik#entry-python-da-olib-tashlash-usuli-drag-and-drop-yordamida-dasturlash) Entry-Python da olib tashlash usuli (Drag&Drop) yordamida dasturlash ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Entry-Pythonda matnli dasturlashda matn terish xatolaridan kelib chiqadigan xatolarni oldini olish uchun blokli kodlashdan olingan fikrdan foydalanish mumkin. Rasmda ko'rsatilgandek, blokli kodlashda bo'lgani kabi, sudrab olib tashlash (Drag&Drop) orqali dasturlashga urinib ko'rishingiz mumkin. ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252F8M9Zs9sMejhCNf9jxwFv%252FScreenshot%25202024-08-14%2520at%252018.39.09%2520copy.png%3Falt%3Dmedia%26token%3D82b9afb7-4684-40b7-a5a3-91aa259f8efd&width=768&dpr=3&quality=100&sign=d9b00375&sv=2) Bu usul qulay, chunki u oddiy matn terish xatolaridan kelib chiqadigan xatolarni kamaytiradi, shuningdek, klaviatura terish vaqtini qisqartiradi. Biroq, yuqorida aytib o'tilganidek, uni ishlatish uchun siz tanlangan dasturlash tilining sintaktik qoidalarini oldindan yaxshi bilishingiz kerak. Bu shuni anglatadiki, ushbu yondashuv faqat dasturlash tili sintaksisining asoslari bilan tanish bo'lgan taqdirdagina qo'llanilishi mumkin. Shuning uchun bizning asosiy vazifamiz Python sintaksisining asosiy qoidalarini o'rganishdan boshlashdir. Keyingi bo'limlarda biz ularni bosqichma-bosqich o'rganamiz. [Previous1\. Entry vs Entry-Pythonchevron-left](https://roboticsware.gitbook.io/entry-python/entry-python_ozi_nima) [Next3\. Entry-Python yordamida Python sintaksisining asoslarini o‘rganamizchevron-right](https://roboticsware.gitbook.io/entry-python/boshlash) Last updated 9 months ago --- # 1. Entry vs Entry-Python | Entry-Python [Entryarrow-up-right](https://playentry.org/) - Naver bilan bog'langan [Connect Foundationarrow-up-right](https://connect.or.kr/) nodavlat notijorat tashkiloti tomonidan ishlab chiqilgan va homiylik qilingan ochiq manbali ta'lim kodlash tilidir ([EPL: Educational Programming Languagearrow-up-right](https://en.wikipedia.org/wiki/List_of_educational_programming_languages) ). Xususan, Koreyada bu yuqori darajali blokli kodlash tili (_a high-level block-based visual programming language,_ yuqori darajadagi bloklarga asoslangan vizual dasturlash tili) dasturlashni o'rgatishda eng keng qo'llaniladi. Dunyoda allaqachon eng mashhur bo'lgan [MIT Scratcharrow-up-right](https://scratch.mit.edu/) bilan solishtirganda, shu bilan eng katta ustunligi u bolalarni blokli kodlash orqali dasturlash dunyosiga kiritib natijada ularni matnli dasturlash(text-based programming)gacha kiritishni oldin mo'ljallangandir. Entry matnli dasturlash uchun Python tilini tanlagan. Python tili matnli dasturlash tillari orasida o'rganish eng oson til bo'lib, ayniqsa, yaqinda e'tibor markazida bo'lgan ma'lumotlarni tahlil qilish va sunʼiy intellekt sohalarida foydalanishga qulay tildir, shuning uchun u umumiy tarzda birinchi matnli dasturlash tilini o'rganishda eng ko'p tavsiya qilinadigan tildir. circle-info **Piton(Python)**: Python 1991-yilda gollandiyalik dasturlash muhandisi Guido van Rossum tomonidan chiqarilgan yuqori darajadagi dasturlash tili. Bu , [interpretatorarrow-up-right](https://en.wikipedia.org/wiki/Interpreter_(computing)) dan ishlatadigan [obyektga yo'naltirilganarrow-up-right](https://en.wikipedia.org/wiki/Object-oriented_programming) til va platformadan mustaqil, [dinamik tiparrow-up-right](https://en.wikipedia.org/wiki/Type_system) li interaktiv til. Pythonning kuchli kutubxonalari va boy ekotizimlari yordamida siz ma'lumotlarni to'plashingiz, tahlil qilishingiz va vizualizatsiya qilishingiz mumkin. Pythonning ma'lumotlarni tahlil qilish sohasida keng qo'llanilishining sabablaridan biri uning boshqa dasturlash tillariga nisbatan oson va soddaligidir. Manba: Wikipedia Biroq, Entryda o'rnatilgan **"Entry-Python"** faqat Entry uchun mo'ljallangan Python tili deb aytish mumkin. Bu asl Python tilining asosiy grammatikasini o'rganish uchun o'quv maqsadlarida asl Pythonning kichik versiyasi sifatida ko'rib chiqilishi mumkin va shuning uchun u to'liq Pythonning o'zi emasligi sababli, kodlashda qo'llab-quvvatlanmaydigan asl Python sintaksisi mavjudligini doimo esda tuting. ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FZLLdeu6xxawSmAyLFL1P%252Fimage%2520%282%29.png%3Falt%3Dmedia%26token%3D9d4315cf-ff86-45d7-a109-adeee7eed361&width=768&dpr=3&quality=100&sign=d1317538&sv=2) Bizning maqsadimiz "Entry-Python" orqali iloji boricha tezroq Pythonning asosiy sintaksisini o‘zlashtirib, imkon qadar tezroq [asl Pythonarrow-up-right](https://www.python.org/) ga o‘tish va blokli kodlashni butunlay tark etib, endilikda faqatgina matnli kodlash (dasturlash) bilan shug‘ullanishdir. Shu sababli, Entry-Python ichida juda katta umid va maqsaddan oshib ketadigan darajada foydalanish ruhiy salomatlik uchun yaxshi bo‘lmasligi mumkin. Buning sababi shundaki, afsuski, Entry-Python o‘zi kutilganidan ko‘ra mukammal emas (masalan, kodda sintaksis xatolari bo‘lmasa ham, xatolik borligini ko‘rsatib, dastur ishlamay qolishi kabi holatlar; buni mashq bajarib ko'rsangiz, tushunasiz). Shuning uchun biroz murakkab kodlashni boshlaganingizda bunday muammolarga duch kelish ehtimoli oshadi. Xulosa qilib aytganda, Entry-Python blokli kodlashdan matnli kodlashga o‘tishni endigina boshlaganlar uchun mo‘ljallangan bo‘lib, matnli kodlash dunyosiga kirib, dastlabki qiyinchiliklarni yengillashtirish uchun yaratilgan. O‘zimizga tanish bo‘lgan blokli kodlash muhiti ichida klaviatura orqali matnli kodlashni sinab ko‘rib, u blokli kodlashdan uncha farq qilmasligini tushunish va shuning evaziga matnli kodlash unchalik murakkab emas degan noto‘g‘ri tasavvurni yo‘qotish Entry-Pythonning asosiy maqsadiga erishish bo‘ladi. [PreviousEntry-Python darsturlash asoslarichevron-left](https://roboticsware.gitbook.io/entry-python) [Next2\. Entry-Python bilan ishlashni boshlashchevron-right](https://roboticsware.gitbook.io/entry-python/mantli_dasturlash_qiyinchlik) Last updated 9 months ago --- # 3. Entry-Python yordamida Python sintaksisining asoslarini o‘rganamiz | Entry-Python Matnli dasturlashning grammatik tizimini o‘rganish chet elliklar bilan muloqot qilish uchun chet tilini o‘rganish jarayoniga o‘xshaydi. Biroq, suhbatdosh chet ellik emas, balki kompyuter. Xuddi chet tilini birinchi marta o‘rganganimizda, biz o‘sha tilni ifodalovchi harflarni bilishdan boshlaymiz (baxtimizga, kompyuterlar bilan suhbatlar faqat ingliz tiliga asoslangan lotin alifbosida yoziladi, buni biz allaqachon bilamiz), va faqatgina harflar bo‘g‘inlarni, bo‘g‘inlar so‘zlarni tashkil etganda, o‘sha so‘zlar gaplar tuzuvchi grammatika tizimiga (masalan, ot-sifat-fel tartibi va boshqalar) muvofiq tartibga solinsagina, biz bir-birimiz bilan suhbatlasha olamiz. Bizda chet tilini o‘rganishda tajriba bor (hech bo'lmaganda ingliz tili va h.k.) va bu biz uchun afzallik bo'lishi mumkin, lekin shu bilan birga, bizda til o‘rganish qiyin degan notog‘ri fikr ham bo‘lishi mumkin. Biroq, kompyuter dasturlash tillari odamlar tomonidan ishlatiladigan tillarning murakkabligiga qaraganda ancha oson va ular orasida Python eng oson kompyuter dasturlash tillaridan biri hisoblanadi. Shuning uchun siz boshidan qiynalmaysiz degan umiddaman. [Previous2\. Entry-Python bilan ishlashni boshlashchevron-left](https://roboticsware.gitbook.io/entry-python/mantli_dasturlash_qiyinchlik) [Next3.1 "Hello World" namuna kodini tushunishchevron-right](https://roboticsware.gitbook.io/entry-python/boshlash/hello_world) Last updated 9 months ago --- # 4. Entry-Python yordamida dasturlashning asosiy tushunchalarini o‘rganamiz | Entry-Python Ushbu bobdan boshlab, tilning o‘ziga xos sintaksisidan tashqari, dasturlash paradigmalari deb ataladigan tushunchalar va ularning ichida asosiy elementlarni Entry-Python yordamida ozgina bo‘lsa ham o‘rganib, Entry-Python bo‘yicha o‘quv jarayonini yakunlashni maqsad qilamiz. **Paradigma umumiy atama bo'lib, lug'at ma'nosida fikrlashni tashkil etuvchi idrok tizimi sifatida ta'riflanishi mumkin. Dasturlash dunyosida bu xuddi shunday ma'noga ega. Dasturlashda siz ma'lum bir yondashuv yoki fikr doirasiga amal qilasiz va shu doirada kod yozasiz.** Ushbu tushunchani to‘liq anglash qiyin bo‘lishi mumkin, shuning uchun uni oldingi boblarda keltirilgan xorijiy tilga o‘xshatib tushuntirishga davom etsak, avval tilning sintaksis qoidalarini o‘rgangan bo‘lsak, endi qanday janr yoki uslubda yozish haqida o‘ylash kerak bo‘ladi. Masalan, yozuvchilikda insho va film/yangi ssenariy yozish janrlari bir-biridan sezilarli darajada farq qiladi. Xuddi shunday, dasturlashda ham oxirgi maqsadga mos keladigan dastur uchun ma’lum bir paradigma tanlanadi va shu forma hamda doira ichida kod yoziladi. Ammo _yozuvchilikda “janrni buzish” yoki bir nechta janrni birlashtirish mumkin bo‘lgani kabi, dasturlashda ham bir nechta paradigmani aralashtirib dasturlash mumkinligini bilish foydali bo‘ladi._ Aslida, bu paradigmalarning tushunchalari Entry blokli kodlash ichida allaqachon mavjud, lekin biz bu vaqtgacha buni anglamasdan kod yozib kelganmiz. Agar siz: “Men faqat blokli kodlash bilan shug‘ullanib, dasturlashni shu yerdan yakunlayman”, deb qaror qilsangiz, bu tushunchalarni bilmasdan ham davom etishingiz mumkin. Bunda ham blokli kodlashdan zavqlanishingizga hech narsa to‘sqinlik qilmaydi. Ammo biz endi blokli kodlash dunyosidan o‘tib, matnli kodlash (text coding) dunyosiga qadam qo‘ymoqdamiz. Ushbu dunyoda kod yozish uchun qo‘shimcha bilimlar talab qilinadi. Ushbu bilimlarni bilgan holda kodlash bilan bilmasdan kodlashning farqi katta bo‘ladi. Matnli dasturlash dunyosida samaraliroq ishlash uchun ushbu bilimlar asos yaratib beradi. Bu dunyoda boshqa hamkasblar bilan hamkorlik qilish odatiy hol bo‘lib, ular bilan muvaffaqiyatli ishlash uchun asosiy bilimlarni o‘rganishni ushbu jarayonning bir qismi sifatida qabul qilish mumkin. [Previous3.8 Funksiya (Function)chevron-left](https://roboticsware.gitbook.io/entry-python/boshlash/funksiya) [Next4.1 Ketma-ket/Parallel ishlov berish (Serial/Parallel)chevron-right](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/ketma_ket-parallel) Last updated 10 months ago --- # Ilova | Entry-Python Kodlashda yordam beruvchi qisqa tugmalar ro‘yxatini taqdim etamiz. Odatda, dasturchilar tezroq ishlash uchun qisqa tugmalarni samarali qo‘llashga o‘rganishgan. Sizga ham qisqa tugmalardan foydalanish odatini shakllantirishni tavsiya qilamiz. [Previous4.4 Obyektga yo‘naltirilgan (Object-Oriented)chevron-left](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/oop) [NextEntry-Pythonning tezkor tugmalarichevron-right](https://roboticsware.gitbook.io/entry-python/ilova/tezkor_tugmalari) Last updated 9 months ago --- # 1. "Pygame Zero" kutubxonasi | Pygame Zero boshlang'ich Ushbu kitobda biz sizni Python matnli dasturlash yordamida foydalanishingiz mumkin bo'lgan o'yinlarni yaratish kutubxonasi bilan tanishtiramiz. Agar siz kutubxona nima ekanligi aniq bilmasangiz, iltimos, avvalgi "[Entry-Pythonarrow-up-right](https://roboticsware.gitbook.io/entry-python) " kitobiga qayting va [tegishli qismarrow-up-right](https://roboticsware.gitbook.io/entry-python/boshlash/hello_world#kutubxona-nima) ni ko'rib chiqing. _**Kutubxonaning maqsadi har doim kerak bo'lgan kodlarni oldindan tayyorlash va har kimga kodlarni tez va samarali kodlash uchun birgalikda ishlatishga imkon berish bo'lgani kabi,**_ shu maqsadda o'yinlarni ishlab chiqishda kutubxonalar mavjud va ular orasida biz "Pygame"ga asoslangan "Pygame Zero"dan foydalanamiz, bu Pythonda o'yin yaratishda eng ko'p ishlatiladigan kutubxonalardan biridir. [hashtag](https://roboticsware.gitbook.io/pygame_zero-entry_basic/pygame-zero_kutubxonasi#pygame-kutubxonasi) Pygame kutubxonasi ------------------------------------------------------------------------------------------------------------------------------------- Bu 2000-yilda birinchi chiqarilganidan beri 20 yildan ortiq vaqt davomida xizmat ko'rsatgan va hali ham takomillashtirilayotgan "ochiq manbali o'yinlarni yaratish kutubxonasi". Aytgancha, **"ochiq manba" so'zi ma'lum shartlarga rioya qilgan holda kodlar hamma uchun bepul ishlatilishini anglatadi.** Ta'limda foydalanish bepul bo'lishi muhim, ya'ni foydalanish uchun har doim to'lashingiz kerak bo'lgan tijorat kutubxonalari ham mavjud. Agar siz batafsilroq va professional ma'lumotlarni bilmoqchi bo'lsangiz, [rasmiy veb-saytarrow-up-right](https://pygame.org/) ni tekshirganingiz ma'qul. Kutubxona logotipi quyidagicha: ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FBtNIAinbHC2VjtJ3880k%252Fimage.png%3Falt%3Dmedia%26token%3Ddc42f729-bea3-4152-8ee8-8acac32b9792&width=768&dpr=3&quality=100&sign=60f61fe5&sv=2) Pygame logotipi [hashtag](https://roboticsware.gitbook.io/pygame_zero-entry_basic/pygame-zero_kutubxonasi#pygame-zero-kutubxonasi) "Pygame Zero" kutubxonasi ------------------------------------------------------------------------------------------------------------------------------------------------- Ammo, afsuski, Pygame kutubxonasidan foydalanish Pythonni endi o'rganayotganlar uchun oson emas. Demak, dasturlashga yangi bo'lganlar ta'lim manfaati uchun to'siqni yanada pasaytirish kerak edi va "Pygame Zero" kutubxonasi shu maqsadda tug'ilgan. Pygame Zero nomidan ko'rinib turibdiki, **minimal kodlash bilan o'yinni yaratishga imkon berish uchun mavjud Pygame kutubxonasi asosida soddalashtirilgan**. _Shuningdek, u ochiq manba sifatida chiqarilgan va_ [_rasmiy veb-sayt_arrow-up-right](https://pygame-zero.readthedocs.io/en/stable/) _da aytilganidek, ushbu kutubxonadan dasturlashni oson va qiziqarli o'rgatish uchun ta'lim maqsadlarida foydalanish kutilmoqda._ ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FpHeHIz9hn4dOqELbukjl%252Fimage.png%3Falt%3Dmedia%26token%3D4efd40b4-097a-43f8-90cd-73c4860b9bbc&width=768&dpr=3&quality=100&sign=3ffe9b37&sv=2) Pygame Zero logotipi _Umid qilamanki, siz ushbu kitob faqat o'yinlar yaratish uchun emas, balki Python tili orqali matnli dasturlashni yaxshiroq o'rganish maqsadida o'yinlar yaratish uchun yozilganligini tushunasiz. Xuddi Entry/Scratch blokli kodlash orqali qiziqarli vaqt o'tkazganimizday. Bizning maqsadimiz Pygame Zero kutubxonasi + Python matnli dasturlash tili kombinatsiyasi orqali o'yin yaratish va blokli kodlashdan tashqari matnli dasturlash dunyosidan zavqlanishdir._ [PreviousKirishchevron-left](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kirish) [Next2\. Dasturlash muhitini tayyorlashchevron-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/dev_muhit) Last updated 10 months ago --- # Dasturlashni o‘rganish uchun bepul kitoblar | Tanishuv kitoblari ![Page cover](https://roboticsware.gitbook.io/tanishuv-kitoblari/~gitbook/image?url=https%3A%2F%2F4110977648-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fh1MP3Z0VzQ1XHSxNuecL%252Fuploads%252F5Sdp9fWKzXhjdMXkbnlG%252Fimage%2520%282%29.avif%3Falt%3Dmedia%26token%3D46117740-1718-4a55-bdb6-4ff19447bdee&width=1248&dpr=3&quality=100&sign=c5f37f09&sv=2) [hashtag](https://roboticsware.gitbook.io/tanishuv-kitoblari#undefined-1) [Python asoslari bilan Entry orqali tanishish (To'liq nashr)arrow-up-right](https://roboticsware.gitbook.io/entry-python) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Ushbu kitob Entry blokli dasturlash orqali kodlash(dasturlash) asoslarini o‘rgangan va endi Python tilidan foydalanib matnli dasturlashga o‘tmoqchi bo‘lganlar uchun oraliq ko‘prik vazifasini bajaradi. "Entry-Python" yondashuvi orqali dasturlash ta’limida **blokli kodlashdan haqiqiy loyihalar uchun matnli dasturlashga o‘tishni maqsad qilgan o‘quvchilar hamda blokli kodlashni o‘rgatgandan so‘ng, o‘quvchilarning matnli dasturlashga silliq o‘tishini ta’minlashni istagan o‘qituvchilar uchun** yozilgan. [hashtag](https://roboticsware.gitbook.io/tanishuv-kitoblari#id-7) [Entry boshlang‘ich kitobi 7-ta misollarini nusxalab dasturlash orqali Pythonni o‘rganish (To‘liq nashr)arrow-up-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Bu kitob, [avvalgi "Entry-Python"arrow-up-right](https://roboticsware.gitbook.io/entry-python) orqali Python dasturlashining asosiy sintaksisini o‘rganib chiqqanlar uchun keyingi bosqich hisoblanadi. [**Naver** tomonidan taqdim etilgan Entry blokli dasturlash asoslari kitobining (asl nomi: Qadamma-qadam o‘zlashtirib, "Entry" dasturlash asoslarini o’rganamiz) 7 ta misoliarrow-up-right](https://ufe.gitbook.io/entry_basic) ni Python dasturlash orqali nusxalab, yanada chuqurroq Python matnli dasturlash va sintaksisini o‘rganishga yordam beradi. Shuningdek, Python dasturlashida o‘yin yaratish uchun ishlatiladigan **PyGame** kutubxonasini soddalashtirilgan versiyasi bo‘lgan **PyGame Zero** dan foydalanish orqali yanada qulay yondashuv taklif etiladi. Bu kitob [keyingi bosqich](https://roboticsware.gitbook.io/tanishuv-kitoblari#id-70) ga tayyorgarlik bo‘lib, haqiqiy Python o‘yinlarini yaratish orqali Python kodlash bo‘yicha mustahkam bilim olishga xizmat qiladi. [hashtag](https://roboticsware.gitbook.io/tanishuv-kitoblari#oyin-yaratish-orqali-loyiha-asosida-python-organish-yumshoq-tam-95-yakunlangan) O‘yin yaratish orqali loyiha asosida Python o‘rganish - _yumshoq ta'm_ (95% yakunlangan) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Bu kitob, avvalgi ikkita kitob ("[Entry-Pythonarrow-up-right](https://roboticsware.gitbook.io/entry-python) " va "[Entry misollari orqali Pythonni o‘rganisharrow-up-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic) ") bilan ishlamagan bo‘lsa ham, Python asosiy sintaksisidan xabardorman deb hisoblaydiganlar uchun keyingi bosqich sifatida yozilgan. An’anaviy til grammatikasi asosidagi kitoblardan farqli ravishda, bu kitob "loyiha asosida o‘rganish" tamoyiliga asoslanadi. Blokli dasturlash davrida biz foydalanib o‘rgangan va rivojlangan yondashuvni to‘g‘ridan-to‘g‘ri qo‘llagan holda, o‘yin yaratish orqali Python dasturlashini o‘rganish metodikasidan foydalaniladi. [Avvalgi kitob](https://roboticsware.gitbook.io/tanishuv-kitoblari#id-7) dagidek, bu kitob ham PyGame kutubxonasining soddalashtirilgan versiyasi bo‘lgan PyGame Zero yordamida qulay yondashuvni taqdim etadi. _Qo‘shimcha eslatma: Agar siz Python asosiy sintaksisidan tashqari, murakkabroq mavzular bo‘yicha ham bilimga egaman deb hisoblasangiz, bu kitobniong yengil versiyasi o‘rniga, bevosita PyGame kutubxonasidan foydalanadigan_ [_o'rtancha versiya_arrow-up-right](https://jjlee.gitbook.io/python-pygame) _kitobini (hali to‘liq nashr qilinmagan) o‘rganishga harakat qilishingiz mumkin. Samarali o‘rganish uchun o‘z darajangizga mos keladigan kitobni tanlashingizni tavsiya qilamiz._ Last updated 10 months ago --- # 4.4 Obyektga yo‘naltirilgan (Object-Oriented) | Entry-Python Nihoyat, **obyektga yo‘naltirilgan(Object-Oriented, OOP)** **dasturlash paradigmasi** haqida gaplashaylik. Ushbu paradigma dasturiy ta'minot ishlab chiqishda eng katta ta'sir ko‘rsatgan innovatsion paradigmalardan biri sifatida qaraladi, ayniqsa dastur hajmi katta yoki ko‘plab dasturchilar bilan hamkorlikda ishlash zarurati bo‘lganda keng qo‘llaniladi. Shuning uchun uni yaxshi tushunish va bilish zarur. Biroq, bu tushunchani to‘g‘ri tushunish va erkin qo‘llash uchun chuqur tushuncha kerak, va agar chuqurroq kirib borsangiz, ba'zi joylarda qiyinchiliklar yuzaga kelishi mumkin. Lekin bunday chuqur tushunchani keyinchalik kerakli paytda o‘rganish mumkin, shuning uchun Entry-Pythonda asosiy va nazariy tushunchalarni tushunish kifoya qiladi. Bu, ayniqsa, matnli dasturlashni boshlashda katta foyda keltirishi mumkin. Avvalgi bo‘limlarda tilga olingan paradigmalarni, ularning nima ekanini bilmasdan, tabiiy ravishda o‘rganganimiz kabi, Entry dasturi dastlab yaratilganidan boshlab, bizni bu paradigmalarni qiyinchiliksiz qabul qilishimiz uchun yaxshi o‘ylangan dizayn mavjud bo‘lgani ko‘rinadi. Avvalo, biz Entryda kod yozishdan oldin, eng avvalo bajarishimiz kerak bo‘lgan ish nima edi, shuni eslab ko‘raylik. Ha, bu ekraniga kamida bitta obyekt qo‘shish edi. Bu yerda **obyekt(Object)** atamasini joriy qilishdan boshlash, aslida, bu tushunchani tushuntirish uchun yaxshi tuzilgan ssenariy bo‘lgani haqida o‘ylayman. Entryda bajarish ekranida ko‘rinadigan barcha narsa obyekt hisoblanadi. _**Faqat rasm yoki obyekt ekanligini aniqlash, aslida, o‘sha elementga mustaqil kodlar qo‘shib, uni boshqarish imkoniyati**__ga bog‘liq._ Biz Entry blokli kodlashni boshlaganimizda, turli xil obyektlar(rasmlar, matnli obyektlar, jumladan fon obyektlari)ni olib, ularni ekraningizda joylashtirishdan boshlagandik. Va, bu joylashtirilgan har bir obyektni jonlashtirish uchun har bir obyektga mos keladigan mustaqil kodlar yoziladi. Ba'zan, obyektlar bir-birlari bilan hamkorlik qilishlari kerak bo‘lsa, obyektlar orasida bir-biriga so‘rov yuboruvchi xabarlar almashish orqali o‘zaro hamkorlikni yaratib, butun dasturni ishlab chiqish tarzida kod yozilgan. Hozirgacha tilga olingan barcha jarayonlar aslida obyektga yo‘naltirilgan dasturlash paradigmidan foydalanish jarayoni edi va bu dasturlash tili dunyosida **obyektga yo‘naltirilgan dasturlash (OOP: Object Oriented Programming)** deb ataladi va ko‘pincha o‘ziga xos nom kabi tilga olinadi. Endi, misol yordamida obyektlarning o‘zaro hamkorlik qilish uchun xabar almashadigan kodni ko‘rib chiqaylik. Ijro natijasi Blokli kodlash Entry-Python ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252F7UNzAOEJoHcPo97WYWxx%252Fimage.png%3Falt%3Dmedia%26token%3D3d5cf1a7-9ddb-4e87-81f0-929a71083a0e&width=768&dpr=3&quality=100&sign=4218dd37&sv=2) ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252F3KSthmg5rnWoAhNGlfGR%252F%25D1%2589%25D1%2582%25D1%2589%25D0%25B0%25D0%25B0.png%3Falt%3Dmedia%26token%3D7b6a7b10-8c90-49aa-b398-a044247e1668&width=768&dpr=3&quality=100&sign=722a6496&sv=2) ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FCzLABZYMoDrEA4rqVNgy%252FDrasts1%2520copy.png%3Falt%3Dmedia%26token%3Dcd8ad14d-e3a8-46df-90b3-3c282080d891&width=768&dpr=3&quality=100&sign=49f91165&sv=2) Aslida, haqiqiy matnli dasturlash asosida obyektga yo‘naltirilgan dasturlashda hamkorlik jarayoni yuqorida ko‘rsatilgan xabar almashish usuli o‘rniga, har bir obyekt ichida mavjud bo‘lgan tashqi interfeys funktsiyalarini tashqi obyektlar tomonidan to‘g‘ridan-to‘g‘ri chaqirilishi orqali amalga oshiriladi. Hozirgi tushuntirish obyektga yo‘naltirilgan dasturlash paradigmasining chuqur tushunilishini talab qiladigan mavzu bo‘lgani uchun, bu mavzuni bu yerda batafsil tushuntirish kitobning doirasiga kiravermaydi. Agar bu mavzu qiziqarli bo‘lsa, obyektga yo‘naltirilgan dasturlash paradigmalariga bag‘ishlangan maxsus kitoblarni o‘qish va Python tilida obyektga yo‘naltirilgan dasturlashni qanday amalga oshirishni o‘rganishni tavsiya qilaman. [hashtag](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/oop#epilog) Epilog --------------------------------------------------------------------------------------------------- Shunday qilib, ushbu kitobning oxirigacha yetib kelganingiz uchun sizlarga samimiy tabriklayman va mehnatingizga e'tibor qaratishingizni istardim. Endi sizlar matnli dasturlash dunyosiga kirib keldingiz, yana bir bor tabriklayman. Muallif sizlarning matnli dasturlash olamidagi qiziqarli sayohatingizni qo‘llab-quvvatlash uchun [keyingi darajadagi kitobarrow-up-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic) ni yozishda davom etmoqda. Ushbu kitob ham dunyodagi ko‘plab insonlarning fikrlash va tafakkur ufqlarini kengaytirishda, erkin bo‘lishda yordam berib, ularga foyda keltirishini tilayman. 2023 yil kuzining so‘nggi lahzalarida... Muallifdan [Previous4.3 Hodisaga asoslangan (Event-Driven)chevron-left](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/event-driven) [NextIlovachevron-right](https://roboticsware.gitbook.io/entry-python/ilova) Last updated 9 months ago --- # 4.2 Protsessual (Procedural) | Entry-Python Dasturlash paradigmalari orasida "tartibga yo‘naltirilgan" (procedural) paradigma mavjud. Bu dasturlashning eng an'anaviy paradigmasi bo‘lib, dastlab paydo bo‘lgan paradigmalar orasida eng birinchisi hisoblanadi. Biz bilib-bilmay Entry blokli kodlashda ham ushbu paradigmani qo‘llab kelganmiz. [3.8-bo‘lim](https://roboticsware.gitbook.io/entry-python/boshlash/funksiya) da funksiyalarning zaruriyati va maqsadini yaxshi tushungan edik. Dastur ichida qayta foydalanish imkoniyati (reusability) yuqori bo‘lgan kodlarni funksiyalarga ajratib, ularni chaqirish orqali kod yozish usuli jarayon yo‘naltirilgan paradigma sifatida tanilgan. Ilgari funksiya(function) atamasi o‘rniga "tartib(procedure)" yoki "sub-programma(sub-routine)" deb atalgan. Shu sababli, tartibga yo‘naltirilgan dasturlashning inglizcha nomi "procedural" bo‘lib kelgan. Tartibga yo‘naltirilgan paradigmaning misollari oldingi bo‘limlarda funksiyalarni o‘rganishda ko‘rgan misollardan unchalik farq qilmaydi, shuning uchun o‘sha misollarni bu yerda ham qo‘llash kifoya. [Previous4.1 Ketma-ket/Parallel ishlov berish (Serial/Parallel)chevron-left](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/ketma_ket-parallel) [Next4.3 Hodisaga asoslangan (Event-Driven)chevron-right](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/event-driven) Last updated 8 months ago --- # 2. Dasturlash muhitini tayyorlash | Pygame Zero boshlang'ich Bu har bir dasturlash tilini o'rganish kitobida paydo bo'ladigan birinchi bob. Chunki, sarlavhadan xulosa qilishingiz mumkinki, bu kodlashni boshlash uchun oldindan o'rnatilishi kerak bo'lgan dasturlar mavjudligini anglatadi va ularni o'rnatish va sozlashdan so'ng kodlashni boshlash mumkin bo'ladi. Odatda, bu jarayon uchun ikkita asosiy talab mavjud. Birinchisi, siz foydalanmoqchi bo'lgan dasturlash tilini (bu holda Python) o'zini o'rnatish, ikkinchisi kodlashni (yoki dasturlashni) osonroq va qulayroq qiladigan yordamchi dasturni o'rnatish, bu kod editori yoki integratsiyalashgan dasturlash muhiti (Integrated Development Environment — IDE) — bu o'rnatilgan til yordamida kompyuter bilan aloqa qilish uchun mazmunli jumlalar va matnlar ya’ni kodlarni yozishni osonlashtiradi. circle-info **Integrated Development Environment (IDE)**: bitta dastur doirasida dasturiy ta'minotni ishlab chiqish bilan bog'liq barcha funksionalliklarni ta'minlaydigan muhitga ega dastur. Dasturiy ta'minotni ishlab chiqish bilan bog'liq barcha ishlar kodni tahrirlash, kompilyatsiya qilish, errorlarni to'g'rilash (debug), birlashtirish(building), binar tarqatish va boshqa dasturchilar bilan hamkorlik qilishni anglatadi. Mashhur mahsulotlarga Microsoft Visual Studio, Google Android Studio kiradi, va faqat Pythonga ixtisoslashtirilgan IDE — PyCharm kiradi. Biroq, ushbu jarayonlar har safar yangi kodlash tilidan foydalanishni boshlaganda bajarilishi kerak bo'lgan odatiy vazifalar bo'lishiga qaramay, ular yangi boshlovchilar uchun hali ham noqulay va murakkab bo'lishi mumkin. Misol uchun, agar o'rnatish jarayonida muammolarga duch kelsa va muammolarni bartaraf etishda muammo yuzaga kelsa, ular matnli dasturlash qiyin degan noto'g'ri fikrni rivojlantirishi mumkin. Yaxshiyamki, shunga o'xshash tashvishlarga duch kelgan chet ellik dasturchilar/o'qituvchilarning yana bir guruhi bor va ular ["Mu Editor" deb nomlangan ochiq manbali loyihaarrow-up-right](https://github.com/mu-editor/mu) ni boshladilar, bu kod editori dasturlash muhitiga qo'shimcha o'rnatmalarsiz darhol kodlashni boshlash uchun zarur bo'lgan hamma narsaga ega. Shuning uchun, **kodlashdan tashqari muhim bo'lmagan vazifalarni osonlashtirish va soddalashtirish niyatimizga muvofiq, biz Mu editoridan faqat matnli dasturlash mohiyatiga e'tibor qaratish uchun foydalanamiz, bu bizga uni tushunish va o'zlashtirishga chuqurroq kirishga imkon beradi.** [hashtag](https://roboticsware.gitbook.io/pygame_zero-entry_basic/dev_muhit#mu-editori-kod-editori-kodni-tahrirlash-vositalari) Mu editori (Kod editori, Kodni tahrirlash vositalari) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ O'rnatish uchun [Mu editorining rasmiy saytiarrow-up-right](https://codewith.mu/en/download) ga kiring va kompyuteringiz muhitiga qarab (kompyuteringizning operatsion tizimiga qarab) eng so'nggi o'rnatuvchini yuklab oling va o'rnating. circle-info Ma'lumot uchun, **men hozirgi vaqtda manba kodini o'zgartirish orqali ochiq manbali Mu editorining maxsus versiyasini yaratmoqdaman, bundan maqsad ta'lim uchun avvalgidan ham qulayroq bo'lishdir.** Kerakli manbalar (masalan, rasmlar va o'rnatishni talab qilinadigan qo'shimcha modullar)ni editorga oldindan kiritmoqdaman. **Bu editorni dastlabki o'rnatilganidan so'ng, resurslarni alohida onlayn o'rnatishga hojat qolmasligi uchun amalga oshirilmoqda, bu esa hamma narsani oflayn muhitda faqat bitta editor bilan qamrab olishga imkon beradi.** **Bundan tashqari, asl editorda yo'q bo'lgan qo'shimcha funksiyadir. U o'zimiz yaratgan o'yinlarni do'stlarga va boshqalarga tarqatishni osonlashtirish uchun qo'shilgan, bu bizga** [**o'yinlarni bitta EXE faylga aylantirib**](https://roboticsware.gitbook.io/pygame_zero-entry_basic/ilova/exe_fayliga) **bahramand bo'lish imkonini beradi.** **Ushbu maxsus editor versiyasini sinab ko'rmoqchi bo'lganlar uni** [**bu yerdan**arrow-up-right](https://github.com/roboticsware/mu/releases/) **yuklab olishlari mumkin.** ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FJiz1ezjb6bf1M2BYwigF%252Fimage.png%3Falt%3Dmedia%26token%3D1c95914a-0e14-4907-9724-a20613b0ff6e&width=768&dpr=3&quality=100&sign=9c265bb3&sv=2) Mu Editorning rasniy sayti Mu editoriga, dasturlash yordamchisi dasturi sifatida, nima yaqinroq: "oddiy kod editori"mi yoki "integratsiyalashgan dasturlash muhiti (IDE) dasturi"mi? Javob ba'zan IDEga, ba'zan esa kod editoriga yaqinroq bo'lishi mumkin. Mu editorining foydalanuvchilariga **istagan turli xil dasturlash muhitlari (rejimlar deb ataladi)** o'rtasida osongina almashishga imkon beradigan xususiyatni taqdim etadi. Python dasturlash bo'yicha turli vazifalarni (masalan, umumiy dasturiy ta'minotni dasturlash, o'yin yaratish, qurilmalarni boshqarish va boshqalar) osongina bitta editor bilan bajarish yangi boshlaganlar uchun juda qulay. Ushbu rejimlarni tanlash uchun siz editorning yuqori qismidagi menyuda **Rejim** tugmasini bosishingiz va kerakli (dasturlash) rejimini tanlashingiz mumkin (televizorning masofadan boshqarish pulti bilan televizor kanallarini o'zgartirishga o'xshash) va biz Pygame Zero yordamida o'yin yaratishni rejalashtirayotganimiz sababli, keling Pygame Zero rejimini tanlaylik. ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FwKvVa9zVypGUXCNIqWTu%252Fimage.png%3Falt%3Dmedia%26token%3D05b99a91-1998-4b92-993f-632e4770edba&width=768&dpr=3&quality=100&sign=90dad180&sv=2) Rejimni tanlash tugmasi ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FLE7toO9FzwNU71lXZcuy%252Fmode_sel.png%3Falt%3Dmedia%26token%3D139c87c4-e843-46a9-8117-5d8a044e42ca&width=768&dpr=3&quality=100&sign=72b5c4c2&sv=2) Rejimni tanlash oynasi Biz tanlagan dasturlash rejimining to'g'riligini joriy tanlangan dasturlash muhiti nima ekanligini ko'rsatadigan holat satri orqali yana bir bor tasdiqlashimiz mumkin. ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252Fuik16iFJyEzPNordSzGQ%252Fimage%2520%281%29.png%3Falt%3Dmedia%26token%3D7adf944a-98a8-4fc3-aedc-a0716cc5033d&width=768&dpr=3&quality=100&sign=6335b22e&sv=2) [hashtag](https://roboticsware.gitbook.io/pygame_zero-entry_basic/dev_muhit#mu-editorning-ozbek-tili-tarjimasi-loyihasi) Mu Editorning o'zbek tili tarjimasi loyihasi -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- circle-info **Yuqoridagi editor oynasi avval aytib o'tilganidek, ishlab chiqarilayotgan maxsus versiyadir. Ko'rib turganingizdek, ba'zi o'zbekcha tarjimalar qo'llanilgan va maqsad uni o'zbek tiliga to'liq tarjima qilishdir. Biroq, to'liq tarjima ko'p vaqt talab etadi, biz sizning ishtirokingizni kutmoqdamiz. Tarjimani tezda yakunlash uchun iloji boricha ko'proq odamlarning ishtirokini intiqlik bilan kutamiz va umid qilamizki, hamma birgalikda imtiyozlardan bahramand bo'ladi. Biz har doim o'z vaqtini hamma uchun bag'ishlashga va ixtiyoriy ravishda ishtirok etishga tayyor bo'lganlarni kutamiz.** 🙏 Tarjimaga qo'shilish havolasi: [https://crowdin.com/project/mu-editor/invite/public?h=f5e4f58d021fb3818e3e368fc105971b1916048&show\_welcomearrow-up-right](https://crowdin.com/project/mu-editor/invite/public?h=f5e4f58d021fb3818e3e368fc105971b1916048&show_welcome) Shu bilan biz kodlashni boshlash uchun dastlabki tayyorgarlikni yakunladik va endi keyingi mashg'ulotdan boshlab bizning ta'limimiz uchun optimallashtirilgan maxsus Mu editori yordamida haqiqiy Python kodlashni boshlaymiz. [Previous1\. "Pygame Zero" kutubxonasichevron-left](https://roboticsware.gitbook.io/pygame_zero-entry_basic/pygame-zero_kutubxonasi) [Next3\. "Hello World" dasturidan boshlaylikchevron-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/hello_world) Last updated 6 days ago --- # Kirish | Pygame Zero boshlang'ich Python dasturlash tili ko'pincha matnli dasturlash uchun eng oson til va bir vaqtning o'zida eng qulay til deb ataladi. Ma'lumki, uni o'rganish oson, lekin shunga qaramay, qanchalik oson bo'lmasin, o'rganish haqiqatan ham oson bo'lgan notanish til bormi? Hech bo'lmaganda, mening xotiramda bunaqasi bor bo'lmagan. Tilni o'rganish qiyin va ko'pincha sabr-toqatni sinovdan o'tkazadigan vazifadir, ammo uni biroz osonlashtiradigan ba'zi o'rganish usullari mavjud. Bilamizki, maqsadli auditoriya blokli kodlashda ma'lum darajada ko'nikmalar hosil qilgan va matnli dasturlash olamiga endi kirgan. Tezda charchatadigan mavjud grammatikaga yo'naltirilgan kitob o‘rniga, biz **Python tilini o'yin ishlab chiqarishga asoslangan o'rganish usulini tavsiflovchi kitob bilan o'zimizni sinab ko'rishga qaror qildik, bizga tanish bo'lgan va blokli kodlashda sanoqsiz qo'llangan "loyihaga asoslangan o'rganish" deb nomlangan o'sish yo'lini** qo'lladik. Xo'sh, muallif bilan birga o'yinlar yaratib, Python olamiga chuqur sho'ng'ishni xohlaysizmi? _Ushbu kitob_ [_"Entry boshlang'ich kitobi"_arrow-up-right](https://ufe.gitbook.io/entry_basic) _dan (Qadamma-qadam o‘zlashtirib, o‘rganadigan "Entry" dasturlash) tanish misollar yordamida matnli dasturlashni o'rganishga o'ziga xos yondashuvni qo'llaydi, siz Entry orqali blokli kodlashni birinchi o'rganishda foydalangan bo'lishingiz mumkin. Ushbu misollarni Pythonda qayta kodlash orqali siz matnli dasturlashni tez va samarali tarzda o'rganishingiz mumkin bo'ladi._ #### [hashtag](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kirish#ozgarishlar-tarixi) O'zgarishlar tarixi: Versiya Sana Tavsif v1 25/07/2024 Birinchi versiya chiqishi v1.2 21/10/2024 5.1.1 bob mazmunini to'ldirish va 6-misolni tuzatish **Muallif: JJ (**[comseong@envelope](mailto:comseong@gmail.com) [mail.comenvelope](mailto:comseong@gmail.com) **)** **O'zbek tiliga tarjima: Komron (**[knmv2311@gmail.comenvelope](mailto:knmv2311@gmail.com) **)** **Malumot materiallari 1:** [Entry boshlang'ich kitobiarrow-up-right](https://ufe.gitbook.io/entry_basic) **Mualliflik huquqi:** [**https://creativecommons.org/licenses/by-nc-sa/4.0/**arrow-up-right](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.ko) ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FmEkq0503UwpbXqcKjKht%252Fimage.png%3Falt%3Dmedia%26token%3De62fdc07-55c9-4bb4-acfa-5b58c09d061d&width=768&dpr=3&quality=100&sign=54cd7960&sv=2) [Previous"Pygame Zero" yordamida Python o'rganishchevron-left](https://roboticsware.gitbook.io/pygame_zero-entry_basic) [Next1\. "Pygame Zero" kutubxonasichevron-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/pygame-zero_kutubxonasi) Last updated 10 months ago --- # Ilova | Pygame Zero boshlang'ich [Dasturimizni EXE fayliga aylantirishchevron-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/ilova/exe_fayliga) [Mu editorining tezkor tugmalarichevron-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/ilova/mu_tezkor_tugmalar) [Previous5.7 Ko'rsichqon o'yini yasash (Jamlash)chevron-left](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/korsichqon_oyini) [NextDasturimizni EXE fayliga aylantirishchevron-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/ilova/exe_fayliga) --- # 5. Entry boshlang'ich darajali kitobini kodlash | Pygame Zero boshlang'ich Va nihoyat, bundan buyon biz ushbu kitobning asosiy mazmuniga sho'ng'iymiz va ["Entry boshlang'ich kitobi"arrow-up-right](https://ufe.gitbook.io/entry_basic) (Qadamma-qadam o‘zlashtirib, o‘rganadigan "Entry" dasturlash) misollarini birma-bir Pythonda yaratib Python matnli dasturlashni o'rganamiz. [Previous4\. O'yin siklini tushunishchevron-left](https://roboticsware.gitbook.io/pygame_zero-entry_basic/oyin-sikli) [Next5.1.1 Kuchuk va mushuk Salom aytadi1 (Ketma-ketlik)chevron-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/kuchuk-mushuk_1) Last updated 10 months ago --- # 4. O'yin siklini tushunish | Pygame Zero boshlang'ich To'liq miqyosli o'yin ishlab chiqarishni boshlashdan oldin, biz yaratadigan o'yin dasturining asosiy operatsion tuzilishini tushunishimiz kerak. Keling, avvalam bor Entry blokli kodlashda umumiy kodlash qanday bo'lganini eslaylik. Odatda, birinchi navbatda, ekranda paydo bo'ladigan bir yoki bir nechta asosiy belgilar obyektlari chaqiriladi va ekranga joylashtiriladi, so'ngra har bir obyekt o'yinda bajarishi kerak bo'lgan harakatlar uchun alohida kodlanadi. Tugallangan o'yin o'ynalganda, har bir obyekt mustaqil ravishda va bir vaqtning o'zida ishga tushadi va hatto "boshlash tugmasi bosilganda" bir obyektga ikki yoki undan ko'p marta qo'yilgan bo'lsa ham, u parallel ravishda harakat qilayotgandek harakat qildi ([tafsilotlar uchun oldingi kitobga qarangarrow-up-right](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/ketma_ketlik-parallel) ). Pygame Zero kutubxonasi bilan Python tilida dasturlash blokli kodlashga biroz o'xshaydi, ammo sezilarli farqlar ham mavjud. Afsuski, eng katta farq shundaki, endi biz har bir asosiy obyektni mustaqil va parallel ravishda harakat qildira olmaymiz, va biz barcha asosiy obektlarning harakatlari bir joyda (o'yin sikli) boshqariladi deb hisoblab kodlashimiz kerak. Agar biz uni diagrammada ifodalasak, o'yin doimiy ravishda takrorlanib turuvchi cheksiz sikl(**o'yin sikli** deb ataladi, chunki u o'yinlar uchun maxsus ishlatiladigan davomiy taqrorlashaga o'xshash)da bajariladi: ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FNNIEsJ8lwOPAH0JwieYd%252Fimage.png%3Falt%3Dmedia%26token%3D25545443-224d-4803-8488-5ee3f96fd079&width=768&dpr=3&quality=100&sign=9f40b4b7&sv=2) Manba: [https://inventwithpython.com/pygame/chapter2.htmlarrow-up-right](https://inventwithpython.com/pygame/chapter2.html) Rasmda tasvirlanganidek, **o'yin siklida uchta asosiy vazifalar(ekranda o'yin obyektini chizish, o'yin obyektlarining harakatlarini boshqarish,** [**klaviatura va sichqoncha kabi hodisalarni ishlov qilish**arrow-up-right](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/event-driven) **)ni doimiy ravishda qayta ishlanadi.** Agar biz Pygame Zero o‘rniga Pygame kutubxonasi bilan kodlayotgan bo‘lsak, ushbu o‘yin siklining tuzilishini yaratish bizning vazifamizdir va biz uni o‘zimiz kodlashimiz kerak. **Biroq, Pygame Zero ataylab yangi boshlovchilar uchun bu qismni yashiradi, va u oldindan belgilangan 3ta** [**kolbek funksiyalari**arrow-up-right](https://roboticsware.gitbook.io/entry-python/boshlash/hello_world#kolbek-callback-funksiyasi-nima) **(draw, update on\_mouse/on\_key) tayyor. Ushbu kolbek funksiyalariga muvofiq kodlash orqali Pygame Zero yangi boshlanuvchilar uchun yanada qulay tuzilmani taklif etadi.** Yaxshiyamki, biz Pythonda Entry-Pythonda kolbek funksiyasi asosida kodlashni sinab ko‘rganimiz uchun, biz ushbu tuzilishga qiyinchiliksiz moslasha olishimiz kerak. Keyingi mashg'ulotdan boshlab biz ushbu tushunchaga asoslangan to'liq o'yinni kodlashga harakat qilamiz. [Previous3\. "Hello World" dasturidan boshlaylikchevron-left](https://roboticsware.gitbook.io/pygame_zero-entry_basic/hello_world) [Next5\. Entry boshlang'ich darajali kitobini kodlashchevron-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash) Last updated 6 days ago --- # 3. "Hello World" dasturidan boshlaylik | Pygame Zero boshlang'ich Bu dasturlashdagi birinchi qadam. Har doimgidek, lekin bu safar siz bilan, biz "[Hello Worldarrow-up-right](https://uz.wikipedia.org/wiki/Hello,_World!) " dasturini birgalikda o'rganishdan boshlashimiz kerak. Biroq, Pygame Zero dasturlash tilining o'zi emas, balki kutubxona bo'lgani uchun biz tanish bo'lgan Hello World dasturini yaratmaymiz. Buning o'rniga, avvalgi Hello World dasturiga nisbatan Pygame Zero kutubxonasi bilan kodlashda zarur bo'lgan minimal koddan iborat eng kichik dastur misolini ko'rib chiqamiz. Birinchidan, Mu Editorni ochaylik. Faylni ochish va birinchi kodlashni boshlash uchun menyu panelidagi **Yangi fayl** tugmasini bosing. Quyidagi bitta chiziqli kodni yozamiz. Copy TITLE = 'Hello World!' Kodlash amalga oshirildi. Ajoyib! Bu juda oddiy emasmi? Ha, shunday. Shuning uchun _Pygame Zero Python kodlash orqali o'yin yaratishni soddalashtiradi, xuddi bizning Entry-Pythondagi Python kodlash tajribamiz kabi. Shunday qilib, Pygame Zero orqali Python dasturashni o'rganish matnli dasturlashni yangi o'rganayotganlar uchun juda mos tanlov bo'lishi mumkin._ Faqat bitta qator kod bilan biz 'Hello World' nomli juda oddiy bo'sh oyna dasturini yaratdik. Endi kodni **hello\_world** nomi bilan faylga saqlash uchun menyu panelidagi **Saqlash** tugmasini bosamiz. Keyin, uni bajarish uchun menyu panelidagi **Boshlash** tugmasini bosing va qanday ishlashini tekshiring. **hello\_world** nomli bo'sh oyna ilovasi biz kutgandek to'g'ri ishladimi? ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FSXoh2JPxxE2PLWv9HApA%252FScreenshot%25202024-03-11%2520at%252011.51.32.png%3Falt%3Dmedia%26token%3Da575fe9e-ae2f-425d-a662-6b9b36d89dd5&width=768&dpr=3&quality=100&sign=195106ea&sv=2) ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FTtnjjshX6qmbKPpbFawW%252Fimage.png%3Falt%3Dmedia%26token%3Ddb706004-c381-4136-89d4-27b650072bd6&width=768&dpr=3&quality=100&sign=c83f2e7e&sv=2) "Hello World" nomli ijro ekrani Kodlashga qaytish uchun biz hozirgina bajarilgan dasturni yopishimiz kerak. Ishga tushrilgan dastur o'zi oynasidagi 'x' tugmasini (dastur o'chirish tugmasi) bosish orqali o'yin ilovasini yopish mumkin bo'lsa-da, **Mu editorida kodlashni davom etish uchun har doim to'g'ri chiqish uchun Menyu panelidagi To'xtatish tugmasini bosishni unutmang**. ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252Fr6nxJtIqQ45rhCIywFWl%252FScreenshot%25202024-03-11%2520at%252012.06.22.png%3Falt%3Dmedia%26token%3Daa90e5d2-24f7-40c9-b3ed-6dd518947103&width=768&dpr=3&quality=100&sign=3d56facf&sv=2) Biroq, bitta qatorli kod bo'lishiga qaramay, keling, uni tushunish uchun kodni tahlil qilaylik. Biz ilova nomini **TITLE** deb nomlangan o'zgaruvchida saqladik. O'zgaruvchining nomi nega TITLE ekanligini intuitiv ravishda taxmin qilishingiz mumkin, u biz yaratmoqchi bo'lgan ilovaning nomini (sarlavhasini) ko'rsatish uchun ishlatiladi. Lekin nima uchun o'zgaruvchining nomi TITLE bo'lishi kerak? Nima uchun o'zgaruvchi kichik harflarda bo'lishi mumkin emas yoki nega men uni shunchaki xohlaganimdek APPNAME deb nomlay olmayman deb o'ylashingiz mumkin. Afsuski, bu tarzda ishlamaydi. Agar siz bu haqiqat yoki yo'qligini tekshirmoqchi bo'lsangiz, o'zgaruvchining nomini boshqa narsaga o'zgartirib, tajriba o'tkazishingiz va kerakli natijaga erishganingizni bilish uchun ilovani qayta ishga tushirishingiz mumkin. Siz kerakli natijaga erisha olmasligingizni bilib olasiz. Pythonni birinchi marta o'rganganimizda biz avval o'rgangan [**oldindan o'rnatilgan funksiyalar**arrow-up-right](https://roboticsware.gitbook.io/entry-python/boshlash/kiritish_chiqarish) va **ldindan o'rnatilgan o'zgaruvchilar** kabi tushunchalarni eslaysizmi? Ushbu o'zgaruvchi shu tushunchalarga o'xshaydi. Agar kutubxonalar haqida avvalgi darslarimizdan eslasangiz, [**kutubxona**arrow-up-right](https://roboticsware.gitbook.io/entry-python/boshlash/hello_world#kutubxona-nima) **dan foydalanish kutubxona yaratuvchisi tomonidan belgilangan qoidalarni o'rganish va shu qoidalarga muvofiq kodlashni anglatadi**. Xuddi shunday, _Pygame Zerodan foydalanish Pygame Zero yaratuvchisi tomonidan belgilangan qoidalarni o'rganish va shunga mos ravishda kodlashni anglatadi. Biz o'rgangan TITLE o'zgaruvchisi yaratuvchi tomonidan allaqachon belgilangan to'g'ri ismga o'xshaydi. Ilova nomini o'zgaruvchida saqlash uchun faqat shu o'zgaruvchi nomidan foydalanish ilova bajarilganda ilova nomi to'g'ri ko'rsatilishini ta'minlaydi._ Endi o'yin ilovamizni biroz kengaytiraylik. Endi quyidagi 2 qator kodlarni qo'shib, bizda jami 3 qator kod mavjud. Ushbu 3ta qatorli kod yordamida biz ilova nomi asosida 'Hello World' nomli 400 x 300 piksel o'lchamdagi bo'sh ekranli juda oddiy dastur yaratdik. Boshlash tugmasini bosib, uni ishga tushiramiz. Copy TITLE = 'Hello World!' WIDTH = 400 HEIGHT = 300 ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FvDcxlUNCN7cZkzxU8IL8%252Fimage.png%3Falt%3Dmedia%26token%3De5cc9769-b363-4db8-ad72-8cf0205bac85&width=768&dpr=3&quality=100&sign=65ba962f&sv=2) Gorizontal ravishda 400 piksel va vertikal ravishda 300 piksel o'lchamdagi ilovani ishga tushirish oynasi Xo'sh, biz dastlab yaratgan birinchi bitta qatorli dastur va ushbu dastur o'rtasidagi farq nima? Ha, biz mos ravishda **WIDTH** va **HEIGHT** ya'ni kenglik va balandlik nomli o'zgaruvchilar yordamida qo'shimcha kodlashni qo'shdik. Siz intuitiv ravishda his qilganingizdek, xuddi o'zgaruvchi TITLE kabi, bu o'zgaruvchi nomlari Pygame Zero kutubxonasida oldindan belgilangan o'zgaruvchilar bo'lib, ilova hajmini aniqlaydi. Ulardan foydalanish tufayli biz endi kerakli o'lchamdagi ilovalarni yaratishimiz mumkin. Hello World dasturini yaratish tugagani uchun, keling, haqiqiy o'yinlarni birma-bir yaratish orqali Python dasturlahni o'rganishdan zavqlanaylik! [Previous2\. Dasturlash muhitini tayyorlashchevron-left](https://roboticsware.gitbook.io/pygame_zero-entry_basic/dev_muhit) [Next4\. O'yin siklini tushunishchevron-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/oyin-sikli) Last updated 3 days ago --- # 3.3 O‘zgaruvchi (Variable) | Entry-Python Biz Entry blokli kodlashda o‘zgaruvchi va ro‘yxat deb nomlangan elementlarni ishlatib ko‘rganmiz. Ikkalasi ham ma'lumotlarni saqlash uchun mo‘ljallangan joy bo‘lib xizmat qiladi. Avval o‘zgaruvchining nima ekanligini va uning maqsadi nimadan iboratligini eslab olaylik. O‘zgaruvchi — nomidan ma’lum bo‘lgandek, o‘zgaruvchi qiymatlarni vaqtinchalik saqlash uchun ajratilgan joy. Blokli kodlashda biz ba'zi bloklarni qo‘llaganimizda, ko‘pincha oldindan belgilangan biror amalni bajarish uchun muayyan qiymatlar aniqlab berilganini ko‘ramiz. Ammo, oldindan belgilab bo‘lmaydigan qiymatlar (masalan, foydalanuvchi tomonidan kiritilgan tasodifiy qiymatlar) asosida ishlaydigan dasturlar uchun o‘zgaruvchilardan foydalanish zarur bo‘ladi. Yuqorida aytib o‘tilgan misolga o‘xshash holda, foydalanuvchi tomonidan tasodifiy kiritilgan ikki raqamni qabul qilib, ularning yig‘indisini hisoblashga qaratilgan oddiy qo‘shish kalkulyatori dasturini o‘zgaruvchidan foydalanib yozamiz. Ijro natijasi Blokli kodlash Entry-Python ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FTpeFoxPWuduhFCOwbdfr%252FUntitled-1234%2520copy.png%3Falt%3Dmedia%26token%3D55e88d9a-94ba-4073-b869-266889c535d5&width=768&dpr=3&quality=100&sign=9538e391&sv=2) ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FuIJY4AUsCasklLUkDG4x%252Fcalcvar.png%3Falt%3Dmedia%26token%3De7dd5a22-c2b9-41d2-9b2d-57dbc0f18d67&width=768&dpr=3&quality=100&sign=1204e4ff&sv=2) Copy # (1)Entrybot's Python code import Entry first = 0 second = 0 result = 0 def when_start(): Entry.print("Bu siz kiritgan ikkita raqamni qo'shadigan dastur.") Entry.wait_for_sec(2) Entry.input("Iltimos, birinchi raqamni kiriting.") first = Entry.answer() Entry.input("Ikkinchi raqamni kiriting.") second = Entry.answer() result = (first + second) Entry.print(("Kiritilgan ikkita raqamning yig'indisi " + result) + " ga teng.") Biz hali matn dasturlash bilan yaxshi tanish bo'lmaganimiz sababli, kod miqdori to'satdan ko'payib ketgandek tuyulishi mumkin, lekin aslida bu o'qishni oshirish uchun ataylab bo'sh qatorlar bilan kod bo'laklariga ajratilgan, shuning uchun qatorlar soni katta tuyulishi mumkin, agar siz uni diqqat bilan izohlasangiz, unda murakkab tarkib deyarli yo'qligini ko'rasiz. Hozirgacha o‘rganilmagan, birinchi marta uchrayotgan qism — bu 5~7-qatorlarda yozilgan 3 ta kod qatoridir. Ushbu qatorlarda **first**, **second**, va **result** deb nomlangan 3 ta o‘zgaruvchi e'lon qilinadi va ushbu o‘zgaruvchilarga dastlabki qiymat sifatida 0 belgilanadi. **Python tilida o‘zgaruvchi yaratish sintaksisi quyidagicha:** > o'zgaruvchi nomi = _boshlang'ich qiymat_ _Bu yerda o‘zgaruvchi nomini kerakli, tasodifiy bir nom bilan belgilash mumkin, lekin maqsadga muvofiq, kodni o‘qishda uning vazifasini osongina tushunish uchun mazmunli nom tanlash tavsiya etiladi. Yuqoridagi misolda foydalanuvchining birinchi kiritgan qiymati (first), ikkinchi kiritgan qiymati (second), va ushbu ikkita qiymatning yig‘indisi (result) ma’nosini ifodalash uchun ushbu o‘zgaruvchi nomlari ataylab ishlatilgan. O‘zgaruvchilarga dastlab yaratilayotganda biron-bir tasodifiy qiymat (bunga "boshlang'ich qiymat" deyiladi) berilib, qiymatga ega holda ishga tushiriladi. Odatda,_ `_0_` _dastlabki qiymat sifatida ishlatiladi. Ushbu sintaksisda e'tibor qaratish kerak bo‘lgan bir narsa bor:_ _**'=' belgisining ma’nosi matematikadagi "teng" degan ma’noni emas, balki, '=' belgisining o‘ng tomonidagi qiymatni chap tomondagi o‘zgaruvchiga tayinlash (sozlash) degan ma’noni anglatadi. Buni albatta yodda saqlash lozim.**_ 🔢 Shunday qilib, 5-qatordagi **first = 0** kodi, `**=**` belgining chap tomonida joylashgan **first** o‘zgaruvchisiga `**=**` belgining o‘ng tomonida joylashgan **0** qiymatini saqlashni anglatadi. circle-info O‘zgaruvchi nomini ixtiyoriy tarzda ishlatish mumkin, deb aytilgan bo‘lsada, aslida Python dasturlash tilida o‘zgaruvchiga nom berishda rioya qilinishi kerak bo‘lgan 2 asosiy qoida mavjud: * O‘zgaruvchi nomi raqam bilan boshlanishi mumkin emas. * O‘zgaruvchi nomi orasida bo‘sh joy bo‘lishi mumkin emas. Bu yerda, matematik ma'noda chap va o‘ng tomondagi qiymatlar bir-biriga tengmi yoki yo‘qligini kodda ifodalash uchun qanday belgi ishlatish kerakligi qiziq bo‘lishi mumkin. Bu holatda **\==** belgisi ishlatiladi. **Ya'ni,** `**=**` **belgisini bitta emas, ketma-ket ikki marta ishlatish orqali chap va o‘ng tomondagi qiymatlarning bir-biriga tengligini solishtirish ma'nosini anglatadi.** 🔢 10~11-qatordagi kodlar to‘plami dasturda foydalanuvchiga dasturimizning qanday dastur ekanligini tushuntirish uchun foydalaniladi. 10-qatordagi chiqarish funksiyasi ilgari ishlatilgan, 11-qatordagi **Entry.wait\_for\_sec(2)** kodi esa birinchi marta uchraydi. Uning ma’nosini tushunish qiyin emas: bu Entry kutubxonasidagi **wait\_for\_sec** funksiyasini chaqirishdir. Ushbu funksiya blok kodlashdagi "~ soniya kutish" blokiga o‘xshaydi. Kutish davomiyligini funksiyaga qiymat sifatida uzatish kerak, va bu yerda 10-qatorda chiqarilgan matnni ekranda 2 soniya davomida ko‘rsatib turish uchun 2 qiymati berilgan. 🔢 13~16-qatordagi kodlar to‘plami foydalanuvchidan ketma-ket ikkita tasodifiy son kiritishni so‘raydi va ularni mos ravishda **first** va **second** o‘zgaruvchilariga saqlaydi. Nima uchun foydalanuvchi kiritgan qiymatni Entry.answer() orqali o‘qib, saqlash kerakligi haqida avvalgi bobda [kiritish-chiqarish funksiyalari](https://roboticsware.gitbook.io/entry-python/boshlash/kiritish_chiqarish) qismida tushuntirilgan. 🔢 18-qatorda esa **first** va **second** o‘zgaruvchilarida saqlangan qiymatlar o‘qilib, ularning yig‘indisi uchinchi o‘zgaruvchi, ya'ni **result** ga saqlanadi. 🔢 19-qator kodda foydalanuvchi kiritgan ikki sonning yig‘indisi saqlangan o‘zgaruvchidagi qiymatni foydalanuvchiga ko‘rsatish orqali dastur o‘z maqsadiga erishadi va yakunlanadi. Agar biz blokli kodlashda o‘zgaruvchilarni ishlatgan bo‘lsak, ularning ma’nosi va qo‘llanilishini yaxshi bilamiz. Matnli dasturlashga o‘tilganda ham bu ma’no va maqsad umuman o‘zgarmaydi. Faqatgina matnli dasturlashda (bu yerda Python) foydalanilganda, shu tilning o‘zgaruvchi ishlatish sintaksisiga amal qilib, foydalanish kifoya. [Previous3.2 Kiritish/Chiqarish (Input/Output)chevron-left](https://roboticsware.gitbook.io/entry-python/boshlash/kiritish_chiqarish) [Next3.4 Shart (Condition)chevron-right](https://roboticsware.gitbook.io/entry-python/boshlash/shart) Last updated 10 months ago --- # 3.7 Tasodifiy son (Random) | Entry-Python Tasodifiy son (yoki random) funksiyasidan foydalanish faqat bitta funksiya chaqiruviga asoslangani sababli, hozirgacha berilgan ma'lumotlarni yaxshi tushungan va kuzatib kelgan odamlar uchun umuman qiyinchilik tug‘dirmaydi. Shunday qilib, ushbu bo‘limda oddiy va qiziqarli bir o‘yin yaratamiz, bunda tasodifiy son funksiyasidan foydalanamiz. O‘yin nomi "Men o'ylagan sonni top!" bo‘lib, kompyuter 1 dan 50 gacha bo‘lgan tasodifiy bir sonni o‘ylaydi, va biz ushbu sonni imkon qadar kam urinishda topishimiz kerak bo‘ladi. O‘yinni yanada qiziqarliroq qilish uchun biz foydalanuvchining kiritgan taxminiy soni to‘g‘ri javobga qanchalik yaqin ekanligi haqida doimiy ravishda maslahatlar beradigan mexanizmni qo‘shamiz. Ijro natijasi Blokli kodlash Entry-Python ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252F9RuPa52VOcjj1tPqzUGC%252FrandomF.png%3Falt%3Dmedia%26token%3D9f2237cf-102b-4d4a-9261-6cd983c20777&width=768&dpr=3&quality=100&sign=ea00ef48&sv=2) ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FCBcGgGGJg1Ka6iDvFERm%252Frandom.png%3Falt%3Dmedia%26token%3D2980c855-2079-419c-bc32-fc56181d9137&width=768&dpr=3&quality=100&sign=c4989d28&sv=2) Copy # (1)Entrybot's Python code import Entry com_num = 0 my_num = 0 try_total = 0 def when_start(): com_num = random.randint(1, 50) while True: Entry.input("Men 1 dan 50 gacha bo'lgan sonni o'ylab qo'ydim, uni topishga harakat qiling! Siz ularni necha martada to'g'ri topasiz?") my_num = Entry.answer() try_total += 1 if (my_num == com_num): Entry.print("Bingo! " + try_total + "-urinishda topib oldingiz-ku!") Entry.stop_code("all") else: if my_num < com_num: Entry.print(my_num + " dan katta son") else: Entry.print(my_num + " dan kichik son") Entry.wait_for_sec(2) 🔢 9-qatorida tasodifiy son yaratish uchun **randint** funksiyasidan foydalanilgan. Ushbu funksiya **random** modulida (yoki kutubxonasida) joylashgan bo‘lib, asl Pythonda ushbu modulni chaqirish uchun kodning eng yuqori qismida **import random** qatori qo‘shilishi kerak bo‘lardi. Biroq, Entry-Pythonda ushbu jarayonsiz ham ushbu funksiyani to‘g‘ridan-to‘g‘ri chaqirib foydalanish mumkin. _Funksiyaga uzatilgan qiymatlar qaysi oraliqda tasodifiy son kerakligini aniq belgilash uchun berilgan: 1 dan 50 gacha bo‘lgan butun sonlar oraliqni anglatadi, shuning uchun_ _**randint(1, 50)**_ _chaqiruviga boshi va oxiri sifatida ikkita qiymat funksiya argumentlariga uzatilgan._ 🔢 14-qatorida **try\_total += 1** qatorida notanish **+=** operatori ishlatilgan, lekin aslida bu operatorning ishlatilishi oldingi bo‘limda ro‘yxatlar bilan ishlash misolida ko‘rsatilgan kodga o‘xshaydi. U yerda umumiy summani hisoblashda avvalgi qiymatga yangi qiymat qo‘shib borilgan edi. Shunday qilib, agar kodni **try\_total = try\_total + 1** shaklida yozsangiz, u xuddi shunday ishlaydi, va bu kodni qisqartirilgan holda **try\_total += 1** shaklida yozish ham aynan shu ma’noni beradi. Ya’ni, **try\_total** ning oldingi qiymatiga ketma-ket 1 qo‘shib borilsin degan ma’noni anglatadi. Boshqa kodlar ilgari o‘rganilgan bo‘lib, ularni tushunishda katta qiyinchilik bo‘lmasligi kutiladi. Shuning uchun qo‘shimcha izohlar berishga hojat yo‘q, va endi ushbu o‘yinni yanada qiziqarli qilish uchun uni rivojlantirish sizning vazifangiz bo‘lib qoladi. [Previous3.6 Ro‘yxat (List)chevron-left](https://roboticsware.gitbook.io/entry-python/boshlash/ruyxat) [Next3.8 Funksiya (Function)chevron-right](https://roboticsware.gitbook.io/entry-python/boshlash/funksiya) Last updated 10 months ago --- # 3.5 Takrorlash (Loop) | Entry-Python Biz blokli kodlashda kodning oqimini boshqarish maqsadida (shuning uchun Entryning blok kategoriyasida "**oqim**" kategoriyasiga kiradi) eng asosiy bloklardan biri bo‘lgan "**takrorlash**"ni ko‘p marta ishlatganmiz. Takrorlanishi kerak bo‘lgan kod qismini qanday va qancha marta takrorlash kerakligini aniqlash uchun Entryning "oqim" kategoriyasidagi takrorlash bilan bog‘liq bloklar uchta asosiy turga bo‘linadi: "davomiy takrorlash / belgilangan marta takrorlash / ma’lum bir shart davomida takrorlash". Birinchi, "ma’lum bir shart davomida takrorlash"ni Python sintaksisida ifodalash quyidagicha bo‘ladi: ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FGLaX7HSXm1s4Ovga633C%252FwhileCond%2520copy.png%3Falt%3Dmedia%26token%3Dc04f2a31-9728-43d9-acc5-fc8d04c76c89&width=768&dpr=3&quality=100&sign=f84e5cfe&sv=2) **while** inglizcha bog‘lovchining o‘zi ham "(biror narsa) **davomida**" degan ma’noni anglatadi. Shunday qilib, while operatorida yozilgan 'shart' qoniqarli bo’lishi davomida uning ostida joylashgan kodlar doimiy ravishda takroran bajariladi. Buni shunday tushunish mumkin: takrorlash amalga oshirilayotgan vaqt davomida har safar 'shart'ning bajarilayotganini yoki bajarilmayotganini tekshirish kerak. Shu vaqt davomida holat o‘zgarishi va shuning uchun 'shart'ning natijasi yolg'on bo'lib bajarilmay qolishi mumkin. O‘sha vaqtda takrorlash to‘xtatiladi, va while operatoridan chiqiladi. Shundan so'ng while kod to'plamidan keyin yozilgan kodlar ketma-ket bajarila boshlaydi. Biz odatda takrorlash davomida 'shart' o‘zgarib, shu bilan birga 'shart'ning natijasi yolg’on bo’lib bajarilmay qolganda, takrorlashdan chiqishni kutamiz. Ammo, agar takrorlashni ataylab cheksiz davom ettirmoqchi bo‘lsak, nima qilish kerak? Buni shunday amalga oshirish mumkin: 'shart'ni hech qachon tekshirilmay qolmaydigan qilib belgilash. Boshqacha qilib aytganda, 'shart'ni doim **rost** (True) bo‘lishiga majbur qilish kerak. Buni Python tilidagi matnli dasturlash sintaksisi yordamida quyidagicha ifodalash mumkin: ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FWB9txR2bYvPwUb1LoagP%252FwhileCond2.png%3Falt%3Dmedia%26token%3Dc002aeb0-f78c-49ee-982f-028547361150&width=768&dpr=3&quality=100&sign=87772a2c&sv=2) Yuqorida o‘rganilgan texnikadan foydalanib, avvalgi bo‘limlarda yaratilgan kalkulyator dastur(yoki ilova)ini yanada takomillashtirib, foydalanuvchining foydalanish qulayligini oshirishga harakat qilamiz. Foydalanuvchi nuqtai nazaridan, kalkulyator yordamida hisoblash jarayonini faqat bir marta bajarish bilan cheklanmaslik, balki davom ettirish imkoniyati muhim. Hozirgi sharoitda foydalanuvchi hisoblashni qayta-qayta davom ettirmoqchi bo‘lsa, dastur(yoki ilova)ni qayta ishga tushirishdan boshqa yo‘li yo‘q. Bu esa foydalanish qulayligini cheklaydi. Foydalanuvchi istagancha hisoblashni davom ettira olishi va kerak bo‘lmaganida dasturni to‘xtata olishi kerak. Ushbu foydalanuvchi talablariga javob berish uchun, biz kodlarimizga takrorlash operatorini qo‘shishimiz zarur. Ijro natijasi Blokli kodlash Entry-Python ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252F5fxcWMun8VFY1K5Pcir7%252Fimage.png%3Falt%3Dmedia%26token%3D50ea5a0a-0fee-4aa3-a4d6-0b75275d05c7&width=768&dpr=3&quality=100&sign=3b5aacbd&sv=2) ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252F0dhDEGZ41KaLVyxrvOrC%252FwhileTrue.png%3Falt%3Dmedia%26token%3D7ccbe69c-a4e0-41b7-8fd1-5b249e326790&width=768&dpr=3&quality=100&sign=9eaec533&sv=2) Copy # (1)Entrybot's Python code import Entry first = 0 second = 0 def when_start(): Entry.print("Bu siz kiritgan ikkita raqamni qo'shadigan yoki ayiradigan dastur.") Entry.wait_for_sec(3) while True: Entry.input("Iltimos, birinchi raqamni kiriting.") first = Entry.answer() Entry.input("Ikkinchi raqamni kiriting.") second = Entry.answer() Entry.input("Agar siz qo'shmoqchi bo'lsangiz, '+' kiriting. Agar ayirmoqchi bo'lsangiz, '-' kiriting. Agar siz ilovadan chiqmoqchi bo'lsangiz, 'x' ni kiriting.") if Entry.answer() == "x": Entry.stop_code("all") if Entry.answer() == "+": Entry.print("Kiritilgan ikkita raqamning yig'indisi " + (first + second) + " ga teng") if Entry.answer() == "-": Entry.print("Kiritilgan ikkita raqamning ayirmasi " + (first - second) + " ga teng") Entry.wait_for_sec(2) Endi yozilgan kodni tushunaylik. Takomillashtirilgan kalkulyator ilovasida cheksiz takrorlanishi kerak bo‘lgan kodlar **while True:** dan keyingi qatordan boshlab joylashganini va ularning barchasi **identatsiya**(indenting - 4 bo'sh joy yoki 1 tab orqali bo‘shliq qoldirish) bilan yozilganini ko‘rish mumkin. Foydalanuvchi bizning kalkulyator ilovamizni yopmoqchi bo‘lganida, unga ko‘rsatmalarda aytilganidek, 'x' qiymatini kiritadi. Ushbu qism kodning 19~20-qatorlarida bajariladi. Agar foydalanuvchi 'x' qiymatini kiritgan bo‘lsa, Entry kutubxonasidagi dastur(ilova)ning kodlarni to‘xtatish funksiyasi bo‘lgan **stop\_code** funksiyasi chaqiriladi. Barcha kodlarni to‘xtatish uchun esa funksiyaga "all" argumenti yuborilganini ko‘rish mumkin. [Previous3.4 Shart (Condition)chevron-left](https://roboticsware.gitbook.io/entry-python/boshlash/shart) [Next3.6 Ro‘yxat (List)chevron-right](https://roboticsware.gitbook.io/entry-python/boshlash/ruyxat) Last updated 9 months ago --- # 3.6 Ro‘yxat (List) | Entry-Python Blokli kodlashda ro‘yxat deb atalgan saqlash joyining maqsadi nima edi? Oldin **o‘zgaruvchi faqat bitta o‘zgaruvchan qiymatni (yoki oldindan aniq bo‘lmagan qiymatni) saqlagan bo‘lsa, ro‘yxat deb ataladigan saqlash joyi faqat bitta emas, balki bir nechta qiymatlarni saqlash imkonini beradi.** Python tilida bunday joy ro‘yxat (list) deb ataladi, boshqa matnli dasturlash tillarida esa odatda "massiv" (array) deb yuritiladi. Blokli kodlashdagi ro‘yxatni Entry-Python matnli dasturlashida qanday ishlatish mumkin? Misol orqali Entry-Pythonda qanday kod yozish mumkinligini batafsil ko‘rib chiqamiz. [3.3-bo‘lim](https://roboticsware.gitbook.io/entry-python/boshlash/uzgaruvchi) da yaratilgan faqat qo‘shish funksiyasiga mo‘ljallangan kalkulyator dasturidan foydalanib, ro‘yxatlar yordamida bu dastur foydalanuvchanligini yanada yaxshilash mumkin. [3.3-bo‘lim](https://roboticsware.gitbook.io/entry-python/boshlash/uzgaruvchi) dagi kalkulyator foydalanuvchidan faqat ikkita tasodifiy qiymatni qabul qilib, ularning yig‘indisini hisoblaydi. Endi foydalanuvchi faqat ikkita qiymat emas, balki ko‘plab ketma-ket qiymatlarni kiritishi va kiritilgan barcha qiymatlarning umumiy yig‘indisini hisoblash imkoniyatiga ega bo‘lsa, bu foydalanuvchi uchun yanada qulayroq dastur(ilova)ga aylanadi. Avval, ro‘yxatni qanday ishlatish mumkinligini belgilaydigan sintaksisni ko‘rib chiqamiz: > ro‘yxat\_nomi = \[matn, raqam va boshqa bir nechta qiymatlar. Qiymatlar vergul ( , ) bilan ajratiladi\] Ro‘yxatning nomini xuddi o‘zgaruvchilar uchun nom qo‘yishda bo‘lgani kabi istalgan tarzda belgilash mumkin. Ammo, kod ma’nosini men yoki boshqa kishi tez va samarali tushunishi uchun har doim mazmunli nom berishga odatlanish kerak. Avval ham aytib o‘tganimizdek, bu odat dasturlash olamidagi asosiy fazilatlardan biridir. circle-info Ro‘yxat nomini istalgancha belgilash mumkin bo‘lsada, aslida Python tilida ro‘yxatga nom qo‘yishda quyidagi ikki muhim qoidaga amal qilish kerak: * Ro‘yxat nomi raqam bilan boshlanishi mumkin emas. * Ro‘yxat nomida bo‘sh joy bo‘lishi mumkin emas. Quyida sintaksisga muvofiq yozilgan ro‘yxatlarning misollari keltirilgan: words = \["apple", "banana", "grape"\] numbers = \[1, 3, 10, 25, 2\] complex = \["apple", 2, 32, "berry", 56, 5\] **words** nomidagi ro‘yxatda satrli(string) turidagi 3 ta elementlar mavjud. **numbers** nomidagi ro‘yxatda sonli turidagi 5 ta elementlar mavjud. **complex** nomidagi ro‘yxatda satrli va sonli turidagi elementlar aralash holda 6 ta elementlar mavjud. Hozirgacha biz ro‘yxatni aniqlash va bir vaqtning o‘zida boshlang‘ich qiymatlarni belgilashni o‘rgandik. Endi o‘rganishimiz kerak bo‘lgan narsa – ro‘yxat ichida saqlangan qiymatlarga(elementlarga) qanday murojaat qilish va ularni o‘qish, ro‘yxatga yangi qiymat qo‘shish yoki mavjud qiymatlarni o‘chirish usullari haqida. Yuqorida tilga olingan ro‘yxat bilan ishlash usullari bo‘yicha bilimlarni bu bo‘limda ko‘rib chiqamiz. Bundan tashqari, rivojlangan qo‘shish kalkulyatori dasturi uchun yozilgan kodlarni tahlil qilish orqali, ushbu usullarni amalda qanday qo‘llashni o‘rganamiz. Ijro natijasi Blokli kodlash Entry-Python ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FFfmE4kgKJaqfkJOlgXXK%252FList23.png%3Falt%3Dmedia%26token%3D31af393f-a7f9-4bd0-b511-f37f75e66536&width=768&dpr=3&quality=100&sign=bbb28478&sv=2) ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FtjpD7nSlyoGfy3SffxmK%252Flist.png%3Falt%3Dmedia%26token%3Dea875c73-1735-418a-8ddc-1cb87646e36a&width=768&dpr=3&quality=100&sign=4b9ce85b&sv=2) Copy # (1)Entrybot's Python code import Entry result = 0 numbers = [] def when_start(): Entry.print("Bu siz kiritgan barcha raqamlarni qo'shadigan kalkulyator") Entry.wait_for_sec(2) while True: Entry.input("Qo'shmoqchi bo'lgan raqamni kiriting. Agar siz hozirgacha kiritgan qiymatlar yig'indisini bilmoqchi bo'lsangiz, '=' kiriting. Agar siz ilovadan chiqmoqchi bo'lsangiz, 'x' ni kiriting.") if Entry.answer() == "x": Entry.stop_code("all") if Entry.answer() == "=": while len(numbers) != 0: result = result + numbers[0] numbers.pop(0) Entry.print(result) Entry.wait_for_sec(2) result = 0 else: numbers.append(Entry.answer()) 🔢 Birinchidan, 5-qatorda **numbers** deb nomlangan ro‘yxatning e’lon qilinishi biroz g‘ayrioddiy. Ko‘rishimiz mumkinki, ro‘yxat dastlabki qiymatlarsiz, ya’ni u to'rtbuchak qavslar ichida hech qanday qiymatlarsiz e’lon qilingan (shunchaki to'rtburchak qavslar ochilgan va yopilgan). Bu kabi e’lon qilishning sababi mantiqan tushunarli: bizning ilovamiz foydalanuvchi cheklanmagan miqdorda kiritishi mumkin bo‘lgan sonlarni saqlash uchun vaqtinchalik joyga muhtoj. Shu maqsadga mos keladigan joy sifatida ro‘yxatdan foydalanamiz. Foydalanuvchi hech narsa kiritmagan bo‘lsa ham, ro‘yxat mavjud bo‘lishi kerak, shuning uchun ro‘yxatda hech elemetlarsiz bo‘sh holatda e’lon qilingan deb taxmin qilish mumkin. 🔢 Endi 26-qatorga nazar tashlaymiz. 26-qator ro‘yxatga foydalanuvchi kiritgan sonli qiymatini yangi element sifatida qo‘shish uchun yozilgan kodni ifodalaydi. Bu yerda **append** funksiyasi yordamida foydalanuvchi kiritgan qiymatni **Entry.answer()** orqali o‘qib, **numbers** ro‘yxatiga qo‘shyapmiz. Shu paytda **numbers.append()** deb chaqirilayotgan funksiyaning ro‘yxat nomi bilan bog‘langan holatda ishlatilayotgani qiziqarli ko‘rinadi. Bu qanday qilib ishlayapti? **Sababi shundaki, ro‘yxatning o‘zi obyekt (Object) hisoblanadi**, shuning uchun shunday obyekt ichidagi funksiyalarni chaqirish mumkin. Ammo obyektlar haqida batafsil tushuntirish ushbu kitobning doirasidan tashqariga chiqish kerak, bu mavzuga qiziquvchilar Pythonda obyektlarni boshqarishni alohida o‘rganishlarini tavsiya qilamiz. Hozircha shuni bilib olish kifoya: ro‘yxatga yangi element qo‘shish uchun **ro‘yxat\_nomi.append(qo‘shilayotgan qiymat)** sintaksisini ishlatish kerak. 🔢 Endi 18~20-qatorlarni ko‘rib chiqamiz. Bu yerda **while** yordamida yozilgan takroriy sikl mavjud. Ammo sikl qachongacha davom etishini belgilovchi shart keltirilgan: **len(numbers) != 0**. Biz allaqachon "==" operatorining ma’nosini bilamiz. Biroq, "!=" operatorining ma’nosi nima? Bu aynan "==" operatorining aksi bo‘lib, ikki qiymat bir-biriga teng emasligini anglatadi. Shunday qilib, ushbu kodning ma’nosini tushuntiradigan bo‘lsak, **len(numbers)** funksiyasining qaytariluvchi(return) qiymati 0 ga teng bo‘lmaguncha sikl davom etadi. Endi **len** funksiyasi nima ekanligini tushunishimiz kerak. Uning ishlatilishini ko‘rib chiqamiz, bunda qiziqarli jihat bor. Funksiyaning oldida uni qaysidir joydan (masalan, biror kutubxona nomidan, ro‘yxat nomidan yoki o‘zgaruvchi nomidan) chaqirilganini ko‘rmaymiz. Bu nimani anglatadi? Ya’ni, **bu funksiya biror joyga tegishli emas, balki Python tilining ichida standart tarzda o‘rnatilgan ichki funksiya ekanligini bildiradi.** Shu sababli, bu funksiyani hech qanday maxsus ko‘rsatmalarsiz, faqat nomini yozib chaqirsa bo‘ladi, va biz bunday funksiyalarni maxsus "**ichki funksiyalar**" deb ataymiz. Shunday qilib, **len** funksiyasi ichki funksiya bo‘lib, uning vazifasini nomidan ham tushunish mumkin: **length** (uzunlik) so‘zining qisqartmasi sifatida olingan. U ma’lum bir ma’lumotning hajmini (ya’ni, uning uzunligini) qaytaradi. Shu sababdan, bu yerda **len** funksiyasiga uzatilgan ma’lumot qiymati **numbers** deb nomlangan ro‘yxatdir. Natijada, bu ro‘yxatdagi elementlar jamini ko‘rsatadi. Masalan, agar 25-qator kodi bo‘yicha foydalanuvchi ikkita sonli qiymat kiritgan bo‘lsa, len funksiyasi yordamida ro‘yxatda hozir 2 ta element borligini aniqlash mumkin. Agar foydalanuvchi uchta sonli qiymat kiritgan bo‘lsa, len funksiyasi hozirgi elementlar jamini 3 deb ko‘rsatadi. Yuqorida alohida-alohida tushunilgan ma’lumotlarni birlashtirib, ushbu kodni aniqroq talqin qiladigan bo‘lsak, _**len(numbers) != 0**_ _sharti bilan ishlaydigan_ _**while**_ _sikli, oxir-oqibat,_ _**numbers**_ _ro‘yxatida birorta ham element qolmaguncha takrorlashni bildiradi._ Foydalanuvchi o‘zi xohlagancha qiymatlarni kiritgani sari **numbers** ro‘yxati elementlar bilan to‘ldiriladi. Ammo, "qanday qilib ro‘yxatda birorta ham element qolmasligi mumkin?" degan savol paydo bo‘lishi mumkin. Bu savolning javobini esa 19~20-qatorlarni tahlil qilib topish mumkin. 🔢 19~20-qatorlarda foydalanuvchi tomonidan **numbers** ro‘yxatiga kiritilgan sonli qiymatlarini birma-bir olib, ularning yig‘indisini hisoblash uchun yozilgan kod mavjud. Yuqorida biz ro‘yxat bilan ishlashning uch xil usulini o‘rgandik (yangi qiymat qo‘shish, mavjud qiymatni o‘qish, mavjud qiymatni o‘chirish), va ulardan bittasi — yangi qiymat qo‘shishni ko‘rdik. Endi esa ro‘yxatda saqlangan qiymatlarni o‘qish usulini o‘rganish vaqti keldi. Buni aniqroq tushunish uchun avvalo, sintaksis va ro‘yxatning indeks(index) orqali murojaat qilish degan tushunchasini o‘rganish kerak. Ro‘yxatning ma’lum bir elementini o‘qish uchun quyidagi sintaksis qo‘llaniladi: > ro‘yxat\_nomi\[indeks\] Quyidagi misolda ko‘rganimizdek, ro‘yxatga element qo‘shilgan vaqtdan boshlab (ro‘yxatni aniqlash va boshlang‘ich qiymat berishda yoki yangi element qo‘shishda), Python ichki tizimi avtomatik tarzda ro‘yxat ichidagi har bir elementning tartib raqamini belgilaydi. **Bu tartib 0 dan boshlanadi va keyingi elementlar uchun birma-bir ortib boradi.** Bu indeks qiymatlari ichki tizimda mavjud bo‘lib, bizga ko‘rinmaydi, lekin ular yordamida ro‘yxat ichidagi har bir elementning qiymatini o‘qib olishimiz mumkin. ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FO7U2hRQD5QVAKGRGI3bz%252FInQ.png%3Falt%3Dmedia%26token%3D39c41eab-e08b-4c31-8420-4d0159eac7a0&width=768&dpr=3&quality=100&sign=58c8483d&sv=2) Agar biz **words** ro‘yxatidagi ikkinchi o‘rinda turgan "banana" elementini (qiymatini) o‘qimoqchi bo‘lsak, ro‘yxatdagi ma’lum bir o‘rindagi elementni o‘qish sintaksisiga muvofiq, **words\[1\]** deb yozib, uni o‘qib olishimiz mumkin. Quyidagi rasmda ko‘rsatilganidek, ro‘yxat ichidagi qiymatlar va ularning indeks qiymatlari real vaqt rejimida vizual ko‘rinishda tasvirlangan. Bizning misolimizda bajarilish natijasi ekranda ko‘rinadi: chap yuqori burchakda **numbers** ro‘yxatida 2 va 3 qiymatlari o‘sha tartibda joylashganligini ko‘rishingiz mumkin. Ya’ni, foydalanuvchi avval 2 sonini kiritgan, keyin esa 3 sonini kiritgan. ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FbslbH0TI3olKC2a1DvL6%252Flist1.PNG%3Falt%3Dmedia%26token%3D995a3c43-2656-4107-b3f8-0b0201788184&width=768&dpr=3&quality=100&sign=4bba1cbe&sv=2) 🔢 19-qatorda **numbers\[0\]** sintaksisi orqali **numbers** ro‘yxatidagi birinchi elementni o‘qib olib, uning qiymatini **result** deb nomlangan o‘zgaruvchiga saqlash vazifasi bajariladi. Keyingi, ya’ni 20-qator kodida nima sodir bo‘ladi? Bu yerda **numbers** ro‘yxati(obyekti) ichida joylashgan **numbers.pop()** funksiyasi chaqirilmoqda. Funksiyaning nomidan ham tushunish mumkinki, **pop** funksiyasi ro‘yxatdan ma’lum bir o‘rinda joylashgan qiymatni olib, uni o‘chirish uchun ishlatiladi. Ushbu funksiyani quyidagi shaklda chaqirib ishlatish mumkin: **ro‘yxat\_nomi.pop(o‘chirilishi kerak bo‘lgan elementning indeksi)**. Shunday qilib, 20-qatordagi **numbers.pop(0) ning ma’nosi** — ro‘yxatdagi birinchi elementni (indeks 0 ga ko‘ra) olib tashlashdir. Bizning misolimizda yuqoridagi bajarilish natijasida (foydalanuvchi 2 va 3 sonlarini ketma-ket kiritgan holatda) ushbu kod bajarilgandan keyin ro‘yxatdagi birinchi qiymat, ya’ni 2 ro‘yxatdan o‘chiriladi. Shu bilan birga, undan keyin turgan 3 soni avtomatik ravishda o‘chirilgan 2 ning joyiga ko‘chadi va endi birinchi o‘rinda turadi. pop(0) funksiyasi har doim joriy vaqtda ro‘yxatning oldingi (birinchi) o‘rnida joylashgan qiymatni olib tashlashni anglatadi. Yuqoridagi kodni Entry muhitida ishga tushirib ko‘ring. Uni matnda o‘qib tushunishdan ko‘ra, vizual ko‘rib tushunish osonroq. Chunki Entry ushbu jarayonlarni bosqichma-bosqich ko‘rsatib, real vaqt rejimida vizual ko‘rsatmalar orqali tushunishni osonlashtiradi. 🔢 18~20-qator kodlarini umumlashtirib qayta tahlil qiladigan bo‘lsak, **numbers** ro‘yxatida saqlanayotgan elementlarni birma-bir o‘qib, avvalgi yig‘indi qiymatiga (ya’ni, result o‘zgaruvchisiga) qo‘shish, so‘ng o‘qilgan qiymatni ro‘yxatdan o‘chirib tashlash jarayonlarini bajaradi. Ushbu jarayon, ro‘yxatda hech qanday element qolmaguncha davom ettiriladi. Bu kodning maqsadi — foydalanuvchi tomonidan kiritilgan barcha qiymatlarning yakuniy yig‘indisini hisoblashdir. Shu bilan birga, yig‘indi hisoblanayotganda ro‘yxatni tozalab, bo‘sh holatga keltirish ham amalga oshiriladi. Boshidan qaytib, bizning maqsadimiz foydalanuvchidan cheksiz ravishda sonlarni qabul qilib, ushbu kiritilgan barcha sonlarning yig‘indisini hisoblash funksiyasiga ega bo‘lgan dasturni muvaffaqiyatli yaratish edi. Bu maqsadga erishildi. Albatta, ushbu funksiyani faqat yuqoridagi usulda dasturlash kerak degan qoidalar yo‘q. Bir xil funksiyani bir necha usul bilan amalga oshirish mumkin, va hozirgi kod shulardan faqat bittasidir. Aslida, bu kod Entry-Python emas, balki original Python bo‘lganida, yanada oddiy va samaraliroq kod yozish mumkin edi. Biroq, biz Entry-Pythonning imkon bergan sintaksis chegaralari doirasida kodlashimiz kerak, va shu bilan birga sizga ro‘yxat bilan ishlashning turli usullarini ko‘rsatish maqsadida aynan shunday tarzda kod yozilganini ham inobatga oling. [Previous3.5 Takrorlash (Loop)chevron-left](https://roboticsware.gitbook.io/entry-python/boshlash/takrorlash) [Next3.7 Tasodifiy son (Random)chevron-right](https://roboticsware.gitbook.io/entry-python/boshlash/tasodifiy_son) Last updated 10 months ago --- # 3.1 "Hello World" namuna kodini tushunish | Entry-Python Agar boshqa turdagi kompyuter dasturlash tillari kitoblarini o‘qib ko‘rgan bo‘lsangiz, [ekranda "Hello World!" degan oddiy jumlani chiqaruvchi kod misoliarrow-up-right](https://en.wikipedia.org/wiki/%22Hello,_World!%22_program) bilan boshlanishini ko‘rgan bo‘lishingiz mumkin. Biz ham ushbu odatiy misol koddan boshlab, grammatikani o‘rganishni boshlaymiz. Ijro narijasi Blokli kodlash Entry-Python ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FT1lgVxmidh1wWhTUzNmY%252Fimage.png%3Falt%3Dmedia%26token%3D4222fa9c-ba8b-4538-a718-6d11a9c5eeb1&width=768&dpr=3&quality=100&sign=2e971d36&sv=2) ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FRHTUAdCEOaggpVn05cL3%252Fentry%2520FEQ.png%3Falt%3Dmedia%26token%3De560c546-b256-476e-89e1-d2800160e2d2&width=768&dpr=3&quality=100&sign=e9edd919&sv=2) Copy # Entrybot's Python code import Entry def when_start(): Entry.print("Hello World!") Kelgusida kod tahlili yuqoridagi kabi 3 ta yorliq shaklida tuziladi: birinchi yorliq kodning bajarilish natijasini ko‘rsatadi, ikkinchi va uchinchi yorliqlarda esa bir xil bajarilish natijasini olish uchun Entry-Python va blokli dasturlash shaklidagi kodlarni taqqoslash imkoniyati yaratiladi. Ushbu misolda bu juda oddiy dastur bo'lib, uni blok kodlashda faqat ikkita blok ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FnV0YwKndosTA8z3AyVmd%252Fentry%2520FEQ.png%3Falt%3Dmedia%26token%3Daf4a7e46-80a7-4194-85f4-44b5bbdd0ac7&width=300&dpr=3&quality=100&sign=6913e1a7&sv=2) bilan kodlash mumkin. Biroq, Entry-Python bilan kodlaganda, u 6 qatordan iborat uzun kodga aylanadi (kodni o'qishni yaxshilash uchun o'rtaga kiritilgan bo'sh qatorlar ham hisobga olingan). Men hozir bu misolni o'zingiz yozishingizni tavsiya etmayman. Keyinchalik kodlash uchun ko'plab imkoniyatlarga ega bo'lasiz va birinchi navbatda matnli dasturlash misoli sifatida eng oson kod deb ataladigan ushbu 6 qatorning ma'nosini aniq tushunish muhimroqdir. Shuning uchun men ushbu tarkibni hozircha blok kodlash bilan kodlashni tavsiya qilaman va keyin uni Entry-Python kodiga aylantirish uchun menyuda avtomatik kod o'zgartirish menyusini tanlang. 🔢 **1-qatordagi** "_\# Entrybot's Python code_" nimani anglatadi? **Matnli dasturlashda siz har bir belgi, hatto ba'zan bo'sh joy ham ma'no va maqsadga ega ekanligini bilasiz**. Demak, 1-qatorda birinchi bo'lib paydo bo'lgan **\#** belgisi ham ma'no va maqsadga ega ekanligini xulosa qilishimiz mumkin va uni joriy **#** belgisidan keyin yozilgan tarkibdan xulosa qilishimiz mumkin. Bu "Ushbu belgidan boshlab va undan keyin (lekin bir qator ichida) yozilgan hamma narsani izoh (comment, komentariya) deb hisoblang" degan ma'noni anglatadi. Matnli kodlashda **izoh (comment, komentariya)** degan tushunchaning ma’nosini tushunib olaylik. Kompyuter biz yozgan kodni yakuniy bajarish uchun bosqichma-bosqich o‘qib chiqadi. Ammo kodda izoh qismiga duch kelganda, uni bajarish jarayoniga hech qanday aloqasi yo‘qligi sababli uni o‘qimay, e’tibordan chetda qoldirishi kerakligi haqida bizdan “xabar” oladi. Shu bois, kompyuter ushbu qismni o‘qishdan voz kechib, uni chetlab o‘tadi. Xo‘sh, **izoh nima uchun kerak?** **Uning ikkita asosiy maqsadi bor**: birinchisi, izohning nomi o‘zi aytib turganidek, yozilgan kodni tushuntirishdir. Ya’ni, qo‘shimcha ma’lumot berish orqali keyinchalik muallifning o‘zi yoki bizning hamkasblarimiz ushbu kodni ko‘rib, uni tez va to‘g‘ri tushunishiga yordam berish uchun ishlatiladi. Ikkinchisi, kodda mantiqiy xatolarni (sintaksis xatolar emas, balki bajarilganda kutilganidek ishlamaydigan xatolarni) tuzatish jarayoni(Debugging – xatolarni topish va tuzatish jarayoni)da ishlatiladi. Bu jarayonda, kodning bir qismini vaqtincha izoh sifatida belgilab, uni bajarishdan chetda qoldirish (o'tib ketish) orqali xatoni tezroq aniqlash uchun ishlatiladi. 🔢 Endi **2-qator** tahliliga o‘tamiz. Bu qator oddiygina bo‘sh qoldirilgan. Bunday qatorlar 2- va 4-qator bo‘lib, umumiy ikki qatorni tashkil etadi. Nega bo‘sh qator kiritilgan? Sababi juda oddiy. Kompyuter uchun kodni tahlil qilishda hech qanday ahamiyatga ega emas, lekin biz, insonlar, kodni o‘qiganimizda uni yaxshiroq va tushunarliroq qilish uchun kiritiladi. Garchi hozir matnli kodlashni endigina boshlayotganimiz bois buni yaxshi anglamasakda, dasturlashning bir oz kattaroq loyihalariga o‘tganimizda, odatda yakkama-yakka emas, balki boshqa dasturchilar bilan hamkorlikda ishlashimiz kerak bo‘ladi. Shu bois, boshqa odamlar sizning kodingizni oson, tez va qulay o‘qiy olishi uchun doim e’tiborli bo‘lish odatini rivojlantirish muhimdir. Bu dasturchilar uchun zarur bo‘lgan asosiy fazilatlardan biridir. Shuning uchun kod yozishda tegishli bo‘sh qatorlardan foydalanish va tegishli joyda izoh kiritish juda muhim. 🔢 Endi **3-qatorga** o‘tamiz. Unda _**import Entry**_ degan ikki so‘z bor. Bu jumlada **import** kalit so‘zining ma’nosi – biz kod yozayotgan faylga tashqi manbadan kutubxona(Libriary, Pythonda paket(Package), undan kichikroq birlik – modul(Module) deb ataladi)ni olib kelib, undan foydalanishni bildiradi. **import** dan keyin keladigan **Entry** so‘zi esa bizga kerak bo‘lgan kutubxonaning nomi. Ushbu kodning umumiy ma’nosi shundan iboratki, **Entry** (kutubxonaning nomi kutubxona muallifi tomonidan beriladi) deb nomlangan kutubxonani tashqi manbadan chaqirib olib foydalanishimiz kerak. Endi kutubxona nima ekanligini bilib olish vaqti keldi. [hashtag](https://roboticsware.gitbook.io/entry-python/boshlash/hello_world#kutubxona-nima) Kutubxona nima? ---------------------------------------------------------------------------------------------------------------- circle-info **Kutubxona (Library):** [Dasturiy ta’minotni ishlab chiqisharrow-up-right](https://en.wikipedia.org/wiki/Software_development) da [kompyuter dasturi arrow-up-right](https://en.wikipedia.org/wiki/Computer_program) tomonidan foydalaniladigan [o'zgarmas resurslararrow-up-right](https://en.wikipedia.org/wiki/Non-volatile_memory) to'plami. Bunga konfiguratsiya ma’lumotlari, hujjatlar, yordamchi materiallar, xabarlar shablonlari, [oldindan yozilgan kodlararrow-up-right](https://en.wikipedia.org/wiki/Code_reuse) , [subrutinlar arrow-up-right](https://en.wikipedia.org/wiki/Function_(computer_programming)) (funksiyalar), [klassarrow-up-right](https://en.wikipedia.org/wiki/Class_(computer_programming)) lar, [qiymatarrow-up-right](https://en.wikipedia.org/wiki/Value_(computer_science)) lar va [ma’lumot turlariarrow-up-right](https://en.wikipedia.org/wiki/Data_type) , spetsifikatsiyasi kiradi. **Manba:** Vikipediya Yuqoridagi kutubxona ta’rifini o‘qib tushundingizmi? **Kutubxonani oddiy qilib tushuntiradigan bo‘lsak, bu dasturchilar tomonidan dasturlarni tez va qulay ishlab chiqish maqsadida oldindan yozib qo‘yilgan kodlar to‘plami (asosan funksiyalar, klasslar, o‘zgaruvchilar va boshqalar)** deb aytish mumkin. Siz allaqachon Entryda funksiyalardan foydalanib ko‘rgansiz va funksiyaning maqsadini yaxshi tushunasizmi? Funksiyaning asosiy maqsadi nima edi? Bir nechta joyda takroran ishlatiladigan kod qismlarini funksiya sifatida ajratib yozib qo‘ysak, keyinchalik ushbu funksiya blokini bir marta chaqirish orqali xohlagan vazifamizni osongina bajarishimiz mumkin bo‘ladi. Natijada kodlash jarayoni sezilarli darajada soddalashadi, kod samaradorligi oshadi va funksiyalar tufayli soddalashtirilgan kod butun dasturning tushunilishini sezilarli darajada yaxshilaydi. Bundan tashqari, **funksiyaning yanada foydali va asosiy maqsadi — yaxshi yozilgan funksiyani dasturdagi turli joylarda (bitta obyekt yoki ko‘p sonli obyektlar ichida) bir necha marta ishlatishdir (buni kodni qayta ishlatish deyishadi). Bu dastur bir marta yozilib tugatilmay, balki doimiy ravishda yangilanish va rivojlanish jarayonini boshdan kechiradigan tirik mavjudot kabi bo‘lgani sababli, keyingi o‘zgarishlarga osonlik bilan moslashishga imkon beradi.** Chunki biror funksiyani alohida bir vazifa uchun ajratib, yozib qo‘yganingizdan keyin, o‘sha funksiyaning mazmunini yaxshilash yoki o‘zgartirish kerak bo‘lsa, ushbu funksiyadan foydalanilgan barcha kodlarda o‘zgarishlar bir vaqtning o‘zida avtomatik ravishda tatbiq etiladi. Agar hozirda funksiyaning maqsadi va uning mazmunini to‘liq tushunmagan bo‘lsangiz, ehtimol siz Entry blokli kodlashda funksiyalardan foydalanib ko‘rmagan yoki funksiyaning maqsadini yaxshi tushunmasdan foydalangan bo‘lishingiz mumkin. Bu yerda funksiya haqida qayta tushuntirish bu kitobning doirasiga kirmaydi, shuning uchun kimga kerak bo'lsa [ma'lumot havolaarrow-up-right](https://ufe.gitbook.io/entry_intermediate/05-elekt-meduzadan-qoch) ni qoldiraman, ularni o‘zlari mustaqil ravishda o‘rganishlari mumkin. Agar bir yaxshi yozilgan funksiyaning qanchalik foydali ekanligini tajribada ko‘rgan bo‘lsangiz, endi shunday savol tug‘ilishi mumkin: "Bu funksiyani faqat o‘zim ishlata olishim juda achinarli emasmi? Buni barcha dasturchilar, kichikroq miqyosda mening hamkasblarim yoki butun dunyo dasturchilari ham ishlatsa, bu yanada foydali bo‘lmaydimi?" Shunday qilib, yaxshi yozilgan va foydali funksiyalarni hammaga ochiq tarzda ishlatish mumkin bo‘lgan tizim yaratildi, bu tizim _kutubxona_ (yoki paket) deb ataladi. Dasturchilar ayniqsa bunday narsalarga juda qiziqishadi. Chunki ular asosan yuqori samaradorlikka intiluvchilardir; birinchi, alohida funksiyalarni bir joyga to‘playdilar, keyin ularni yana kattaroq bir tuzilma ostida birlashtiradilar. Buni grafik ko‘rinishda tasvirlasak, quyidagicha ko‘rinadi. ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FcqUXQSKbY8CxGbcGrNVc%252Fimage%2520%281%29%2520copy.png%3Falt%3Dmedia%26token%3D082d8cc6-f3de-49c6-aa23-c1a90268b1e0&width=768&dpr=3&quality=100&sign=33d4255a&sv=2) _Kutubxona (library) tushunchasini tushuntirish uchun osonroq va mosroq taqqoslash haqida o‘ylaganimda, uning nomi bejiz tanlanmagan bo‘lsa kerak. Chunki bu aynan kitoblar bilan to‘lgan kutubxonaga o‘xshaydi. Kutubxonada ayrim alohida kitoblar mavjud (bularni modul deb tasavvur qilish mumkin), ba’zan esa ketma-ketlikdagi kitoblar to‘plamlari ham uchraydi (buni paket deb qarash mumkin). Kitobning ichida esa mazmunni tashkil etuvchi boblar, bo‘limlar, matnlar va jumlalar bor. Bu tuzilmalarni klasslar, funksiyalar va o‘zgaruvchilar bilan taqqoslash ham o‘rinli._ _Hozircha, kutubxona ichida biz uchun oldindan boshqalar tomonidan ishlab chiqilgan foydali kod to‘plamlari (asosan funksiyalar) bor, biz esa ularni olib, kodlash jarayonida foydalanamiz, deb bilib qo‘ysangiz yetarli._ 🔢 Nihoyat, biz **5-qator**ga yetdik. Buni kod tahlilining oxiri deb xisoblashingiz mumkin. Buning sababi shundaki, 5 va 6 qatorlar alohida kodlar emas, balki bitta ma'noga ega bo'lgan kodlar to'plamidir. Copy def when_start(): Entry.print("Hello World!") _**def when\_start():**_ Bu kod nimani anglatadi? Bu avval bir necha marta aytib o'tilgan funksiyani bevosita yaratuvchi koddir. Biz boshidanoq funksiyani ishlatish uchun uni tashqaridan chaqirishni o'rgandik va endi uni o'zimiz yaratishni ham o'rganyapmiz! Matnli kodlashda funksiya shu qadar muhim. Birinchidan, Python matnli dasturlashda funksiya yaratish uchun umumiy grammatikani o'rganamiz. [hashtag](https://roboticsware.gitbook.io/entry-python/boshlash/hello_world#funksiyani-qanday-yaratish-elon-qilish) Funksiyani qanday yaratish (e'lon qilish) ------------------------------------------------------------------------------------------------------------------------------------------------------------------ ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FtSKGcQgldgui3R5jZoS4%252Fimage%2520%283%29.png%3Falt%3Dmedia%26token%3D6f7b34a4-7544-4fb9-818d-186995227e96&width=768&dpr=3&quality=100&sign=7fc227b8&sv=2) Yuqoridagi standart sintaksisning har bir so‘z va belgilarining ma’nosini tushunib chiqaylik. _Funksiya yaratish uchun har doim qator boshida def ("definition"ning qisqartmasi) kalit so‘zi bilan boshlash kerak._ Bu so‘z "endi yozadigan narsalarim funksiya yaratish(e'lon qilish) jarayoni" degan ma’noni bildiradi. Keyin, yaratmoqchi bo‘lgan funksiyaga ma’noli va o‘zingizga qulay nom berish kerak. Shundan so‘ng, funksiya chaqirilganda chaqiruvchidan olinadigan qiymatlar (bular dasturlash dunyosida "parametr" deb ataladi) qavs ichida vergul (`,`) bilan ajratilgan holda yoziladi. Va nihoyat, (`:`)belgisi bilan funksiya qobig‘i tugallanganini ko‘rsatib, keyingi qatordan funksiya ichida bajarilishi kerak bo‘lgan haqiqiy kodlar yozilishi boshlanishi kerakligini bildiradi. circle-info **Funktsiyalarda parametr va argument o'rtasidagi farqlar** **Parametr** Parametrlar funksiyani e'lon qilishda foydalaniladigan o'zgaruvchilardir. Funktsiyani e'lon qilishda qavs ichida keltirilgan o'zgaruvchilardir. **Argument** Argumentlar funktsiyani chaqirishda qabul qilingan qiymatlardir. Funktsiyani chaqirishda qavs ichida berilgan haqiqiy qiymatlardir. _**def when\_start():**_ yuqoridagi standart sintaksisga yana bir bor murojaat qilib tushuntiradigan bo‘lsak, bu `when_start` nomli funksiya yaratilayotgani va bu funksiya hech qanday qiymat (parametr) qabul qilmasligini (shuning uchun qavs ichida hech narsa yo‘q) bildiradi. 🔢 Endi oxirgi, ya’ni **6-qator**ga o‘tamiz. Bu yerda funksiya chaqirilganda bajarilishi kerak bo‘lgan kod yoziladi. Qiziq tomoni shundaki, boshqa qatorlardan farqli o‘laroq, bu qator boshlanishidan oldin ma’lum miqdorda bo‘sh joy qoldiriladi (bu bo‘shliqni **Tab** tugmasini bir marta bosish yoki **Probel(spacebar)** tugmasini to‘rt marta bosib hosil qilish mumkin). Dasturlash dunyosida bo‘shliq ham ma’noga ega ekanligi haqida ilgari gaplashgan edik. Bu xuddi shunday holatlardan biri bo‘lib, Python standart sintaksisiga ko‘ra bo‘shliq maqsadli ishlatiladi. Bu nafaqat funksiyalarda, balki boshqa ko‘plab kodlarda ham qo‘llaniladi. Shu sababli, boshidanoq uni yaxshilab o‘rganib olish muhimdir. **Bu bo‘shliqning ma’nosini oddiy qilib tushuntirsak: har bir qatorda bir xil miqdorda bo‘sh joy qoldirilishi bilan, o‘sha qatorlar bir kod to'plamiga tegishli ekanligini ko‘rsatish uchun ishlatiladi.** Buni bizning kodimizga taqqoslaydigan bo‘lsak, **when\_start** funksiyasiga tegishli bo‘lgan kodning qayerdan qayergacha ekanligini kompyuterga bildirish uchun bo‘sh joy ishlatilgan. Hozir bu funksiya chaqirilganda faqat bitta qator kodni bajaradigan juda oddiy funksiya bo‘lgani sababli bu gapni tushunish qiyin bo‘lishi mumkin. Lekin kelajakda ko‘proq kodlarni bajaradigan va bajarish tarkibi uzun bo‘lgan funksiyalarni ko‘rganingizda, bu bo‘shliqning ma’nosi yanada yaqqolroq bo'ladi. Endi _**Entry.print("Hello World!")**_ kodini tahlil qilamiz. Uni qismlarga ajratsak: **Entry** — bu kutubxona nomi, undan keyin nuqta (`.`) qo‘yilgan, so‘ngra esa _**print("Hello World!")**_ yozilgan. Oldin aytganimizdek, dasturlashda nuqta (`.`) ham o‘ziga xos ma’noga ega. Agar kutubxona nomidan keyin nuqta qo‘yilsa, bu o‘sha kutubxona ichidagi narsalarni (masalan, funksiyalar, klasslar, o‘zgaruvchilar va boshqalar) ishlatishni anglatadi. Bu holda _**print("Hello World!")**_ — **Entry** kutubxonasi ichida joylashgan funksiyadir. Shu sababli, 1-qatorda import orqali olib kelingan **Entry** kutubxonasidagi **print** funksiyasini chaqirayotganimizni bildiradi. **print** nomidan xulosa qilganimizdek, u ekranga ma’lum bir qiymatni chiqarish uchun ishlatiladi. Ekranga chiqariladigan mazmun esa, `"` (qo‘shtirnoq) ichida yoziladi. Bu qo‘shtirnoqlar ekranda ko‘rsatiladigan matnning boshlanishi va tugashini aniqlab beradi. Masalan, bu kodda "Hello World!" ekranga chiqariladi. Xo‘sh~ mana shunday qilib 6 qatorlik juda oddiy dastur kodi tahlili nihoyasiga yetdi! O‘zingizni yengil his qilyapsizmi? Endi, agar siz Entry da “Boshlash” tugmasini bossangiz, o‘sha 6 qatorlik kod ishga tushadi va ekranda biz xohlagan natija, ya’ni **"Hello World!"** yozuvi paydo bo‘ladi. Hammasi yaxshi ishlaydi. Kod to‘liq tushuntirildi va muvaffaqiyatli bajarildi. Shunga qaramay, sizda nimadir yechimsiz qolayotgandek yoki qandaydir javobsiz savollar qolayotgandek tuyilishi kerak. Sizda bu his qoldimi? Agar qolmagan bo‘lsa ham, xafa bo‘lmang. Qolgan savol shundan iboratki, bizning shu 6 qatorlik kodimizda qanday qilib istalgan natijani olish mumkin? Aslida, natija chiqishi uchun kod to‘liq emas. Albatta, kodning boshqa qismi bo‘lishi kerak edi. Biz **when\_start** funksiyasini faqat e'lon qilidik, ammo uni ishlatish uchun chaqirgan kodni hech qayerda ko‘rmayapmiz. Ya'ni, **when\_start** funksiyasini kodingizda bir joyda chaqirishingiz kerak va faqat shunday qilib, chaqirilgan funksiyaning bajarilishi bilan ekranda chiqishi amalga oshadi. Biroq, bizning 6 qatorlik dasturda hech qayerda **when\_start** funksiyasini bevosita chaqiradigan kod yo‘q. Shunda, bu funksiyani kim va qanday chaqirib, qanday qilib ishga tushirdi? [hashtag](https://roboticsware.gitbook.io/entry-python/boshlash/hello_world#kolbek-callback-funksiyasi-nima) Kolbek (callback) funksiyasi nima? ---------------------------------------------------------------------------------------------------------------------------------------------------- Javobni aytadigan bo'lsak, bizning dasturimizdagi funksiyani to'g'ridan-to'g'ri chaqirmagan bo'lsak ham, bizning dasturimizdan tashqarida, ya'ni tashqi tomondan ushbu funksiya chaqirilgan. Demak, kim chaqirdi? Ha, chaqiruvchi Entry dasturini o'zidir. Entry bizning **when\_start** funksiyamizni avtomatik ravishda chaqirgan. Bu yerda umumiy ma'lumot sifatida bilish kerak bo'lgan bir atama mavjud. Agar funksiya bo‘lsa-yu, lekin uni men bevosita chaqirmasdan, tashqi tizim tomonidan biror vaqtda avtomatik tarzda chaqirilsa, bunday funksiyani kolbek (callback - so'zma so'z tarjimasi "qayta chaqirish") funksiyasi deb ataladi. Ha, **when\_start** kolbek funksiyasi edi. Bunday kolbek funksiyalarining nomini biz o'zimiz xohlagancha belgilay olmaymiz. Entry o'zi oldindan belgilab qo'ygan funksiya nomlarini ishlatishimiz kerak. Ya'ni, Entry ichida qandaydir kelishuv bor, ya'ni foydalanuvchi "Boshlash" tugmasini bosgan zahoti, Entry ichida doimo **when\_start** funksiyasini chaqirishi uchun dasturlangan. Agar bu gapga ishonmasangiz, **when\_start** nomini atayin o'zgartirib, "Boshla" tugmasini bosing. Kutgan xatti-harakat amalga oshadimi? Biz kutgandek ishlamaydi. Chunki bizning dasturimizda oldindan belgilangan va mavjud bo'lishi kerak bo'lgan o'sha **when\_start** funksiyasi yo'q. Faqatgina 6 qatorlik kichik dastur bo'lsada, matnli kodlashning ko'plab asosiy jihatlarini tushunish uchun yaxshi misol ekanligi shubhasiz. Keyingi bosqichda dasturlashning asosiy elementlarini (ketma-ketlik, takrorlash, shartlar va boshqalar) birma-bir o'rganib chiqamiz. [Previous3\. Entry-Python yordamida Python sintaksisining asoslarini o‘rganamizchevron-left](https://roboticsware.gitbook.io/entry-python/boshlash) [Next3.2 Kiritish/Chiqarish (Input/Output)chevron-right](https://roboticsware.gitbook.io/entry-python/boshlash/kiritish_chiqarish) Last updated 9 months ago --- # 5.2 Bitta gulbargdan gul yasash (Takrorlash) | Pygame Zero boshlang'ich Ushbu bob "**takrorlash**"ni o'rganish uchun Entry boshlang'ich kitobining ikkinchi misolidir. Oldingi bobda biz allaqachon Pygame Zero tomonidan taqdim etilgan obyektlardan foydalangan holda kodlashning asosiy va muhim mazmunini ko'rib chiqdik, shuning uchun qolgan misollarning kodlanishini tushunish bundan buyon unchalik qiyin bo'lmasligini kutishimiz mumkin. Shuning uchun biz faqat oldingi boblarda o'rganilmagan yangi kiritilgan kodlarga e'tibor qaratamiz, mavjud tarkibni takrorlamasdan. Copy from pgzhelper import * WIDTH = 480 HEIGHT = 270 leaf = Actor('pink_leaf', (WIDTH / 2, HEIGHT / 2), anchor=('middle', 'bottom')) leaf.scale = 0.5 def draw(): for _ in range(6): leaf.draw() leaf.angle += 60 Yangi paydo bo‘lgan kod 6-qatorida birinchi marta uchraydi va avval Actor obyektini yaratish hamda ishlatishda uchramagan **anchor** nomli xususiyat paydo bo‘ladi. Anchor so‘zining lug‘at ma’nosi kemani harakatsiz turishi uchun joyiga mahkamlovchi 'langar'ni anglatadi va shu ma’no orqali uning maqsadini taxmin qilish mumkin. To‘g‘ri javobni aytadigan bo‘lsak, **bu har bir obyektning markaziy nuqtasi bo‘lib, biz buni Entry blokli kodlashda ham ishlatgan edik, Pygame Zeroda esa bu anchor deb ataladi.** Entry dasturida ham shunday edi: **odatda Actor obyektining standart anchor qiymati rasmdagi markaziy nuqta (center) bo‘ladi.** Ammo zaruratga ko‘ra, obyektning markaziy nuqtasini ekranda ko‘rsatilganidek obyektning pastki o‘rta qismi (middle-bottom yoki bottom-middle)ga ko‘chirish mumkin. Bunday holatda, Actor obyektining anchor xususiyatiga **anchor=('middle', 'bottom')** qiymatini o‘rnatib, obyektni yaratish kifoya. Ushbu misolda, nega markaziy nuqta gultojining o‘rtasida emas, uning pastki chetida joylashishi kerakligini siz allaqachon Entry blokli kodlashda amaliyot qilib tushunganingizga ishongan holda, qisqacha tushuntiradigan bo‘lsak, gultojining qaysi qismi markaz qilib olinib, u doira bo‘ylab aylanganda butun bir gul shakllanishi markaziy nuqtaning qayta o‘rnatilishini talab qiladi. ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FWxXWAiz6baF0kMdxdEzL%252Fimage.png%3Falt%3Dmedia%26token%3D151f53ce-bbf0-4d5b-a547-72e6c09fb31b&width=768&dpr=3&quality=100&sign=454dbac&sv=2) Endi ilgari foydalanib ko‘rmagan Actor obyektining faqat bitta xususiyati qolgan, u esa 12-qatordagi **angle** xususiyatidir. Bu xususiyat, nomidan ham taxmin qilish mumkinki, obyektni burchak ostida aylantirib ekranga chiqarish uchun mo‘ljallangan. Butun gul shaklini yaratish uchun, har bir gulbargni chizishdan oldin 60 daraja aylantirib, jami 6 marta takrorlash orqali dumaloq (360 daraja) to‘liq gul hosil qilish maqsad qilingan. Lekin, diqqat qilish kerak bo‘lgan jihat shuki, quyidagi rasmda ko‘rsatilganidek, Actor obyektining aylanish yo‘nalishi soat yo‘nalishi bo‘yicha (CW: ClockWise) yoki teskari soat yo‘nalishi bo‘yicha (CCW: Counter ClockWise) ekaniga qarab, **angle** qiymati musbat yoki manfiy bo‘lishi mumkin. ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FIQSFmKFAQhRe75RTqLsx%252Fimage%2520%284%29.avif%3Falt%3Dmedia%26token%3Deb67a51c-05ac-43fb-927f-0ff3284521d8&width=768&dpr=3&quality=100&sign=ab422f65&sv=2) Agar oldingi boblarning asosiy tushunchalarini yetarlicha o'zlashtirgan bo'lsangiz, keyingi bobni tushunish qiyin bo'lmasligi kerak. Va nihoyat, keling, dasturimizni natijalarini ko'rib chiqish orqali ushbu bobni yakunlaymiz va keyin uchinchi misolga o'tamiz. ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FvawOTdYJ94upV3WbfHDO%252Fimagegg.gif%3Falt%3Dmedia%26token%3Dfbb86a0b-3633-4b6c-92cc-a9489977116c&width=768&dpr=3&quality=100&sign=eead064a&sv=2) E'tibor bering, yuqoridagi kodni ishlatganda rasmdagidek bosqichma-bosqich chizilishni ko'rmaysiz. Qadamma-qadam chizishni ko'rmoqchi bo'lganlar uchun men qo'shimcha kodni qoldiraman. E'tibor bering, Pygame Zeroning draw kolbek funksiyasi chaqirilsa ham, u ekranda ichki chizilmaydi, shuning uchun **pygame.display.update()** funksiyasi(metodi) orqali darhol chizishga majburlash uchun kod qo'llanilganligini ko'rishingiz mumkin. Faqat undan foydalanish uchun alohida tashqi kutubxona, ya'ni pygame kutubxonasini 2-qatoridek import qilish kerakligiga e'tibor bering. Copy from pgzhelper import * import pygame WIDTH = 480 HEIGHT = 270 leaf = Actor('pink_leaf', (WIDTH / 2, HEIGHT / 2), anchor=('middle', 'bottom')) leaf.scale = 0.5 def draw(): for _ in range(6): leaf.draw() pygame.display.update() game.time.sleep(0.5) leaf.angle += 60 [Previous5.1.3 Kuchuk va mushuk Salom aytadi3 (Ketma-ketlik)chevron-left](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/kuchuk-mushuk_3) [Next5.3 Robot changyutkich to'siqga duch kelsa nima bo'ladi? (Shart)chevron-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/changyutgich) Last updated 7 days ago --- # 4.1 Ketma-ket/Parallel ishlov berish (Serial/Parallel) | Entry-Python **Ketma-ket/parallel ishlov berish tushunchasi aslida dasturlash paradigmasi emas. Oddiy qilib aytganda, bu bir nechta vazifalarni ketma-ket yoki bir vaqtning o'zida ularga ishlov berish tartibida farqdir.** Ketma-ket ishlov berish (Serial processing) — kod qatorlarini birin-ketin ishlov berishni anglatadi. Bu tushuncha kompyutersiz(unplugged) kodlash ta'limida ham eng asosiy mavzu bo‘lib, aslida hammamiz yaxshi biladigan oddiy tushuncha, shuning uchun alohida tushuntirishga hojat yo‘q. Parallel ishlov berish (Parallel processing) esa kompyuter muhandisligi nazariyasida murakkabroq tushuncha bo‘lib, yangi boshlovchilar uchun tushunish qiyin bo‘lishi mumkin. Bundan tashqari, Entry-Pythonda bunday darajadagi parallel ishlov berish qo‘llab-quvvatlanmaydi, shuning uchun faqat asosiy tushunchani bilib o‘tish yetarli. **Parallel ishlov berish bir nechta vazifani bir vaqtning o‘zida** ishlov berish usuli sifatida tushuntiriladi. Bunda haqiqiy vazifalar butunlay mustaqil holda bajariladimi (Parallelism, paralellik), yoki vazifalar go‘yoki bir vaqtda bajarilayotgandek ko‘rinish hosil qiluvchi texnika (Concurrency, sinxronlik) yordamida bajariladimi, bu ikki tushunchani farqlash muhim. Entry-Python ikkinchi usulga — sinxronlikka tayanadi. Entry-Pythonda sinxronlik(concurrency) bilan bog‘liq dasturlash texnikalari (Thread(Oqimlar), Multi-processing(Ko‘p-jarayonlik) va boshqalar) qo‘llab-quvvatlanmagani sababli, bu usullardan foydalanib kod yozishni yoki sinxronlikka oid dasturlash usullarini o‘rganishni imkonsiz qiladi. Kitobning boshida ham ta'kidlanganidek, bu Entry-Pythonning cheklovidir. Shu bilan birga, Entry-Python dastlab blokli kodlashdan birinchi matnli dasturlashga o‘tganlar uchun mo‘ljallangan bo‘lib, murakkab darajadagi o‘rganish maqsad qilinmagan. Shuning uchun, asosiy tushunchalarni o‘zlashtirib, texnik tafsilotlarga chuqur kirmasdan o‘tishning o‘zi kifoya. Haqiqatan ham, bu darajadagi tushunchalar ham o‘z ahamiyatiga ega ekanligini bilish foydali bo‘ladi. Entry blokli kodlashida, quyidagi misolda ko‘rganingizdek, biz allaqachon ko‘p bor parallel ishlov berishni kodlab ko‘rganmiz. Ijro natijasi Blokli kodlash Entry-Python ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252Febcqad4SBcxmyFCDb1Ec%252Fimage.png%3Falt%3Dmedia%26token%3D23e4b211-1b64-4765-869b-502f5cf25516&width=768&dpr=3&quality=100&sign=eb156274&sv=2) ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FNa6gLoKQRR7FztQTrsAT%252Fsr.png%3Falt%3Dmedia%26token%3D0d4b3c05-56b5-4764-82be-d812af1d09ba&width=768&dpr=3&quality=100&sign=f5211013&sv=2) Copy # Changyutgich robot(1)'s Python code import Entry def when_start(): Entry.start_drawing() Entry.set_brush_color_to("#FFFFFF") Entry.set_brush_size(50) def when_start(): while True: Entry.move_to_direction(10) if Entry.is_touched("edge"): Entry.move_to_direction(-15) Entry.add_rotation(133) “Boshlash tugmasini bosganda” deb nomlangan blokni bir obyektda bir necha marta ishlatib, mustaqil ko‘rinadigan vazifalarni go‘yoki bir vaqtning o‘zida bajarilayotgandek kodlagan tajribamiz bor edi. Bu orqali biz turli dasturlashning asosiy tushunchalaridan foydalanib kelganmiz, buni o‘zimiz sezmagan holda bajargan bo‘lsak ham. Shu sababli, Entry-Pythonda parallel ishlov berish blokli kodlashda qilgan ishlarimizdan unchalik farq qilmaydi. Faqat yuqoridagi misolda ko‘rsatilganidek, **when\_start** funksiyasini bir necha marta ishlatish mumkin. Foydalanuvchi dastur ishga tushishi uchun “Boshlash” tugmasini bosganda, har bir **when\_start** funksiyasi bir vaqtning o‘zida chaqiriladi. Shu tarzda, har bir funksiyada bajarilishi kerak bo‘lgan vazifalarni mustaqil ravishda tasvirlab, ularni go‘yoki bir vaqtda bajarilayotgandek ko‘rinish hosil qilish mumkin. Bu usulni kodlashda va dasturda samarali foydalanish kifoya qiladi. [Previous4\. Entry-Python yordamida dasturlashning asosiy tushunchalarini o‘rganamizchevron-left](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma) [Next4.2 Protsessual (Procedural)chevron-right](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/procedural) Last updated 8 months ago --- # 5.5 Qo'llarni cho'zgan holda sakrashlar sonini sanang (O'zgaruvchi) | Pygame Zero boshlang'ich Entry blokli dasturlashda biz ko'pincha obyektlar animatsiyasidan foydalanganmiz. Pygame Zeroda ham xuddi shunday qilish mumkinmi? Albatta, mumkin. O'yinlardagi animatsiya odatiy holdir. Ushbu misolda biz birinchi marta Actor obyektlari animatsiyasidan foydalanamiz. Copy from pgzhelper import * WIDTH = 480 HEIGHT = 270 boy = Actor('boy_1', (WIDTH / 2, HEIGHT / 2)) boy.images = ['boy_1', 'boy_2', 'boy_3'] times = 0 pressed = False def draw(): screen.fill('white') boy.draw() game.time.sleep(0.5) screen.draw.text('Times: ' + str(times), (20, 20), color='black') def update(): global times, pressed if pressed: if boy.next_image() == 0: times += 1 pressed = False def on_mouse_down(): global pressed pressed = True 🔢 7-qatorda **images** deb nomlangan obyekt xususiyati paydo bo'ladi. Nomidan ko'rinib turibdiki, u bir nechta tasvirlar(rasmlar)ni ro'yxat(list) formatida saqlaydi va uning maqsadi obyekt tasvirlarini jonlantirishdir. Ro'yxatdagi uchta rasmlari (boy\_1, boy\_2, boy\_3) biz Entryda ko'rgan "Qo'llarini ochib yugurayotgan bola" obyektining uchta shakllari bilan bir xil. ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FU3Ncsd0YU7OxoI7rgmck%252FScreenshot%25202024-10-09%2520at%252014.13.30.png%3Falt%3Dmedia%26token%3D8ab870f4-322a-4995-b2ec-8c51b4fbe937&width=768&dpr=3&quality=100&sign=1aae2f55&sv=2) 🔢 Animatsiya haqida gapirganimizdan kelib chiqib, avval tegishli kodni ko‘rib chiqadigan bo‘lsak, Entryda animatsiya yaratish uchun uchta rasmni ketma-ket o'zgartirish orqali animatsiya yaratganimizni eslasangiz kerak. O‘shanda rasm o‘rtasidagi o‘tishni amalga oshirish uchun **"Keyingi shaklga o'zgartirish"** degan blokdan foydalangan edik, va 21-qatorda ishlatilgan **next\_image** funksiyasi aynan o‘sha blok bilan mos keladigan metod(funksiya) hisoblanadi. Biroq, bu metod Actor obyektining tashqi ko‘rinishini o‘zgartirish bilan bog‘liq bo‘lgan ekran o‘zgarishlari **update** kolbek(callback) funksiyasi ichida bajarilishi kerakligiga e’tibor bering. next\_image metodi bajarilgandan so'ng, animatsiya yoqilgan images ro'yxatidagi rasmning indeksini (joylashuv qiymati) qaytariladi. 21-qatorda **boy.next\_image() == 0** shart mavjud. Ushbu shart tasvirni almashtirishning to'liq sikli tugaganligini va animatsiya birinchi rasm (indeks 0 ga teng)ga qaytganligini tekshiradi. Shunday qilib, "qo'llarni ko'tarib sakrash" animatsiyasida uchta rasmning barchasi bajarilganligi tekshiriladi. Aynan shu vaqtda tugallangan animatsiya sikllarining umumiy sonini hisoblash uchun eng yaxshi vaqt. Ushbu umumiy miqdor **9-qatorda e'lon qilingan** _**times**_ **global o'zgaruvchisi**ga yoziladi, va o'sha yerda u to'planadi. 🔢 10-qatorda e'lon qilingan global o'zgaruvchining maqsadini tushunasizmi? Uning maqsadi animatsiyani faqat sichqoncha tugmasi bosilganda amalga oshirishdir (faqat bosilgan qiymat 27-qatorda True bo'lganda). Shuning uchun, animatsiya tugagandan so'ng, uni 23-qatorda **False** holatiga qaytarish kerak. Shundan keyingina animatsiya yana sichqoncha tugmachasini bosganda davom etishi mumkin. 🔢 Nihoyat, 16-qatorda **text** deb ataladigan metod mavjud. Bu metod **screen** obyektining ichida joylashgan **draw** obyektiga tegishli bo‘lgan metod bo‘lib, u **screen.draw.text** kabi davomiy chaqirish strukturasiga ega. Ushbu metoddan foydalanish yo‘li topshirilgan argument qiymatlaridan kelib chiqib osonlikcha tushuniladi, ya’ni ekranda qaysi joyda, qanday matn mazmunini va qanday rangda matn chiqarishni belgilash uchun qo‘llaniladi. Bu yerda ko‘rsatilayotgan qiymat, ya'ni '**Times: ' + str(times)** iborasi yangilik emas va ilgari [Entry-Python kitobiarrow-up-right](https://roboticsware.gitbook.io/entry-python/boshlash/kiritish_chiqarish) da bir necha bor qo‘llangan. Bu yerda ' + ' operatori yordamida ikki satrli qiymatlarni birlashtirib, bitta matn hosil qilinadi. O‘rtada ishlatilgan **str(times)** esa **str** deb nomlangan ichki funksiyadan foydalanilgan bo‘lib, **times** o‘zgaruvchisi sonli qiymat bo‘lgani uchun uni matnga qo‘shishdan oldin **string(satrli)** turiga o‘zgartirish kerak bo‘ladi. 🔢 Ma’lumot uchun, 15-qatordagi **game.time.sleep()** metodi ushbu ilovaning amalga oshirilishi uchun majburiy bo‘lmasa-da, qo‘l-oyoqlarni keng yozish harakati animatsiyasining juda tez o‘tib ketmasligi uchun qo‘llanilgan. Bu metod orqali harakatlarni batafsilroq kuzatish imkoniyatini yaratish maqsadida, tasvir kadrlarining orasida 0.5 soniyalik kutish vaqti qo‘shilgan. Biz oldingi boblardan oldingi bilimlarni to'plaganimiz sababli, biz yangi kiritilgan narsalarni tezda o'rganishga muvaffaq bo'ldik. Nihoyat, biz ushbu misolning bajarilishi natijalarini ko'rib chiqish orqali ushbu bobni yakunlaymiz. ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252Fnu1DEaKZNTiQwtWmnPpK%252Fimage.gif%3Falt%3Dmedia%26token%3D62628d51-2ff2-46b5-9f01-4f039486f334&width=768&dpr=3&quality=100&sign=5307acca&sv=2) [Previous5.4 O'zingizga rasm chizish taxtasini yasang (Hodisa)chevron-left](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/rasm_chizish) [Next5.6 Xazina sandig'ini ochish uchun parolni kiriting (Kiritish/Chiqarish)chevron-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/xazinani_ochish) Last updated 7 days ago --- # Mu editorining tezkor tugmalari | Pygame Zero boshlang'ich Qo'shimcha ma'lumot [shu yerarrow-up-right](https://codewith.mu/en/tutorials/1.2/shortcuts) ga kiring. [hashtag](https://roboticsware.gitbook.io/pygame_zero-entry_basic/ilova/mu_tezkor_tugmalar#windows-uchun) Windows uchun ---------------------------------------------------------------------------------------------------------------------------- Funktsiya Tezkor tugma Muning qaysi versiyalarda Indentatsiya darajasini sozlash Tab, Shift + Tab Tanlangan qatorni izoh qilish Ctrl + K Joriy qatorni tozalash Ctrl + L Izlash (so'zni) Ctrl + F Oldinga izlash F3 Orqaga izlash Shift + F3 Kodlash oynasini kattalashtirish/kichraytirish Ctrl + Shift + = , Ctrl + - Kodni boslash va to'xtatish F5 Kodni tekshirish F2 Kodlash rejimini o'zgartirish Ctrl + Shift + M Sozlamalar oynasini ochish Ctrl + Shift + D Kodlash ekranini suratga olish (skrinshot) Ctrl + Alt + S Faylni yangi nom bilan saqlash Ctrl + Shift + S Joriy tab (oyna) ni yopish Ctrl + W Maxsus 1.2.5 va keyingi Tablar orasida chapga/o'ngga ko'chirish Ctrl + , yoki Ctrl + . Maxsus 1.2.6 va keyingi [hashtag](https://roboticsware.gitbook.io/pygame_zero-entry_basic/ilova/mu_tezkor_tugmalar#mac-uchun) Mac uchun -------------------------------------------------------------------------------------------------------------------- Windows tezkor tugmalariga o'xshash, faqat Ctrl tugmasi o'rniga Command tugmasidan foydalanish kerak. [PreviousDasturimizni EXE fayliga aylantirishchevron-left](https://roboticsware.gitbook.io/pygame_zero-entry_basic/ilova/exe_fayliga) Last updated 10 months ago --- # 3.4 Shart (Condition) | Entry-Python Blok kodlashda juda ko‘p ishlatiladigan ikki xil blok mavjud: "**Agar ~ bo‘lsa**" va "**Agar ~ bo‘lsa, bo'lmasa ~**". Ularning vazifasi shundaki, bizning kodimiz ketma-ket bajarilayotganida, ma’lum bir shartga qarab, ba’zi harakatlarni bajarish yoki bajarmaslikni ta’minlashdir. Oldingi bobda yaratilgan kalkulyator dasturida foydalanuvchidan kiritilgan ikkita tasodifiy qiymatni faqat qo‘shib berishdan tashqari, foydalanuvchiga yaxshiroq foydalanish imkoniyatini yaratish uchun, faqat qo‘shish emas, balki ayirishni ham amalga oshirish va qaysi amalni bajarishni tanlash imkoniyatini foydalanuvchiga taqdim etuvchi yaxshiroq dasturga rivojlantiraylik. Shuni yodda tutish kerakki, dasturiy ta’minot yaratish bir martalik jarayon bilan tugamaydi. U doimiy ravishda rivojlanib, yaxshilanib, yangi versiyalarni chiqara boradi. Bu jarayon dasturiy ta’minotning hayot sikli (software lifecycle) deb ataladi. Ijro natijasi Blokli kodlash(1) Entry-Python(1) Blokli kodlash(2) ellipsis ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FrmNUhzCFSS8kuAZR3w1J%252F5images.png%3Falt%3Dmedia%26token%3Dc418a556-7aa9-4b78-9bd0-91fe982fd637&width=768&dpr=3&quality=100&sign=d23449bc&sv=2) ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FxHj5CGBaHh9xdD39FMv0%252FCondv1.png%3Falt%3Dmedia%26token%3Df57a5c29-c08b-4446-a839-60eac97ff0eb&width=768&dpr=3&quality=100&sign=ad5ac188&sv=2) Copy # (1)Entrybot's Python code import Entry first = 0 second = 0 def when_start(): Entry.print("Bu siz kiritgan ikkita raqamni qo'shadigan yoki ayiradigan dastur.") Entry.wait_for_sec(3) Entry.input("Iltimos, birinchi raqamni kiriting.") first = Entry.answer() Entry.input("Ikkinchi raqamni kiriting.") second = Entry.answer() Entry.input("Agar siz qo'shmoqchi bo'lsangiz, '+' kiriting va agar siz ayirmoqchi bo'lsangiz, '-' kiriting.") if Entry.answer() == "+": Entry.print("Kiritilgan ikkita raqamning yig'indisi " + (first + second) + " ga teng") if Entry.answer() == "-": Entry.print("Kiritilgan ikkita raqamning ayirmasi " + (first - second)) + " ga teng") ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252F4clmqgwEPU8J8uL8o3ne%252FCondv2.png%3Falt%3Dmedia%26token%3Defa33ffb-7764-4c45-acbf-9ad3db7652ac&width=768&dpr=3&quality=100&sign=93703fd7&sv=2) Copy # (1)Entrybot's Python code import Entry first = 0 second = 0 def when_start(): Entry.print("Bu siz kiritgan ikkita raqamni qo'shadigan yoki ayiradigan dastur.") Entry.wait_for_sec(3) Entry.input("Iltimos, birinchi raqamni kiriting.") first = Entry.answer() Entry.input("Ikkinchi raqamni kiriting.") second = Entry.answer() Entry.input("Agar siz qo'shmoqchi bo'lsangiz, '+' kiriting va agar siz ayirmoqchi bo'lsangiz, '-' kiriting.") if Entry.answer() == "+": Entry.print("Kiritilgan ikkita raqamning yig'indisi " + (first + second)) + " ga teng") else: if Entry.answer() == "-": Entry.print("Kiritilgan ikkita raqamning ayirmasi " + (first - second)) + " ga teng") Agar avvalgi dasturda 3-ta o‘zgaruvchi (first, second, result) ishlatilgan bo‘lsa, **bu safar o‘zgaruvchilar soni 2-ta (first, second) ga qisqartirildi.** Qisqartirish usuli shundan iboratki, avvalgi dasturda ikki qiymatning hisoblangan natijasi result o‘zgaruvchisiga saqlanib, keyin shu o‘zgaruvchidagi qiymat chiqarilgan bo‘lsa, bu safar hisoblash natijasi o‘zgaruvchi ishlatmasdan, bevosita **(first + second)** yoki **(first - second)** ko‘rinishida hisoblash ifodasini qavslar ichida yozilib, chiqarish funksiyasi (print funksiyasi) ichida to‘g‘ridan-to‘g‘ri hisoblash va natijani chiqarish amalga oshirildi. 🔢 17-qatorni ko‘rib chiqaylik. Foydalanuvchiga '**+**' yoki '**\-**' belgilaridan birini tanlash va kiritish imkoniyati berilganligi sababli, foydalanuvchi ushbu amallardan birini to‘g‘ri kiritadi, deb faraz qilinadi. Foydalanuvchi tanlagan amal turiga qarab, kodni boshqacha bajarish talab qilinadi. Shu sababdan **shart operatori** ishlatilgan. Python tilida shart operatorini ishlatish sintaksisi quyidagicha bo‘ladi: ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FSwxRtQgOSlHddKhyK03w%252F4space1tab1copy.png%3Falt%3Dmedia%26token%3D668765ee-67eb-4549-a2f6-6712c937b669&width=768&dpr=3&quality=100&sign=94eeb29c&sv=2) 🔢 Keling, yuqorida keltirilgan sintaksisga asoslanib 18-19 qatorlardagi kodni tushuna olamizmi. Copy if Entry.answer() == "+": Entry.print("Kiritilgan ikkita raqamning yig'indisi " + (first + second) + " ga teng") [Oldingi bob](https://roboticsware.gitbook.io/entry-python/boshlash/uzgaruvchi) da '==' belgisining (operatorining) ma’nosi tushuntirilgan edi. U chap va o‘ng tomondagi ikkita qiymatning tengligini tekshirish uchun ishlatiladigan operator bo‘lib, bu yerda foydalanuvchi kiritgan qiymatning '+' ekanligini aniqlash uchun ishlatilmoqda. Agar foydalanuvchi kiritgan qiymat '+' bo‘lsa, **if** bilan boshlangan qatordan keyingi kodlar bajariladi. Bu yerda kod yozishda e’tibor berilishi kerak bo‘lgan jihat — **biz oldingi** [**Hello World misoli**](https://roboticsware.gitbook.io/entry-python/boshlash/hello_world) **ning tahlilida ko‘rganimizdek, if shartidan keyin ataylab bo‘shliq (odatda klaviaturada bo‘sh joy(spacebar) tugmasi bilan 4 marta yoki tab tugmasi bilan 1 marta bosish orqali yaratiladi) qoldirish lozim. Har bir qatorning bir xil hajmdagi bo‘shliq bilan boshlanishi, if sharti bajarilgan holda ishga tushiriladigan kodlar to‘plamining boshlanishi va tugash joylarini aniqlash imkonini beradi.** Shuning uchun, bo‘shliqlarni to‘g‘ri va aniq kiritishni yaxshi tushunib olish kerak. 🔢 Yuqorida shart operatorining ishlatilishi to‘liq tushunarli bo‘lsa, keyingi 20~21-qator kodlarni tushunish juda oson bo‘ladi. Oxirgi masala sifatida, yuqoridagi misol kodni blokli kodlash (1 va 2) va matnli dasturlash (1 va 2) ga ajratganimizning sababini tushuntirish lozim. 1 va 2 turdagi kodlar bir xil vazifani bajaradi, ammo ularning amalga oshirilish usulida ozgina farq bor. Shu bilan birga, bitta qo‘shimcha shart operatori sintaksisini tushuntirish maqsadi bor edi. Agar biz blokli kodlashdagi "Agar ~ bo‘lsa" blokining matnli kodlashda qanday ifodalanishini o‘rgangan bo‘lsak, endi "Agar ~ bo‘lsa, bo'lmasa ~" blokining matnli dasturlashda ham mavjud ekanligini taxmin qilishimiz mumkin. Buni ishlatish sintaksisi quyidagicha bo‘ladi: ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FSEXWmG11wWCzdyhWiQTN%252Fshart%28if-else%29.png%3Falt%3Dmedia%26token%3D57b3a906-c21b-4bfb-992d-5f825cc26a9a&width=768&dpr=3&quality=100&sign=26e207ab&sv=2) Copy if Entry.answer() == "+": Entry.print("Kiritilgan ikkita raqamning yig'indisi " + (first + second) + " ga teng") else: if Entry.answer() == "-": Entry.print("Kiritilgan ikkita raqamning ayirmasi " + (first - second) + " ga teng") Ushbu kodni quyidagicha ko'rsatilgan blokli kodlash bilan taqqoslash orqali osonroq tushunish mumkin: ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FbSigHcP7Zv086UJg8wC9%252Felseblock.png%3Falt%3Dmedia%26token%3D1d2dcded-c50b-48cb-993e-3353013ceb14&width=768&dpr=3&quality=100&sign=845d598a&sv=2) Biroq, if~else~ ko‘rinishidagi matnli dasturlashda shart operatoridan foydalanishda ham oldingi kabi har bir kod qatorida bir xil bo‘shliq uzunligini saqlashga e’tibor qaratish kerak. **Blokli kodlashda shart operatorining boshlanishi va tugash joyi vizual tarzda aniq ko‘rsatilgani sababli, uni intuitiv tarzda tushunishimiz oson edi. Ammo matnli dasturlashda buni faqat matn orqali ifodalashda cheklovlar mavjud. Shu sababli, blokli kodlashda yopilgan kodlar to‘plami matnli dasturlashda har bir qatorni bir xil miqdorda bo‘shliq(identatsiya) bilan to‘g‘rilash orqali ifodalanishini tushunish lozim.** [Previous3.3 O‘zgaruvchi (Variable)chevron-left](https://roboticsware.gitbook.io/entry-python/boshlash/uzgaruvchi) [Next3.5 Takrorlash (Loop)chevron-right](https://roboticsware.gitbook.io/entry-python/boshlash/takrorlash) Last updated 9 months ago --- # 3.8 Funksiya (Function) | Entry-Python Nihoyat, endi bu bo‘limning oxirgi qismi — funksiya mavzusi qoldi. Funksiyalarni biz hozirgacha faqat kimdir biz uchun oldindan yaratib qo‘ygan funksiyalarni chaqirib ishlatib ko‘rganmiz. Ammo o‘zimizning funksiyalari(foydalanuvchi funksiyalari)mizni hali hech qachon yaratib ko‘rmaganmiz. Endi esa shu funksiyalarni o‘zimiz yozishni sinab ko‘ramiz. [3.7-bo‘lim](https://roboticsware.gitbook.io/entry-python/boshlash/tasodifiy_son) da yozgan o‘yin kodimizning ayrim qismlarini funksiya sifatida alohida amalga oshirib, xuddi shu funksionallikni qayta bajarish orqali funksiyalarni o‘rganamiz. Avval kodning qaysi qismini foydalanuvchi funksiyasi(o‘zimizning shaxsiy funksiyamiz) sifatida alohida ajratib yaratishni aniqlashimiz kerak. Masalan, foydalanuvchi kiritgan son bilan kompyuter o‘ylagan sondan farqini solishtirish qismiga e'tibor qaratamiz. Shu qismni ajratib, o‘zimizning foydalanuvchi funksiyamizni yaratamiz va ikki sonni solishtirish vazifasini shu funksiyaga topshiramiz. Ijro natijasi Blokli kodlash(foydalanuvchi funksiyasiz) ellipsis ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252F9RuPa52VOcjj1tPqzUGC%252FrandomF.png%3Falt%3Dmedia%26token%3D9f2237cf-102b-4d4a-9261-6cd983c20777&width=768&dpr=3&quality=100&sign=ea00ef48&sv=2) ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FCBcGgGGJg1Ka6iDvFERm%252Frandom.png%3Falt%3Dmedia%26token%3D2980c855-2079-419c-bc32-fc56181d9137&width=768&dpr=3&quality=100&sign=c4989d28&sv=2) Copy # (1)Entrybot's Python code import Entry com_num = 0 my_num = 0 try_total = 0 def when_start(): com_num = random.randint(1, 50) while True: Entry.input("Men 1 dan 50 gacha bo'lgan sonni o'ylab qo'ydim, uni topishga harakat qiling! Siz ularni necha martada to'g'ri topasiz?") my_num = Entry.answer() try_total += 1 if my_num == com_num: Entry.print("Bingo! " + try_total + "-urinishda topib oldingiz-ku!") Entry.stop_code("all") else: if my_num < com_num: Entry.print(my_num + " dan katta son") else: Entry.print(my_num + " dan kichik son") Entry.wait_for_sec(2) ![](https://roboticsware.gitbook.io/entry-python/~gitbook/image?url=https%3A%2F%2F3319256292-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FjJyCrnfh129pME0V24XE%252Fuploads%252FVsykIAEwD1yIWkV5ND37%252FrandomFunk.png%3Falt%3Dmedia%26token%3D0c308b99-a4c7-403b-a1d8-59de719e9c88&width=768&dpr=3&quality=100&sign=e564dfe6&sv=2) Copy # (1)Entrybot's Python code import Entry com_num = 0 my_num = 0 try_total = 0 def compare_num(num1, num2): if my_num == com_num: Entry.print("Bingo! " + try_total + "-urinishda topib oldingiz-ku!") Entry.stop_code("all") else: if my_num < com_num: Entry.print(my_num + " dan katta son") else: Entry.print(my_num + " dan kichik son") Entry.wait_for_sec(2) def when_start(): com_num = random.randint(1, 50) while True: Entry.input("Men 1 dan 50 gacha bo'lgan sonni o'ylab qo'ydim, uni topishga harakat qiling! Siz ularni necha martada to'g'ri topasiz?") my_num = Entry.answer() try_total += 1 compare_num(my_num, com_num) Biz ushbu bo‘limning [birinchi bob](https://roboticsware.gitbook.io/entry-python/boshlash/hello_world) ida funksiyalarni qanday yaratishni o‘rganganimiz sababli, agar hali funksiyalarni yaratish sintaksisini tushunishda qiyinchiliklar bo‘lsa, o‘sha bo‘limga qaytib, uni takrorlashni tavsiya qilamiz. 🔢 8~17-qatorlardagi kod [avvalgi dastur kodi](https://roboticsware.gitbook.io/entry-python/boshlash/tasodifiy_son) ning 16~24-qatorlarini ajratib, **compare\_num** deb nomlangan foydalanuvchi funksiyasini yaratishga bag‘ishlangan. Ushbu funksiya ikkita sonli qiymatlarini parametr sifatida qabul qiladi va funksiya ichida bu ikkita sonlarning kattaliklarini solishtirish natijasiga ko‘ra shartli bajarish natijasini ko‘rsatadi. Agar funksiyalarni yaratish va ulardan foydalanish usulini allaqachon o‘zlashtirgan bo‘lsangiz, bu qismni tushunishda hech qanday qiyinchilik bo‘lmaydi. Biroq, ushbu foydalanuvchi funksiyasi amalda unchalik samarali emas, chunki **funksiyaning asosiy maqsadi — dastur kodidagi turli qismlarda takrorlanadigan funksionallikni bitta funksiya orqali almashtirib, umumiy kodni soddalashtirish, shu bilan birga kodning o‘qilishiga qulaylik yaratish va keyinchalik yana qaytadan yuzaga kelishi mumkin bo‘lgan kodni tahrirlash jarayonlarini osonlashtirishdir.** Ammo hozir yaratilgan foydalanuvchi funksiyasi bu maqsadga unchalik mos emas va asosan o‘rganish maqsadida — o‘z funksiyamizni yaratib, undan foydalanishni sinab ko‘rish uchun sun’iy misol sifatida yaratilganini aytish mumkin. Bundan tashqari, **foydalanuvchi funksiyasini ko‘proq joyda ishlatish uchun imkon qadar umumiy funksionallikni amalga oshirgan ma’qul**. Masalan, hozirgidek kattalikni solishtirish + solishtirish natijasini ekranga chiqarishni birlashtirishdan ko‘ra (bunday holatda funksiya faqat muayyan kodlarda cheklangan holda foydalanish mumkin bo‘ladi), faqatgina kattalikni solishtirish funksionalligini alohida bir funksiya sifatida amalga oshirish yaxshiroq bo‘lardi. Ammo, afsuski, hozirgi Entry-Python darajasida bunday funksiyani yaratishning ba’zi cheklovlari bor (masalan, funksiyaning natija qiymatini funksiya chaqiruvchisiga qaytarish (return) funksiyasi amalga oshirilmagan). Shuning uchun bunday ko‘rinishda amalga oshirilganligini hisobga olish kerak. Bundan tashqari, yuqorida ko‘rsatilgandek funksiya yozilganidan so‘ng "Boshlash" tugmasini bosib dasturni ishga tushirib, keyin uni yopganingizda, yaqinda yozgan funksiyangizning kutilmaganda yo‘qolgandek ko‘rinishi mumkin. Aslida, ushbu funksiya avtomatik ravishda blokli kodlashning "Funksiyalar" bo‘limiga ro‘yxatdan o‘tadi va kod u yerga ko‘chiriladi. Bu holat, afsuski, Entry-Pythonda funksiya yozishda foydalanuvchi uchun chalkashliklar keltirib chiqarishi mumkin bo‘lgan jihatlardan biridir. [Previous3.7 Tasodifiy son (Random)chevron-left](https://roboticsware.gitbook.io/entry-python/boshlash/tasodifiy_son) [Next4\. Entry-Python yordamida dasturlashning asosiy tushunchalarini o‘rganamizchevron-right](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma) Last updated 10 months ago --- # 5.1.1 Kuchuk va mushuk Salom aytadi1 (Ketma-ketlik) | Pygame Zero boshlang'ich Oldingi bobda biz Entry blokli kodlash va Pygame Zeroda dasturlashning asosiy tuzilish farqini tushunib oldik. Shu asosida, Entry asosiy kitobidan yettita misolni Entry-Python emas, balki haqiqiy Python dasturlash orqali yaratib ko'ramiz. Ammo buni amalga oshirish uchun faqat Pygame Zero kutubxonasi funksional jihatdan yetarli emas. Shuning uchun qo'shimcha foydalanuvchi kutubxonasi kerak bo'ladi, va biz ushbu foydalanuvchi **pgzhelper kutubxonasi** (user library, ya'ni odatda oldindan o'rnatilmagan va ehtiyojga ko'ra foydalanuvchi tomonidan yaratilgan kutubxona) chaqirishdan boshlaymiz. circle-info pgzhelper birinchi bo'lib **Cort**, Singapurdagi dasturchi, Scratch blokli kodlashni Pygame Zeroga o'tkazishda(porting) Pygame Zero cheklovlari tufayli yuzaga kelgan qiyinchiliklarni(o'xshash funksiyalarni bajarishni) yaxshilash uchun yaratgan. Shunga o'xshash sabablarga ko'ra [Roboticsware arrow-up-right](https://roboticsware.uz/) ham Pygame Zeroga Entry bloklarini python kodga aylantirishni osonlashtirish uchun mavjud kutubxonaning funksiyalarini to'ldirdi va buni ochiq kodlar GitHub sayti ( [https://github.com/roboticsware/pgzhelper arrow-up-right](https://github.com/roboticsware/pgzhelper) ) orqali ommaga tarqatmoqda. Copy from pgzhelper import * Kodning birinchi qatori pgzhelper kutubxonasini chaqiradigan qismdir. Kutubxonani chaqirishning ikki asosiy usuli mavjud. Odatda siz _import pgzhelper_ deb ishlatishga odatlangan bo'lsangiz kerak, lekin bu holda kutubxonani yangi sintaksis yordamida chaqirish kerak bo'ladi. > **from** kutubxona nomi **import** \* Uni shunday chaqirishning afzalligi **avval siz kutubxona ichidagi funksiyani chaqirish uchun doimo <> sintaksisidan foydalanishingiz kerak bo'lgan bo'lsa, endi siz uni avvalgidek, xuddi shu tarzda ishlatishingiz mumkin, faqat funksiya nomi yordamida, old tomonda kutubxona nomi ko'rsatmasdan.** ### [hashtag](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/kuchuk-mushuk_1#entry-koordinatalari-tizimi-va-pygame-koordinatalari-tizimini-taqqoslash) Entry koordinatalari tizimi va Pygame koordinatalari tizimini taqqoslash Biz yaxshi bilganimizdek, Entrydagi koordinatalar tizimi quyidagi chapdagi rasmda ko'rsatilgan va uning xususiyati shundaki, ekranning belgilangan o‘lchami (kengligi 480 piksel, balandligi 270 piksel) bor va ekranning markazi x va y koordinatalarining boshlanish nuqtasi (0, 0) hisoblanadi. Boshqa tomondan, **Pygame koordinatalar tizimida ekranning umumiy o'lchamini foydalanuvchi o'zi belgilashi mumkin, ammo bu holda koordinatalarning boshlanish nuqtasi (0, 0) yuqori chap burchakda joylashgan bo'ladi va o'ngga va pastga qarab qiymatlar oshib boradi.** Entry Pygame ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FxgMCTNpSYx5deeuhpDtb%252Fimage.png%3Falt%3Dmedia%26token%3Dec614ab8-1e92-4bc6-8adc-31bb3773d53b&width=300&dpr=3&quality=100&sign=610f88dc&sv=2) ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252F8SBeH7mb76ZAzbqoCQy7%252Fimage.png%3Falt%3Dmedia%26token%3D9c4456d0-1cbd-4765-abdc-f1b52743b622&width=300&dpr=3&quality=100&sign=e8d66616&sv=2) Keling, hozircha Entryning natijalar ekrani hajmini taqlid qilaylik. Shuning uchun ekranning kengligi va balandligi mos ravishda 480 va 270 pikselni tashkil qiladi va shunga asoslanib, kod quyidagicha bo'ladi: Copy from pgzhelper import * TITLE = 'Kuchuk va Mushuk salom aytadi' WIDTH = 480 HEIGHT = 270 O‘yinda alohida fon rasmi mavjud emas. Entryda fon rangi avtomatik ravishda oq rangda bo‘ladi, ammo Pygame Zeroda bu avtomatik ravishda bo‘lib o‘tmaydi. Shuning uchun, bizning ehtiyojimizga ko‘ra fonni oq rangda bo‘yash kerak bo‘ladi. Buni kodlashning uchta usuli mavjud: #### [hashtag](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/kuchuk-mushuk_1#oldindan-belgilangan-rang-qiymati-kalit-sozlari-yordamida-kodlash) Oldindan belgilangan rang qiymati kalit so'zlari yordamida kodlash Copy def draw(): screen.fill('white') _**draw**_ _funksiyasi oldingi bobda ko'rganimizdek, Pygame Zero o'yin siklida mavjud bo'lgan oldindan belgilangan kolbek funksiyasi._ Ekranda biror narsa chizmoqchi bo'lganimizda, u avtomatik ravishda chaqiriladi. Ekranni rangga to'dirish uchun kod ushbu funksiya ichida yozilishi kerak va ekranni to'ldirish uchun biz oq rangni [argumentarrow-up-right](https://roboticsware.gitbook.io/entry-python/boshlash/hello_world#funksiyani-qanday-yaratish-tariflash) sifatida o'tkazib, **fill** deb nomlangan funksiyadan foydalanamiz. **fill** funksiyasi "**screen.**" yordamida chaqiriladi, chunki **fill** funksiyasi Pygame Zero kutubxonasining **screen** obyektida mavjud. Obyektlar haqida keyingi bobda batafsil yoritilganligi sababli, hozircha yetarli. **Ekranni to'ldirish uchun rang qiymatini o'tkazishning uchta usuli mavjud. Ulardan biri til o'rnatilgan kalit so'zlar kabi oldindan belgilangan qiymatlardan foydalanish, ikkinchisi esa RGB (Red / Green / Blue) vakolatxonasidan foydalanishdir.** Oldindan belgilangan rang kalit so'zlarini quyidagi rang qiymatlari jadvalida topish mumkin. ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FKCH9bNn4FjrTYy0y7zot%252Fimage.png%3Falt%3Dmedia%26token%3Dba4b918c-bba3-491f-b0dd-be3e9ca4c460&width=768&dpr=3&quality=100&sign=f4ab75b8&sv=2) Keyin rangni RGBning uchta asosiy rangi (qizil, yashil, ko'k) kombinatsiyasi orqali ifodalash mumkin, bu yerda har bir asosiy rang maksimal qiymati 256 tadir. Istalgan rangni ifodalash uchun har bir asosiy rangni o'nlik (0 dan 255 gacha) yoki o'n oltili (00 dan FF gacha) sanoq sistemasida ifodalash usullari mavjud. ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FtkGyJBWJPdjDg5GuPzPV%252Fimage.png%3Falt%3Dmedia%26token%3Db9107785-0238-40b2-9fa5-31e6e27cc2fd&width=300&dpr=3&quality=100&sign=362220e1&sv=2) ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FHwLalnThNZJijP30gQxi%252Fimage.png%3Falt%3Dmedia%26token%3D2c84c00e-49dc-44a8-a1db-b6733269b0e6&width=768&dpr=3&quality=100&sign=dc067435&sv=2) ### [hashtag](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/kuchuk-mushuk_1#rgb-rang-qiymatlarining-onlik-korinishida-oq-rangni-kodlash) RGB rang qiymatlarining o'nlik ko'rinishida oq rangni kodlash Copy def draw(): screen.fill((255, 255, 255)) ### [hashtag](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/kuchuk-mushuk_1#rgb-rang-qiymatlarining-on-oltilik-tizimdagi-korinishida-oq-rangni-kodlash) RGB rang qiymatlarining o'n oltilik tizimdagi ko'rinishida oq rangni kodlash Copy def draw(): screen.fill('#FFFFFF') Ranglarning ifodasiga kelsak, internetda juda ko'p manbalar mavjud, shuning uchun har bir kishi ushbu materiallar bilan to'g'ridan-to'g'ri tanishib chiqishi yaxshiroqdir. Ma'lumot uchun, nega ranglarni ifodalash uchun RGBning uchta asosiy ranglari ishlatilishi haqida mana bu [havolaarrow-up-right](https://en.wikipedia.org/wiki/RGB_color_model) dan tekshiring. Keling, shu vaqtgacha yozilgan kodni ishga tushirib, u kutilganidek ishlashini tekshirib ko‘raylik. Ishga tushirish uchun avvalo dastur kodini faylga saqlash kerak. Dastur kodlari (manba kodlar) saqlanishi lozim bo‘lgan asosiy joy — bu _**\[foydalanuvchi nomi\]\\mu\_code**_**\\** (quyidagi rasmga qarang). ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FDCQXdHAX1GPx65bs5eRN%252Fimage.png%3Falt%3Dmedia%26token%3D673df903-a48f-4f46-80c3-0b3a256e04a4&width=768&dpr=3&quality=100&sign=76a01c8a&sv=2) circle-info _**Yozilgan dastur kodini saqlaganda, saqlash joyi, albatta, qat’iy belgilanmagan bo‘lib, foydalanuvchi uni istagan joyiga saqlashi mumkin. Biroq, ushbu kitobdagi misol amaliyotlarini bajarishda kerak bo‘ladigan resurslar (rasmlar, fontlar, effekt ovozlari, fon musiqasi)dan foydalanish uchun fayllarni yuqorida aytib o'tilgan Mu editorining asosiy kod saqlash joyi (\[foydalanuvchi nomi\]\\mu\_code\\)ga saqlashingizni so‘raymiz.**_ Nega bunday qilish kerakligi haqida keyingi qismlarda batafsil tushuntiriladi. Dastur kodini saqlab bo‘lganingizdan so‘ng, endi F5 tugmasi (Ishga tushirishning tezkor tugumasi)ni bosib, uni ishga tushiring. Ekran oq rang bilan to‘g‘ri bo‘yalgan bo‘ladi. Ekran rangini yuqorida o‘rgangan uchta usulni qo‘llab o‘zgartirib ko‘rish sizga amaliyot uchun topshiriq sifatida qoldiriladi. Copy from pgzhelper import * TITLE = 'Kuchuk va mushuk Salom aytadi' WIDTH = 480 HEIGHT = 270 def draw(): screen.fill('white') Endi keyingi qadam — o‘yin qahramonlari bo‘lgan «Kuchukcha» va «Mushukcha» obyektlarini chaqirib, ularni ekranga joylashtirishdir. Buni kodlash uchun har bir obyektning tashqi ko‘rinishini ifodalovchi rasm fayllari kerak bo‘ladi. Entry blokli kodlashdagi tajribangizni eslang. O‘yinni yaratishda birinchi qilgan ishingiz nima edi? Ehtimol, siz o‘yinda ishtirok etadigan obyektlarni ekranga joylashtirish bilan boshlagansiz. Matnli dasturlashda ham shunga o‘xshash. Biz ham qahramon obyektlarini ekranga chiqarishdan boshlaymiz. ### [hashtag](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/kuchuk-mushuk_1#pygame-zeroda-resurlarni-boshqarish) **Pygame Zeroda resurlarni boshqarish** Biroq, Entryda bo‘lgani kabi, agar o‘yinda foydalaniladigan obyektlar dasturga oldindan kiritilmagan bo‘lsa, o‘yin uchun kerak bo‘lgan rasm fayllarini kiritib, keyin kodlashni boshlashingiz kerak edi. Xuddi shunday, agar kodlashda foydalaniladigan rasmlar oldindan kiritilgan rasmlar bo‘lmasa, ularni alohida saqlash kerak bo‘ladi. Saqlash yo‘li — bu Mu editori o‘rnatilganda avtomatik ravishda yaratiladigan _**\[foydalanuvchi nomi\]\\mu\_code\\images**_ papkasi(direktoriyasi) va rasmlar shu papkada joylashishi kerak bo‘ladi. Ushbu papkaning joylashuvini osongina topmoqchi bo‘lsangiz, Mu editoridagi menyu panelidagi **"Rasmlar" tugmasi**ni bosing. Bu tugma siz foydalanayotgan rasmlar saqlangan papkani darhol ochib beradi. Papka ichida ushbu kitobda foydalaniladigan rasmlar sizning qulayligingiz uchun oldindan saqlanganini ko‘rishingiz mumkin. Manba kodini asosiy saqlash joyiga saqlashingizni so‘raganimizning sababi, biz ushbu oldindan saqlangan rasmlardan foydalanib, qo‘shimcha resurslar bilan bog‘liq ishlarni chetlab o‘tib, faqat kodlashga e'tibor qaratishingiz uchun edi. ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FnkTv0kA73WfSiQpRzFu2%252FScreenshot%25202024-10-21%2520at%252016.28.41.png%3Falt%3Dmedia%26token%3Dd370d946-398d-4cd4-b7d9-6a6718de5e94&width=768&dpr=3&quality=100&sign=a1e8b09d&sv=2) ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FzRq6EIK2Gwe2DUpSOjYC%252Fimageaa.avif%3Falt%3Dmedia%26token%3Dad88ebe9-1db7-42a6-89fa-2f4b101a3da2&width=768&dpr=3&quality=100&sign=dcaf5440&sv=2) circle-info Aytgancha, **o'yinni dasturlashda zarur bo'lgan resurslarni (rasmlar, fontlar, ovoz effektlari, fon musiqasi) saqlaydigan papkalarni yaratish uchun siz Pygame Zero kutubxonasining asosiy cheklovlarida o'rnatilgan ushbu pastki papkalar uchun oldindan belgilangan nomlarga (tartibda: images(rasmlar), fonts(fontlar), sounds(effektlar), music(ovozlar)) rioya qilishingiz kerak**. Ushbu muvofiqlik Mu editorining menyu panelidagi tugmalarining nomlari aytib o'tilgan papkalarning nomlariga mos kelishi bilan bog'liq. Shuning uchun, tegishli tugmalarni bosish orqali resurs turiga mos papkalarni avtomatik ravishda ochishga qaratilgan dasturlash, resurslarni topa olmaslik bilan bog'liq ish vaqtida xatolar ehtimolini kamaytiradigan qulay usuldir. Shunga tegishli Mu editorning qo'llanmasiga qarang: [https://codewith.mu/en/howto/1.2/pgzero\_sounds\_imagesarrow-up-right](https://codewith.mu/en/howto/1.2/pgzero_sounds_images) Keyingi keltiriladigan ma’lumotlar siz bilishingiz kerak bo'lgani uchun berilgan. Biz foydalanayotgan maxsus Mu Editori holatida, kodlashda kerak bo‘ladigan barcha resurslar (rasmlar, ovozlar va hokazo) sizga qulay bo'lish uchun oldindan kiritib qo‘yilgan, shuning uchun bunday qo‘shimcha ishlar talab qilinmaydi. Biroq, bu qism Entryda har bir obyektning rasmlarini qanday olib kirish mumkinligi bilan qiziqadiganlar uchun qo‘shimcha tushuntirishdir. ### [hashtag](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/kuchuk-mushuk_1#entrydan-rasm-obyektining-rasmini-olib-kirish) Entrydan rasm obyektining rasmini olib kirish Entrydagi "kuchuk" va "mushuk" obyektlarining rasmlaridan foydalanish uchun Entryni oching va kerakli obyektlarning rasmlarni fayl sifatida saqlab olsangiz bo'ladi. Rasmni olish uchun "shakl" yorlig'ini bosing, olmoqchi bo'lgan shaklni sichqonchaning o'ng tugmasi bilan bosing va paydo bo'lgan menyudan "kompyuterga yuklab olish"ni tanlang. Uni Pygame Zero uchun yuqorida aytib o'tilgan "images" papkasiga saqlang. ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252F4LSmrhHGlAtKW674b1mm%252FScreenshot%25202024-03-20%2520at%252012.14.25.png%3Falt%3Dmedia%26token%3D13e457b8-e313-4432-b7e7-f95277fbcb07&width=768&dpr=3&quality=100&sign=196731f1&sv=2) circle-info Ushbu kitobdagi misollar uchun zarur bo'lgan barcha rasmlarni [bu yerarrow-up-right](https://github.com/roboticsware/python-pygame_zero-samples/tree/main/entry_basic/images_ko) dan yuklab olishingiz ham mumkin. Endi har bir obyektni («Kuchukcha» va «Mushukcha») ekranda aks ettirishga o‘tamiz va keyingi bo‘limda ularning o‘zaro salomlashishini kodlashni yakunlaymiz. [Previous5\. Entry boshlang'ich darajali kitobini kodlashchevron-left](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash) [Next5.1.2 Kuchuk va mushuk Salom aytadi2 (Ketma-ketlik)chevron-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/kuchuk-mushuk_2) Last updated 1 day ago --- # 5.6 Xazina sandig'ini ochish uchun parolni kiriting (Kiritish/Chiqarish) | Pygame Zero boshlang'ich Biz o‘tgan boblarda sichqoncha orqali kiritish (click(bosish), drag(harakatlantirish) va boshqalar) haqida yetarlicha tajriba orttirdik. Bu bobda, mavzuga mos ravishda, klaviatura orqali kiritishni boshqarishni birinchi marta ko‘rib chiqamiz va o‘yin qiziqarliroq bo‘lishi uchun ovoz effektlari fayllarini ishlatib, ovozni qanday chiqarishni ham o‘rganamiz. Ma'lumotingiz uchun, Entryda klaviatura kiritishida alohida kiritish oynasi orqali kerakli tarkiblarni kiritib yakuniy kiritishini belgilash uchun Enter tugmasini bosish orqali amalga oshiriladi, lekin Pygame Zeroda esa klaviaturadagi har bir bosish(hodisalar)da chaqiriladigan kolbek funksiyasi orqali kiritilgan tarkibni darhol yig'adi. Boshqacha qilib aytganda, u [hodisaga asoslangan paradigmadarrow-up-right](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/event-driven) an foydalanib dasturlash qilinadi. Siz avvalgi 5 ta misolni muvaffaqiyatli bajarganingiz sababli, endi sizni Pygame Zeroda endigina boshlovchi deb atash qiyin. Qolgan 2 ta misol ustida ishlash jarayonida, avvalo, kodning pastki qismidagi tushuntirishlarni ko‘rmasdan oldin, butun kodni ko‘zdan kechirish orqali tushunishga harakat qiling. Shundan keyin kod tushuntirishlariga e’tibor berib sinab ko‘ring. Bu kabi o‘rganish usuli sizning mahoratingizni oshirishning samarali yo‘lidir. Sizga ma’lumki, tezkor javoblar hech qachon bizning fikrlarimizni rivojlantirish imkoniyatini bermaydi. Copy import pygame from pgzhelper import * WIDTH = 960 HEIGHT = 540 treasure = Actor("treasure_box", (WIDTH / 2, HEIGHT / 2)) treasure.images = ["treasure_box", "treasure_box_o"] input_text = "" input_done = False input_rect = Rect(350, 450, 200, 50) guide_rect = Rect(300, 50, 400, 50) password = "1234" def draw(): screen.blit("desert", (0, 0)) treasure.draw() # Tavsif matn maydoni screen.draw.filled_rect(guide_rect, 'black') if input_done: if input_text == password: screen.draw.textbox("Xazina sizniki!", guide_rect) else: screen.draw.textbox("Parol noto'g'ri!", guide_rect) pygame.display.update() game.exit() else: screen.draw.textbox("Iltimos, parolni kiriting.", guide_rect) # Kiritish matn maydoni screen.draw.filled_rect(input_rect, "pink") screen.draw.textbox(input_text, input_rect) def update(): if input_done: if input_text == password: treasure.sel_image("treasure_box_o") sounds.cheer.play() else: sounds.warning.play() def on_key_down(key, unicode): global input_text, input_done if key == keys.RETURN: input_done = True elif key == keys.BACKSPACE: input_text = input_text[:-1] else: input_text += unicode 🔢 Keling, avval ushbu kodda bir necha marta ishlatilgan Rect haqida bilib olaylik. Nomining bosh harfi katta harf bilan boshlanishidan, Rect obyekt ekanini bilib olish mumkin. **Rect - bu Rectangle (to'rtburchak) so'zining qisqartmasi va u to'rtburchak shaklidagi maydonni ushlab turuvchi obyekt** bo'lib, o'yin sahnasida paydo bo'ladigan ko'pchilik obyektlar asosan to'rtburchak shaklida bo'lgani uchun Rect ishlatish keng tarqalgan. _Uni yaratish uchun 4 ta qiymat (left(chap), top(yuqor), width(kenglik), height(balanlik)) kerak bo'ladi. Birinchi ikkita qiymat (left, top) - bu to'rtburchakning ekranda qayerdan boshlanishini ko'rsatuvchi yuqori chap burchak koordinatalari, oxirgi ikkita qiymat (width, height) esa to'rtburchakning kengligi va balandligi bo'lib, ular bu maydonning o‘lchamini belgilaydi._ ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FUkMgWUMS4RZBIgtiJAAr%252Fimage%2520%283%29.avif%3Falt%3Dmedia%26token%3D19d5308b-5f20-4b32-8d1f-b15e5d9cb529&width=768&dpr=3&quality=100&sign=52ae53ed&sv=2) Biz bu misolni ilgari Entry orqali yaratib ko'rganimiz uchun, ushbu misolda foydalanuvchi bilan matn orqali aloqa borligini bilamiz. Xazina sandig'ini ochish uchun parol kiritish talab qilinadi va kiritilgan parol to'g'ri yoki noto'g'riligiga qarab, yakunda xazinani olganingiz yoki yo'qmi ovoz va matn bilan ko'rsatiladi. Shunday qilib, biz ushbu misolda ikkita Rect kerakligini anglaymiz: biri foydalanuvchidan parolni kiritishni qabul qiladigan to'rtburchakli kiritish maydoni (**input\_rect**), ikkinchisi esa foydalanuvchiga nima qilish kerakligini yoki natijani ko'rsatadigan matn maydoni (**guide\_rect**) sifatida ishlatiladi. 🔢 11-qatordagi **input\_done** o'zgaruvchisi flag(bayroq) o'zgaruvchisi bo'lib, pastdagi eslatmalarda aytilgan. U True(rost) yoki False(yolg'on) qiymatlaridan birini qabul qiladi. circle-info Flag o'zgaruvchisi: dasturlashda kodlar orasidagi holatni ko'rsatish uchun ishlatiladigan "True yoki False" yoki "0 yoki 1" ikkilik qiymati (boolean)ga ega o'zgaruvchi. Malumot: Wikipedia ([https://en.wikipedia.org/wiki/Flag\_(programming)arrow-up-right](https://en.wikipedia.org/wiki/Flag_(programming)) ) Aslida flag(bayroq) o'zgaruvchisi birinchi marta paydo bo'layotgani yo'q, u 5.4-bo'limdagi misollardan boshlab doim ishlatilgan. Uni asosan kiritish qurilmalari, masalan, sichqoncha va klaviatura yordamida kiritish tugagan paytni aniqlash uchun ishlatishadi. Qachon input\_done True(rost) qiymatiga ega bo'ladi? Bu ma'lumot 54-qatorda saqlanadi, parol raqamlari kiritilgandan so'ng **Enter** tugmasi bosilib, parol kiritish tugaganida **draw** funksiyasida 24-qatorda input\_done qiymati True bo'lganda parol to‘g‘ri yoki noto‘g‘ri kiritilgani aniqlanadi. _Odatda flag o‘zgaruvchilarini ko‘p ishlatadigan kod yozish uslubi tavsiya etilmaydi, chunki bu kodning murakkabligini oshiradi va kodga texnik xizmat ko'rsatish qiyinlashadi. Ammo Pygame Zero kabi katta o‘yin sikli (game loop) va kolbekcallback) funksiyalariga asoslangan strukturalarda ularni ishlatishning muqarrar tomoni borligini tushunish foydali bo‘lishi mumkin._ 🔢 26, 28, 33-qatorlarda ishlatilgan **screen.draw.textbox** metodiga nazar solaylik. Ilgari ko'rganimiz **screen.draw.text** metodidan unchalik farq qilmaydi. Metod chaqirilganda ishlatilgan argumentlarni solishtirsak, matn chiqarilishi kerak bo'lgan joy Rect orqali berilmoqda. **text** metodida faqat matnning joylashuvini belgilash kerak bo'lsa, **textbox** metodida esa chiqarish maydoni belgilanadi. _Agar Rect bilan belgilansa, u holda maydondan chiqmasdan matn maksimal kattalikda chiqariladi._ Chiqarish maydonining hajmi doimiy bo‘lishi bizning maqsadimizga mos keladi, chunki ushbu maydonda matnning mazmuni doimiy ravishda o'zgarib turadi. Bunday holatda yangi matn yozishdan oldin eski matnni o'chirish kerak bo'ladi va maydonning doimiy bo‘lishi o‘chirishni osonlashtiradi. Agar maydon o‘zgaruvchan bo‘lsa, uni har safar eslab qolish va boshqarish kerak bo‘ladi. Shuningdek, **screen.draw.filled\_rect** metodidan foydalanib, Rectga fon rangini berishimiz matnni aniqroq ko‘rinishiga yordam beradi va avvalgi matnni o‘chiradi. Ekranda ko‘rsatiladigan matnlar uchta asosiy holatni ifodalaydi: 33-qatorda parol kiritishdan oldingi holat, 26 va 28-qatorlarda esa parolning to‘g‘ri yoki noto‘g‘riligiga bog‘liq bo‘lgan natija. Parol kiritilishi tugagandan so‘ng, 30-qatorda ishlatilgan **pygame.display.update()** metodi orqali natija darhol ekranga chiqariladi va **game.exit()** metodi bilan o‘yin tugatiladi, va shu bilan Pygame dasturi tugaydi. 🔢 Agar parol kiritilishi muvaffaqiyatli bo‘lsa, xazina sandig‘i ochilgan tasviriga o'zgarishi kerak. Bunday holda, Actor obyektining tashqi ko‘rinishini o‘zgartirish va ovozli effektni chiqarish kabi jarayonlar **update()** kolbek funksiyasi ichida amalga oshirilishi kerakligini yodda tuting. [Oldingi bob](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/sakrashni_sanash) da Actor obyektining tashqi ko‘rinishi bir nechta rasmdan tashkil topganida, rasmlarni almashtirish uchun **next\_image** metodidan foydalangan edik. Biroq, bu safar 43-qatorda ma'lum bir rasmlarni to‘g‘ridan-to‘g‘ri almashtirish uchun **sel\_image** metodidan foydalanildi. O'yinda ovoz effektlaridan foydalanish foydalanuvchini jalb qilish va o'yin qiziqarligini oshirish uchun deyarli ajralmas deb aytish mumkin. Uni ishlatish qiyin emas. 45 va 47-qatorlardagi kabi **sounds.ovoz\_fayl\_nomi.play** metodi orqali chaqiriladi. Ovoz effektlari o'yinda ishlatiladigan resurslar (rasmlar, fontlar, ovozlar va hokazo) qatoriga kiradi va avvalgi resurslar kabi boshqariladi, lekin ovoz fayli oldindan **sounds** nomli papkada saqlangan bo'lishi kerak. Ovoz fayllari barcha fayl formatlarini qo'llab-quvvatlamaydi, faqat **wav** va **ogg** formatlaridan foydalanishni unutmang. _Ovozlar ikkita bo'limga bo'linadi: o'yindagi muayyan hodisalar uchun ishlatiladigan ovoz effektlari va butun o'yin davomida yangraydigan fon musiqasiga bo'linadi. Fon musiqasini ijro etish uchun_ _**Pygame Zero**_ _tomonidan taqdim etilgan_ _**Music**_ _obyektidan foydalanish mumkin. Undan qanday foydalanishni_ [_kutubxona qo'llanmasi_arrow-up-right](https://pygame-zero.readthedocs.io/en/stable/builtins.html#music) _dan o'rganish tavsiya etiladi._ 🔢 Nihoyat, 50-qatordagi har safar klaviatura tugmasi bosilganda ishlaydigan **on\_key\_down** kolbek funksiyasini ko'rib chiqamiz. Klaviatura tugmachasi bosilganida, key va unicode qiymatlari uzatiladi. **key** qaysi tugma bosilganligini aniqlash uchun ishlatiladi, **unicode** esa maxsus tugma (Ctrl, Shift, Esc) emas, balki harflar yoki raqamlar bo'lsa, bu qiymatni oladi. 58-qatordagi **input\_text += unicode** kodi klaviaturada bosilgan qiymatni **input\_text** o'zgaruvchisiga qo'shib boradi. Agar foydalanuvchi parolni noto‘g‘ri kiritgan bo‘lsa, u **Backspace** tugmasini bosib o‘chira oladi. Bu 55 , 56-qatorlarda amalga oshirilgan. 56-qatordagi **input\_text\[:-1\]** sintaksisi Python tilining qulay **slicing** (kesish)sintaksislaridan biri bo'lib, boshqa tillarda bu odatda mavjud emas. -1 qiymati **input\_text** satrli qiymatining oxirgi belgisi tashlab yuborilishini bildiradi va shu tariqa oxirgi belgi o‘chiriladi. Slicing juda foydali bo'lsada, agar bu mavzu haqida batafsil yozsam, bu mavzu ancha uzunlashib ketadi, shuning uchun yaxshisi internetdagi yaxshi manbalarni o'rganishni tavsiya qilamiz. 6-misolning natijasini tekshirib chiqqanimizdan so‘ng, kitobning so‘nggi, 7-misoliga o‘tamiz. ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252F31N1DZVOdjqGb9dgLfgq%252Fezgif-6-731cb19a92.gif%3Falt%3Dmedia%26token%3D9691ce2d-0c72-4bee-b3e3-af71b9d968ba&width=768&dpr=3&quality=100&sign=b8c18a34&sv=2) [Previous5.5 Qo'llarni cho'zgan holda sakrashlar sonini sanang (O'zgaruvchi)chevron-left](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/sakrashni_sanash) [Next5.7 Ko'rsichqon o'yini yasash (Jamlash)chevron-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/korsichqon_oyini) Last updated 7 days ago --- # 5.7 Ko'rsichqon o'yini yasash (Jamlash) | Pygame Zero boshlang'ich Va nihoyat, sizni ushbu kitobning so‘nggi misoliga yetib kelganingiz bilan sizni tabriklayman. Oldingi misollarni muvaffaqiyatli o‘zlashtirib, shu bosqichga yetib kelganingizda, Python kodlashning zavqini ham asta-sekin his qila boshlagan bo‘lsangiz kerak. Kutilganidan ko‘ra matnli kodlash juda qiyin yoki zerikarli bo‘lmaganiga ishonaman. Agar shunday bo'lsa, siz bu kitobning asosiy maqsadi bo‘lgan matnli kodlash olamiga kirish vazifasini to‘liq bajardim deb hisoblasangiz bo‘ladi. So‘nggi misol hozirgacha bo‘lgan misollarning umumiy ko‘rinishi bo‘lib, oldingilariga qaraganda biroz murakkabroq. Ammo, vaqt ajratib, bosqichma-bosqich tushunib borsangiz, buni ham uddalaysiz. Copy from pgzhelper import * import random WIDTH = 960 HEIGHT = 540 hammer = Actor('toy_hammer', (WIDTH / 2, HEIGHT / 2)) hammer.scale = 0.5 hammer.angle = 40 score= 0 hammer_pressed = False GAP_FROM_SCR = 50 moles = [] for _ in range(6): mole = Actor('mole') mole.anchor = ('left', 'top') x = random.randint(GAP_FROM_SCR, WIDTH - mole.width + GAP_FROM_SCR) y = random.randint(GAP_FROM_SCR, HEIGHT - mole.height + GAP_FROM_SCR) mole.pos = (x, y) mole.scale = 0.5 mole.visible = False moles.append(mole) def draw(): global score screen.blit('field', (0, 0)) for mole in moles: if mole.visible: mole.draw() if hammer_pressed and mole.visible and mole.collide_pixel(hammer): sounds.toi.play() moles.remove(mole) score += 1 hammer.draw() screen.draw.text('Hisob: ' + str(score), (20, 20), color='black') def update(): if random.randint(0, 10) == 0: if len(moles) != 0: mole_list = random.sample(moles, 1) mole_list[0].visible = not mole_list[0].visible else: game.exit() def on_mouse_move(pos): hammer.centerx, hammer.centery = pos def on_mouse_down(): global hammer_pressed hammer_pressed = True animate(hammer, angle=75, tween='accelerate', duration=0.1, on_finished=animation_done) def animation_done(): global hammer_pressed animate(hammer, angle=40, tween='accelerate', duration=0.1) hammer_pressed = False 🔢 Entry versiyasidagi ko'rsichqonlarni tutish o‘yinidan farqli jihati shundaki, Entry versiyasida ko'rsichqonlarning joylashuvi o‘zgarmas, lekin Pygame Zero versiyasida ko'rsichqonlar boshlang‘ich holatda tasodifiy(random) tarzda joylashtiriladi. Avval tasodifiylikdan foydalanish uchun alohida tashqi modul, ya'ni **random** moduli kerak bo‘ladi, shuning uchun 2-qatorda ushbu modul **import** qilinmoqda. 14~24-qatorlardagi kodlar ekranda tasodifiy joylashishi kerak bo‘lgan jami 6 ta ko'rsichqon Actor obyektlarini yaratib, bu yaratilgan 6-tasini **moles**(ko'rsichqonlar) degan ro‘yxat(list)ga joylashtirib ishlatadi. 19-20-qatorlarda foydalanilgan **randint** metodini Entryda foydalanilgan "tasodifiy son" bloki bilan solishtirsak, katta farqi yo‘q. U tasodifiy son tanlash uchun diapazonning eng kichik va eng katta qiymatlarini argument sifatida qabul qiladi. Lekin, metod nomida int(integer, butun son) bo‘lganligi sababli, u faqat butun sonlar diapazonida tanlov qilishi mumkin. Agar haqiqiy sonlar (float) qiymatlari kerak bo‘lsa, **randfloat** metodidan foydalanish mumkin. **randint** metodiga yuborilayotgan eng kichik va eng katta qiymatlar uchun **GAP\_FROM\_SCR** deb nomlangan 50 piksellik bo‘shliq(margin) qiymati ishlatilmoqda. Maqsad shuki, tasodifiy joylashuv paytida o‘yin ekrani chetiga juda yaqin joylashib qolmasligi uchun, ko'rsichqonlar tasvirlari ekran chetida chiqib ketmasligi va qirqilib qolmasligi uchun ekrandan 50 piksellik ichkariga tortib tasodifiy qiymatlarni aniqlash kerak. 23-qatordagi **visible**(ko‘rinuvchan) deb nomlangan yangi obyekt xususiyati ishlatilmoqda, **aslida bu Actor obyektida mavjud bo‘lmagan xususiyatdir. Bizning o‘yinda ko’rsichqonlar ekranda ko‘rinishi yoki ko‘rinmasligini aniqlash uchun bu yangi xususiyatni qo‘shimcha qilib atayin yasadik. Shu kabi Pythonda siz ham kerak bo‘lsa, mavjud obyektlarga o‘z yangi xususiyatlaringizni qo‘shishingiz mumkin.** _Maqsad, ko'rsichqonlar o‘yinida ko'rsichqonlar ko‘rinib yoki ko‘rinmasligini farqlash, bu o‘tgan bobda ko‘rsatilgan flag(bayroq) o‘zgaruvchisi kabi ishlaydi._ 🔢 O‘yinni qiziqarli qilish uchun tasodifiy ko'sichqonning ko‘rinishi yoki ko‘rinmasligi ham tasodifiy bo‘lishi kerak. Buni amalga oshiruvchi kod **update** kolbek funksiyasida 44~47-qatorlarda joylashgan. Biz o‘yinda ishlatiladigan obyektlarning joylashuvi, holati va boshqa ma'lumotlarini yangilab turadigan update(yangilash) funksiyasi juda tez-tez chaqirilishini bilamiz, lekin qancha tez-tezligini yaxshi bilmasdik. Endi nihoyat, bu tezlik haqida gapirishimiz kerak, bu soniyada 60 kadr tezlik (60 FPS: Frames Per Second)da amalga oshiriladi. Bu juda tez, soniyasiga 60 marta chaqiriladi. Masala shundaki, 60 FPS tezligi biz uchun juda tez, bizga juda tez yoki juda sekin bo‘lmagan holda o‘yin qiziqarli bo‘lishi uchun qolgan ko'rsichqonlar orasidan tasodifiy tarzda (0-10 oralig‘idagi qiymatlarda 0 tanlanganida) ko‘rinish/ko‘rinmasligini aniqlash kerak. Ushbu tasodifiy tezligi 44-qatorda amalga oshirilgan. Tirik qolgan ko'rsichqonlardan birini tasodifiy tanlash **random.sample** metodi yordamida 45, 46-qatorlarda amalga oshirildi va 47-qatorda tanlangan ko'rsichqonning ko‘rinish xususiyatini o‘zgartirish orqali ko‘rinish yoki ko‘rinmasligi boshqariladi. 🔢 Endi qolgan kodning katta qismi rezina bolg‘achaning animatsiyasi bilan bog‘liq. Agar oldingi misolda animatsiya bitta Actor ichida bir nechta tasvirlarning aylanishi orqali amalga oshirilgan bo‘lsa, bu safargi animatsiya hozirgi joydan belgilangan joyga yoki burchakka ma’lum bir vaqt ichida harakat qilishni o‘z ichiga oladi. Rezina bolg‘acha sichqoncha bosilgan vaqtda bolg‘achaning urish harakatini taqlid qilish uchun oldinga taxminan 75 daraja burchakka buriladi, so‘ngra yana hozirgi burchak (40 daraja) holatiga tezda qaytadi. 59-qatorda **animate** metodi birinchi marta ishlatilgan bo‘lib, jami 5 ta argumentlar qabul qiladi. Bularni quyidagicha umumlashtirish mumkin: qaysi obyekt (bu yerda **hammer**), uning qaysi xususiyati (bu yerda **angle**), qancha vaqt ichida (bu yerda **0,1 soniya**), qanday animatsiya turi (bu yerda **accelerate**) bajariladi. accelerate nomli animatsiyaning turi vaqt o‘tishi bilan tezlik oshib borishini ta’minlovchi animatsiyadir. Bunday turlarning jami 10 tasi mavjud bo‘lib, ularning har biri haqida batafsil ma’lumotni [kutubxona qo‘llanmasiarrow-up-right](https://pygame-zero.readthedocs.io/en/stable/builtins.html#animations) dan topishingiz mumkin. Argumentlar orasida oxirgi **on\_finished** parametri ham qiziqish uyg‘otishi mumkin. Bu yerda 62-qatorda e'lon qilingan **animation\_done** nomli funksiya nomi qiymat sifatida uzatilgan. Ha, bu parametrning nomi kabi, animatsiya tugagach, uzatiladigan kolbek funksiyasini ta’minlaydi. Buning turli maqsadlari bo‘lishi mumkin, lekin bizning maqsadimiz shundaki, rezina bolg‘achaning egilishi animatsiyasi tugagandan so‘ng, darhol hozirgi joyga qaytish animatsiyasi davom ettiriladi. 🔢 Foydalanuvchi ko'rsichqonni qachon urganligini qanday aniqlashimiz mumkin? 34-qatorda bu savolga javob mavjud. 3 ta shart bir vaqtda bajarilishi kerak. Rezina bolg‘achaning animatsiyasi oldinga egilib turgan bo‘lishi kerak (ya'ni bolg‘acha ko‘tarilayotgan paytda emas), ko'rsichqon yashirin holatda emas, balki ekranda ko‘rinib turishi kerak va oxirgi shart, bolg‘acha va ko'rsichqon o‘rtasida to‘qnashuv tekshiruvi muvaffaqiyatli o‘tishi kerak. Ushbu 3 ta shart bajarilganda ko'rsichqon urilgan hisoblanadi. Muvaffaqiyatli zarbadan so‘ng ovozli effekti chiqadi (35-qator), urilgan ko'rsichqon moles ro‘yxatidan o‘chirib tashlanadi (36-qator) va oxirgi bosqichda o‘yinda to‘plangan ochkolar hisoblanadi (37-qator). Shu bilan ko'rsichqon o‘yinining barcha kodlari haqida tushuntirish yakunlandi va oxirgi bosqichda o‘yin natijasini ko‘rish bilan tugatamiz. ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FKfwjWStJGCG0afzwQx8d%252Fimage%2520%281%29.gif%3Falt%3Dmedia%26token%3D9d80881e-af3d-4191-aa30-6f281641d3b4&width=768&dpr=3&quality=100&sign=9b912bb&sv=2) Ushbu kitobni shu misolgacha tugatganlarni yana bir bor tabriklayman. Bu bilan siz nihoyat Pygame Zero boshlang'ich darajasidan o'tdingiz. Shunday qilib, endi siz Pygame Zeroning yanada ilg'or darajasiga o'tishga tayyorsiz. [Kitobning keyingi darajasiarrow-up-right](https://roboticsware.gitbook.io/python-pygame_zero) da siz Python kodlash ko'nikmalaringizni biz hozirgacha ko'rgan misollardan farq qiladigan va haqiqiy o'yinga o'xshash o'yinlar yaratish orqali yanada qiziqarli tarzda rivojlantirasiz. Siz hayajonlana boshladingizmi? Matnli dasturlash bo'yicha birinchi sayohatingizda sizga hamroh bo'lganimdan xursand bo'ldim va muallif sizning sayohatingizda sizni xursand qilishda davom etadi. Bundan tashqari, men kodlash sayohatingizda sizga amaliy yordam beradigan va o'rganishingizga yordam beradigan kodlash vositalari va kitoblarni tayyorlashni davom etaman. Va nihoyat, agar sizda tushunarsiz misollar haqida savollaringiz yoki qo'shimcha fikrlaringiz bo'lsa, iltimos, onlayn hamjamiyat orqali bog'laning. Sizning sayohatingiz hech qachon yolg'iz emas! ☀️ Muallif tomonidan 2024 yilning jazirama yozi oxirida chop etilgan ☀️ [Previous5.6 Xazina sandig'ini ochish uchun parolni kiriting (Kiritish/Chiqarish)chevron-left](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/xazinani_ochish) [NextIlovachevron-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/ilova) Last updated 7 days ago --- # 5.1.3 Kuchuk va mushuk Salom aytadi3 (Ketma-ketlik) | Pygame Zero boshlang'ich Bu safar, Mushuk obyektini yaratish va uni ekranda ko'rsatish vaqti keldi. Kuchuk obyekti bilan allaqachon kod yozganimiz uchun bu juda qiyin bo'lmasligi kerak. Biroq, quyidagi 11-qatorda biz ilgari ko'rmagan kod paydo bo'ldi. Biz buni **flip\_x** xususiyat nomidan intuitiv ravishda taxmin qilishimiz mumkin va agar Mushuk obyektini Kuchuk obyektiga qarashi uchun maxsus qo'shilgan blokli kodlashdagi blokni (shaklni chapga va o'ngga aylantirish) eslasak, uning o'sha blok bilan bir xil rol o'ynashini ko'rishimiz mumkin. Boshqacha qilib aytganda, x yo'nalishida (gorizontal yo'nalish) tasvirni aylantirish uchun xususiyatga **True** qiymatini berish orqali tasvir ekranda chizilishidan oldin aylantiriladi. Copy from pgzhelper import * TITLE = 'Kuchuk va Mushuk salom aytadi' WIDTH = 480 HEIGHT = 270 dog = Actor('dog', (100, 150)) dog.scale = 0.5 cat = Actor('cat', (350, 150)) cat.scale = 0.5 cat.flip_x = True def draw(): screen.fill('white') dog.draw() cat.draw() Endi faqat kuchuk va mushuk navbatma-navbat bir-biri bilan salomlashishi va xayrlashishi qoldi. Agar biz buni kodda ifodalasak, u 18 dan 21 gacha bo'lgan to'rt qator kod bo'ladi. Copy from pgzhelper import * TITLE = 'Kuchuk va Mushuk salom aytadi' WIDTH = 480 HEIGHT = 270 dog = Actor('dog', (100, 150)) dog.scale = 0.5 cat = Actor('cat', (350, 150)) cat.scale = 0.5 cat.flip_x = True def draw(): screen.fill('white') dog.draw() cat.draw() dog.say_for_sec("Vov-vov!", 2) cat.say_for_sec("Miyov~", 2) dog.say_for_sec("Xayr~", 2) cat.say_for_sec("Yaxshi boring!", 2) Ushbu kodni tushunish ham intuitivdir. Obyekt amalga oshirishi mumkin bo'lgan harakatlardan biri bu obyekt ichidagi **say\_for\_sec** funksiyasidan (usulidan) foydalanish, uninig vazifasi ma'lum soniyalar davomida biror narsa aytishda. ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FGf8R8ZQjhIPogTOkDleH%252FKapture%25202024-07-17%2520at%252017.11.31.gif%3Falt%3Dmedia%26token%3D19d5dbc9-a0f1-4e6c-817b-557f96682c81&width=768&dpr=3&quality=100&sign=8647417d&sv=2) Shu bilan Pygame Zerodan foydalangan holda Entry boshlang'ich kitobidagi birinchi misolni kodlash yakunlandi. Nihoyat, 4-bobda “O‘yin tsiklini tushunish”da aytib o‘tganimdek, Pygame Zero yordamida matnli kodlash va Entry blokli kodlash o‘rtasidagi farq shundan iboratki, Entryda kuchuk va mushuk obyektlari har biri mustaqil ravishda mavjud bo‘lgan va obyektlarga mos keladigan kodlash ham mustaqil ravishda har biri uchun mavjud bo‘lgan, lekin Pygame Zero hali bunday parallel/sinxronlikni qo'llab-quvvatlamaydi ([batafsil ma'lumot uchun oldingi kitobga qarangarrow-up-right](https://roboticsware.gitbook.io/entry-python/dasturlash_paradigma/ketma_ketlik-parallel) ). Agar siz hozirgacha o'yin siklining asosiy tamoyillarini va obyektlarning asosiy tushunchalarini yaxshi tushunsangiz, qolgan misollarni kodlash qiyin bo'lmaydi. [Previous5.1.2 Kuchuk va mushuk Salom aytadi2 (Ketma-ketlik)chevron-left](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/kuchuk-mushuk_2) [Next5.2 Bitta gulbargdan gul yasash (Takrorlash)chevron-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/gul_yasash) Last updated 7 days ago --- # 5.4 O'zingizga rasm chizish taxtasini yasang (Hodisa) | Pygame Zero boshlang'ich Endi yettita misoldan 4-sini ko'rib chiqish vaqti keldi. Kitobning yakuniga oz qoldi. Kod miqdori, albatta, avvalgidan ko'proq bo'ladi. Biroq, tashvishlanishning hojati yo'q, chunki qiyinchiliklar bilimni oshirishda ijobiy xizmat qilishini tushunsak, biz uchun foydali bo'ladi. Copy from pgzhelper import * WIDTH = 960 HEIGHT = 540 drawing = False pencil = Actor('pencil', (WIDTH / 2, HEIGHT / 2), anchor=('left', 'bottom')) pencil.scale = 0.3 pencil.brush_init((WIDTH, HEIGHT), 5, 'blue') eraser = Actor('eraser', (900, 50)) eraser.scale = 0.5 def draw(): screen.fill('white') pencil.brush_draw() pencil.draw() eraser.draw() if drawing is False: pencil.brush_stop() def on_mouse_move(pos): pencil.left, pencil.bottom = pos def on_mouse_down(pos): global drawing drawing = True if eraser.collidepoint_pixel(pos): pencil.brush_clear() def on_mouse_up(): global drawing drawing = False 🔢 Keling birinchi 8-qatorda qalam nomli aktyor(actor) obyektini yaratuvchi kodni ko'rib chiqamiz. Obyektning langar qiymati (anchor qiymati) "chap", "pastki" ('left', 'bottom')ligi sababi Entry blokli kodlashdagi bilan bir xil. Buning sababi shundaki, ekranda qalam tanasidan chizish noodatiy, qalam uchidan chizishi tabiiydir. ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252F8MpyDz6Yh91t651tZm57%252Fimage.png%3Falt%3Dmedia%26token%3D0d973f84-595b-437c-a315-e0209055dbb0&width=768&dpr=3&quality=100&sign=ca028aa&sv=2) 🔢 6-qatorda, avvalgi ichki kutubxona o‘zgaruvchilaridan farqli o‘laroq, bizning ehtiyojlarimizga mos ravishda biz tomonidan aniqlangan o‘zgaruvchi birinchi marta paydo bo‘ladi. **drawing** deb nomlangan o‘zgaruvchining maqsadini nomidan ma’lum darajada taxmin qilish mumkin (o‘zgaruvchi yaratishda mazmunli nom berish muhimligini avvalgi darslarda bir necha marta eslatganmiz). Bu o‘zgaruvchi sichqoncha tugmachasi bosilgan holda chizish holatida ekanini yoki sichqoncha tugmachasidan barmoqni ko‘tarib, chizishni to‘xtatgan holatni aniqlash uchun ishlatiladi. Oxir-oqibat, faqat ikkita holatni bilish kifoya bo‘lgani uchun ushbu o‘zgaruvchi qiymati sifatida faqat **Rost/Yolg'on (True/False)** qiymatlaridan foydalanish yetarli. Endi drawing o‘zgaruvchisining maqsadi va vazifasini tushunib oldik. Navbatda _ushbu o‘zgaruvchini e'lon qilish (definition) kod ichida qayerda joylashgani va nima uchun bu o‘zgaruvchi funksiyaning ichki sohasi(scope)da emas, balki tashqi sohasida joylashganini o‘rganish zarur._ **Bu masala o‘zgaruvchini qayerda yaratish kerakligi haqidagi kodlash qoidalariga bog‘liq. Agar o‘zgaruvchi faqat bitta funksiyada ishlatilishi kerak bo‘lsa, u holda u funksiyaning ichida e'lon qilinadi(joylashtiriladi). Ammo agar bir nechta funksiyalarda yoki kodning umumiy qismlarida birgalikda ishlatilishi kerak bo‘lsa, bu kabi funksiyalardan tashqarida e'lon qilinadi(joylashtiriladi). Shuni ham yodda tutingki, kodning umumiy qismlarida birgalikda ishlatiladigan o‘zgaruvchilar global (umumiy) o‘zgaruvchilar deb ataladi.** 🔢 Ko'rishingiz mumkin, **drawing o'zgaruvchisi ikkita joyda ishlatilgan**: 26-qatorda **on\_mouse\_up** kolbek funksiyasi (funksiya nomi **on\_** bilan boshlanganligi sababli, u PygameZero kutubxonasi tomonidan hodisaga (masalan, sichqoncha tugmasi bosilishiga) koʻra avtomatik ravishda chaqirilishini bildiradi) va 33-qatorda **on\_mouse\_down** kolbek funksiyasi. U ikkala funksiya tomonidan umumiy bo'lishi kerak bo'lgan o'zgaruvchi bo'lgani sababli funksiyalardan tashqarida yaratilgan. Keling, ushbu o'zgaruvchidan funksiyada qanday foydalanishni batafsil ko'rib chiqaylik. **U funksiyadan tashqaridagi o'zgaruvchi bo'lsa ham, avvalgiday siz shunchaki o'zgaruvchining qiymatini o'qib, uni funksiya ichida ishlatishingiz mumkin. Ammo, agar siz ushbu o'zgaruvchini funksiya ichida o'zgartirmoqchi bo'lsangiz, Pythonning yangi grammatikasini bilishingiz kerak. 27 va 34 qatorlarda ko'rib turganingizdek, o'zgaruvchi nomining oldiga global kalit so'zi (keyword)ni qo'shish orqali o'zgaruvchini e'lon qilishingiz kerak, bu o'zgaruvchining qiymatini o'zgartirishdan oldin uning funksiyadan tashqarida mavjudligini aniq ko'rsatadi.** circle-info _Aytgancha, bu erda_ _e'tibor berish kerak._ _**Grammatikaga qat'iy rioya qilmaydigan Pythonning moslashuvchanligi afzallik, lekin shu bilan birga, bu kamchilik.**_ _Agar boshda siz global kalit so'zini aniq ishlatmasangiz va uni ishga tushirmasangiz, u oldindan xatosiz ishlaydi. Biroq, aynan o'zgaruvchi qiymatini o'zgartirishga urinayotganda xatolik yuz beradi. Nima uchun siz xohlaganingizcha ishlamasligi haqida oldindan mantiqiy xatolarni topish oson bo'lmagan vaziyatlarga duch kelishingiz mumkin, shuning uchun e'tibor bering._ 🔢 15~18-qatorlarda **draw** kolbek funksiyasida fon rangi o'rnatiladi va ekranda paydo bo'ladigan obyektlar chiziladi. Yuqorida aytib o'tilganidek, har bir obyekt uchun **draw** funksiya ichida chaqirish tartibini, ya'ni ularni ekranda ko'rsatish tartibini hisobga olish muhimdir. Bizning chizganimiz qalam ustida paydo bo'ladigan xatoli vaziyatlarga duch kelmaslik uchun ushbu tartibni saqlang. 🔢 20-21-qatorlarda **drawing** o'zgaruvchisining qiymatidan foydalanib, cho'tka bilan chizishni to'xtatish vaqtini aniqlash uchun shart ishlatiladi. Qiymat **yolg'on**(False) bo'lganda, **brush\_stop** funksiyasi(metodi) cho'tkadan foydalanishni to'xtatadi. 🔢 23-24 qatorlarda qalam(**pencil**) obyektining markazini sichqoncha koordinatalari bilan real vaqtda joylashtirish vazifasini bajariladi. Bu qalam obyekti sichqonchaning ko'rsatgichi bilan birga harakatlanishi uchun kerak. 24-qatordagi sintaksis biroz g'alati tuyulishi mumkin, chunki **"pos" qiymati bittalik qiymatga o'xshaydi, lekin aslida (x, y) koordinatalarini o'z ichiga olgan** _**o'zgarmas ro'yxat**_ _**(Tuple)**_ **ni ifodalaydi.** O'zgarmas ro'yxat (Tuple) — bu biz hali duch kelmagan yangi ma'lumotlar turi, shuning uchun uni batafsilroq ko'rib chiqamiz. **O'zgarmas ro'yxat (keyinchalik "Tupl" deb ataladi)** Tupl biz allaqachon tanish bo'lgan [ro'yxat(list)arrow-up-right](https://roboticsware.gitbook.io/entry-python/boshlash/ruyxat) ma'lumotlari turiga o'xshaydi, shuning uchun avval ulardan foydalanish sintaksisini ajratib olaylik. Tashqi farq shundaki, ro'yxatning to'rtburchak qavslar "\[ \]" odatiy qavslar "( )" bilan almashtiriladi. > **tupl\_nomi = (bir nechta qiymatlar, masalan, satrlar, sonlar va boshqalar, lekin qiymatlar vergul (,) bilan ajratiladi)** **Biroq, ro'yxat va tupl o'rtasidagi asosiy farq keyinchalik qiymatlarni o'zgarish imkonidir. Bu o'zgaruvchan va faqat o'qish mumkin bo'lgan (read only) ma'lumotlar turlari o'rtasidagi farq.** Tupl ikkinchisiga qarashli — yaratilgandan keyin ularning qiymatlarini o'zgartirib bo'lmaydi. Bu yaratuvchi va dasturning boshqa foydalanuvchilari tomonidan dasturlash jarayonida tasodifiy o'zgarishlarning oldini olish orqali dastlabki qiymatlarni himoya qiladi. Funksiya muallifi tomonidan belgilangan cheklovlarga rioya qilishimiz kerak. Boshqa dasturchilar tomonidan yozilgan funksiyalar yoki kutubxonalardan foydalanganda, biz shikoyat qilishimizga huquq yo'q va kodlashni funksiya muallifi tomonidan taklif qilingan yoki cheklangan doirada kodlash shart deb hisoblash kerak. Barcha cheklovlar to'g'risidagi ma'lumotlarni [tegishli funksiya uchun kutubxona qo'llanmasiarrow-up-right](https://pygame-zero.readthedocs.io/en/stable/hooks.html#on_mouse_move) da topish mumkin. Shunday qilib, yana bir bor xulosa qilish uchun 24-qator sintaksisi pos **tupl**idan x-koordinataning qiymatini oladi va uni **pencil.left** o'zgaruvchisiga saqlaydi, va y-koordinataning qiymati olinadi va **pencil.bottom**da saqlanadi. 🔢 26-qatordagi **on\_mouse\_down** kolbek funksiyasi, uning nomidan taxmin qilganingizdek, sichqoncha tugmasi bosilganda kutubxona orqali avtomatik ravishda chaqiriladi. Bunday holda, bosish paytida sichqoncha ko'rsatgichi joylashgan nuqtaning koordinatalari avtomatik ravishda pos funksiya argumenti sifatida uzatiladi. Ushbu qiymatdan foydalanib, biz qiziqarli dasturlarni yaratishimiz mumkin. Endi, nihoyat, ushbu bob kodining oxirgi 30-31 qatorlarini ko'rib chiqamiz. Bizning kodimizda birinchi marta obyektlar o'rtasida to'qnashuvni tekshirish paydo bo'ladi, bu ko'pincha o'yin kodlashda ishlatiladi. O‘chirgich(**eraser**) obyekti ichidagi **collidepoint\_pixel** funksiyasi(metodi) sichqonchani bosgan nuqtaning koordinata qiymatlari (bu yana pos tupl qiymati) o‘chirgich obyektining ichida ekanligini tekshiradi. Demak biz sichqoncha orqali o‘chirgich obyektini bosganimizni tekshiramiz va agar shunday bo‘lsa (natija rost bo'lsa), chizganimizni butunlay o‘chirib tashlaymiz. Bobning boshida juda ko'p kod paydo bo'lgan bo'lsa-da, uni tahlil qilgandan so'ng, dasturlash ko'rinadigan darajada murakkab emasligi aniq bo'ladi. Shunday qilib, kod hajmidan qo'rqishning hojati yo'q. Biz ushbu rasm chizish taxtasining natijasini ko'rib chiqib, bobni yakunlaymiz. ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252FJZKBRYUJO5HqMUiVLCKk%252Fimage%2520%282%29.gif%3Falt%3Dmedia%26token%3Dd1a355ee-5e55-4c17-b69b-8e76402e15aa&width=768&dpr=3&quality=100&sign=4f6816e6&sv=2) [Previous5.3 Robot changyutkich to'siqga duch kelsa nima bo'ladi? (Shart)chevron-left](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/changyutgich) [Next5.5 Qo'llarni cho'zgan holda sakrashlar sonini sanang (O'zgaruvchi)chevron-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/sakrashni_sanash) Last updated 7 days ago --- # 5.3 Robot changyutkich to'siqga duch kelsa nima bo'ladi? (Shart) | Pygame Zero boshlang'ich Bu uchinchi, "Robot changyutgich" misoli. Bu misolda biz ilgari foydalanmagan Actor obyektlarining qo'shimcha harakatlari(metodlari) keltirilgan, ammo oldingi boblarda o'rganilgan asosiy tamoyillar unchalik o'zgarmaganligi sababli, bu juda qiyin bo'lmasligi kerak. Copy from pgzhelper import * WIDTH = 960 HEIGHT = 540 robot = Actor('cleaner', (WIDTH / 2, HEIGHT / 2)) robot.scale = 0.3 robot.angle = 90 robot.brush_init((WIDTH, HEIGHT), 50, 'white') def draw(): screen.blit('floor', (0, 0)) robot.brush_draw() robot.draw() def update(): robot.move_forward(10) if robot.top < 0 or robot.right > WIDTH \ or robot.bottom > HEIGHT or robot.left < 0: robot.move_back(10) robot.angle += 133 🔢 Birinchidan, 3-4 qatorlarda ekran o'lchami mavjud o'lchamdan ikki barobarga oshirildi (480 kenglik, 270 balandlik). Buning alohida sababi yo'q, bu faqat ijro natijasi ekranini kattaroq hajmda ko'rish uchundir. 🔢 6-qatorda robot changyutgichni ekranning o'rtasiga joylashtirish uchun markaziy koordinata gorizontal va vertikal uzunliklarning yarmiga o'rnatildi. 🔢 8-qatorda robot changyutgich obyekti birinchi marta ishga tushirilganda ekranda yuqoriga qarab harakatlanishi uchun uning boshlang'ich burchagi 90 darajaga o'rnatiladi. 🔢 9-qatordan robot changyutgichning harakat izlarini bo‘yashning asosiy sozlamalari **brush\_init** funksiyasi(metodi) orqali amalga oshiriladi. Uchta argument talab qilinadi: cho'tka bilan bo'yalgan umumiy maydon, qalinligi va rangi. 🔢 12-qatorda men nihoyat birinchi marta o'yin fonini chizish uchun kodni qo'lladim. **Ekran** deb nomlangan oldindan o'rnatilgan obyektda turli xil funksiyalar (metodlar) mavjud bo'lib, **ular o'yin ekraniga ishora qiladi (**[**batafsil ma'lumot**arrow-up-right](https://pygame-zero.readthedocs.io/en/stable/builtins.html#screen) **uchun Pygame Zero qo'llanmasiga qarang) va blit metodi** ulardan biri bo'lib, tasvirni to'g'ridan-to'g'ri ekranga chiqaradi va bizning kodda pol tasviri(rasmi)ni chiqaradi. **🔢** 16-qatorda paydo bo'lgan **update** **kolbek funksiyasi o'yin siklini tashkil etuvchi asosiy funksiyadir. Bu o'yinda doimiy ravishda o'zgarib turadigan narsalar (masalan, Actor obyekti harakatlanayotganda) yoki doimiy tekshirilishi kerak bo'lgan narsalar (masalan, qaysi klaviatura yoki sichqoncha tugmasi bosilgan) uchun kod yozadigan qismdir.** Shuning uchun robot changyutgich har safar 10 o'lchamdagi harakatni takrorlashi uchun 17-qatorda **move\_forward(10)** ishlatilgan. 🔢 Va nihoyat, 19-qatordan so'ng, robot changyutgich o'yin ekranining oxiriga yetganda nima bo'lishi kerakligini tavsiflovchi shart bilan kod keladi. Bu Entry daturida odatiy kodlashdan biroz farq qiladi. _Entryda o'yin ekranining chegaralari "devor" deb nomlangan va obyektlar sifatida nazarga tutilgan. Bu devor chegarasiga tegganligini (chiqib ketganini) aniqlash uchun obyektlar orasidagi to'qnashuvni tekshirishdan foydalanilgan._ **Biroq,** **Pygame Zeroda orqa fon rasmi o'zi obyekt emas. Shuning uchun** _**ekran chegarasiga tegganligini aniqlash uchun doimiy ravishda harakatlanadigan robot changyutgichning hozirgi holati (joylashuvi) orqali amalga oshiriladi.**_ Masalan, **robot.top** qiymatining 0 dan kichik bo‘lishi robot changyutgich obyektining o‘yin ekrani yuqori chegarasidan chiqib ketayotganini anglatadi. Shu bilan birga, **robot.right** qiymatining ekran kengligidan kattalashishi o‘yin ekrani o‘ng chetiga yetib borganini bildiradi. Ushbu holatda, robotni biroz (10 birlik miqdorida) orqaga qaytarib, keyin yo‘nalishni o‘zgartirishga urinayotganini yodda tutish kerak. Bunday algoritmning zarurati shundaki, ekranning chetiga yetganda darhol yo‘nalishni o‘zgartirishga urinish, ba’zan yo‘nalish o‘zgartirilgan paytda ham obyekt hali ham ekranning chekkasida bo‘lib qolishi mumkin. Natijada, robot doim bir joyda aylanib qolib, boshqa yo‘nalishda harakat qila olmaydi. Buning oldini olish uchun robotni bir oz orqaga qaytarib, keyin yo‘nalishni o‘zgartirishga harakat qilinadi. Ma’lumot uchun, 19-qator oxirida joylashgan '\\' belgisiga qiziqayotganlar bo‘lishi mumkin. 19~20-qatorlarga bo‘lingan kod aslida bitta uzun qator sifatida 19-qatorga joylashishi kerak edi. Ammo muallif bu kodni ikki qatorga ajratdi, bu esa kodni o‘qishda tez va intuitiv tarzda tushunish imkonini berish, ya’ni kodni o‘qish qulayligini oshirish uchun qilingan. Ammo, **kodlashda, agar bitta uzun qatorni bir necha qatorlarga ajratish kerak bo‘lsa, ajratilgan qatorning oxirida '\\' belgisi qo‘yilishi shart. Bu belgidan foydalanish ajratilgan qator hali tugamaganligini va keyingi qator bilan bog‘langanligini bildiradi.** Nihoyat, biz robot changyutgichning yakuniy natijalarini ko'rib chiqish orqali ushbu bobni yakunlaymiz. ![](https://roboticsware.gitbook.io/pygame_zero-entry_basic/~gitbook/image?url=https%3A%2F%2F2073194744-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FABxmaepOJffXWEUdeexU%252Fuploads%252F4L4EnotP39bVAFuc1WLk%252FScreen%2520Recording%25202024-07-17%2520at%252016.59.34.gif%3Falt%3Dmedia%26token%3D674dc24a-1f8d-4f60-8c5c-b9ca4e7291c6&width=768&dpr=3&quality=100&sign=42fe825f&sv=2) [Previous5.2 Bitta gulbargdan gul yasash (Takrorlash)chevron-left](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/gul_yasash) [Next5.4 O'zingizga rasm chizish taxtasini yasang (Hodisa)chevron-right](https://roboticsware.gitbook.io/pygame_zero-entry_basic/kodlash_boshlash/rasm_chizish) Last updated 7 days ago --- # Entry-Pythonning tezkor tugmalari | Entry-Python [hashtag](https://roboticsware.gitbook.io/entry-python/ilova/tezkor_tugmalari#windows-uchun) Windows uchun --------------------------------------------------------------------------------------------------------------- Funksiya Tezkor tugma Indentatsiya darajasini sozlash Tab, Shift + Tab Blok/Shakl/Ovoz/Xususiyatlar yorliqini tanlash Alt + 1, Alt +2, Alt +3, Alt + 4 Oldingi/Keyingi obyektni tanlash Alt + \[, Alt + \] Blokli kodlash/Entry-Pythonga o'tish Ctrl + \[, Ctrl + \] Dasturni bajarish Ctrl + R [hashtag](https://roboticsware.gitbook.io/entry-python/ilova/tezkor_tugmalari#mac-uchun) Mac uchun ------------------------------------------------------------------------------------------------------- Funksiya Tezkor tugma Indentatsiya darajasini sozlash cmd + \[, cmd + \] Tab, Shift + Tab Blok/Shakl/Ovoz/Xususiyatlar yorliqini tanlash Alt + 1, Alt +2, Alt +3, Alt + 4 Oldingi/Keyingi obyektni tanlash Alt + \[, Alt + \] Blokli kodlash/Entry-Pythonga o'tish Ctrl + \[, Ctrl + \] Dasturni bajarish Ctrl + R [PreviousIlovachevron-left](https://roboticsware.gitbook.io/entry-python/ilova) Last updated 10 months ago ---