اذهب إلى المحتوى

لوحة المتصدرين

  1. سمير عبود

    سمير عبود

    الأعضاء


    • نقاط

      3

    • المساهمات

      3552


  2. Hamada Sayed

    Hamada Sayed

    الأعضاء


    • نقاط

      1

    • المساهمات

      106


  3. Yomna Raouf

    Yomna Raouf

    الأعضاء


    • نقاط

      1

    • المساهمات

      2193


  4. Lamees Majed

    Lamees Majed

    الأعضاء


    • نقاط

      1

    • المساهمات

      27


المحتوى الأكثر حصولًا على سمعة جيدة

المحتوى الأعلى تقييمًا في 11/30/20 في كل الموقع

  1. سنتعلّم مبادئ HTML و CSS لإنشاء مشاريع ويب خاصة بنا. سيتميّز هذا الدرس بتركيزه على الجانب العملي بشكل كبير، حيث سنبدأ فورًا بإنشاء مشروع خاص بنا. أمّا بالنسبة للنواحي النظرية فسنشرحها عند الحاجة أثناء تقدّمنا ببناء المشروع. بهذه الطريقة سنكتسب أساسًا متينًا وسريعًا في مجال تطوير الويب. سأوجّهك خلال هذا المشروع إلى روابط خارجية تُشير إلى مصادر أخرى للتوسُّع في نقاط معيّنة إن أحببت ذلك. المشروع سيكون المشروع عبارة عن بناء ملف شخصي portfolio على الويب. سيضم صفحة بداية Home ومدوّنة Blog وصفحة تُظهر مشاريع ويب المستقبلية التي تنوي إنشائها Projects، بالإضافة إلى صفحة للتواصل Contact. الهدف من المشروع الهدف منه هو جعلك تدخل عالم برمجة الويب ومساعدتك كي تتعلّم كيفية إيجاد المزيد من المعلومات حول أي موضوع لوحدك. ستصبح قادرًا بعد ذلك على معالجة مشاريع ويب أكثر تعقيدًا. ما هو HTML و CSS؟ لغة الرُماز المعلَّم Hypertext Markup Language والتي ندعوها اختصاراً HTML هي لغة مسؤولة عن بُنية structure صفحة الويب. فمثلًا يمكنك تعريف عناوين headings وفقرات paragraphs ونصوص texts وصور images في HTML. أمّا بالنسبة لأوراق الأنماط المتتالية Cascading Style Sheet وندعوها اختصاراً CSS فهي مسؤولة عن تنسيق (تنميط) style وتخطيط layout صفحة الويب. يمكنك تعريف تنسيقات جديدة خاصة بالألوان والخطوط وطرق المحاذاة وحتى يمكنك إنشاء بعض التحريكات animations البسيطة في CSS. تذكّر: تزوّدنا HTML بالمحتوى في حين تُنسّق CSS هذا المحتوى. دورة تطوير واجهات المستخدم ابدأ عملك الحر بتطوير واجهات المواقع والمتاجر الإلكترونية فور انتهائك من الدورة اشترك الآن موقع ويب أم تطبيق ويب يمكننا بناء مواقع ويب websites معقّدة جدًّا باستخدام HTML و CSS فحسب. لكن ستكون مواقع الويب هذه ساكنة static، ويعني ذلك أنّ زوّار الموقع يمكنهم استعراض الصفحات لكنّهم لا يمكنهم التفاعل مع هذه الصفحات (باستثناء النقر على الروابط الموجودة في الصفحات). لبرمجة مواقع ويب ديناميكية dynamic تكون تفاعلية مع المستخدم، سنحتاج إلى لغة برمجة إضافية مثل JavaScript أو Dart. ويمكننا باستخدامهما تطوير (هو مفهوم أوسع من البرمجة) تطبيقات ويب Web Applications كاملة مثل التطبيقات التي تهتم بإجراء الحسابات المختلفة أو تطبيقات الألعاب أو تطبيقات المحادثة وغيرها الكثير. تعمل هذه التطبيقات في الواقع ضمن متصفّح الويب. كما توجد لغات برمجة وتقنيات أخرى مثل PHP وRuby وASP.NET تسمح ببناء تطبيقات ويب ديناميكية أيضًا ولكن تعمل هذه التطبيقات ضمن مزوّد خدمة الاستضافة (على المخدّم). كما يمكن المزج بين هذين الأسلوبين لإنشاء مواقع ويب فعّالة للغاية. يمكنك بعد الانتهاء من هذه الدروس، البدء بتعلّم مثل هذه اللغات والتقنيات وإنشاء تطبيقات ويب ديناميكية. أنشئ موقع احترافي لأعمالك وعزّز حضورك الرقمي صمم موقع إلكتروني فريد وجذاب لعملائك في دقائق دون خبرة برمجية باستخدام سنديان منشئ المواقع العربي أطلق موقعك الآن الأجهزة المحمولة يُشكّل الوصول إلى مواقع الويب عن طريق الأجهزة المحمولة كالهواتف الذكيّة أو الأجهزة اللوحية نسبة كبيرة من عمليات الوصول العامة. وهكذا فإنّه من الضروري أن يظهر موقعنا بشكل جيّد على الشاشات الصغيرة. على العموم سنولي هذا الأمر اهتمامًا خلال هذه السلسلة التعليمية. الأدوات المستخدمة نحتاج إلى تطبيقين للدخول في عالم تطوير وبرمجة الويب، محرّر نصوص لإنشاء الملفات الخاصة بموقع الويب، ومتصفّح ويب لعرض وتجربة الموقع. 1- المحرر Editor سيكون كافيًا استخدام محرّر نصوص عادي (كبرنامج المفكرة Notepad في ويندوز مثلًا). ولكن من الأفضل استخدام محرّر نصوص يسهّل عملنا إلى حدٍّ كبير. لهذا الغرض أنصح باستخدام محرّر نصوص عصري ومخصّص لتحرير HTML. محرّر النصوص الذي أنصح به حاليًا هو Brackets (مجّاني من شركة أدوبي Adobe). يمكنك أن تستخدم أي محرّر تريده، ولكنّني في هذه السلسلة سأُشير أحيانًا إلى بعض وظائف تطبيق Brackets. يوجد محرّر نصوص جيّد أيضاً ويمكنك استخدامه وهو Atom، ويوجد محرّر نصوص آخر أيضًا، قديم قليلًا لكنّه جيّد وهو ++Notepad. حمّل ونصّب المحرّر Brackets إذا أردت ذلك. 2- المتصفح Browser يتوجّب على موقعنا أن يعمل على جميع المتصفحات الرئيسية بالطبع (Internet Explorer و Firefox و Chrome و Safari). على أية حال، أنصح باستخدام المتصفح Chrome لأغراض التطوير والبرمجة. يضم Chrome أدوات مفيدة للغاية لمطوّر الويب والتي سيستخدمها على نحو متكرّر. بالإضافة إلى ذلك، يدعم المحرّر Brackets المتصفّح Chrome بشكل جيّد، بحيث أنّ التغييرات التي تحدث في النص ستظهر مباشرةً ضمن Chrome (عن طريق ميزة اسمها Live Reload). حمّل ونصّب المتصفح Chrome الآن من هنا. إنشاء مستند HTML لنبدأ الآن بإنشاء مستند HTML الأوّل لنا من أجل موقع الويب: أنشئ مجلّدًا من أجل المشروع. سمّ المجلّد بالاسم Portfolio (أو أي اسم آخر ترغبه). افتح برنامج Brackets. من القائمة File اختر الأمر …Open Folder لتحديد وفتح المجلّد الذي أنشأناه قبل قليل. انقر بزر الفأرة الأيمن أسفل اسم المجلّد واختر New File لإنشاء ملف جديد، سمّه index.html. لديك الآن ملف نصّي فارغ اسمه index.html لماذا الملف index.html؟ في الواقع للملف index.html معنى خاص، فعندما نطلب من المتصفّح عنوان موقع ويب ما، وليكن مثلًا http://code.makery.ch، فعند ذلك سيُعرَض الملف index.html أولاً بشكل تلقائي، أي كأنّنا طلبنا العنوان http://code.makery.ch/index.html. بالنسبة إلينا، سيمثّل الملف index.html الصفحة الرئيسية. عمليتا العرض والتحديث يمكننا الآن تعبئة مستند HTML (الملف index.html) بالمحتوى. اكتب الأسطر التالية ضمن مستند HTML. لعرض الصفحة ضمن المتصفّح، انقر الأيقونة التي تُشبه البرق في الطرف الأيمن من البرنامج (المعاينة الحية Live Preview). سيُفتَح المتصفّح Chrome وسيُعرض المستند ضمنه، وفي حال أجريت أي تغيير جديد على مستند HTML فسترى نتيجة ذلك على المتصفّح مباشرةً، وهي في الحقيقة ميزة هامة وفعّالة. إذا لم تظهر الصفحة، اذهب إلى المكان الذي يوجد فيه الملف index.html وافتحه مباشرةً باستخدام Chrome أو أي متصفّح آخر. أمّا لم تُحدّث الصفحة تلقائياً، فاحفظ جميع الملفات المفتوحة (سننشئ ملفات أخرى تباعاً) ثم من نافذة المتصفح اضغط F5 على لوحة المفاتيح. تهانينا، لقد أنشأت موقع ويب الأوّل الخاص بك. التحييد Indentation لكي نُبقي الشيفرة نظيفة وواضحة، من المهم أن تعمل على تحييد النص بشكل صحيح باستخدام مفتاح الجدولة Tab من لوحة المفاتيح. يأخذ مفتاح Tab في برنامج Brackets أربعة فراغات بشكل افتراضي. بالنسبة لي أجد ذلك كثيراً بعض الشيء، لذلك أنصح أن تغيّر هذا لتصبح الفراغات spaces التي يأخذها المفتاح Tab تساوي 2، وذلك من أسفل نافذة Brackets. من المهم جدًّا أن ننتبه إلى تحييد الشيفرة من البداية، لكي نكتب شيفرة نظيفة وواضحة من بداية تعلّمنا للبرمجة عموماً. تلميح 1: استخدام Shift+Tab لكي تنقل المحاذاة إلى اليسار بدلاً من اليمين. تلميح 2: يمكنك محاذاة عدة أسطر بنفس الوقت إذا اخترتهم وضغطت Tab أو حتى Shift+Tab. عناصر HTML 1- الوسوم Tags في المثال السابق رأيت رموزًا مكتوبة ضمن رمزي <> تشكل هذه الرموز كلمات نُسميها الوسوم Tags. تتألف عناصر HTML عادةً (ولكن ليس دائماً) من وسمين، وسم للفتح opening tag ووسم للإغلاق closing tag. في مثالنا السابق كان <html> هو وسم للفتح، أمّا <html/> هو وسم للإغلاق حيث نلاحظ وجود محرف slash قبل اسم الوسم. أي نص موجود بين وسمي الفتح والإغلاق يُعتبر محتوى لعنصر HTML هذا. فمثلاً بالنسبة للوسمين <html> و <html/> نُخبر متصفّح الويب عن بداية ونهاية مستند HTML لصفحة الويب الخاصة بنا. أمّا الوسم الثاني الذي صادفناه هو الوسم <body>. يُحدّد هذا الوسم أنّ جميع المحتوى الواقع بين وسم الفتح <body> والإغلاق <body/> سيظهر بشكل مرئي للمستخدم في المنطقة الرئيسية من نافذة المتصفّح. 2- السمات Attributes تُعرّف السمات معلومات إضافية لعنصر HTML. وتقع هذه السمات ضمن وسم الفتح لعنصر HTML، ويكون لها دائماً اسم name وقيمة value. كمثال على السمات، دعنا ننظر إلى عنصر HTML الخاص بالروابط. وهو ربما من أهم العناصر على الإطلاق. يضم عنصر الروابط <a> السمة href (وهي اختصار للكلمتين hypertext reference) التي تحمل القيمة في هذا المثال http://code.makery.ch.ولكن سيعرض المتصفّح هذا الرابط على شكل النص التالي: My Website. البنية الأساسية لصفحة HTML لقد رأينا قبل قليل عنصري HTML وهما <html> و <body>. ولكن بنية صفحة (مستند) HTML تتكوّن عادةً من المزيد من العناصر. استبدل محتويات الملف index.html بالشيفرة التالية، بعد ذلك سنناقش كل عنصر HTML موجود فيها. بنية ملف (مستند) HTML <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Web Portfolio of Marco</title> </head> <body> <h1>Web Portfolio of Marco</h1> <p>Write anything you want to tell the world.</p> </body> </html> الشرح نضع في السطر الأوّل <DOCTYPE html!> دوماً. فهي تخبر المتصفّح عن نوع المستند. يشير الوسم <html> إلى بداية المستند والوسم <html/> إلى نهايته. يحتوي العنصر <head> (بين وسمي الفتح والإغلاق له) على معلومات إضافية حول الصفحة. وبشكل مختلف عن العنصر <body>، لا تظهر هذه المعلومات في نافذة المتصفح الرئيسية. يجب أن تكون هناك إشارة ضمن العنصر <head> حول الترميز character set المستَخدَم في هذا المستند: <"meta charset="utf-8>. إذا لم تحدّد الترميز المستَخدَم فإنّ بعض الرموز قد لا تظهر بصورة صحيحة. ربما قد لاحظت أنّ العنصر <meta> لا يمتلك وسم إغلاق. توجد بعض عناصر HTML التي لا تمتلك أيضًا وسوم إغلاق، ولكنها تعتبر استثناءً. نرى بعد ذلك الوسم <title> الذي يضم عنوان المستند والذي سيظهر على شريط العنوان لنافذة المتصفّح. كل شيء ضمن الوسم <body> سيظهر ضمن نافذة المتصفّح الرئيسية. يُعرّف العنصر <h1> العنوان الرئيسي الذي سيظهر للمستخدم ضمن صفحة الويب. ويمكن إنشاء عناوين فرعية أيضاً باستخدام العناصر <h2> <h3> <h4> <h5> <h6>. النص الموجود بين الوسمين <p> و <p/> يُعتبر فقرة مستقلة، وهذا ما يُعبّر عنه العنصر <p>. بعد كل وسم فتح لعنصر ما، يجب أن نحاذي العنصر التالي (بمفتاح الجدولة Tab) لتحسين عرض الشيفرة. ورغم أنّ ذلك ليس ضرورياً ولا يؤثّر أصلاً في عرض المستند، ولكن تأكّد من امتلاكك لهذه العادة الجيّدة. تلميح 1: يمكنك استخدام بنية HTML السابقة لأي صفحة HTML جديدة. تلميح 2: استخدم الاختصار Ctrl+S من لوحة المفاتيح لحفظ الملف الحالي. تلميح 3: استخدم الاختصار Ctrl+Z من لوحة المفاتيح للتراجع عن العمليات التي أجريتها. نحن مستعدّون الآن وبعناصر HTML البسيطة هذه، أن نرتقي بموقعنا إلى مستوى أعلى. في البداية لنُضِف صورة بحيث تبدو الصفحة الرئيسية لمشروعنا أكثر جمالًا. إدراج صورة لإدراج صورة نستخدم العنصر <img>. المثال التالي سيُدرج صورة موجودة ضمن ملف اسمه marco.jpg: <img src="marco.jpg" alt="Picture of me"> للعنصر <img> وسم فتح فقط ولا يوجد له وسم إغلاق. وهو يحتوي على سمتين src و alt. السمة src تُحدّد عنوان URL الذي يُعبّر عن اسم ملف الصورة ومساره. أمّا السمة alt فتمثّل النص البديل، وهو النص الذي يصف محتويات الصورة. يُستخدم هذا النص من قِبل محرّكات البحث، وفي حال تعذّر عرض الصورة ضمن الصفحة سيُعرض هذا النص بدلاً عنها. 1- عناوين URL النسبية والمطلقة تُستخدم عناوين URL من أجل السمة src الخاصة بعنصر الصورة، وأيضاً من أجل السمة href الخاصة بعنصر الارتباط. يُحدّد عنوان URL عنوان (مسار) ملف، وبصورة عامة العنوان هو مصدر resource قد يكون صورة أو صفحة ويب من موقع آخر. بالاعتماد على موقع الملف نستخدم إمّا العنوان النسبي relative أو العنوان المطلق absolute. فإذا كان الملف موجودًا ضمن نفس موقع الويب، عندها يمكن استخدام عنوان نسبي. فكما رأينا في المثال السابق اسم الملف وحده موجود دون عنوانه الفعلي (المطلق). يكون عنوان URL من النوع النسبي، نسبيًا دومًا إلى صفحة HTML الحالية، فإذا كان الملف المستهدف وصفحة HTML التي ستستخدمه موجودان ضمن نفس المجلّد فعندها يكفي الإشارة إلى اسم الملف فقط، أمّا إذا كانا ضمن مجلّدين مختلفين فعندها يحب أن يؤخذ ذلك بعين الاعتبار. فإذا فرضنا مثلًا أنّ ملف الصورة من المثال السابق موجودة ضمن مجلّد فرعي اسمه images سيكون عنوان URL النسبي لملف الصورة images/marco.jpg. أمّا إذا كان ملف الصورة موجود ضمن المجلّد الأب، فيمكنك عندئذ الوصول إليه باستخدام البادئة ( /.. ) أي سيصبح عنوان الملف في هذه الحالة marco.jpg/.. أمّا إذا كان الملف موجوداً ضمن موقع ويب آخر، فعندها يجب استخدام عنوان URL مطلق. تحتوي عناوين URL المطلقة على الاسم والمسار الكاملين للملف. حقائق عن عناوين URL: عنوان URL الذي يبدأ بـ //:http هو عنوان URL مطلق. عنوان URL بدون //:http هو عنوان URL نسبي بالنسبة إلى صفحة ويب الحالية. تُشير النقطة ( . ) إلى المجلّد الحالي. تُشير النقطتان ( .. ) إلى المجلّد الأب. أمثلة عن عناوين ويب النسبية والمطلقة: <!-- عناوين نسبية --> <a href="image-gallery.html">Image Gallery</a> <a href="blog/first-blog-entry.html">My First Blog Entry</a> <a href="../image-gallery.html">Back to Image Gallery</a> <!-- عناوين مُطلقة --> <a href="http://www.my-colleague.com/blog.html">Blog of a Colleague</a> 2- إضافة صورة إلى موقعنا لندرج صورة ضمن الصفحة، ينبغي نسخ ملف الصورة إلى المجلّد Portfolio. من الممكن أن تستخدم نفس الصورة الموجودة مع هذا الدرس، أو أن تستخدم صورة من عندك، ولكن احرص في جميع الأحوال على أنّك ستُحدّد اسم الملف مع الامتداد بدقّة. يجب أن تحصل على شيفرة شبيهة بما يلي (لاحظ أنّني أضفت عناوين فرعية بالإضافة إلى مزيد النصوص): الملف index.html مع الشيفرة اللازمة: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Web Portfolio of Marco</title> </head> <body> <h1>Web Portfolio of Marco</h1> <h2>Welcome!</h2> <p>Thanks for stopping by.</p> <p>Please have a look around. In the blog section I document my experiences in programming. You may also look at my web projects. Have Fun.</p> <img src="marco.jpg" alt="Picture of me"> <p>Marco :-)</p> </body> </html> والصورة التالية لما ستبدو عليه الصفحة في متصفّح الويب: إن أردت تعلم المزيد حول HTML و CSS وأن تصبح خبيرًا بهما وأن تطور مواقع وتطبيقات ويب عالية الجودة، فأنصحك بالاطلاع على دورة تطوير واجهات المستخدم المقدمة من أكاديمية حسوب. سنتعلّم في الدرس الثاني كيف ننشر موقعنا على الانترنت. ترجمة -وبتصرّف- للدّرس HTML & CSS Tutorial - Part 1: Your First Website لصاحبه Marco Jakob. اقرأ أيضًا المدخل الشامل لتعلم تطوير الويب دليل تعلم لغة HTML دليل تعلم البرمجة
    1 نقطة
  2. الإصدار 1.0.0

    116600 تنزيل

    سطع نجم لغة البرمجة بايثون في الآونة الأخيرة حتى بدأت تزاحم أقوى لغات البرمجة في الصدارة وذاك لمزايا هذه اللغة التي لا تنحصر أولها سهولة كتابة وقراءة شيفراتها حتى أصبحت الخيار الأول بين يدي المؤسسات الأكاديمية والتدريبية لتدريسها للطلاب الجدد الراغبين في الدخول إلى مجال علوم الحاسوب والبرمجة. أضف إلى ذلك أن بايثون لغةً متعدَّدة الأغراض والاستخدامات، لذا فهي دومًا الخيار الأول في شتى مجالات علوم الحاسوب الصاعدة مثل الذكاء الصنعي وتعلم الآلة وعلوم البيانات وغيرها، كما أنَّها مطلوبة بشدة في سوق العمل وتعتمدها كبرى الشركات التقنية. دورة تطوير التطبيقات باستخدام لغة Python احترف تطوير التطبيقات مع أكاديمية حسوب والتحق بسوق العمل فور انتهائك من الدورة اشترك الآن بني هذا العمل على كتاب «How to code in Python» لصاحبته ليزا تاغليفيري (Lisa Tagliaferri) وترجمه إلى العربية محمد بغات وعبد اللطيف ايمش، وحرره جميل بيلوني، ويأتي شارحًا المفاهيم البرمجية الأساسية بلغة بايثون، ونأمل في أكاديمية حسوب أن يكون إضافةً نافعةً للمكتبة العربيَّة وأن يفيد القارئ العربي في أن يكون منطلقًا للدخول إلى عالم البرمجة من أوسع أبوابه. رُبط هذا الكتاب مع توثيق لغة بايثون في موسوعة حسوب لتسهيل عملية الاطلاع على أي جزء من اللغة مباشرة وقراءة التفاصيل باللغة العربية. هذا الكتاب مرخص بموجب رخصة المشاع الإبداعي Creative Commons «نسب المُصنَّف - غير تجاري - الترخيص بالمثل 4.0». يمكنك قراءة فصول الكتاب على شكل مقالات من هذه الصفحة، «المرجع الشامل إلى تعلم لغة بايثون»، أو مباشرةً من الآتي: المقال الأول: دليل تعلم بايثون اعتبارات عملية للاختيار ما بين بايثون 2 و بايثون 3 المقال الثاني: تثبيت بايثون 3 وإعداد بيئتها البرمجية المقال الثالث: كيف تكتب أول برنامج لك المقال الرابع: كيفية استخدام سطر أوامر بايثون التفاعلي المقال الخامس: كيفية كتابة التعليقات المقال السادس: فهم أنواع البيانات المقال السابع: مدخل إلى التعامل مع السلاسل النصية المقال الثامن: كيفية تنسيق النصوص المقال التاسع: مقدمة إلى دوال التعامل مع السلاسل النصية المقال العاشر: آلية فهرسة السلاسل النصية وطريقة تقسيمها المقال الحادي عشر: كيفية التحويل بين أنواع البيانات المقال الثاني عشر: كيفية استخدام المتغيرات المقال الثالث عشر: كيفية استخدام آلية تنسيق السلاسل النصية المقال الرابع عشر: كيفية إجراء العمليات الحسابية المقال الخامس عشر: الدوال الرياضية المضمنة المقال السادس عشر: فهم العمليات المنطقية المقال السابع عشر: مدخل إلى القوائم المقال الثامن عشر: كيفية استخدام توابع القوائم المقال التاسع عشر: فهم كيفية استعمال List Comprehensions المقال العشرون: فهم نوع البيانات Tuples المقال الحادي والعشرين: فهم القواميس المقال الثاني والعشرين: كيفية استيراد الوحدات المقال الثالث والعشرين: كيفية كتابة الوحدات المقال الرابع والعشرين: كيفية كتابة التعليمات الشرطية المقال الخامس والعشرين: كيفية إنشاء حلقات تكرار while المقال السادس والعشرين: كيفية إنشاء حلقات تكرار for المقال السابع والعشرين: كيفية استخدام تعابير break وcontinue وpass عند التعامل مع حلقات التكرار المقال الثامن والعشرين: كيفية تعريف الدوال المقال التاسع والعشرين: كيفية استخدام *args و**kwargs المقال الثلاثين: كيفية إنشاء الأصناف وتعريف الكائنات المقال الحادي والثلاثين: فهم متغيرات الأصناف والنسخ المقال الثاني والثلاثين: وراثة الأصناف المقال الثالث والثلاثين: كيفية تطبيق التعددية الشكلية (Polymorphism) على الأصناف المقال الرابع والثلاثين: كيف تستخدم منقح بايثون المقال الخامس والثلاثين: كيفية تنقيح شيفرات بايثون من سطر الأوامر التفاعلي المقال السادس والثلاثين: كيف تستخدم التسجيل Logging المقال السابع والثلاثين: كيفية ترحيل شيفرة بايثون 2 إلى بايثون 3
    1 نقطة
  3. منذ أكثر من مئة عام عندما وضعت جامعة هارفارد أول منهج أكاديمي يدرس إدارة الأعمال وحتى اليوم كانت العلوم الإدارية كلها تركّز على إدارة المشاريع القائمة وتطويرها و حلِّ مشاكلها، وبهذا وجدنا مثلًا الإدارة المالية تبحث في سبل تأمين الموارد المالية اللازمة لتكبير المشروع، وإدارة الموارد البشرية تبحث في طرق تعيين الموظفين الأكثر كفاءة، وحتى الإدارة الاستراتيجية كانت تبحث في مستقبل المشروع الحالي. اليوم مع تطور شكل منظمات الأعمال والمشاريع بدأت تظهر هناك ما تعرف بالشركات الناشئة Startups والتي تشترك في أنها تقدّم منتجات أو خدمات أو تدخل في أسواق جديدة كليًا. بالتالي ظهرت فجوة كبيرة وهي أنَّ علم إدارة الأعمال لم يكن جاهزًا لتقديم أدوات تساعد على تأسيس هذه الشركات على الرّغم من أنّه يملك خبرة تزيد عن القرن في تطوير وإنماء الشركات القائمة بحد ذاتها. ومن هذا المنطلق كانت أداة مخطط نموذج العمل التجاري Business Model Canvas واحدة من الأدوات الثوريّة التي لبّت حاجة رواد الأعمال في التخطيط لمشاريعهم وشركاتهم الناشئة على الورق قبل إطلاقها. لماذا نحتاج مخطط نموذج العمل التجاري؟يعود الفضل لابتكار مخطط نموذج العمل التجاري إلى المؤلفين أليكس اوسترفالدر Alexander Osterwalder وإيف بينورYves Pigneur اللذين قدّماه في كتابهما Business Model generation والذي أطلق عام 2010. وتمت ترجمته للعربية العام الماضي (ابتكار نموذج العمل التجاري). وباختصار شديد يمكن أن نعرّف هذا المخطط على أنّه طريقة بصرية تخطيطية يمكن استخدامها أثناء مرحلة التخطيط للمشروع من أجل تدارُك الوقوع بالأخطاء قدر الإمكان. وهنا يبرز الفارق ما بين التخطيط للمشاريع التقليدية ولنقل محل لبيع العصائر والكوكتيل وبين المشاريع الناشئة الابتكارية مثل تطبيقات الهواتف الذكية. حيث أنّ المشاريع التقليدية لا تحتاج لبذل الكثير من الجهد في التخطيط فكل ما تحتاجه هو دراسة سريعة للجدوى الاقتصادية، بينما المشاريع الابتكارية فهي تحتاج لمزيد من التخطيط قبل الوصول لمرحلة دراسة الجدوى. سابقًا عندما كنت تود إطلاق مشروع ما تقوم بإعداد دراسة الجدوى، ومن ثم كتابة خطة العمل لتقديمها للمستثمرين (بنك أو رجل أعمال) من أجل الحصول على التمويل اللازم. أما اليوم مع الشركات الناشئة والمشاريع الابتكارية فإنك بحاجة لإعداد مخطط نموذج العمل التجاري قبل كتابة خطة العمل ودراسة الجدوى. لأنّ دراسة الجدوى تجيبك عن سؤال هام وهو: لو نفّذنا المشروع بهذه المعطيات، هل سيربح أم يخسر؟ بينما خطة العمل تجيبك عن سؤال هام هو: كيف سننفّذ العمل ونديره؟ لكن مخطط نموذج العمل يبدأ من مرحلة أبكر وهي الإجابة عن سؤال: ما الذي يجب أن نقدّمه؟ ولمن؟. فبدون مخطط نموذج العمل التجاري الصحيح لن نتمكن من الوصول إلى خطة عمل صحيحة وبالتالي فإنّ دراسة الجدوى الاقتصادية لن تكون صحيحة أيضًا. الدور الهام الذي يلعبه مخطط نموذج العمل التجاري هو أنّ الشركات الناشئة ليست مجرد نسخة بدائية من الشركات القائمة، بل هناك اختلاف جوهريّ في وظيفة كلٍّ منهما، حيث أنّ الشركة الناشئة دورها البحث عن نموذج عمل ناجح، بينما المشروع القائم دوره تنفيذ نموذج العمل أو النموذج الربحي Business Model. وهنا يأتي دور مخطط نموذج العمل حيث يسهّل على الشركات الناشئة عملية البحث عن النموذج الربحي المناسب لهم. الصورة مأخوذة من الترجمة العربية من الكتاب الذي يُمكن الحصول عليه من هنا ينقسم مخطط نموذج العمل التجاري إلى تسعة مكونات رئيسة وهي: 1- القيمة المقترحة أو العرض المقدّم Value Proposition 2- شرائح العملاء أو الزبائن Customer Segments 3- قنوات التوزيع Channels 4- العلاقة مع العملاء Customer Relationship 5- مصادر الإيرادات Revenue Stream 6- الموارد الأساسية Key Resources 7- الأنشطة الأساسية Key Activities 8- هيكل التكاليف structure Costs 9- الشركاء الأساسيون Key Partners 1- القيمة المقترحة أو العرض المقدّم Value Propositionقبل أن نشرّع في الحديث عن القيمة المقترحة، لنعرّف أولًا ما هي القيمة؟ وبم تختلف عن السعر و الثمن؟ ببساطة شديدة القيمة هي ما تحصل عليه من المنتج أو الخدمة، والسعر هو المبلغ المالي المطلوب دفعه لقاء الحصول على المنتج أو الخدمة، أما الثمن فهو يشمل إضافة للسعر الوقت والجهد المبذولان في المفاضلة ما بين المنتجات أو الخدمات المشابهة والبحث عنها واتخاذ القرار النهائي في شراء منتج أو خدمة معينة. إذًا السعر هو ما تدفعه والقيمة هي ما تحصل عليه. يقسّم خبراء التسويق عادة أي منتج إلى ثلاث طبقات، الخارجية وهي كافة العناصر المعنوية الإضافية التي تحصل عليها من المنتج كالشعور بالفخامة مع علامة تجارية معينة أو الثقة من شراء علامة تجارية أخرى أو حتى الصيانة المجانية أو التركيب المجاني. والطبقة الثانية الوسطى وهي التي عادة ما تعرف بها المنتجات وهي كافة العناصر الملموسة التي تشكّل كيان المنتج، أي الشكل واللون والوزن والرائحة والمواد الداخلة بصنعه .. إلخ. والطبقة الجوهرية الثالثة هي في الحقيقة أهم شيء في المنتج، هي السبب الذي يدفع الزبون لشراء المنتج وهي القيمة الحقيقية التي يقدّمها هذا المنتج. ليكن لدينا هاتف الآيفون كمثال، فالطبقة الخارجية هي إحساس التميّز من شراء أحد منتجات شركة آبل والطبقة الوسطى هي الخصائص الفنية للمنتج بحدّ ذاته كالتصميم والشاشة والكاميرا والطبقة الجوهرية هي خدمة الاتصال المحمول وتصفح الإنترنت واستخدام التطبيقات. لاحظ أن الزبون لا يشتري الآيفون لمجرد التميّز وإحساس الفخامة ولا من أجل شراء شاشة وكاميرا ودارات إلكترونية، إنّما من أجل الاتصال وهذه هي القيمة الجوهرية التي يقدّمها الآيفون ويتم تدعيمها بكافة الطبقات والخصائص الأخرى لتميّزه عن غيره حيث أن هناك طيفًا واسعًا من المنتجات التي تقدّم الخدمة الجوهرية نفسها. هناك عدة مداخل يمكن استخدامها في العرض المقدّم أو القيمة التي تودّ الشركة توصيلها لزبائنها: 1- القيمة المبتكرة أو الجديدة وهي المنتجات التي تكون جديدة كليًا على السوق مثل الآيباد حيث لم يكن هناك من قبله تعرف الحواسيب اللوحية على الرغم من أنه كانت هناك حاجة لها لكنها لم تكن واضحة تمامًا ولم يقم أحد بصنع منتج يلبيها. فالقيمة التي يدفع الناس مقابلها هي أنه منتج لا يوجد له بديل يمكن أن يحلّ محلّه. 2- القيمة بالأداء العاليوهنا عندما يكون منتجك مشابه لمنتجات كثيرة في السوق ويلبّي نفس القيمة التي يبحث عنها الزبون، يمكنك التميّز بتقديم قيمة أعلى من خلال الأداء الأعلى. ومن الأمثلة على هذا شركات صناعة الحواسب المحمولة فهي تواصل طرح المزيد من المنتجات التي تتميز عن بعضها فقط في أن أداءها أفضل وأعلى من السابق بالتالي يمكنها إنجاز الأعمال بسرعة وكفاءة أعلى. 3- القيمة بالتخصيص في العادة تقدم الشركات منتجاتها بشكل نمطي لكلّ الأسواق، وهنا يمكن التميّز وتقديم قيمة جديدة من خلال إتاحة تخصيص المنتج بحسب رغبات كل زبون بشكل منفصل. كما فعلت شركة موتورولا عندما أتاحت لكلّ زبون تصميم الهاتف الخاص به وحتى اختيار مواد صناعة الغطاء الخلفي لجهاز موتو إكس وهو ما لا توفّره باقي شركات الهواتف الذكية. 4- القيمة بالخدمة الشاملةبعض المنتجات المعقّدة والتي تحتاج لكثير من التخطيط قبل شرائها نظرًا للمخاطرة العالية فيها كالسعر المرتفع، يمكن تقديم قيمة أعلى من خلال الخدمة الشاملة. فمثلًا يمكن لشركة تصنع معدات طبية مثل أجهزة الليزر أن تقدّم خدمة النقل والتركيب والتدريب المجاني وحتى توفير الصيانة وقطع الغيار ما يخلق لها قيمة جديدة لا توفّرها الشركات المنافسة التي تكتفي ببيعك المنتج فقط. 5- القيمة بالتصميم في المنتجات المتشابهة التي تصنعها العديد من الشركات نجد أنّ بعضها يتميّز بتصميمه الجذّاب أو الذي يسهل استخدامه أو يمكن التعلّم على استعماله بسهولة حتى لكبار السنّ أو الأطفال وهنا مدخل جديد لوضع قيمة في المنتج هي بتحسين تصميمه، ومن أبرز الأمثلة على هذا المدخل بعض الهواتف الذكية التي تحمل مواصفات فنية متشابهة بالتالي تتميّز شركات عن غيرها بتصميم هواتفها. 6- القيمة بالسعر وهنا عندما يكون لديك منتج نمطي يشبه الكثير من المنافسين ولا تتمكن من تقديمه بتصميم جميل أو مفيد وسهل، يبقى أمامك المنافسة بالسعر بالتالي تتميّز عن باقي المنافسين. وهو ما فعلته العديد من شركات صناعة الهواتف الذكية الصينية حيث أنها تمكّنت من تقديم منتجاتها بأسعار رخيصة للغاية ما يجعلها تستهدف شريحة الزبائن التي تكون حساسة للسعر. 7- القيمة بالأمان وهي قيمة تعاكس السعر حيث يبحث هنا الزبون عن الأمان الأعلى ولو على حساب السعر، ونلاحظ هذه القيمة في المنتجات التي ترتبط بحياة الزبون كالسيارات مثلًا تميّزت فولفو السويدية بهذا المجال حيث أن سياراتها ليست الأفضل أداء ولا الأجمل تصميمًا ولا الأرخص سعرًا لكنها الأعلى أمانًا. 8- القيمة بسهولة الحصول على المنتج في المنتجات الاستهلاكية أو متكررة الشراء يكون معيار سهولة الحصول على المنتج حاسمًا بصنع القيمة بخاصة عندما يكون منتج نمطي كالمشروبات الغازية مثلًا عندما يتوفر منتجك في قنوات توزيع أكبر تغطي كلّ شارع في المدينة حيث سيجعل الزبون يفضّل هذا المنتج عن غيره الذي يحتاج لبحث عنه. إذًا القيمة المقترحة أو العرض المقدّم في منتجك هو كلّ العناصر التي تميّز شركة عن منافسيها ويدفع الزبون من أجلها ماله. وهذه كانت بعض الأمثلة عن طرق صنع القيمة في المنتج ويمكن الاعتماد على أكثر من مدخل معًا ما يجعل تقليد المنتج أصعب. 2- شرائح العملاء Customers Segmentsوهي الأفراد أو الشركات أو الجهات التي تسعى الشركة لخدمتهم من خلال العرض المقدّم. ويمكن أن يقسّم العملاء لعدّة شرائح أو مجموعات تشترك فيما بينها بصفات أو معايير معيّنة ويكون لكلّ شريحة قيمة أو عرض مقدّم مختلف عن الشريحة الأخرى. يمكن الاعتماد على عدّة معايير لتقسيم الشرائح، مثلًا بحسب احتياجاتهم فكلّ نوعية من الزبائن لديها احتياجات مختلفة تبحث عنها في منتجات الشركة لتلبيتها ويمكن الأخذ بالمعايير الديموغرافية هنا كالعمر والجنس ومعدل الدخل وغيرها، أو طرق الوصول للزبائن وذلك بتقسيم الأسواق إلى محلية وإقليمية وعالمية وغيرها. هناك أربعة أنواع لقطاعات شرائح العملاء تعدّ الأشهر ويمكن التعرّف على خصائصها: 1- كامل السوق وهنا توجّه أنشطة الشركة بكاملها إلى السوق باعتباره كتلة واحدة من الزبائن المتشابهين، كما في صناعة السيارات عندما يكون الزبائن المحتملون كافتهم يرغبون بالحصول على السيارات من أجل قيمة واحدة وهي النقل السريع المريح. 2- السوق المخصّصيتم تقسيم السوق إلى شريحة دقيقة لديها احتياجات خاصة من العرض المقدّم ويتم تحويل الأنشطة كافتها لتلبيتها. وبمثل صناعة السيارات هناك شركات تصنع سيارات فاخرة للغاية وأخرى تصنع سيارات رياضية فهذه الشركات تتجاهل معظم حجم السوق الذي يرغب بقيمة النقل السريع المريح وتقوم بتلبية الشريحة التي تبحث عن الفخامة أو السيارات السريعة. 3- التجزئة تقوم الشركة بتقسيم إضافي لشريحة زبائن بناءً على معايير جديدة. فيمكن لشركة أدوات صناعية أن تقسّم زبائنها من الشركات الصناعية بحسب مجالات صناعاتها. 4- التنويع وهنا تقوم الشركة بتلبية عدّة شرائح مختلفة من العملاء لها احتياجات أو قيم مختلفة, مثلًا فيس بوك يلبي احتياجات المستخدمين العاديين الباحثين عن التواصل الاجتماعي، بينما المعلنين يبحثون عن الوصول لزبائن أكثر، في حين أن المطوّرين يرغبون بمستخدمين أكثر لتطبيقاتهم. لاحظ كيف أن فيس بوك يلبي هذه الشرائح الثلاثة بالوقت نفسه. 3-قنوات التوزيع Channelsهي كافة الطرق والآليات التي تعتمد عليها الشركة في توصيل كلّ شريحة من شرائح العملاء المذكورة أعلاه مع القيمة التي يبحثون عنها. أي هي صلة الوصل ما بين المنتج أو الخدمة من جهة و شرائح العملاء من جهة أخرى. وكلّ قناة توزيع ناجحة يجب أن تؤدي خمس وظائف: 1- زيادة الوعيبخاصة عندما تكون الشركة أو المنتج جديدًا على السوق فيجب أن تعمل قناة التوزيع المستخدمة على زيادة وعي شرائح العملاء بالشركة أو المنتج وتعريفهم بتواجدها. 2- التقييم بعد أن أصبحت شريحة العملاء على وعي بوجود الشركة ومنتجاتها، يجب أن تساعد قناة التوزيع العملاء على تقييم ما تمت توعيتهم به، والتقييم هنا يصبّ على إيصال العرض المقدّم الحقيقي لشريحة العملاء المطلوبة. 3- الشراءبعد أن تعرّف العملاء على المنتج وقاموا بتقييم المنفعة المتحصّلة من ورائه، يجب أن تساعدهم قناة التوزيع على شراء المنتج بحيث تقوم بتذليل كافة مصاعب الشراء الممكنة. 4- التوصيل بعد الشراء يفترض بالقناة أن تساعد المستخدم على توصيل المنتج أو الخدمة واستهلاكها بالمكان الذي يريده وذلك بفعالية عالية فتكون سريعة وغير مكلفة. 5- خدمة ما بعد البيع بعد الانتهاء من توصيل واستهلاك المنتج أو الخدمة تأتي خدمات ما بعد البيع وذلك بعدة أشكال من أبسطها الدعم الفني وحلّ المشاكل أو الصيانة أو المساعدة بالتخلّص من المنتج حتى. هناك اليوم عدد كبير من قنوات التوزيع التي يمكن اعتمادها، ففي السابق كانت هناك القنوات الفيزيائية الحقيقية فقط من أجل الحصول على المنتج عليك التوجّه إلى مكان صنعه أو بيعه ويمكن للشركات فتح منافذ بيع خاصة بها أو توكيلها لشركاء تجزئة. أما اليوم فهناك منتجات وخدمات إلكترونية تعتمد على قنوات إلكترونية لتقديمها كالتطبيقات والمواقع. سنواصل شرح باقي المُكوّنات في المقال القادم
    1 نقطة
  4. كما نعلم جميعا أن الصور والتفاصيل التي يتم إضافتها للتصاميم من أهم الاشياء التي تساعد على جعل التصميم يبدو جذاب ومميزا .. لذا سؤالي هنا ماهي أفضل طريقه ومواقع للحصول على الملحقات الصور التي قد نحتاجها وعلى إي اساسا اقوم باختيارها ؟ نوع الصور التي اريدها هي الزخارف والصور الاسلاميه .. وشكرا لكم ^ ^
    1 نقطة
  5. تعد طريقة ForEach إحدى الطرق العديدة للتكرار خلال المصفوفات. لكل طريقة ميزات مختلفة ، والأمر متروك لك ، اعتمادًا على ما تفعله ، لتحديد الطريقة التي يجب استخدامها. بفرض لديك المصفوفة التالية: const numbers = [1, 2, 3, 4, 5]; فإن الحلقة التكرارية التقليدية خلال المصفوفة هي: for (i = 0; i < numbers.length; i++) { console.log(numbers[i]); } أما ما يميّز ForEach هو أنها تستخدم ظيفة مختلفة عن "for loop" الكلاسيكية. فيمرر التابع forEach تابع للرد Callback لكل عنصر من عناصر المصفوفة مع البارمترات التالية: القيمة الحالية للعنصر رقم فهرس Index العنصر الحالي غرض Object من المصفوفة الذي ينتمي إليه العنصر الحالي فمثلاً يمكن تنفيذ تابع محدد عند المرور على كل عنصر ضمن المصفوفة: numbers.forEach(function(number) { console.log(number); }); فيكون الناتج: طباعة الأرقام 1،2،3،4،5 ومثال على استخدام الفهرس كمتحول في الحلقة: numbers.forEach((number, index) => { console.log('Index: ' + index + ' Value: ' + number); }); وعندها يكون الناتج: طباعة الأرقام مع فهارسها كالتالي: Index: 0 , Value 1 - Index: 1 Value 2 - Index 2 Value 3 .... وبالمقابل يمكن استخدام (السهم) أو ما يعرف بـ ES6 كالتالي: numbers.forEach(number => console.log(number)); وهي تقوم بنفس الوظيفة تماماً ولكن تستخدم فقط لتسهيل قراءة الكود وترتيبه وجعله مختصر خصوصاً في الأكواد المعقدة و الحلقات والشروط المتداخلة والمتكررة بحيث يمكن اختصارها بأسطر بسيطة ضمن الكود.
    1 نقطة
  6. مرحباً بك، لم يتغير شيء لأنه لا يوجد في المستند أي عُنصر يحمل المُعرف test حتى يتغير النص الموجود داخل الdiv يجب إضافة الid المطلوب كما هو موضح أدناه: <div class="test" id="test">C</div> أو بإمكانك تغيير طريقة تحديد العُنصر عن طريق إسم الصنف: window.onload = function () { document.getElementsByClassName("test")[0].innerHTML = "asma"; } التابع getElementsByClassName يأخذ كمعامل إسم الصنف و يُرجع مصفوفة تضم كل العناصر التي تملك صنف التنسيقات المطلوب. هناك عدة توابع أخرى يُمكنك إستخدامها ك querySelector getElementsByTagName بالتوفيق.
    1 نقطة
  7. مرحبًا أسماء. لاحظي أنك قمت بتحديد الحاوية باستخدام التابع getElementById بالرغم من أن test تعتبر صنفًا class و ليس مُعرفًا id. <div class="test">C</div> فقط قومي بتعديل class إلى id و سيعمل بشكل صحيح: <!DOCTYPE html> <html> <head> <script> window.onload = function () { document.getElementById("test").innerHTML = "asma";} </script> </head> <body> <div id="test">C</div> </body> </html>
    1 نقطة
  8. هنالك العديد من الإضافات اللتي تستخدم لتنسيق النصوص على محررات الأكواد على سبيل المثال هنالك إضافة مخصصة للأندرويد إستديو وهي : و كذلك إذا لم تجدها مناسبة فيمكنك التحول لإستخدام أحد محررات النصوص الأخري المعروفة مثل VS Code و Atom اللتي لديها عدد كبير من المطورين الذين يوفرون عدد كبير من إضافة تعمل على تنسيق النصوص مثل : يمكنك أن تجد قسم الإضافات في كل محرر نصوص من خلال شريط المهام في أعلى المحرر
    1 نقطة
  9. مرحباً بك، لعمل هذا الشيء تحتاج إلى إنشاء جدول تُخزن فيه تفضيلات كل مستخدم مبدئيا فإن الأعمدة التي يمكننا وضعها في الجدول هي كالآتي: id مُعرف التفضيلة user_id مُعرف المُستخدم صاحب التفضيلة و يمكن أيضا إنشاء مفتاح ثانوي يربط هذا العمود بجدول المستخدمين model_type: من النوع النصي لتفريق نوع التفضيلة إن كانت كتاب أو مقال أو منتج أو أي شيء آخر model_id: مُعرف الشيء الذي قام المستخدم بتفضيله فإن كان كتاب فسيتم تخزين مُعرف الكتاب فيه بإمكانك إضافة أعمدة أخرى مثلا لحفظ تاريخ إضافة التفضيلة و غيرها. عندما يختار المُستخدم إضافة منتج للمفضلة فإنه يجب عليك إنشاء إستعلام لإضافة سجل جديد في جدول التفضيلات بحيث يكون: user_id هو مُعرف المستخدم الذي يحاول إضافة المنتج للمفضلة model_type سيكون إسم الصنف و في هذه الحالة سيكون Product model_id سيكون معرف المنتج الذي يحاول المستخدم إضافته للمفضلة و عند عرض السجلات الموجودة في مفضلة المستخدم الخاصة بالمنتجات مثلاً تحتاج إلى عمل إستعلام تحدد فيه تفضيلات المستخدم و بإستخدام (joins) يمكنك دمج جدول المنتجات مع جدول التفضيلات لجلب ما قام المستخدم بتفضيله من منتجات. بالتوفيق.
    1 نقطة
  10. جهازي يعمل على ويندوز 10 الرام فيه 16 قيقا والمستهلكة 15,8 ولا أعرف السبب حقيقة كل شي سويته ودي اعرف وش اللي مستهلك الرام !! كيف أعرف هذا التطبيق؟
    1 نقطة
  11. لقد تَعلَّمت، على مدار الفصلين السابقين، نوعية البرمجة المُستخدَمة أثناء كتابة برنامج فرعي وحيد (subroutine)، فيما أطلقنا عليه اسم "البرمجة في نطاق ضيق". سنُركز أكثر خلال الفصول المُتبقّية من الكتاب على بناء البرامج ضِمْن نطاق أوسع، ولكن ما يزال ما تَعلَّمته حتى الآن هو البذرة الأساسية والضرورية لكل ما ستَتَعرَّض له فيما بَعْد. سنرى، في هذا القسم، كيف يُمكِن تطبيق ما قد تَعلَّمته خلال الفصول السابقة ضِمْن سياق برمجة واجهات المُستخدِم الرسومية (graphical user interface)، والتي تُعرَف اختصارًا باسم GUI، وهو سِّياق مُختلف نوعًا ما عما اعتدته من برامج الطرفيّة النصية. ستَعتمِد برمجة الواجهات الرسومية (GUI) سواء التي سنَتَعرَّض لها خلال هذا القسم أو خلال بقية الكتاب على منصة JavaFX، والتي تَضُمّ مجموعة من الأصناف (classes) المُستخدَمة لكتابة هذه النوعية من البرامج، أيّ أن جميع الأصناف (classes) المذكورة بهذا القسم هي جزء من منصة JavaFX، وبالتالي يَنبغي أن تقوم باستيرادها (import) إلى البرنامج حتى تَتَمكَّن من اِستخدَامها. اُنظر القسم ٢.٦ لمزيد من المعلومات عن تَصرِّيف (compiling) البرامج المُستخدِمة لمنصة JavaFX وكيفية تَشْغِيلها. عند تَشْغِيل برامج واجهات المُستخدِم الرسومية (GUI)، ستُفتَح نافذة واحدة (window) أو أكثر على شاشة الحاسوب الخاصة بك. يُمكِنك، كمبرمج، التَحكُّم الكامل بما يَظهر على تلك النافذة، وكذلك بالكيفية التي يُمكِن للمُستخدِم التَفاعُل (interact) بها مع النافذة. سنَفْحَص خلال هذا القسم أمثلة بسيطة مثل طباعة بعض الأشكال البسيطة كالخطوط والمستطيلات على النافذة بدون أي تَفاعُل من المُستخدِم، فالنقطة المُهمّة، في الوقت الحالي، هو أن تتعرَّف على الطريقة التي تُستخدَم بها أساليب "البرمجة في نطاق ضيق" ضِمْن سياقات اخرى غَيْر برامج الطرفية المُعتمدة على النصوص، وسترى بنفسك أنه يمكن تطبيق نفس تلك الأساليب لكتابة أيّ برنامج فرعي (subroutine) وليس فقط البرنامج main. رسم الأشكال ستحتاج إلى أن تَكُون على دراية ببعض المفاهيم كالبكسل (pixels)، وأنظمة الإِحداثيَّات (coordinate systems)؛ كي يتَسَنَّى لك فهم الرسومات الحاسوبية (computer graphics)، ولذلك سنمر على بعض المفاهيم الأساسية سريعًا. تتكون عامةً شاشة الحاسوب (computer screen) من مربعات صغيرة تُسمى البكسل (pixels)، مُرَتَّبة بصورة صفوف وعواميد، بدقة تَصِل عادةً إلى ١٠٠ بكسل لكل بُوصَة (pixels per inch). تَحتوِي الكثير من الشاشات حاليًا على عدد أكبر بكثير من البكسلات المَلْموسة (physical pixels) لكل بُوصَة، لدرجة أنه مِنْ المُحتمَل لبكسل منصة JavaFX أن يُشير إلى بكسل مَلْموس (physical pixel) بمثل هذه الشاشات عالية الدقة (high-resolution)، ولكنه على الأرجح يُشيِر إلى بكسل مَنطقي (logical pixel)، والتي هي وَحدة قياس تُعادِل ٠.٠١ بوصة تقريبًا. لمّا كان باستطاعة الحاسوب التَحكُّم بلون البكسل، فإنه، في الواقع، يَرسِم (drawing) الأشكال عن طريق تَغْيِير ألوان البكسلات المُفردة (individual pixels). كل بكسل له زوج من الإِحداثيَّات (coordinates)، يُشار إليها عادة باسم الإِحداثيّ x والإِحداثيّ y، وتُستخدَم لتَحْدِيد المَوْضِع الأفقي (horizontal) والرأسي (vertical) للبكسل على الترتيب. عند الرسم بمساحة مستطيلية الشكل على الشاشة، تَكُون إِحداثيَّات البكسل بالرُكْن العُلوِي الأيسر (upper left corner) هي (٠،٠)، وبحيث تزداد قيمة الإِحداثيّ x من اليسار إلى اليمين، بينما تزداد قيمة الإِحداثيّ y من الأعلى إلى الأسفل. يُستخدَم البكسل لتَحْدِيد الأشكال وتَعرَيفها، فعلى سبيل المثال، يُعرَّف أيّ مستطيل من خلال الإِحداثيّ x والإِحداثيّ y بالرُكْن العُلوِي الأيسر للمستطيل، بالإضافة إلى كُلًا من عَرْضه (width)، وارتفاعه (height) بوَحدة البكسل. تَعرَض مساحة الرسم (drawing area) بالصورة التالية نطاق كلًا من الإِحداثيَّات x و y، ويُمثِل العَرْض والارتفاع بها حجم مساحة الرسم بوَحدة البكسل: بفَرْض أن مساحة الرسم (drawing area) -بالأعلى- مُكوَّنة من ٨٠٠*٥٠٠ بكسل، سيكون المستطيل، الواقع بالجزء العُلوِي الأيسر من الصورة، تقريبًا بعَرْض ٢٠٠ بكسل وارتفاع ١٥٠ بكسل، كما يَقع الرُكْن العُلوِي الأيسر (upper left corner) للمستطيل بالإِحداثيَّات (٥٠،٥٠) تقريبيًا. يَتمّ الرسم بلغة الجافا باِستخدَام كائن سِّياق رُسومي (graphics context) من النوع GraphicsContext. يَشتمِل هذا الكائن على بعض البرامج الفرعية (subroutines)، مثل برامج (routines) لرسم الأشكال البسيطة كالخطوط، والمستطيلات، والأشكال البيضاوية، والنصوص. (عندما يَظهر النص على الشاشة، يَرسِم الحاسوب حروف النص مثلما يَرسِم أيّ أشكال آخرى). بالإضافة إلى ذلك، يَشتمِل كائن السِّياق الرُسومي (graphics context) أيضًا على مجموعة من البيانات (data)، مثل نوع الخط المُختار حاليًا للرَسْم ولونه. (يُحدِّد نوع الخط كلًا من حجم وشكل الحروف). تَشتمِل بيانات كائن السِّياق أيضًا على سطح رسم (drawing surface)، وهو ما يَتمّ الرسم عليه، وفي حالتنا، سيكون سطح الرسم هو مساحة مُحتوَى النافذة بدون الحواف (border) وشريط العنوان (title bar)، ولكن تَتوفَّر أسطح رَسْم مختلفة يمكن الرَسْم عليها أيضًا. تُوفِّر منصة JavaFX طريقتين لرسم الأشكال: إِمّا بمَلْئ الشكل (filling) أو بتَحْدِيد حوافه (stroking). مَلْئ الشكل (filling) هو ضَبْط لون كل بكسل بداخله، أمَا تَحْدِيد حواف الشكل (stroking) فهو ضَبْط لون البكسلات الواقعة بحوافه (border)، وهو ما يُشبه عملية سَحب قلم على طول حواف الشكل، وفي هذه الحالة، تُعدّ صفات القلم -كحجمه (width/size) أو ما إذا كان يَستخدِم خط صلب (solid line) أو مُتقطِّع (dashed line)- خاصيات (properties) ضِمْن كائن السِّياق الرُسومي (graphics context). يُخصِّص كائن السِّياق الرُسومي أيضًا لونين مُنفصلين، أحدهما لمَلْئ الأشكال (filling)، والآخر لتَحْدِيد حوافها (stroking). لاحظ اقتصار بعض الأشكال -كالخطوط- على طريقة تَحْدِيد الحواف فقط. يُستخدَم مُتَغيِّر من النوع GraphicsContext لتَمثيِل السِّياق الرُسومي (graphics context)، ويَحمِل هذا المُتَغيِّر عادةً الاسم g. ليس هذا ضروريًا بالطبع، حيث يَتوقَف اسمه بالنهاية على المُبرمج. نَعرِض هنا بعض البرامج الفرعية (subroutines) المُتوفرة ضِمْن كائن السِّياق الرُسومي g. لاحظ أن كل قيم المُعامِلات العددية هي من النوع double: البرنامج الفرعي g.setFill(c)‎: يَضبُط اللون المُستخدَم لمَلْئ الأشكال (filling)، حيث المُعامِل c هو كائن من الصَنْف Color. تَتوفَّر الكثير من الثوابت (constants) المُمثِلة للألوان القياسية (standard colors)، والتي يُمكِن اِستخدَامها كمُعامِل لهذا البرنامج الفرعي. تتراوح الألوان القياسية من الألوان الشائعة مثل Color.BLACK و Color.WHITE و Color.RED و Color.GREEN و Color.BLUE و Color.YELLOW، إلى بعض الألوان الغريبة مثل Color.CORNFLOWERBLUE. (يُمكِنك أيضًا إِنشاء ألوان جديدة مُخصَّصة). على سبيل المثال، إذا أردت مَلْئ الأشكال باللون الأحمر، فإنك ستَستدعِي البرنامج الفرعي g.setFill(Color.RED);‎. لاحظ أن اللون المُخصَّص أثناء الاستدعاء سيُستخدَم لجميع عمليات المَلْئ التالية وحتى الاستدعاء التالي لنفس البرنامج الفرعي، أما الأشكال المَرسومة مُسْبَّقًا فلا تتأثر بهذا التَغْيِير. البرنامج الفرعي g.setStroke(c)‎: يَضبُط اللون المُستخدَم لتَحْدِيد حواف الأشكال (stroking)، ويَعمَل بصورة مشابهة للبرنامج الفرعي g.setFill. البرنامج الفرعي g.setLineWidth(w)‎: يَضبُط حجم القلم المُستخدَم خلال عمليات تَحْدِيد الحواف التالية (stroking). لاحظ أن المُعامِل w يَستخدِم وَحدة البكسل. البرنامج الفرعي g.strokeLine(x1,y1,x2,y2)‎: يَرسِم خطًا مُمتدًا من إِحداثيَّات نقطة البداية (x1,y1) وحتى إِحداثيَّات نقطة النهاية (x2,y2). يُرسَم الخط باللون الأسود وبحجم ١ بكسل افتراضيًا، ومع ذلك، يُمكِنك تَخْصِيص كلًا منهما باستدعاء g.setStroke()‎ و g.setLineWidth()‎ على الترتيب. البرنامج الفرعي g.strokeRect(x,y,w,h)‎: يَرسِم الحواف الخارجية (stroking) لمستطيل مع جوانبه الأفقية والرأسية، بحيث يَبعُد الرُكْن العُلوِي الأيسر (top-left corner) لهذا المستطيل مسافة قدرها x بوَحدة البكسل عن الحافة اليسرى لمساحة الرسم (drawing area)، ومسافة قدرها y بوَحدة البكسل عن حافتها العُلوِية. يُحدِّد كلًا من المُعامِلين w و h عَرْض المستطيل الأفقي وارتفاعه الرأسي بوَحدة البكسل على الترتيب. يُمكِن ضَبْط لون الخط المُستخدَم وحجمه باستدعاء g.setStroke()‎ و g.setLineWidth()‎ على الترتيب. البرنامج الفرعي g.fillRect(x,y,w,h)‎: يَعمَل بصورة مشابهة للبرنامج الفرعي g.strokeRect()‎ باستثناء أنه يَملْئ المستطيل (filling) بدلًا من رسم حوافه الخارجية (stroking). اِستدعي g.setFill لضَبْط اللون المُستخدَم. البرنامج الفرعي g.strokeOval(x,y,w,h)‎: يَرسِم الحواف الخارجية لشكل بيضاوي. يُرسَم الشكل البيضاوي بحيث يَقع ضِمْن المستطيل الذي كان سيُرسَم في حالة استدعاء g.strokeRect(x,y,w,h)‎ بنفس قيم المُعامِلات. لاحِظ أنه يُمكِنك اِستخدَام نفس القيمة لكُلًا من المُعامِلين w و h لرسم حواف دائرة. البرنامج الفرعي g.fillOval(x,y,w,h)‎: يَعمَل بصورة مشابهة للبرنامج الفرعي g.strokeOval()‎ باستثناء أنه يَملْئ الشكل البيضاوي بدلًا من رَسْم حوافه الخارجية. تُعدّ هذه البرامج الفرعية كافية لرَسْم بعض الصور باِستخدَام الجافا. لنبدأ بشئ بسيط مثل رَسْم عشرة خطوط متوازية، كالتالي: نحتاج أولًا لمجموعة افتراضات هي كالتالي: سيكون طول الخطوط حوالي ٢٠٠ بكسل، والمسافة بين كل خط والخط الذي يَليه حوالي ١٠ بكسل، وأخيرًا، سنفْترِض أن نقطة بداية (start) أول خط تقع بالإِحداثيَّات (١٠٠،٥٠). الآن، كل ما نحتاج إليه لرَسْم خط هو استدعاء البرنامج الفرعي g.strokeLine(x1,y1,x2,y2)‎ بقيم مُعامِلات مناسبة. نلاحِظ أن نقطة البداية (start) لجميع الخطوط لها نفس قيمة الإِحداثيّ x ‏(x-coordinate) وتُساوِي ١٠٠، ومِنْ ثَمَّ، سنَستخدِم قيمة ثابتة تُساوِي ١٠٠ كقيمة للمُعامِل x1. لمّا كانت جميع الخطوط بطول ٢٠٠ بكسل، فإننا سنَستخدِم قيمة ثابتة تُساوِي ٣٠٠ كقيمة للمُعامِل x2. في المقابل، تَختلف إِحداثيَّات y ‏(y-coordinates) بكل خط عن الخط الذي يَليه، ولكن يُمكِننا أن نرى أن قيمة الإِحداثيّ y بنقطتي البداية (start) والنهاية (end) لكل خط منها هو نفسه، وعليه، سنَستخدِم مُتَغيِّر وحيد لكُلًا من قيمتي y1 و y2، هو المُتَغيِّر y. الآن، أصبح أمر الاستدعاء لرَسْم أحد الخيوط كالتالي g.strokeLine(100,y,300,y)‎. اِفْترَضنا قبلًا أن قيمة المُتَغيِّر y لأول خط هي ٥٠، ثم ستزداد تلك القيمة بمقدار ١٠ مع كل انتقال للخط التالي، مما يَعنِي أننا سنحتاج إلى التأكد من أن قيمة y تأخذ القيمة الصحيحة من متتالية الأعداد. يُمكِننا اِستخدَام حَلْقة تَكْرار for، كالتالي: int y; // ‫إحداثي y للخط int i; // المتغير المتحكم بالحلقة y = 50; // ‫تبدأ y بالقيمة 50 لأول خط for ( i = 1; i <= 10; i++ ) { g.strokeLine( 100, y, 300, y ); y = y + 10; // ‫أزد y بمقدار 10 قبل رسم الخط التالي } نستطيع أيضًا اِستخدَام المُتَغيِّر y ذاته كمُتحكِّم بالحَلْقة (loop control variable). لاحِظ أن قيمة y للخط الأخير هي ١٤٠. انظر الشيفرة التالية: int y; for ( y = 50; y <= 140; y = y + 10 ) g.strokeLine( 100, y, 300, y ); إذا أردت تلوين الخطوط باللون الأزرق، اِستدعي البرنامج الفرعي g.setStroke(Color.BLUE)‎ قبل رَسْمها، حيث سيُستخدَم اللون الأسود افتراضيًا إذا قُمت برَسْمها دون ضَبْط اللون. أما إذا أردت أن يَكُون حجم تلك الخطوط ٣ بكسل، اِستدعي البرنامج الفرعي g.setLineWidth(3)‎ قَبْل رَسْمها. لننتقل إلى مثال أكثر تعقيدًا، فمثلًا، لنَرسِم عددًا كبيرًا من الدوائر بشكل عشوائي سواء فيما يَخُص مَوْضِعها (position) أو لونها. لمّا كنا على علم بعدد قليل من الألوان المُتوفرة، فإننا سنختار عشوائيًا واحدًا من الألوان التالية : الأحمر، والأخضر، والأزرق، والأصفر. سنستعمل تَعْليمَة switch بسيطة للاختيار، وذلك بطريقة شبيهة للمثال بالقسم الفرعي ٣.٦.٤: switch ( (int)(4*Math.random()) ) { case 0: g.setFill( Color.RED ); break; case 1: g.setFill( Color.GREEN ); break; case 2: g.setFill( Color.BLUE ); break; case 3: g.setFill( Color.YELLOW ); break; } لمّا كنا نريد للدوائر أن تكون عشوائية التَموْضع، فسنحتاج إلى اختيار مركز الدوائر (center of circles) بصورة عشوائية. بفَرْض أن عَرْض مساحة الرسم (drawing area) وارتفاعها مُعطيين من خلال المُتَغيِّرين width و height على الترتيب، فسينبغي للمَوْضِع الأفقي (horizontal position) للمركز أن يكون قيمة عشوائية تتراوح من القيمة ٠ وحتى width-1. بالمثل، يَنبغي للمَوْضِع الرأسي (vertical position) لمركز الدائرة أن يَكُون قيمة عشوائية تتراوح من القيمة ٠ وحتى height-1. أخيرًا، ما زِلنا بحاجة لتَحْدِيد حجم الدائرة. سنكتفي، في هذا المثال، باِستخدَام نصف قطر (radius) ثابت لجميع الدوائر مُساوِي للقيمة ٥٠ بكسل. تُرسَم الدائرة باِستخدَام التَعْليمَة g.fillOval(x,y,w,h)‎، لكن، في الواقع، لا يُمثِل المُعامِلان x و y، بهذا الأمر (command)، إِحداثيَّات مركز الدائرة؛ وإنما إِحداثيَّات الرُكْن العُلوِي الأيسر (upper left corner) للمستطيل المرسوم حول الدائرة، ولهذا سنحتاج إلى تَحرِيك مركز الدائرة بمسافة قدرها يُساوِي نصف قطر الدائرة أي ٥٠ بكسل؛ وذلك للحصول على قيم x و y المُناظِرة. في المقابل، يُمثِل المُعامِلان w و h عَرْض وارتفاع المستطيل على الترتيب، واللذين ستكون قيمتهما مُساوِية لضعف نصف قطر الدائرة أي ١٠٠ بكسل بهذا المثال. تُراعِي الشيفرة التالية جميع النقاط المذكورة بالأعلى، وتُستخدَم لرَسْم دائرة عشوائية واحدة: centerX = (int)(width*Math.random()); centerY = (int)(height*Math.random()); g.fillOval( centerX - 50, centerY - 50, 100, 100 ); لاحِظ أن الشيفرة بالأعلى تُستدَعى بَعْد استدعاء الشيفرة المسئولة عن ضَبْط اللون. تبدو الصورة عامةً بشكل أفضل بَعْد تَحْدِيد حافة الدائرة (border) باللون الأسود (stroking)، ولذلك أضيفت الشيفرة التالية: g.setStroke( Color.BLACK ); g.strokeOval( centerX - 50, centerY - 50, 100, 100 ); وأخيرًا، للحصول على عدد كبير من الدوائر، ضُمِّنت الشيفرة بالأعلى داخل حَلْقة تَكْرار for، ونُفِّذت ٥٠٠ مرة، فكانت الرسمة الناتجة عن البرنامج كالتالي: الرسم داخل برنامج كما تعلم، لا يُمكِن لأيّ شيفرة بلغة الجافا أن تكون مُستقلة بذاتها، فلابُدّ لها أن تُكتَب ضِمْن برنامج فرعي (subroutine)، والذي بدوره يَكُون مُعرَّفًا داخل صَنْف (class)، ولهذا تَعرِض الشيفرة التالية التَعرِيف الكامل لبرنامج فرعي (subroutine definition)، والذي يُستخدَم لرَسْم الصورة من المثال السابق : public void drawPicture(GraphicsContext g, int width, int height) { g.setFill(Color.WHITE); g.fillRect(0, 0, width, height); // املأ لون الخلفية بالأبيض // As an example, draw a large number of colored disks. // To get a different picture, erase this code, and substitute your own. int centerX; // ‫احداثي x لمركز القرص int centerY; // ‫احداثي y لمركز القرص int colorChoice; // قيمة اللون العشوائي int count; // المتغير التحكم بالحلقة for (count = 0; count < 500; count++) { centerX = (int)(width*Math.random()); centerY = (int)(height*Math.random()); colorChoice = (int)(4*Math.random()); switch (colorChoice) { case 0: g.setFill(Color.RED); break; case 1: g.setFill(Color.GREEN); break; case 2: g.setFill(Color.BLUE); break; case 3: g.setFill(Color.YELLOW); break; } g.fillOval( centerX - 50, centerY - 50, 100, 100 ); g.setStroke(Color.BLACK); g.strokeOval( centerX - 50, centerY - 50, 100, 100 ); } } // ‫نهاية drawPicture() هذه هي المرة الأولى التي تَتعرَّض فيها لتَعرِيف برنامج فرعي (subroutine definition) -إلى جانب main()‎-. سنتناول هذا الموضوع تفصيليًا بالفصل التالي، ولكن سنَمر عليه سريعًا هنا، يُتيِح السَطْر الأول من التَعرِيف الولوج لبعض القيم التي يَحتاجها البرنامج الفرعي، وهي السِّياق الرُسومي g، وكلًا من عَرْض وارتفاع مساحة الرسم width و height. يَستقبِل البرنامج الفرعي هذه القيم من مصدر خارجي، ويستطيع اِستخدَامها. ما يَهمّ هنا هو أن تُدرِك أنه لكي تَرِسم شيئًا (يَقصِد الكاتب أن هذا هو هدف البرنامج الفرعي، فاِسم البرنامج الفرعي هو drawPicture)، فستحتاج فقط إلى كتابة مُحتوَى البرنامج الفرعي، مثلما تَكتُب مُحتوَى البرنامج main()‎ عند كتابة برنامج (الهدف من main()‎). يَنبغي لتَعرِيف البرنامج الفرعي (subroutine definition) أن يَكُون بالصَنْف (class) الذي يُعرِّف البرنامج، وهو في هذه الحالة الصَنْف SimpleGraphicsStarter. شَّغِل البرنامج -مُتاح بالكامل بالملف SimpleGraphicsStarter.java- لترى الرَسمة، كما يُمكِنك اِستخدَام هذا البرنامج كنقطة بداية لرَسْم الصور الخاصة بك. لاحِظ أنك لن تَفهم كل الشيفرة المكتوبة بالبرنامج، لكن ما يزال بإمكانك التَعديل عليها، فلا حاجة إلى فهم الشيفرة بأكملها، كل ما قد يَعَنيك هو الشيفرة الموجودة بالبرنامج الفرعي drawPicture()‎. اِحذف تلك الشيفرة، وضَعْ مكانها شيفرة الرسوم خاصتك، وستَتمكَّن بعدها من عَرْض رسوماتك. بالمناسبة، قد تُلاحِظ أن الكلمة static مُستخدَمة بتَعرِيف البرنامج الفرعي main()‎، بعكس البرنامج الفرعي drawPicture()‎، الذي لا يَستخدِمها، وهو ما يَعنِي أن البرنامج الفرعي drawPicture()‎ موجود بكائن (object) وليس بصَنْف (class). تُعدّ البرامج الفرعية التي تَستخدِم الكلمة static بتَعرِيفعها ساكنة (static)، أما التي لا تَستخدِمها فتُعدّ غَيْر ساكنة (non-static). الفرق بينهما مُهِمّ، ولكنه ليس بالأمر الذي يَنبغي أن تَقْلَق حِياله في الوقت الحاضر؛ حيث سنتناوله تفصيليًا بالفصل الخامس على أية حال. التحريكة (Animation) يَعتمِد التَحرِيك الحاسوبي (computer animation) على متتالية من الصور المُنفصلة، يُطلَق على كُل منها اسم الإطار (frame). تُعرَض هذه الصور بشكل سريع واحدة تلو الآخرى، فإذا كان التَغْيِير بين كل صورة والصورة التي تَليها طفيفًا، ستبدو متتالية الصور وكأنها تَحرِيكة مُستمرة (continuous animation). يُمكِنك اِستخدَام المثال التوضيحي بالملف SimpleAnimationStarter.java كنقطة بداية، حيث يَحتوِي على البرنامج الفرعي drawFrame()‎ المَسؤول عن رَسْم إطار (frame) وحيد ضِمْن تَحرِيكة (animation)، بالإضافة إلى ذلك، يُنفَّذ البرنامج الفرعي drawFrame()‎ أتوماتيكيًا حوالي ٦٠ مرة بالثانية، مما يَضمَن استمرار عَرْض الأُطُر (frames)، أيّ أنك تستطيع إِنشاء تَحرِيكة (animation) بمُجرَّد إضافة الشيفرة إلى هذا البرنامج الفرعي. تستطيع تمييز المرة الحالية من التَّنْفيذ من خلال مُتَغيِّرين إضافيين -إلى جانب السِّياق الرُسومي وكُلًا من عَرْض وارتفاع مساحة الرسم- يَستقبِلهما البرنامج الفرعي، وهما frameNumber و elapsedSeconds؛ حيث يأخذ المُتَغيِّر frameNumber القيم ٠، ١، ٢، ٣، .. والتي تَزداد بمقدار الواحد مع كل اِستدعاء للبرنامج الفرعي، أمَا قيمة المُتَغيِّر elapsedSeconds فتُشيِر إلى عدد الثواني التي مَرَّت على تَّنْفيذ التَحرِيكة حتى الآن. إجمالًا، تَستطيع رَسْم صورة مختلفة في كل مرة يُستدَعى فيها البرنامج الفرعي (subroutine) بالاعتماد على قيمة أيًا من هذين المُتَغيِّرين. سنَرسِم بالمثال التالي مجموعة من المستطيلات المُتداخِلة (nested rectangles)، والتي ستنكمش باتجاه مركز الرَسْمة، مما سيُعطِي انطباعًا زائفًا بوجود حركة لا نهائية (infinite motion). تَعرِض الصورة التالية إِطارًا واحدًا من التَحرِيكة (animation): لنُفكر كيف يُمكِن رَسْم مثل هذه الصورة. عامةً، يُمكِن اِستخدَام حَلْقة التَكْرار while لرَسْم المستطيلات، بحيث تبدأ أولًا برَسْم المستطيل الخارجي، ثُمَّ تنتقل إلى الداخل وهكذا. يَنبغي الآن أن نُفكر بالمُتَغيِّرات التي سنحتاج إليها خلال حَلْقة التَكْرار (loop)، وكذلك بالطريقة التي ستَتغَيَّر بها قيم تلك المُتَغيِّرات من تَكْرار (iteration) معين إلى التَكْرار الذي يليه. ستساعدنا الملاحظات التالية على مَعرِفة تلك المُتَغيِّرات، أولًا، مع كل تَكْرار، يكون المستطيل المرسوم أصغر منه في المرة السابقة، كما أنه يَتحرك للداخل قليلًا. يتركز عامةً الفارق بين أيّ مستطيلين على حجمهما وإِحداثيَّات (coordinates) رُكْنيهما اليساريين العُلوِيين (upper left corners)، ولهذا سنحتاج، أولًا، إلى مُتَغيِّرين لتَمثيِل كلًا من عَرْض المستطيل وارتفاعه، وهما المُتَغيِّران rectWidth و rectHeight على الترتيب. أما بالنسبة لإِحداثيَّات الرُكْن الأيسر العُلوِي x و y، فيُمكِن تَمثيِل كليهما بمُتَغيِّر وحيد للمستطيل الواحد، هو المُتَغيِّر inset؛ لأن قيمتهما مُتساوِية؛ حيث يَبعُد أيّ مستطيل عن حافتي مساحة الرسم (drawing area) بنفس مقدار المسافة. نُلاحِظ أنه مع كل تَكْرار، تَنقُص قيمة كلًا من عَرْض المستطيل rectWidth وارتفاعه rectHeight، بينما تزداد المسافة inset التي يَبعُدها المستطيل عن الحافتين. أخيرًا، تنتهي حَلْقة التَكْرار while عندما يُصبِح عَرْض المستطيل أو ارتفاعه أقل من أو يُساوِي الصفر. اُنظر خوارزمية رَسْم إِطار (frame) وحيد: // املأ مساحة الرسم باللون الأبيض Fill the drawing area with white // ‫اضبط قيمة inset المبدئية للمستطيل الأول الخارجي Set the amount of inset for the first rectangle // اضبط قيمة عرض وارتفاع المستطيل الأول الخارجي Set the width and height for the first rectangle // اضبط اللون المستخدم لتحديد الحواف إلى اللون الأسود Set the stroke color to black // طالما كان العرض والارتفاع أكبر من الصفر while the width and height are both greater than zero: // ‫ارسم مستطيل باستخدام البرنامج الفرعي g.strokeRect draw a rectangle (using the g.strokeRect subroutine) // ‫أزد قيمة inset حتى ينتقل المستطيل التالي إلى الداخل increase the inset (to move the next rectangle over and down) // ‫انقص عرض وارتفاع المستطيل التالي حتى يصبح المستطيل التالي أصغر decrease the width and height (to make the next rectangle smaller) ضُبطَت هذه النسخة من البرنامج بحيث يَبعُد كل مستطيل مسافة قدرها ١٥ بكسل عن المستطيل المُحيِط به، ولهذا فإن قيمة المُتَغيِّر inset تَزداد بمقدار ١٥ بكسل مع كل تَكْرار. في المقابل، يَتقَلص المستطيل حوالي ١٥ بكسل يمينًا ويسارًا، أيّ يَنقُص عَرْض المستطيل بمقدار ٣٠ بكسل. وبالمثل، يَنقُص ارتفاعه بمقدار ٣٠ بكسل مع كل تَكْرار ضِمْن الحلقة. يَسهُل إعادة كتابة الخوارزمية بلغة الجافا، لكن تتبقَى فقط حاجتنا إلى معرفة القيم المبدئية للمُتَغيِّرات inset و width و height لأول مستطيل-(المستطيل الخارجي). لحساب ذلك، سنُفكر في حقيقة كَوْن الصورة متحركة (animated)، أي يَعتمِد ما نَرسِمه بطريقة ما على رقم الإِطار (frame number) الحالي. لمّا كان الرُكْن الأيسر العُلوِي (top-left corner) للمستطيل الخارجي يتحرك للأسفل وللداخل من أيّ إِطار إلى الإِطار الذي يَليه، فإن قيمة المُتَغيِّر inset المبدئية تزداد مع كل إِطار. قد تُفكر إذًا بضَبْط قيمة المُتَغيِّر inset المبدئية إلى القيمة ٠ بالإِطار رقم ٠، وإلى القيمة ١ بالإطار رقم ١ وهكذا. للأسف، لن يكون هذا صالحًا إلى الأبد؛ فعندما تَصِل التحريكة للإِطار ١٥، يَنبغِي أن يَظهر مستطيل خارجي جديد بمساحة الرَسْم (drawing area)، هو في الواقع ليس جديدًا، وإنما أُعيد فقط ضَبْط قيمة المُتَغيِّر inset المبدئية إلى القيمة ٠. إجمالًا، يَنبغِي لقيمة المُتَغيِّر inset أن تأخذ القيم ٠، ١، ٢، ٣،… حتى تَصِل إلى القيمة ١٤، لتُعاد الكَرَّة من جديد، وهو ما يُمكِن إنجازه باِستخدَام الشيفرة التالية: inset = frameNumber % 15; لاحِظ أن المستطيل يَملأ مساحة الرسم باستثناء حافة (border) تُحيِط به، عَرْضها يُساوِي قيمة المُتَغيِّر inset، أي بعبارة آخرى، عَرْض المستطيل هو عَرْض مساحة الرسم مطروحًا منه ضعف قيمة المُتَغيِّر inset، وبالمثل لارتفاعه. انظر شيفرة البرنامج الفرعي drawFrame()‎ كاملة بالأسفل والمسئولة عن تَحرِيك المستطيل: public void drawFrame(GraphicsContext g, int frameNumber, double elapsedSeconds, int width, int height) { g.setFill(Color.WHITE); g.fillRect(0,0,width,height); // املأ مساحة الرسم باللون الأبيض // المسافة بين بين المستطيل الخارجي ومساحة الرسم double inset; double rectWidth, rectHeight; // عرض وطول أحد المستطيلات // اضبط اللون المستخدم لرسم حواف المستطيل g.setStroke(Color.BLACK); // إضافة القيمة 0.5 هو أسلوب للحصول على صورة أكثر وضوحًا inset = frameNumber % 15 + 0.5; rectWidth = width - 2*inset; rectHeight = height - 2*inset; while (rectWidth >= 0 && rectHeight >= 0) { g.strokeRect(inset, inset, rectWidth, rectHeight); inset += 15; // تبعد المستطيلات عن بعضها بمقدار 15 بكسل rectWidth -= 30; rectHeight -= 30; } } البرنامج مُتاح بالكامل بالملف MovingRects.java. يُمكِنك أيضًا الإِطلاع على مثال توضيحي آخر للتحريك (animation) بالملف RandomCircles.java، والذي يُضيِف قرصًا ملونًا (colored disk) بشكل عشوائي مع كل إِطار جديد. سيُظهِر لك هذا المثال أن صورة الإِطار لا تُحذَف تلقائيًا قبل إِعادة رسم الإِطار التالي. ترجمة -بتصرّف- للقسم Section 9: Introduction to GUI Programming من فصل Chapter 3: Programming in the Small II: Control من كتاب Introduction to Programming Using Java.
    1 نقطة
  12. 1 نقطة
  13. هناك عدة خيارات يمكنك عن طريق برنامج الالستراتر رسم الشكل وتقسيمه الى اجزاء ثم تصديره الى الافتر ايفيكت وتحريكه هناك او من داخل برنامج الافتر ايفيكت يمكنك القيام بالرسم ثم التحريك اذا كانت الرسمة غير معقدة كثيرا انا اقوم بالرسم بالالستراتر واقوم بالتحريك في الافتر ايفيكت
    1 نقطة
  14. مرحباً بك، الخطأ الذي يظهر هو كالتالي: cannot convert 'int (*)[3]' to 'int**' ما يعني أن الدالة print المفروض تستقبل وسيط من النوع **int لكن ما تم تمريره هو int (*)[3] و هو نوع المُتغير mm بطبيعة الحال يجب توحيد الأنواع حتى لا تحدث أخطاء هناك طريقتين إما بتعديل نوع الوسيط او المُعامل أو تعديل نوع المتُغير الذي تم تمريره كوسيط الطريقة الأولى بإمكانك تعديل الدالة print للشكل التالي: int* print(int (*arr)[3], int m, int n) { for(i = 0; i < 3; i++) for(j = 0; j < n; j++) return (*(arr+i) + j); } بالإضافة إلى تعديل السطر التالي: int** p = print(mm, m, n); إلى int* p = print(mm, m, n); لأن ما تُرجعه الدالة print هو مؤشر(pointer) و ليس مؤشر على مؤشر(pointer to pointer) بإمكانك تجربة الطريقة من خلال هذا : الرابط الطريقة الثانية تعديل نوع المُتغير الذي تم تمريره كوسيط بهذا الشكل: int main() { int arr[][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; int m = 3, n = 3; int *mm[3]; for (int i = 0; i < 3; ++i) { mm[i] = arr[i]; } int* p = print(mm, m, n); for(i = 0; i < 3; i++) for(j = 0; j < n; j++) cout << (*(p+i) + j); return 0; } بإمكانك تجربة هذه الطريقة من خلال هذا : الرابط بالتوفيق.
    1 نقطة
×
×
  • أضف...