ट्यूटोरियल्स लूप्स के साथ दोहराना

लूप्स के साथ दोहराना

By Joanne Amarisa, Layla Quiñones, Greg Benedis-Grab

परिचय

क्या आपने कभी अपने प्रोजैक्ट्स को अगले स्तर पर ले जाना चाहा है, जहाँ कोड की सिर्फ़ कुछ लाइनों से कई शेप्स ड्रॉ हो सकें? सोचिए — पेड़ों की एक कतार, किताबों का एक ढेर, इंद्रधनुष के आर्च, या मधुमक्खी के छत्ते की अंदरूनी बनावट। ऐसे विज़ुअल्स बनाने के लिए, जो एक ही शेप के कई वर्ज़न्स से बने हों, हम हर शेप को अलग-अलग कोड करने से आगे बढ़ते हैं और लूप्स तथा सरणियाँ की अद्भुत दुनिया में प्रवेश करते हैं। आइए सीखें कि कोड की सिर्फ़ कुछ लाइनों से दोहराने वाले पैटर्न कैसे बनाएं!

एक आर्च और हेक्सागन शेप वर्टिकली अलाइन हैं, जिन पर "single object" लेबल है। तीर इन शेप्स से उन पैटर्न्स की ओर इशारा करते हैं जो "multiplied objects" लेबल के नीचे वर्टिकली अलाइन हैं। एक आर्च पाँच वर्टिकली स्टैक्ड आर्च की ओर इशारा करता है जो इंद्रधनुष का आकार बनाते हैं। हेक्सागन कई हेक्सागन की ओर इशारा करता है जो मधुमक्खी के छत्ते जैसी बनावट में व्यवस्थित हैं।

एक आर्च और हेक्सागन शेप वर्टिकली अलाइन हैं, जिन पर "single object" लेबल है। तीर इन शेप्स से उन पैटर्न्स की ओर इशारा करते हैं जो "multiplied objects" लेबल के नीचे वर्टिकली अलाइन हैं। एक आर्च पाँच वर्टिकली स्टैक्ड आर्च की ओर इशारा करता है जो इंद्रधनुष का आकार बनाते हैं। हेक्सागन कई हेक्सागन की ओर इशारा करता है जो मधुमक्खी के छत्ते जैसी बनावट में व्यवस्थित हैं।

हर शेप को नई लाइन ऑफ़ कोड से ड्रॉ करना एक थकाऊ प्रक्रिया होगी। इसके बजाय, हम लूप्स का उपयोग कर सकते हैं, जो हमें कोड के ब्लॉक्स को जितनी बार चाहें उतनी बार एक्सीक्यूट और दोहराने की सुविधा देते हैं। इस ट्यूटोरियल में, हम लूप्स और सरणियाँ का उपयोग करके एक रेसिंग कैटरपिलर स्केच बनाएंगे।

तीन गुलाबी कैटरपिलर कैनवास के दाईं ओर हरी फ़िनिश लाइन तक पहुँचने के लिए रेंग रही हैं।

तीन गुलाबी कैटरपिलर कैनवास के दाईं ओर हरी फ़िनिश लाइन तक पहुँचने के लिए रेंग रही हैं।

कैटरपिलर का एक समूह रेस की शुरुआती लाइन पर शुरू करेगा, और पहली कैटरपिलर जो फ़िनिश लाइन को पार करेगी वह जीतेगी। जीतने वाली कैटरपिलर हर बार स्केच चलाने पर अलग होगी!

इस ट्यूटोरियल में, आप:

  • for loops का उपयोग करके दोहराने वाले कार्यों और शेप्स को ड्रॉ और अपडेट करेंगे
  • कस्टम कार्य का उपयोग करके चर और प्रोग्राम स्टेट्स को अपडेट करेंगे और स्केच चलने के दौरान प्रोग्राम में बदलाव करेंगे।
  • शर्त कथन और random() का उपयोग करके अलग-अलग परिणाम जनरेट करेंगे
  • माउस ट्रिगर्स और बूलियन चर का उपयोग करके अपने स्केच को चलाएंगे और रोकेंगे
  • कैटरपिलर की पोज़िशन्स को सरणी में स्टोर करेंगे

आपको क्या चाहिए

  • p5.js Web Editor
  • x- और y-निर्देशांक का उपयोग करके p5.js में बेसिक शेप्स और टेक्स्ट ड्रॉ करने की समझ
  • चर और शर्तें की समझ
  • कस्टम कार्य और पैरामीटर्स की समझ

चरण 1 – रेसट्रैक ड्रॉ करें

  • p5.js Web Editor में एक नया प्रोजैक्ट खोलें, उसे “Caterpillar Race” जैसा नाम दें, और सेव करें।
  • setup() में, एक 500x500 पिक्सेल का कैनवास बनाएं।
  • setup() के ऊपर दो नए ग्लोबल चर डिक्लेयर करें, जो आपकी स्टार्ट लाइन और फ़िनिश लाइन के x-निर्देशांक को डिफ़ाइन करेंगे। हम दोनों चर का नाम startLine और finishLine रखेंगे।
    • उन्हें x-axis पर वैल्यूज़ असाइन करें, जहाँ आप अपनी स्टार्ट और फ़िनिश लाइन रखना चाहते हैं। इस उदाहरण में, हम startLine को 30, और finishLine को 360 सेट करेंगे।
  • draw() कार्य में:
    • एक बैकग्राउंड रंग सेट करें। उदाहरण के लिए, हम इसे background(121, 96, 76) से भूरा सेट करेंगे;
    • एक रेक्टैंगल ड्रॉ करें और उसका x-निर्देशांक startLine सेट करें। उसकी ऊँचाई height सेट करें ताकि यह कैनवास पर वर्टिकली फैल जाए।
    • finishLine पर एक और रेक्टैंगल ड्रॉ करें और वही स्टेप दोहराएं।
    • दोनों रेक्टैंगल्स को अलग-अलग रंगों से भरें।
  • अपने स्केच को नाम दें और सेव करना न भूलें।

आपका कोड कुछ इस तरह दिख सकता है:

चरण 2 – एक कैटरपिलर सेगमेंट ड्रॉ करें और उसे मूव कराएं।

अगला, हम कैनवास पर कैटरपिलर का एक सेगमेंट ड्रॉ करेंगे और उसे स्टार्ट लाइन से फ़िनिश लाइन तक ले जाएंगे। यह रेस के अंत में रुक जाएगा।

  • एक नया ग्लोबल चर circX डिक्लेयर करें और उसे startLine की वैल्यू असाइन करें।

    • यह कैटरपिलर सेगमेंट का x-निर्देशांक होगा।
  • एक नया ग्लोबल चर circY डिक्लेयर करें और उसे 250 (या ऊँचाई का आधा) की वैल्यू असाइन करें।

    • यह कैटरपिलर सेगमेंट का y-निर्देशांक होगा।
  • draw() में:

    • circle() कार्य का उपयोग करके कैटरपिलर सेगमेंट ड्रॉ करें। x निर्देशांक, y निर्देशांक, और डायमीटर निर्दिष्ट करने के लिए circX, circY, और 50 को तर्क के रूप में शामिल करें: circle(circX, circY, 50);
    • हम सर्कल को सफ़ेद fill रंग और पतली काली stroke भी देंगे।
    • circle कमांड के नीचे, circX += 20; का उपयोग करके circX को 20 से बढ़ाएं
      • इसका मतलब है कि हर बार draw() कार्य चलता है, चर circX 20 पिक्सेल बढ़ जाएगा। स्केच पिछले सर्कल से 20 पिक्सेल दाईं ओर एक नया सर्कल ड्रॉ करेगा, जिससे कैटरपिलर का आकार बनेगा।
  • draw() के अंत में निम्नलिखित शर्त कथन जोड़ें:

    if (circX > finishLine) {
      noLoop();
    }

noLoop() कार्य draw() कार्य को दोबारा चलने से रोकता है। if स्टेटमेंट noLoop() का उपयोग करके draw() को रोकता है जब सर्कल का x-निर्देशांक finishLine की वैल्यू को पार कर जाता है। noLoop() के बारे में अधिक जानकारी के लिए p5.js reference देखें।

setup() में, जोड़ें: frameRate(3);

  • frame rate वह संख्या है जो बताती है कि draw() एक सेकंड में कितनी बार चलता है। इसे कम संख्या पर सेट करने से इस एनिमेशन में गतिविधियाँ अधिक ध्यान देने योग्य और नाटकीय होंगी।

आपका कोड इस तरह दिखना चाहिए:

If-स्टेटमेंट्स

If-स्टेटमेंट्स, जैसा कि ऊपर उपयोग किया गया है, कोड के ऐसे ब्लॉक्स को संदर्भित करते हैं जो केवल तभी एक्सीक्यूट होते हैं जब दी गई कंडीशन true हो। इसे आमतौर पर इस तरह लिखा जाता है:

if (<condition>) {
  <code>
}

कंडीशन if-स्टेटमेंट के कोष्टक के अंदर निर्दिष्ट की जाती है। घुंघराले कोष्ठक { } कोड ब्लॉक की शुरुआत और अंत को चिह्नित करते हैं। चरण 2 में, कंडीशन circX > finishLine noLoop() को कॉल करके draw() को दोबारा चलने से रोकती है जब सर्कल का x-निर्देशांक finishLine की वैल्यू से अधिक होता है।

अधिक जानने के लिए if का p5.js reference देखें।

चरण 3 – एक कैटरपिलर ड्रॉ करें

हम चरण 2 के कैटरपिलर सेगमेंट को दोहराकर सर्कल्स की एक पंक्ति बनाएंगे जो कैटरपिलर का शरीर बनाती है। हम एक for loop का उपयोग करके एक पंक्ति में कई सर्कल ड्रॉ करेंगे।

3.1 – कैटरपिलर के शरीर की प्रॉपर्टीज़ डिक्लेयर करें

setup() के ऊपर:

  • एक नया चर segments डिक्लेयर करें और उसे 6 की वैल्यू असाइन करें।
    • यह चर डिफ़ाइन करता है कि कैटरपिलर के शरीर में कितने सर्कल हैं।
  • एक नया चर spacing डिक्लेयर करें और उसे 20 की वैल्यू असाइन करें।
    • यह चर कैटरपिलर के बॉडी सेगमेंट्स के बीच पिक्सेल स्पेसिंग डिफ़ाइन करता है।
  • एक नया चर segmentSize डिक्लेयर करें और उसे 50 की वैल्यू असाइन करें।
    • यह चर सर्कल बॉडी सेगमेंट्स का डायमीटर डिफ़ाइन करता है।

3.2 – for loop से कैटरपिलर का शरीर बनाएं

draw() में:

  • फ़िनिश लाइन ड्रॉ करने वाले कोड के बाद, सभी बॉडी सेगमेंट्स को पोज़िशन करने के लिए एक नया लोकल चर x डिक्लेयर करें: let x = circX;
  • एक for loop जोड़ें: for (let i = 0; i < segments; i += 1) { }
    • एक for loop हमारे द्वारा घुंघराले कोष्ठक के अंदर लिखे गए कोड को कई बार दोहराएगा।
    • circle() ड्रॉ करने वाली कोड लाइनों को for loop के घुंघराले कोष्ठक में मूव करें।
  • for loop के बाद, जोड़ें: circX += spacing
    • यह हर बार draw() चलने पर कैटरपिलर बॉडी को दाईं ओर मूव करता है।

आपका कोड इस तरह दिखना चाहिए:

For loops

एक for loop कोड के एक सेक्शन (या ब्लॉक) को कई बार एक्सीक्यूट कर सकता है। For loops इस तरह लिखे जा सकते हैं:

for (let i = 0; i < number; i += 1) { 
  // वह कोड जिसे आप number बार एक्सीक्यूट करना चाहते हैं
}

for loop के घुंघराले कोष्ठक {} के अंदर, हम वह कोड लिखते हैं जिसे हम बार-बार एक्सीक्यूट करना चाहते हैं। हम लूप की कंडीशन सेट करके निर्दिष्ट कर सकते हैं कि कोड कितनी बार दोहराया जाए।

एक for loop को उसके कोष्टक के अंदर तीन स्टेटमेंट्स द्वारा डिफ़ाइन किया जाता है, जो सेमीकोलन से अलग होते हैं। ये हैं:

for (
 let i = 0; 
 
i < number;
 
  i += 1  
) { }
इनिशियलाइज़ेशनकंडीशनइंस्ट्रक्शन
  • इनिशियलाइज़ेशन: पुनरावर्तन चर i को गिनती शुरू करने के लिए एक संख्या से इनिशियलाइज़ करें।

    let i = 0;
  • कंडीशन: वह कंडीशन जो लूप को चालू रखती है। जब तक यह कंडीशन true है, for loop चलता रहेगा। जब यह कंडीशन false होगी, for loop रुक जाएगा।

    i < number;
  • इंस्ट्रक्शन: यह प्रोग्राम को बताता है कि हर बार लूप चलने पर गिनती की संख्या कैसे बदलनी है।

    i += 1;

पहली एक्सप्रेशन, let i = 0, for loop को इनिशियलाइज़ या शुरू करती है।

  • i एक चर है जो for loop की प्रारंभिक स्थिति को डिफ़ाइन करता है। इसे अनुक्रमणिका चर भी कहा जाता है। आमतौर पर, अनुक्रमणिका 0 की वैल्यू से शुरू होता है, और हर लूप में बढ़ता है। इस चर का नाम कुछ भी हो सकता है। आमतौर पर, i, j और k जैसे सिंगल-लेटर चर का उपयोग किया जाता है, लेकिन आप कुछ अधिक वर्णनात्मक भी उपयोग कर सकते हैं।

दूसरी एक्सप्रेशन, i < number, लूप को चालू रखने की कंडीशन है। इसे बूलियन एक्सप्रेशन के रूप में जाना जाता है, क्योंकि यह एक्सप्रेशन true या false रिटर्न कर सकती है। जब तक यह एक्सप्रेशन true है, for loop चलता रहेगा, और इस मामले में अनुक्रमणिका चर (i) बढ़ता रहेगा।

  • number कोई भी न्यूमेरिकल वैल्यू या चर हो सकता है जो न्यूमेरिकल वैल्यू स्टोर करता है। गिनती के लिए, अक्सर इंटीजर्स का उपयोग किया जाता है।
    • उदाहरण: i < 5; या i < segments;
  • इस मामले में, number for loop के चलने की संख्या निर्धारित करता है क्योंकि प्रारंभिक वैल्यू i 0 से शुरू होती है।
  • ऊपर के कैटरपिलर उदाहरण में, हमने इस वैल्यू को segments चर पर सेट किया, जो कैटरपिलर के शरीर बनाने वाले सर्कल्स की संख्या निर्दिष्ट करता है। जब तक अनुक्रमणिका segments में स्टोर की गई संख्या तक नहीं पहुँचता, लूप सर्कल ड्रॉ करता रहेगा।
    • एक बार जब ड्रॉ किए गए सर्कल्स की संख्या segments से कम नहीं रहती, प्रोग्राम for loop से बाहर निकलता है, और कोड की अगली लाइन पर जाता है।

तीसरी एक्सप्रेशन, i += 1, बताती है कि हर लूप पुनरावर्तन के अंत में अनुक्रमणिका कैसे बदलेगा।

  • एक लूप पुनरावर्तन एक लूप के एक बार चलने को कहते हैं। उदाहरण के लिए, अगर एक for loop 3 बार चलता है, तो उसमें 3 पुनरावर्तन हैं।
  • इस उदाहरण में, हर बार for loop चलने पर i चर 1 से बढ़ेगा। इसका मतलब है कि पहली बार जब यह for loop चलता है, i 0 है। दूसरी बार लूप चलता है, i 1 है। तीसरी बार i 2 है, और इसी तरह (जब तक यह number वैल्यू तक नहीं पहुँचता)। इस एक्सप्रेशन i += 1 को i++ भी लिखा जा सकता है।

सारांश में:

  1. जब कोई प्रोग्राम for loop एक्सीक्यूट करता है, तो वह पहले पहली एक्सप्रेशन में लूप के अनुक्रमणिका चर को डिक्लेयर करता है।
  2. वह दूसरी एक्सप्रेशन चेक करता है, जो एक बूलियन एक्सप्रेशन है। अगर यह true है, तो वह घुंघराले कोष्ठक के अंदर लिखा कोड चलाता है।
  3. एक लूप के अंत में, पुनरावर्तन चर i की वैल्यू तीसरी एक्सप्रेशन द्वारा डिफ़ाइन किए अनुसार बदलती है।
  4. लूप इस प्रक्रिया को तब तक दोहराता है जब तक दूसरी एक्सप्रेशन की कंडीशन false नहीं हो जाती। जब कंडीशन false होती है, प्रोग्राम for loop से बाहर निकलता है और स्केच में कोड की अगली लाइनों पर जाता है।

अधिक जानने के लिए for loops reference देखें।

3.3 – कैटरपिलर में और डिटेल्स जोड़ें

  • अगर आप चाहें तो अपनी कैटरपिलर के शरीर के लिए fill() रंग बदलें। इस उदाहरण में, हम इसे गुलाबी रंग देंगे: fill(255, 0, 200);
  • कैटरपिलर की आँखें ड्रॉ करें। आँखों की पोज़िशन बॉडी के लिए ड्रॉ किए गए आखिरी सर्कल के x- और y-निर्देशांक के समान है। इसका मतलब है कि यह for loop द्वारा सभी सर्कल ड्रॉ करने के बाद आता है, इसलिए हम आँखें for loop के बाद, लेकिन noLoop() से पहले जोड़ेंगे। यह सुनिश्चित करता है कि आँखें कैटरपिलर के शरीर के आखिरी सर्कल के ऊपर ड्रॉ होती हैं।
    • setup() के ऊपर eyeSize को एक नए ग्लोबल चर के रूप में डिक्लेयर करें, और इसे 15 की वैल्यू असाइन करें।
    • दो सर्कल ड्रॉ करें।
      • उन्हें काली fill और मोटी सफ़ेद stroke दें।
    • पहली आँख जोड़ें और उसके निर्देशांक और साइज सेट करें: circle(x, circY-eyeSize, eyeSize);
      • यह आँख को आखिरी ड्रॉ किए गए सर्कल के ऊपर रखता है।
    • दूसरी आँख जोड़ें और उसके निर्देशांक और साइज सेट करें: circle(x - eyeSize, circY-eyeSize, eyeSize);
      • हम दूसरी आँख के x-निर्देशांक से eyeSize घटाते हैं ताकि दोनों आँखें बिना ओवरलैप के एक साथ हों।
  • जब आपकी कैटरपिलर पूरी हो जाए, अपने कोड को drawCaterpillar() नाम के कस्टम कार्य में ऑर्गनाइज़ करें। कैटरपिलर को अपनी पसंद के अनुसार मॉडिफ़ाई करें!
    • drawCaterpillar() कार्य को draw() के बाहर डिफ़ाइन करें।
    • कार्य में कैटरपिलर के शरीर के लिए सर्कल्स का for loop और कैटरपिलर की आँखों के लिए दो सर्कल शामिल होने चाहिए।
    • इसे draw() कार्य में कॉल करना न भूलें! if-स्टेटमेंट से पहले draw() में drawCaterpillar(); टाइप करें जो लूप को रोकता है।

आपका स्केच अब तक कुछ इस तरह दिख सकता है:

Try this!

bodySize और eyeSize चर को एडजस्ट करके कैटरपिलर के शरीर और आँखों के अलग-अलग साइज़ आज़माएं।

चरण 4 – drawCaterpillar() कार्य को जनरलाइज़ करें

जब स्केच पहली बार चलता है, हम चाहते हैं कि हर कैटरपिलर स्टार्टिंग लाइन पर हो। इसका मतलब है कि हमें अपने कार्य में पैरामीटर्स जोड़ने होंगे ताकि हम निर्दिष्ट कर सकें कि कैटरपिलर कहाँ ड्रॉ होंगी।

  • drawCaterpillar() कार्य पर जाएं।
    • कार्य के कोष्टक में x को पैरामीटर के रूप में जोड़ें: function drawCaterpillar(x) { ...}
      • ध्यान दें कि हमने पहले से ही drawCaterpillar() कार्य में x को लोकल चर के रूप में डिक्लेयर किया था। हम उस डिक्लेरेशन को हटा सकते हैं और इसके बजाय x पैरामीटर का उपयोग कर सकते हैं।
    • कार्य के कोष्टक में y को दूसरे पैरामीटर के रूप में जोड़ें: function drawCaterpillar(x,y) { ... }
      • कार्य बॉडी में circY की जगह y रखें।

आप कस्टम कार्य, तर्क, और पैरामीटर्स के बारे में हमारे पिछले ट्यूटोरियल, Organizing Code with Functions, और functions के p5.js reference में अधिक जान सकते हैं।

आपके कस्टम कार्य अब इस तरह दिखने चाहिए:

function drawCaterpillar(x,y) {
  // शरीर बनाने के लिए
  // सर्कल्स का लूप बनाएं।
  for (let i = 0; i < segments; i += 1) {
    fill(255, 0, 200);
    stroke(0);
    strokeWeight(1);
    circle(x, y, 50);

    x += spacing;
  }
 
  // कैटरपिलर की आँखें ड्रॉ करें।
  fill(0);
  stroke(255);
  strokeWeight(3);
  circle(x, y - eyeSize, eyeSize);
  circle(x - eyeSize, y - eyeSize, eyeSize);
}
  • draw() में, तीन कैटरपिलर पाने के लिए drawCaterpillar() को तीन बार कॉल करें

आपका draw कार्य इस तरह दिखना चाहिए:

function draw() {
  // बैकग्राउंड ड्रॉ करें।
  background(121, 96, 76);
  // स्टार्ट और फ़िनिश लाइन ड्रॉ करें।
  noStroke();
  fill(0);
  rect(startLine, 0, 5, height);
  fill(0, 255, 0);
  rect(finishLine, 0, 20, height);

  // 3 कैटरपिलर ड्रॉ करें।
  drawCaterpillar(circX,circY-150);
  drawCaterpillar(circX,circY);
  drawCaterpillar(circX,circY+150);

  circX += spacing;
  // जब x फ़िनिश लाइन
  // पर पहुँचे तो लूप रोकें।
  if (circX > finishLine) {
    noLoop();
  }
}

चरण 5 – एक drawCaterpillars() कार्य बनाएं

अब हमारे पास 3 कैटरपिलर एक साथ पर्दा पर चल रही हैं। हम तीन अलग-अलग drawCaterpillar() कार्य कॉल्स के बजाय एक लूप का उपयोग करके तीनों कैटरपिलर ड्रॉ कर सकते हैं।

  • अपने स्केच में setup() के ऊपर कैटरपिलर की संख्या के लिए एक नया ग्लोबल चर डिक्लेयर करें: let numCaterpillars = 3;
  • draw() के बाहर एक नया कस्टम कार्य बनाएं और उसका नाम drawCaterpillars() रखें
    • drawCaterpillars() कार्य के अंदर एक नया for loop बनाएं।
      • लूप की पहली एक्सप्रेशन में लूप के चर को 0 से इनिशियलाइज़ और शुरू करें।
      • लूप की दूसरी एक्सप्रेशन में कंडीशन i < numCaterpillars सेट करें।
      • तीसरी एक्सप्रेशन में लूप के चर को इंक्रीमेंट करें।
    • for loop के घुंघराले कोष्ठक के अंदर drawCaterpillar(circX, circY); कॉल करें।
  • draw() में, drawCaterpillars(); कॉल करें

आपके draw() और drawCaterpillars() कार्य इस तरह दिखने चाहिए:

let numCaterpillars = 3;

// ...चर डिक्लेरेशन्स और setup

function draw() {
  // बैकग्राउंड ड्रॉ करें।
  background(121, 96, 76);
  // स्टार्ट और फ़िनिश लाइन ड्रॉ करें।
  noStroke();
  fill(0);
  rect(startLine, 0, 5, height);
  fill(0, 255, 0);
  rect(finishLine, 0, 20, height);

  circX += spacing;

  // कैनवास पर कैटरपिलर ड्रॉ करें
  drawCaterpillars();

  // जब x फ़िनिश लाइन
  // पर पहुँचे तो लूप रोकें।
  if (circX > finishLine) {
    noLoop();
  }
}

function drawCaterpillars() {
  for (let i = 0; i < numCaterpillars; i += 1) {
    drawCaterpillar(circX,circY);
  }
}

स्केच चलना चाहिए लेकिन इस बार आपको सिर्फ़ एक कैटरपिलर दिखाई देगी। ऐसा इसलिए है क्योंकि तीनों कैटरपिलर एक-दूसरे के ऊपर ड्रॉ हो रही हैं। इसे ठीक करने के लिए अगले स्टेप में हम हर कैटरपिलर का y निर्देशांक एडजस्ट करेंगे:

चरण 6 – रेस के लिए कैटरपिलर को पोज़िशन करें

रिकैप! चरण 3 और 4 से, हमारे स्केच में दो कस्टम कार्य हैं।

  • drawCaterpillar(x,y) पैरामीटर्स x और y का उपयोग करके एक कैटरपिलर ड्रॉ करता है।
  • drawCaterpillars() drawCaterpillar() कार्य को कॉल करता है और इसे for loop के अंदर रखता है ताकि हम कई कैटरपिलर ड्रॉ कर सकें।

अभी, हर कैटरपिलर एक ही x- और y-निर्देशांक पर है। हम y-निर्देशांक के साथ कैटरपिलर को अलग-अलग करने के लिए for loop के कोड को एडजस्ट करेंगे।

  • drawCaterpillars() कार्य डिक्लेरेशन पर जाएं।
    • for loop के अंदर, कोड की एक नई लाइन जोड़ें: let padding = height / numCaterpillars;
      • यह padding नाम का एक नया चर डिक्लेयर करता है जो हर कैटरपिलर के बीच वर्टिकल स्पेस निर्धारित करता है।
      • हम इसे कैनवास की height को स्केच में कैटरपिलर की संख्या से विभाजित करके असाइन करते हैं। यह कैनवास को वर्टिकली पंक्तियों में विभाजित करता है (हर कैटरपिलर के लिए एक)। हर पंक्ति की ऊँचाई padding की वैल्यू है।
    • चर y को इस वैल्यू से इनिशियलाइज़ करें: let y = (i + 0.5) * padding, जहाँ y हर कैटरपिलर का y-निर्देशांक निर्धारित करता है।
      • i चर का उपयोग करके, for loop की हर पुनरावर्तन एक कैटरपिलर को उसकी अपनी पंक्ति में पोज़िशन करती है
      • i में 0.5 जोड़ने से कैटरपिलर उस पंक्ति के बीच में सेंटर होती है।
  • चरण 5 की तरह, drawCaterpillar() कार्य कॉल के कोष्टक में y को तर्क के रूप में जोड़ें।
    • कोड की लाइन अब यह होनी चाहिए: drawCaterpillar(circX, y);

सारांश में, हमने drawCaterpillar() कार्य के अंदर उपयोग करने के लिए x और y को पैरामीटर्स के रूप में असाइन किया है। हम drawCaterpillars() में इस कार्य को कॉल करते समय circX और y को तर्क के रूप में उपयोग करते हैं।

आप कस्टम कार्य, तर्क, और पैरामीटर्स के बारे में हमारे पिछले ट्यूटोरियल, Organizing Code with Functions, में अधिक जान सकते हैं।

आपका drawCaterpillars() कार्य अब तक इस तरह दिखना चाहिए:

function drawCaterpillars() {
  for (let i = 0; i < numCaterpillars; i += 1) {
    let padding = height/numCaterpillars;
    let y = (i + 0.5) * padding;

    drawCaterpillar(circX, y, 6);
  }
}

For loop अनुक्रमणिका चर के साथ ड्रॉइंग

for loop का अनुक्रमणिका चर (i) हर लूप पुनरावर्तन के साथ इंक्रीमेंटली बढ़ या घट सकता है। इस ट्यूटोरियल में, i चर 0 से शुरू होता है और हर बार for loop चलने पर 1 से बढ़ता है।

  • पहली बार जब यह for loop चलता है, i 0 है।
  • दूसरी बार लूप चलता है, i 1 है।
  • तीसरी बार i 2 है, और इसी तरह आगे।

हम अपनी ड्रॉइंग में अनुक्रमणिका चर का उपयोग संख्याओं को जोड़ने, घटाने, गुणा करने और विभाजित करने के लिए कर सकते हैं ताकि for loop की हर पुनरावर्तन के लिए उनका परिणाम अलग हो।

इस उदाहरण में, हम i का उपयोग हर कैटरपिलर के बीच सुसंगत स्पेसिंग की गणना करने के लिए करते हैं (नीचे दी गई टेबल देखें):

  • पहली पुनरावर्तन के दौरान i 0 है और y 0.5 * padding है। पहली कैटरपिलर उस y वैल्यू के साथ ड्रॉ होती है।
  • दूसरी पुनरावर्तन के दौरान, i 1 है और y 1.5 * padding बन जाता है। दूसरी कैटरपिलर नई y वैल्यू पर ड्रॉ होती है।
  • तीसरी पुनरावर्तन के दौरान, i 2 है और y 2.5 * padding बन जाता है। तीसरी कैटरपिलर नई y वैल्यू पर ड्रॉ होती है।

कैटरपिलर (लूप पुनरावर्तन)

x

y

पहली

0

0.5 * padding

दूसरी

1

1.5 * padding

तीसरी

2

2.5 * padding

drawCaterpillar() और drawCaterpillars() अब इस तरह दिखने चाहिए:

// ... चर डिक्लेरेशन्स, setup(), और draw()

function drawCaterpillars() {
  for (let i = 0; i < numCaterpillars; i += 1) {
    // हर कैटरपिलर के बीच स्पेस।
    let padding = height / numCaterpillars;
    let y = (i + 0.5) * padding;

    // कैटरपिलर ड्रॉ करें
    drawCaterpillar(circX, y);
  }
}

function drawCaterpillar(x, y) {
  // शरीर बनाने के लिए
  // सर्कल्स का लूप बनाएं।
  for (let i = 0; i < segments; i += 1) {
    fill(255, 0, 200);
    stroke(0);
    strokeWeight(1);
    circle(x, y, 50);

    x+=spacing;
  }

  // कैटरपिलर की आँखें ड्रॉ करें।
  fill(0);
  stroke(255);
  strokeWeight(3);
  circle(x, y - eyeSize, eyeSize);
  circle(x - eyeSize, y - eyeSize, eyeSize);
}

यह सब एक साथ इस तरह दिखना चाहिए:

Try this!

numCaterpillars ग्लोबल चर की वैल्यू बदलें और देखें कि drawCaterpillars() में for loop उन्हें कैनवास पर वर्टिकली कैसे स्पेस करता है।

चरण 7 – हर कैटरपिलर की पोज़िशन सेव करने के लिए सरणी बनाएं

अब जबकि हमने कैटरपिलर को कैनवास पर वर्टिकली पोज़िशन कर दिया है, हम हर एक को एक यूनीक x-निर्देशांक देना चाहते हैं। हम सरणी का उपयोग करके यह कर सकते हैं। सरणी में हर कैटरपिलर के x निर्देशांक होंगे। फिर हम कैटरपिलर को पर्दा पर रैंडमली मूव कर सकते हैं, जिससे रेस संभव हो।

7.1 – एक सरणी बनाएं

  • numCaterpillars के ठीक बाद caterpillarEnds सरणी डिक्लेयर करें: let caterpillarEnds = [];
    • यह सरणी हर कैटरपिलर के सबसे बाएं सेगमेंट की x पोज़िशन को होल्ड करेगा।

आप अगले ट्यूटोरियल, Data Structure Garden में सरणियाँ के बारे में और जानेंगे। अधिक जानने के लिए arrays के MDN reference देखें।

  • setup() में, हर कैटरपिलर के लिए x निर्देशांक जोड़ें, उन सभी को स्टार्ट लाइन पर रखें।
    • एक for loop बनाएं जो हर कैटरपिलर के लिए एक बार दोहराए: for (let i=0; i < numCaterpillars; i++) { }
    • घुंघराले कोष्ठक के अंदर, लाइन caterpillarEnds.push(startLine); जोड़ें
      • यह caterpillarEnds सरणी में हर कैटरपिलर के लिए startLine की वैल्यू जोड़ देगा जिसे स्केच में ड्रॉ करना है।
      • .push() मेथड का उपयोग सरणी के अंत में एक नई वैल्यू जोड़ने के लिए किया जाता है।

अब setup() इस तरह दिखना चाहिए:

function setup() {
  createCanvas(500, 500);

  // धीमी frame rate सेट करें।
  frameRate(6);

  for (let i=0; i < numCaterpillars; i++) {
    // आखिरी सेगमेंट की पोज़िशन सरणी में जोड़ें
    caterpillarEnds.push(startLine);
  }
}
  • drawCaterpillars() कार्य में, drawCaterpillar(circX,y) लाइन बदलें:
    • circX के बजाय, अब हम caterpillarEnds सरणी की वैल्यूज़ का उपयोग करेंगे।
    • चूंकि for loop में अनुक्रमणिका i caterpillarEnds सरणी में सही अनुक्रमणिका पोज़िशन को दर्शाता है, हम circX को caterpillarEnds[i] में बदल सकते हैं: drawCaterpillar(caterpillarEnds[i], y);
  • कार्य से circX हटा दें।
    • नोट: circX अभी भी draw() के अंत में उपयोग हो रहा है। उसे भी हटा दें और हम बाद में वापस जोड़ेंगे।

आपका drawCaterpillars() कार्य इस तरह दिखना चाहिए:

function drawCaterpillars() {
  for (let i = 0; i < numCaterpillars; i += 1) {  
    // हर कैटरपिलर के बीच स्पेस।
    let padding = height / numCaterpillars;
    let y = (i + 0.5) * padding;

    // सरणी का उपयोग करके कैटरपिलर ड्रॉ करें।
    drawCaterpillar(caterpillarEnds[i], y);
  }
}

7.2 – कैटरपिलर को रैंडमली मूव कराएं

  • draw() के बाहर एक नया कस्टम कार्य बनाएं और उसका नाम moveCaterpillars() रखें

  • एक नया for loop डिफ़ाइन करें जो कैटरपिलर की संख्या जितनी बार इटरेट करे: for (let i = 0; i < numCaterpillars; i += 1) { }

    • यह वही for loop वाक्य-विन्यास है जो drawCaterpillars() कार्य में उपयोग किया गया है क्योंकि यह आपको हर कैटरपिलर को अलग-अलग संदर्भित करने की सुविधा देता है।
  • लूप के अंदर, move को एक लोकल रैंडम वैल्यू असाइन करें:

    let move = random(5,30);
  • एक बार रेस शुरू होने पर, यह हर बार draw() चलने पर हर कैटरपिलर को 5 से 30 पिक्सेल के बीच रैंडमली दाईं ओर मूव करेगा।

  • अपनी कैटरपिलर के लिए इच्छित गति सीमा के अनुसार random() में वैल्यूज़ मॉडिफ़ाई कर सकते हैं। अधिक जानने के लिए random() का p5.js reference देखें।

आपका कार्य इस तरह दिख सकता है:

function moveCaterpillars() {
  for (let i = 0; i < numCaterpillars; i += 1) {
    // हर कैटरपिलर को
    // रैंडम स्पीड दें।
    let move = random(5, 30);
    caterpillarEnds[i] += move;
  }
}

सारांश में, ऊपर दिए गए कार्य में इवेंट्स का क्रम है:

  • हर लूप पुनरावर्तन के लिए, हम move को 5 और 30 के बीच एक रैंडम नंबर असाइन करते हैं।
    • इसका मतलब है कि हर कैटरपिलर को एक अलग रैंडम move असाइन होता है।
  • फिर हम caterpillarEnds सरणी की iवीं पोज़िशन में वैल्यू अपडेट करते हैं, जिसे drawCaterpillar() कार्य कैटरपिलर दिखाने के लिए उपयोग करता है।

7.3 – कैटरपिलर को मूव कराएं

  • अंत में, draw() में drawCaterpillars() कार्य कॉल से पहले moveCaterpillars() कार्य कॉल करें।

आपका कोड इस तरह दिखना चाहिए!

चरण 8 – कैटरपिलर को रेंगने जैसी गति दें

‘रेंगने’ जैसी गति बनाने के लिए, हम random() कार्य का उपयोग करके हर कैटरपिलर के सेगमेंट्स की संख्या को रैंडमाइज़ करेंगे। याद दिलाने के लिए, ग्लोबल segments चर कैटरपिलर के दिखाए जाने वाले सेगमेंट्स की संख्या निर्धारित करता है। अब हम इसे drawCaterpillar() कार्य में एक पैरामीटर में बदलेंगे।

  • drawCaterpillar() कार्य डेफ़िनिशन पर जाएं।
    • segments नाम का एक नया पैरामीटर जोड़ें। यह अब इस तरह दिखना चाहिए: function drawCaterpillar(x, y, segments) { ... }
    • आप स्केच के ऊपर segments ग्लोबल चर को हटा सकते हैं।
  • drawCaterpillars() कार्य डेफ़िनिशन पर जाएं।
    • drawCaterpillar() कार्य कॉल के कोष्टक में तीसरे तर्क के रूप में crawl जोड़ें: drawCaterpillar(x, y, crawl);
    • इस लाइन के ऊपर, crawl चर को एक नई रैंडम वैल्यू असाइन करें: let crawl = round(random(3, 6));
      • इसका मतलब है कि स्केच चलने के दौरान, प्रोग्राम कैटरपिलर को रैंडम लंबाई (3 से 6 सर्कल के बीच) पर लगातार ड्रॉ करेगा जबकि उन्हें स्टार्ट से फ़िनिश लाइन तक मूव करेगा।
      • कैटरपिलर कितनी लंबी और छोटी होकर रेंगें, इसके अनुसार random() में वैल्यूज़ मॉडिफ़ाई कर सकते हैं।
      • crawl चर की रैंडम वैल्यू drawCaterpillar() कार्य डेफ़िनिशन में segments पैरामीटर को पॉपुलेट करेगी, जो निर्धारित करती है कि कितने सर्कल ड्रॉ होंगे।

आपके कार्य इस तरह दिखने चाहिए:

// ... चर डिक्लेरेशन्स, setup(), draw(), moveCaterpillars() कार्य
function drawCaterpillars() {
  for (let i = 0; i < numCaterpillars; i += 1) {
    // हर कैटरपिलर का x-निर्देशांक अपडेट करें
    let padding = height / numCaterpillars;
    let y = (i + 0.5) * padding;

    // कैटरपिलर की लंबाई अपडेट करें।   
    let crawl = round(random(3, 6));

    // कैटरपिलर ड्रॉ करें।
    drawCaterpillar(x, y, crawl);
  }
}

function drawCaterpillar(x, y, segments) {
  // शरीर बनाने के लिए
  // सर्कल्स का लूप बनाएं।
  for (let i = 0; i < segments; i += 1) {
    fill(255, 0, 200);
    stroke(0);
    strokeWeight(1);
    circle(x, y, 50);
    x += spacing;
  }

  // कैटरपिलर की आँखें ड्रॉ करें।
  fill(0);
  stroke(255);
  strokeWeight(3);
  circle(x, y - eyeSize, eyeSize);
  circle(x - eyeSize, y - eyeSize, eyeSize);
}

चरण 9 – माउस ट्रिगर से रेस शुरू करें

  • isRacing नाम का एक नया बूलियन ग्लोबल चर डिक्लेयर करें और इसे false सेट करें: let isRacing = false;

    • यह चर एक स्टेट चर की तरह काम करेगा, जो बूलियन वैल्यू (true या false) के रूप में यह जानकारी स्टोर करेगा कि कैटरपिलर रेस कर रही हैं या नहीं।
  • एक mousePressed() कार्य डिफ़ाइन करें।

    • कार्य में, isRacing बूलियन को true सेट करें।
  • कार्य इस तरह दिखना चाहिए:

    // जब यूज़र माउस प्रेस करे
    // तो रेस शुरू करें।
    function mousePressed() {
      isRacing = true;
    }
  • draw() कार्य में, drawCaterpillars() कार्य कॉल से पहले एक नया if-स्टेटमेंट बनाएं: if (isRacing === true) { }

  • moveCaterpillars() कार्य कॉल को if-स्टेटमेंट में मूव करें।

    • इसका मतलब है कि कैटरपिलर तभी मूव करना शुरू करेंगी जब रेस शुरू होगी (माउस प्रेस करने के बाद)।
  • आपका कोड इस तरह दिखना चाहिए:

// ... ग्लोबल चर डिफ़ाइन करें

let isRacing = false;

function setup() {
  createCanvas(500, 500);
  // धीमी frame rate सेट करें।
  frameRate(3);

  for (let i=0;i<numCaterpillars;i++) {
    caterpillarEnds.push(startLine)
  }
}

function draw() {
  // बैकग्राउंड ड्रॉ करें।
  background(121, 96, 76);

  // स्टार्ट और फ़िनिश लाइन ड्रॉ करें।
  noStroke();
  fill(0);
  rect(startLine, 0, 5, height);
  fill(0, 255, 0);
  rect(finishLine, 0, 20, height);

  // अगर रेस शुरू हो गई है
  // तो कैटरपिलर मूव कराएं।
  if (isRacing === true) {
    moveCaterpillars();
  }

  drawCaterpillars();
}

// जब यूज़र माउस प्रेस करे
// तो रेस शुरू करें।
function mousePressed() {
  isRacing = true;
}

// ... moveCaterpillars, drawCaterpillars, और drawCaterpillar कार्य।

चरण 10 – रेस की शुरुआत और अंत के लिए मैसेज जोड़ें

बहुत बढ़िया! आपके स्केच के इस स्टेज पर, आपके पास एक कैटरपिलर रेस है जो माउस क्लिक करने पर शुरू होती है।

अब, हमें बस कैनवास पर प्रोग्राम का उपयोग करने के निर्देश जोड़ने हैं। हम रेस के अंत में विजेता कैटरपिलर की घोषणा करने के लिए एक मैसेज भी जोड़ेंगे, जो रैंडम होगा। हम noLoop() कार्य वापस जोड़ेंगे ताकि विजेता घोषित होने पर रेस रुक जाए।

10.1 – स्टार्ट मैसेज लिखें

  • draw() के बाद एक नया कस्टम कार्य बनाएं और उसका नाम writeStart() रखें।

  • कार्य के अंदर, जोड़ें: text(" 🏁 Click to start!", width / 2, height / 2);

    • यह निर्देश टेक्स्ट लिखता है और इसे कैनवास के केंद्र में रखता है।
    • text() कमांड के ऊपर textAlign(CENTER); जोड़कर टेक्स्ट को सेंटर में अलाइन करें।
    • टेक्स्ट में स्टाइल्स जोड़ें। इस उदाहरण में, हम इसे सफ़ेद रंग, बिना stroke और 24 का टेक्स्ट साइज देंगे।
  • आपका writeStart() कार्य इस तरह दिखना चाहिए:

    function writeStart() {
     
      // टेक्स्ट स्टाइल करें।
      textSize(24);
      textAlign(CENTER);
      fill(255);
      noStroke();
     
      // मैसेज दिखाएं।
      text("🏁 Click to start!", width / 2, height / 2);
    }
  • draw() कार्य पर वापस जाएं और एक else-स्टेटमेंट जोड़ें: else {}

    • यह else-स्टेटमेंट तब एक्सीक्यूट होगा जब रेस अभी शुरू नहीं हुई है
  • इस else-स्टेटमेंट कोड ब्लॉक के अंदर writeStart() कार्य कॉल करें।

draw() कार्य इस तरह दिखना चाहिए:

function draw() {
  // बैकग्राउंड ड्रॉ करें।
  background(121, 96, 76);

  // स्टार्ट और फ़िनिश लाइन ड्रॉ करें।
  noStroke();
  fill(0);
  rect(startLine, 0, 5, height);
  fill(0, 255, 0);
  rect(finishLine, 0, 20, height);

  // अगर रेस शुरू हो गई है
  // तो कैटरपिलर मूव कराएं।
  if (isRacing === true) {
    moveCaterpillars();
  } else { 
    // अगर रेस शुरू नहीं हुई,
    // तो शुरू करने के निर्देश लिखें।
    writeStart();
  }

  // नई पोज़िशन पर कैटरपिलर ड्रॉ करें
  drawCaterpillars();
}

10.2 – विजेता चेक करें और लिखें कि कौन जीता।

हमें चेक करना होगा कि क्या किसी कैटरपिलर ने जीत हासिल की है। अगर हाँ, तो हमें वह जानकारी दिखानी होगी और रेस खत्म करनी होगी।

  • विजेता चेक करने के लिए draw() के नीचे एक नया कार्य बनाएं: function checkWinner() {}

  • कार्य के घुंघराले कोष्ठक के अंदर, हर कैटरपिलर की x वैल्यूज़ चेक करने के लिए एक for loop लिखें कि क्या उन्होंने जीता है: for (let i = 0; i < caterpillarEnds.length; i += 1) {}

  • for loop के घुंघराले कोष्ठक के अंदर, एक if स्टेटमेंट शामिल करें यह देखने के लिए कि क्या हर कैटरपिलर फ़िनिश लाइन पार कर चुकी है: if (caterpillarEnds[i] >= finishLine) {}

  • इस if स्टेटमेंट के अंदर, टेक्स्ट लिटरल का उपयोग करके विजेता को डायनामिकली टेक्स्ट में लिखें:

    text(`Caterpillar ${i + 1} wins!`, width / 2, height / 2);
    • यह डायनामिकली विजेता कैटरपिलर का अनुक्रमणिका दिखाने वाला टेक्स्ट लिखता है। चूंकि अनुक्रमणिका 0 से शुरू होते हैं और आमतौर पर हम कैटरपिलर 1 से गिनते हैं, हमने i की वैल्यू में 1 जोड़ा
    • चरण 9.1 की तरह, textAlign(CENTER); जोड़कर टेक्स्ट को सेंटर में अलाइन करें और टेक्स्ट में स्टाइल्स जोड़ें।
  • if स्टेटमेंट के अंदर noLoop() कार्य भी शामिल करें ताकि draw() चलना बंद हो जाए।

आपका checkWinner() कार्य इस तरह दिख सकता है:

function checkWinner() {
  for (let i = 0; i < caterpillarEnds.length; i += 1) {
    if (caterpillarEnds[i] >= finishLine) {
      // टेक्स्ट स्टाइल करें।
      textSize(24);
      textAlign(CENTER);
      fill(255);
      noStroke();

      // मैसेज दिखाएं।
      text(`Caterpillar ${i + 1} wins!`, width / 2, height / 2);

      noLoop();
    }
  }
}

आपका अंतिम स्केच इस तरह दिखना चाहिए:

निष्कर्ष

इस ट्यूटोरियल को पूरा करने पर बधाई! अब आपने p5.js में कई मूविंग शेप्स जनरेट करने के लिए लूप्स का उपयोग करना सीख लिया है। शर्त कथन, इंटरएक्टिविटी, चर, और कार्य के बारे में अधिक जानने के लिए p5.js Reference या पिछले ट्यूटोरियल्स देखें।

अगले कदम

संदर्भ