البحث في الموقع
المحتوى عن 'pacman'.
-
سبَقَ وأن تعلّمنا في الجزء الأول كيفية استخدام أدوات رسم أشكال الفكتور وخيارات التحويل والأدلّة والمطابقة والمحاذاة وغيرها من التقنيات في برنامج الإنكسكيب للقيام بتصميم حلبة اللعبة الخاصة بلعبة PACMAN. في هذا الدرس سنتعلّم كيفية استخدام تقنيات رسم وتحويل الأشكال مع تقنيات إضافة أنماط للأشكال والنصوص والتحّكم بنقاط الأشكال وتحريكها للحصول على الشكل المطلوب. سنتابع من حيث انتهينا في الجزء الأول. افتح برنامج الإنكسكيب وافتح ملف الحلبة الذي رسمناه في الجزء الأول. والآن لنبدأ برسم شخصيات اللعبة. أولًا سنرسم باكمان عبر رسم دائرة صفراء بدون حدود من أداة الدوائر مع الاستمرار بالضغط على Ctrl لرسم دائرة متساوية الأبعاد تمامًا. ولتكن الدائرة بحجم مناسب لحركتها داخل مسارات اللعبة. اصنع نسخةً عن الدائرة سنحتاجها لاحقًا. انقر على النقطة الموجودة على الجانب الأيمن من الدائرة وحّركها للأعلى قليلًا ثم حرّك النقطة الأخرى في اليمين إلى الأسفل حتى يصبح شكل باكمان واضحًا بفمه الكبير. يمكنك التلاعب بحجم الفتحة من شريط الأدوات الخاص بالدائرة ولكننا سنحاول هنا إتقان الرسم اليدوي التقريبي غير الدقيق. حوّل الدائرة الثانية إلى مسار من القائمة Path > Object to Path انقر مرتين على الجانب السفلي الأيمن للدائرة لتحصل على نقطة ارتكاز جديدة كما في الشكل. اسحب هذه النقطة إلى الركن الأيمن. نفّذ ذات العملية مع الجزء الأيسر. اضغط على Ctrl أثناء النقر على أحد مقابض تعديل المسار لإحدى النقاط وستختفي المقابض. اسحب النقطة الآن إلى أقصى الزاوية تمامًا. كرّر العملية ذاتها للجزء الأيمن. انقر مرتين على الحدود السفلية وألغِ مقابض النقاط التي ستظهر ثم حرّكها (من الممكن الاستعانة ببعض الأدلّة هنا). استمر في هذا العمل حتى تحصل على شكل الشبح التقليدي. ارسم دائرة بيضاء بحدود رقيقة سوداء في الجزء العلوي من الشبح لتكون العين. اصنع نسخة عن العين وضعها في مكانها الصحيح في الجهة المقابلة. ارسم بؤبؤ العين بدائرة سوداء صغيرة. اصنع نسخة عن البؤبؤ وضعه فوق العين الثانية. لتوجيه نظر الشبح حدّد شكل العين والبؤبؤ معًا ثم حاذِهما لليمين، اليسار، الأعلى أو الأسفل بحيث ستكون جهة النظر هي الاتجاه الذي سيسلكه الشبح. بدّل اللون الأصفر للشبح إلى اللون الأحمر وبذلك أصبح شبحنا جاهزًا للعمل. حدّد شكل الشبح والعينين والبؤبؤ ثم اجمعهم في Group واحد. اصنع ثلاث نسخ إضافية من الشبح. أصبح نسخها أسهل بعد جمعها. لوّن هذه الأشباح بالألوان المُعتمدة في مختلف سلاسل هذه اللعبة. سنعيد تصميم الشبح الأخير ليظهر في حالة الخمول التي يستطيع فيها باكمان التهامه ولذلك لوّنه بالأزرق الداكن. أزِل البؤبؤ من العينين وأزل الحدود ولوّنهما باللون الأصفر. ارسم خطًّا أصفر مكان الفم. أضف عددًا من النقاط ثم عدّل في أماكنها مع الاستعانة بالأدلة الذكية لجعل الفم يبدو متعرّجًا. تصميم مخطط اللعبة والشخصيات قد اكتمل. وزّع الشخصيات داخل هذه اللعبة لتظهر وكأن هذه الصورة هي لقطة شاشة لهذه اللعبة ولا تنسَ تغيير اتجاه العيون بحسب اتجاه حركة الأشباح. في الموضع تحت منتصف منزل الأشباح تظهر الفواكه هنا عادةً أثناء اللعب لتمنح باكمان نقاطًا إضافية إذا التهمها. هنا سنرسم تفاحة، لذلك ارسم بدايةً دائرة حمراء بدون حدود. حوّل هذه الدائرة إلى مسار عبر القائمة Path > Object to Path أنشئ نقاطًا إضافيةً على محيط الدائرة عبر النقر المزدوج على الإطار ثم تلاعب بمواقع هذه النقاط حتى تحصل على شكل التفاحة. استخدم أداة القلم لرسم مسار مغلق على طرف التفاحة لتبدو طازجة ولمّاعة. استخدم أداة القلم أيضًا لرسم عود التفاحة الأخضر فوق التفاحة. والآن سننتقل سريعًا إلى خطوات تصميم العنوان. اكتب كلمة PACMAN بالخط الذي تريده، شريطة أن يكون خطًّا عريضًا، أزِل لون التعبئة، لوّن الحدود بالأصفر، عرض الحدود 1px وOpacity بقيمة 100% وBlur بقيمة 0. ضاعف النص واجعل عرض الحدود للنص الجديد 5px وOpacity بقيمة 100% وBlur بقيمة 3، أرسله خلف النص الأول بالضغط على PageDown. سنرسم شبح العنوان بالخطوات التالية: - ارسم دائرة حمراء بدون حدود أكبر من ارتفاع النص. - حوّلها إلى مسار من Path > Object to Path. - انقر نقرًا مزدوجًا على الحدود السفلية للدائرة لإنشاء نقاط جديدة وحرّكها حتى تأخذ شكل الشبح السفلي. - حدّد هذه النقاط السفلية وانقر على Smooth من شريط أدوات Nods العلوي لأداة تحديد Nods. - حرّك النقطتين الجانبيتين من الأسفل إلى الخارج قليلًا. - دوّره قليلًا نحو اليسار. سنرسم فم الشبح. ارسم شكلًا بيضويًّا ثم اجعل التعبئة Fill عبارة عن نقش Pattern واختر النقش Stripes 1:4، ارسم مستطيلًا وغطِّ به نصف الشكل البيضوي ثم حدّدهما معًا وقاطع بينهما بالاختصار Ctrl+-، ضاعف الشكل الناتج ولوّنه باللون الأبيض الكامل ثم أرسله خلف الشكل الأساسي بالضغط على مفتاح PageDown. ارسم شكلين بيضويين متقاطعين كما في الصورة ثم حدّدهما معًا وقاطع بينهما من خلال الضغط على Ctrl+- لتكون العين. ضاعف شكل العين وضعهما في موقعهما الصحيح على جسم الشبح. ارسم دائرة سوداء صغيرة ستكون بؤبؤ العين وضاعفها ثم ضع الدائرتين داخل شكل العينين. حدّد شكل جسم الشبح ثم استخدم أداة التدرج اللوني مع وضع شريط تدرج قاتم عند الأطراف وفاقع في المنتصف لمنح الانطباع ثلاثي الأبعاد. وأخيرًا انتهينا من رسم لقطة لشاشة لعبة PACMAN باستخدام التقنيات المتنوعة ببرنامج Inkscape، استخدمنا في هذا الدرس مجموعة من أدوات وتقنيات الإنكسكيب، رسمنا الشخصيات بالأشكال الأساسية وعدّلنا عليها واستخدمنا ألوان التعبئة والحدود والنقوش والتدرجات اللونية، كما استخدمنا تقنيات تحويل المسارات والعناصر والتعديل على المسارات، واستخدمنا ميزات المحاذاة والتوزيع المتساوي لوضع النقاط بشكل سليم في أماكنها الصحيحة، وأخيرًا استخدمنا تقنية التمويه Blur لصناعة نصٍّ متوهج. أرجوا أن تكونوا قد استفدتم من هذا الدرس.
-
من أهم مميزات CSS3 أنها تقلل من استخدام الصور في تصاميم الويب، وتسمح لك بإنشاء أشكال مختلفة بواسطتها. فالأشكال الشائعة التي تراها عادة في فوتوشوب أو Illustrator يمكنك عملها الآن بكل سهولة مستخدمًا CSS3. تقوم الخصائص الجديدة مثل transform و border-radius بإضافة تشكيلات جديدة إلى الأشكال الأساسية بدلاً من رسمها وتصميمها على برامج الرسم والتصميم. في درسنا لهذا اليوم، دعنا ننشئ قائمة بالأشكال الأكثر شيوعًا، وذلك باستخدام CSS3. يمكنك تحميل الملفات المصدرية لهذا الدرس من هنا. الدائرة HTMLلإنشاء دائرة في الـCSS، نحتاج أولاً إلى div واسمٍ للشكل id. وهنا ستأخذ الدائرة هذا الإسم: <div id="circle"></div>CSSضع مقاسات العرض والارتفاع width و height بالـCSS واجعل قيمة border-radius نصف قيمة العرض والارتفاع: #circle } width: 120px; height: 120px; background: #7fee1d; -moz-border-radius: 60px; webkit-border-radius: 60px; border-radius: 60px; }المربع HTMLنحتاج إلى div مع وضع اسمٍ له، لإنشاء شكل مربع وربطه بالاسم: <div id="square"></div>CSSاضبط مقاسات العرض والارتفاع بنفس القيمة، حتى يبدو واضحًا: #square } width: 120px; height: 120px; background: #f447ff; }المستطيل HTMLأنشئ div وضع اسمًا له، ويفضل أن يكون الاسم نفس نوع الشكل: <div id="rectangle"></div>CSSنضبط العرض والارتفاع تمامًا مثل المربع؛ ولكن بزيادة قيمة العرض أكثر من الارتفاع: #rectangle } width: 220px; height: 120px; background: #4da1f7; }الشكل البيضاوي HTMLلنقم بإنشاء div ونعطه اسم oval: <div id="oval"></div>CSSيشابه الشكلُ البيضاوي الدائرةَ إلى حد كبير؛ ومع ذلك، فإن الشكل البيضاوي هو مستطيل زواياه مستديرة بقيمة نصف الارتفاع: #oval } width: 200px; height: 100px; background: #e9337c;- webkit-border-radius: 100px / 50px;- moz-border-radius: 100px / 50px; border-radius: 100px / 50px; } المثلث HTMLيحتاج المثلث إلى div باسم triangle: <div id="triangle"></div>CSSلإنشاء مثلث بواسطة الـCSS، نقوم بالتعديل في خاصية border. سنقوم بتعديل عرض الـborder حتى يعطينا نتائج مغايرة في قياس الزاويا: #triangle } width: 0; height: 0; border-bottom: 140px solid #fcf921; border-left: 70px solid transparent; border-right: 70px solid transparent; }المثلث المقلوب HTMLقُم بإنشاء div وأعطه اسمًا: <div id="triangle_down"></div>CSSنحتاج إلى تعديل خاصية الحدّ السفليّ، لينتُج لدينا مثلث معكوس: #triangle_down } width: 0; height: 0; border-top: 140px solid #20a3bf; border-left: 70px solid transparent; border-right: 70px solid transparent; }مثلث متجه إلى اليسار HTMLيتطلب هذا الشكل وجود div مع اسمٍ للشكل وليكن triangle_left: <div id="triangle_left"></div>CSSنقوم بالتعديل في خاصية الحدّ الأيمن، حتى نحصلَ على مُثلث مُتَّجه لليسار: #triangle_left } width: 0; height: 0; border-top: 70px solid transparent; border-right: 140px solid #6bbf20; border-bottom: 70px solid transparent; }مثلث متجه لليمين HTMLلنقم بإنشاء div ونعطه اسم triangle_right: <div id="triangle_right"></div> CSSبعد ذلك نقوم بالتعديل على خاصية الحدّ الأيسر، ليصبح عندنا مثلثًا متجهًا إلى اليمين: #triangle_right } width: 0; height: 0; border-top: 70px solid transparent; border-left: 140px solid #ff5a00; border-bottom: 70px solid transparent; }الشكل المعين (الماسة) HTMLيحتاج المُعين إلى div باسم diamond: <div id="diamond"></div>CSSيُمكن عرض المُعيّن بعدة طرق، وذلك باستخدام خاصية transform مع rotate. بهذا يصبح لديك مُثلثان متقابلان ومتلاصقان ببعضهما: #diamond } width: 120px; height: 120px; background: #1eff00; -webkit-transform: rotate(-45deg); -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg); webkit-transform-origin: 0 100%; moz-transform-origin: 0 100%; -ms-transform-origin: 0 100%; -o-transform-origin: 0 100%; transform-origin: 0 100%; margin: 60px 0 10px 310px; }شبه المنحرف HTMLيتطلب هذا الشكل وجود div مع اسمٍ للشكل ولنسمه trapezium: <div id="trapezium"></div>CSSنقوم الآن بصناعة الشكل المطلوب، حيث نجعل الحدَّ الأيمن والأيسر متساويين مع الاحتفاظ بالحدّ السفليّ مُسَطّحًا: #trapezium } height: 0; width: 120px; border-bottom: 120px solid #ec3504; border-left: 60px solid transparent; border-right: 60px solid transparent; }متوازي الأضلاع HTMLقُم بإنشاء div وأعطه اسم parallelogram: <div id="parallelogram"></div>CSSثم قم بضبط قيمة الانحراف skew لخاصية transform لحرفه بزاوية 30 درجة: #parallelogram } width: 160px; height: 100px; background: #8734f7; -webkit-transform: skew(30deg); -moz-transform: skew(30deg); -o-transform: skew(30deg); transform: skew(30deg); }النجمة HTMLيلزمنا div لإنشاء النجمة مع اسمٍ له وليكن star: <div id="star"></div>CSSيتطلب إنشاء النجمة بالـCSS تعديلات عجيبة في خصائص الحدود مع استعمال قيمة rotate لخاصية transform، لاحظ ذلك في الكود: #star } width: 0; height: 0; margin: 50px 0; color: #fc2e5a; position: relative; display: block; border-right: 100px solid transparent; border-bottom: 70px solid #fc2e5a; border-left: 100px solid transparent; -moz-transform: rotate(35deg); -webkit-transform: rotate(35deg); -ms-transform: rotate(35deg); -o-transform: rotate(35deg); } #star:before { height: 0; width: 0; position: absolute; display: block; top: -45px; left: -65px; border-bottom: 80px solid #fc2e5a; border-left: 30px solid transparent; border-right: 30px solid transparent; content: ''; -webkit-transform: rotate(-35deg); -moz-transform: rotate(-35deg); -ms-transform: rotate(-35deg); -o-transform: rotate(-35deg); } #star:after { content: ''; width: 0; height: 0; position: absolute; display: block; top: 3px; left: -105px; color: #fc2e5a; border-right: 100px solid transparent; border-bottom: 70px solid #fc2e5a; border-left: 100px solid transparent; -webkit-transform: rotate(-70deg); -moz-transform: rotate(-70deg); -ms-transform: rotate(-70deg); -o-transform: rotate(-70deg); }النجمة السداسية HTMLتتطلب النجمة السداسية وجود div مع اسمٍ للشكل، ولنطلق عليه اسم parallelogram: <div id="parallelogram"></div>CSSبخلاف النجمة السابقة، فإننا سنقوم بتعديل خصائص الحدود. سننشئ مجموعة من الأشكال ومن ثم نُلصقُها ببعضها البعض لنحصل على الشكل المطلوب: #star_six_points} width: 0; height: 0; display: block; position: absolute; border-left: 50px solid transparent; border-right: 50px solid transparent; border-bottom: 100px solid #de34f7; margin: 10px auto; } #star_six_points:after } content: ''; width: 0; height: 0; position: absolute; border-left: 50px solid transparent; border-right: 50px solid transparent; border-top: 100px solid #de34f7; margin: 30px 0 0 -50px; } المضلع الخماسي HTMLيتطلب المُضلعُ الخماسي وجود div مع اسمٍ للشكل ولنسمه pentagon: <div id="pentagon"></div>CSSنحتاج إلى عنصرين لإنشاء المضلع الخماسي. أول عنصر نقوم بإنشائه هو شكل شبه المنحرف والعنصر الثاني هو المثلث حيث سيكون أعلى الشكل الأول: #pentagon } width: 54px; position: relative; border-width: 50px 18px 0; border-style: solid; border-color: #277bab transparent; } #pentagon:before } content: ''; height: 0; width: 0; position: absolute; top: -85px; left: -18px; border-width: 0 45px 35px; border-style: solid; border-color: transparent transparent #277bab; }المضلع السداسي HTML يلزمنا div لإنشاء المُضلع السداسي مع اسم له وليكن hexagon: <div id="hexagon"></div> CSSهناك عدة طرق لإنشاء المُضلع السداسي. إحدى هذه الطرق مطابقة بشكل كبير لطريقة إنشاء المُضلع الخماسي. حيث نقوم بإنشاء مستطيل في البداية ومن ثم نضيف أعلاه مُثلثين: #hexagon } width: 100px; height: 55px; background: #fc5e5e; position: relative; margin: 10px auto; } #hexagon:before } content: ''; width: 0; height: 0; position: absolute; top: -25px; left: 0; border-left: 50px solid transparent; border-right: 50px solid transparent; border-bottom: 25px solid #fc5e5e; } #hexagon:after } content: ''; width: 0; height: 0; position: absolute; bottom: -25px; left: 0; border-left: 50px solid transparent; border-right: 50px solid transparent; border-top: 25px solid #fc5e5e; }المضلع الثماني HTML قُم بإنشاء div وأعطه اسم octagon: <div id="octagon"></div>CSSيُمكن إنشاء هذا الشكل بطرق مُشابهة للشكل السابق. حيث نقوم بإنشاء شكلين شبه منحرفين ومن ثم نضع مُثلثين على كل جانب منهما. على الرغم من وجود بعض الطرق الأخرى لعمل ذلك؛ إلا أن هذه هي أفضل طريقة لذلك: #octagon } width: 100px; height: 100px; background: #ac60ec; position: relative; } #octagon:before } content: ''; width: 42px; height: 0; position: absolute; top: 0; left: 0; border-bottom: 29px solid #ac60ec; border-left: 29px solid #f4f4f4; border-right: 29px solid #f4f4f4; } #octagon:after } content: ''; width: 42px; height: 0; position: absolute; bottom: 0; left: 0; border-top: 29px solid #ac60ec; border-left: 29px solid #f4f4f4; border-right: 29px solid #f4f4f4; }شكل القلب HTML يتطلب شكل القلب وجود div مع اسمٍ للشكل ولنسمه heart: <div id="heart"></div> CSSيُمكن أن يكون إنشاءُ شكل القلب صعبًا بعض الشيء؛ ولكن نستطيع القيام بذلك عن طريق عمل استدارة للعناصر من زوايا مختلفة وتغيير قيمة خاصية transform-origin حتى نتمكن من تغيير موضع العنصر المُحَدَّد: #heart } position: relative; } #heart:before, #heart:after } content: ''; width: 70px; height: 115px; position: absolute; background: red; left: 70px; top: 0; -webkit-border-radius: 50px 50px 0 0; -moz-border-radius: 50px 50px 0 0; border-radius: 50px 50px 0 0; -webkit-transform: rotate(-45deg); -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg); -webkit-transform-origin: 0 100%; -moz-transform-origin: 0 100%; -ms-transform-origin: 0 100%; -o-transform-origin: 0 100%; transform-origin: 0 100%; { #heart:after { left: 0; -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -ms-transform: rotate(45deg); -o-transform: rotate(45deg); transform: rotate(45deg); -webkit-transform-origin: 100% 100%; -moz-transform-origin: 100% 100%; -ms-transform-origin: 100% 100%; -o-transform-origin: 100% 100%; transform-origin: 100% 100%; }البيضة HTML يلزمنا div لإنشاء شكل البيضة مع اسمٍ له وليكن egg: <div id="egg"></div>CSSإنَّ شكل البيضة مطابق إلى حدٍّ ما للشكل البيضاوي؛ إلا أن ارتفاعها أكبر بقليل من عرضها. نقوم بضبط خاصية الزوايا المستديرة بشكل دقيق حتى نحصل على مرادنا بالضبط: #egg } width: 136px; height: 190px; background: #ffc000; display: block; -webkit-border-radius: 63px 63px 63px 63px / 108px 108px 72px 72px; border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%; } شكل اللانهائية HTML قُم بإنشاء div وأعطه اسم infinity: <div id="infinity"></div>CSSيمكن الحصول على شكل اللانهائية بالضبط الدقيق لخصائص الحدود وزاويا الدائرة كما بالشكل السابق: #infinity } width: 220px; height: 100px; position: relative; } #infinity:before, #infinity:after } content: ''; width: 60px; height: 60px; position: absolute; top: 0; left: 0; border: 20px solid #06c999; -moz-border-radius: 50px 50px 0; border-radius: 50px 50px 0 50px; -webkit-transform: rotate(-45deg); -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg); } #infinity:after { left: auto; right: 0; -moz-border-radius: 50px 50px 50px 0; border-radius: 50px 50px 50px 0; -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -ms-transform: rotate(45deg); -o-transform: rotate(45deg); transform: rotate(45deg); }بالون التعليقات HTML قُم بإنشاء div وأعطه اسم comment_bubble: <div id="comment_bubble"></div>CSSنقوم بصناعة هذا الشكل بواسطة إنشاء مستطيل ذي زوايا مستديرة، ثم ننشيء مُثلثًا ونضعه على الجانب الأيسر كما بالصورة: #comment_bubble } width: 140px; height: 100px; background: #088cb7; position: relative; -moz-border-radius: 12px; -webkit-border-radius: 12px; border-radius: 12px; } #comment_bubble:before } content: ''; width: 0; height: 0; right: 100%; top: 38px; position: absolute; border-top: 13px solid transparent; border-right: 26px solid #088cb7; border-bottom: 13px solid transparent; }شكل باكمان (لعبة آكلة الجبنة) HTMLيتطلب شكل الباكمان وجود div مع اسمٍ للشكل ولنسمه pacman: <div id="pacman"></div>CSSإنشاء شكل الباكمان غير صعب، فكل ما يحتاجه هو نفس خطوات إنشاء الدائرة مع تعديل بسيط في الحدود وخاصية radius لصنع فتحة على الجانب الأيسر من الدائرة: #pacman } width: 0; height: 0; border-right: 70px solid transparent; border-top: 70px solid #ffde00; border-left: 70px solid #ffde00; border-bottom: 70px solid #ffde00; border-top-left-radius: 70px; border-top-right-radius: 70px; border-bottom-left-radius: 70px; border-bottom-right-radius: 70px; }في الختامتوجد هناك العديد من الميزات في استخدام الأشكال المصنوعة بالـCSS، فهي أفضل بكثير من وضع صور جاهزة على موقعك. فأنت تستطيع استخدامها الآن كجزء من تصاميم المواقع، على الرغم من أنها قد لا تعمل على بعض المتصفحات مثل إنترنت إكسبلورر بإصداراته القديمة. الآن وقد انتهيت من درس اليوم، أتمنى أن تكون قد استمتعت فيه، وأنا على استعداد لتقبل أي تعليقات أو تساؤلات أو اقتراحات في هذا المجال. ترجمة وبتصرف للمقال: How to Create Different Shapes in CSS. حقوق الصورة البارزة: Designed by Freepik.
-
من منّا لا يعرف لعبة باكمان PACMAN، غالبًا لعب بها الجميع، هذه اللعبة رائعةٌ وبسيطةٌ وتُشكّل جزءًا من ذكرياتي وذكريات الكثيرين حول العالم، سنقوم في هذا الدرس بالعمل على برنامج Inkscape لتصميم شاشة من اللعبة باستخدام تقنيات مختلفة نتعلّم فيها الإمكانات الرائعة لبرنامج الإنكسكيب. سنقسّم شرح هذا التصميم إلى درسين وسيكون الجزء الأول عن تصميم حلبة اللعبة والواجهة الرسومية الخاصة بها وسيكون الجزء الثاني عن تصميم شخصيّات اللعبة من الأشباح وشخصية باكمان مع تفاحة تظهر عادة في اللعبة. بدايةً افتح برنامج الإنكسكيب ثم اذهب إلى القائمة File > Document Properties لتظهرَ نافذة خصائص الملف الذي سنعمل عليه. سنقوم بإلغاء خيَار Show Page Border حتى نلغي ظهور حدود الصفحة (الملف) الذي سنعمل عليه. سنبدأ بتصميم حلبة اللعب، يمكنك طبعًا تأليف حلبة من مخيلتك أو يمكنك نسخ تصميم جاهز من إحدى إصدارات اللعبة الكثيرة، أنا اخترت إصدار اللعبة التي كنت ألعبها دائمًا في صغري وهو إصدار أجهزة MSX. قم بلصق المخطط في الإنكسكيب (يكفي سحب الصورة وإفلاتها داخل البرنامج). طبعًا يمكننا القيام بسهولة بتحويل صورة الحلبة إلى مسارات جاهزة عبر الأمر Trace Bitmap الموجود في قائمة Path ولكننا سنقوم في هذا الدرس بتعلّم كيفية تتبع المسارات ورسمها عبر أدوات رسم مسارات الفكتور المتنوعة وخصائها لذلك سنقوم برسم الحلبة يدويًّا، على الرغم من أن العملية ستكون طويلة وشاقة بعض الشيء ولكنها ستكون مهمّة لتعلّم أهم ميزة من مزايا تصاميم الفكتور وهي تتبع ورسم المسارات المتوجهة أو مسارات الفكتور. أدرج مجموعةً من الأدلّة عبر سحبها من المسطرة حتى تحدّد حدود مخطط اللعبة، سنحتاج إليها لرسم هذا المخطط بدقة. افتح مجدّدًا نافذة خصائص الملف واذهب إلى Snap سنحتاج إلى زيادة حساسية التطابق أو جعلها مطلقة بالنسبة للأدلّة. قد نحتاجُ أحيانًا أثناء سير العمل إلى العودة مجدّدًا إلى هذه الخيارات وإعادتها إلى ما كانت عليه لنستطيع العمل بسلاسة أكبر. استخدم أداة القلم Pen وذلك بالضغط على Shift+F6 لرسم الجزء العلوي من مخطط اللعبة بالاستعانة بالأدلّة وتجاهل الخط الصغير العمودي في الأعلى، سنقوم برسمه لاحقًا. أصبح هذا الخط المرسوم عبارة عن عنصر وهذه الخطوط هي الحدود الخارجية المفتوحة. الآن سنحوّل هذا العنصر إلى مسار وذلك من القائمة: Path > Stroke to Path ثم سنحوّله إلى مسار ديناميكي من القائمة: Path > Dynamic Offset وبذلك يصبح هذا الخط له جسم وحدود ويمكن تلوين الجسم وكذلك الحدود ويمكن التحكم بسماكة هذا الجسم (المقصود هنا جسم الخط). ألغِ لون التعبئة لهذا الخط وامنح الحدود لونًا أزرقَ وهو لون مخطط اللعبة الأصلية في معظم إصدارات اللعبة ولتكُن عرض الحدود نحو 3px وقم بتحريك النقطة المركزية الجانبية حتى تغيّر من سماكة جسم الخط بشكل مقارب لما هو عليه في المخطط الأصلي الذي نرسم من خلاله. ارسم الخط العمودي الصغير وسط أعلى الخط الذي رسمناه للتو. كرّر ذات العملية التي قمنا بها مع الخط السابق: Path > Stroke to Path Path > Dynamic Offset ومن ثم امنحه اللون المناسب والسماكة ذاتها. حدّد كلا الخطين السابق والجديد الصغير ثم اذهب للقائمة: Path > Union وبذلك يتوحّد الشكلان معًا، انتبه أن سماكة الخطوط الداخلية للمخطط أكبر من سماكة الخطوط الخارجية. الآن أصبح الجزء العلوي من المخطط جاهزًا وسنتابع بقية الخطوط. ارسم الخط السفلي باستخدام أداة القلم وذلك بالضغط على Shift+F6 واستعن بخطوط الأدلة. كرّر ذات العملية لجميع الخطوط في التصميم. ارسم النتوء الصغير أيسر الشاشة. ومجدّدًا طبّق عليه ذات التأثرات أيضًا ولاحظ أنه أكبر عرضًا من الخط الخارجي المحيط بالتصميم. مجدّدًا أدمج الخطين في الأسفل معًا باستخدام Union من قائمة Path. والآن كرّر العملية لرسم النتوء الأيمن من الخط السفلي. أدمج هذا النتوء مع الشكل السفلي. الآن أصبحت الخطوط الأساسية المحيطة بمخطط اللعبة جاهزة. اسحب المزيد من خطوط الأدلّة حتى يصبح عملك أسهل وأفضل وأسرع. ارسم خطًّا من أحد الخطوط الداخليّة الصغيرة ثم حوّله كما فعلنا سابقًا وكبّر سماكة العنصر كما في المخطط الأصلي. بعض العناصر تشبه الحرف T لذلك سنرسم الخطين المتقاطعين ونضيف عليهما كامل التأثيرات السابقة. سندمج هذين العنصرين معًا لتتم معالجتهما كعنصر واحد. كرّر العملية ولكن هذه المرة استخدم أداة المستطيلات لرسم المربع غير الكامل مع إلغاء لون التعبئة وتلوين الحدود بذات اللون المستخدم سابقًا. حرّك النقطة في الزاوية لكي تزداد قيمة نصف قطر الزاوية للمستطيل وجعله يبدو متناسقًا مع باقي التصميم. كرّر ذات العملية مع باقي المستطيلات. استمر في رسم الخطوط وتحويلها وتلوينها حتى تنتهي منها جميعًا ويصبح مخطط اللعبة بهذا الشكل. ارسم الآن خطًّا حول منزل الأشباح ثم حوّله ثم تابع ذات الإجراءات المُتّبعة حتى النهاية. اضبط عبر النقاط المركزية وباستخدام أداة Node النقاط في أطراف الشكل الخطّي حتى تصبح ملائمة للمخطط الأصلي العامة. ارسم مستطيلًا صغيرًا عند مدخل المنزل ثم أرسله أسفل خطوط المنزل. مبدئيًّا، المخطط العام للعبة أصبح جاهزًا. أزِل كل الأدلة. وكذلك صورة المخطط التي رسمنا فوقها. ارسم مستطيلًا أسود فوق مساحة مخطط اللعبة حيث سيكون الخلفية. أرسل هذا المستطيل إلى أسفل جميع الأشكال من القائمة التي في الصورة أو بالضغط على مفتاح END. اضبط وركّز حجم الخلفية السوداء بالنسبة لحجم مخطط اللعبة. بدّل لون التعبئة لبوابة منزل الأشباح إلى اللون الأبيض. ارسم الآن النقطة التي سيتوجب على باكمان أكلها وذلك باستخدام أداة المستطيلات وتعديل الزوايا المستديرة. انسخ وألصق عبر Ctrl+D لإنشاء مجموعة جديدة من النقاط. للحصول على مسافة موحّدة بين جميع النقاط قم بتحديد جميع النقاط المتجاورة ثم انقر على خيَار تساوي المسافات بحسب المركز من Distribute ثم حاذِها من Align . كرّر هذه العملية على جميع مجموعات النقاط المتجاورة. ارسم نقطةً أكبر عند الزوايا تمامًا وهي ما يُمكّن باكمان من التهام الأشباح. سنرسم نصف النقاط تقريبًا للدلالة على سير اللعبة وأن على باكمان التهام المزيد للفوز في هذه المرحلة. وبهذا ينتهي الجزء الأول من درس تصميم شاشة لعبة PACMAN حيث تعلمنا كيفية استخدام أدوات رسم وتحويل مسارات الفكتور بشكل يدوي وهي من أهم المهارات الواجب إتقانها من قبل أي مصمم رسوميات. يمكننا اختصار الوقت واستخدام الأمر Trace Bitmap للقيام بعملية تحويل صورة الحلبة إلى مسارات بسهولة وفي ثوانٍ معدودة ولكننا تعمَّدنا القيام بعملية الرسم اليدوية هنا لإتقان مهارات استخدام أدوات الفكتور وخيارات التحويل وتقنيات الأدلّة والمُطابقة والمُحاذاة وغيرها من تقنيات الإنكسكيب الرائعة. في الجزء الثاني سنتعلّم كيفية تصميم شخصيّات اللعبة واللمسات النهائية لعملية التصميم.
-
قبل التعرف على التنسيقات والألوان في Canvas سنقوم بتطبيق مثال رسومي للعبة شهيرة باستخدام أنواع المسارات التي تعلّمناها في الدرس السابق لإنشاء شخصيات لعبة Pacman الشهيرة. تصميم واجهة اللعبة سنحتاج لرسم مستطيلات بحواف دائرية لتمثيل الحواجز في اللُّعبة لذا سننشئ دالة ولتكن roundRect ونعطيها المعاملات parameters المناسبة لإنشاء مستطيل بحواف دائرية. السّياق Context سنحتاج لتمرير نوع السّياق للدالة التي سيتم إنشاؤها. إحداثيات نقطة بداية الرسم (x,y). عرض المستطيل width. طول المستطيل height. القطر radius. function roundedRect(ctx, x, y, width, height, radius) في بداية كل عملية رسم سنحتاج لاستدعاء الدالة beginPath لإنشاء القائمة List التي ستحوي نقاط المسار كما شرحنا في الدرس السّابق. تتبعها الدالة moveTo لتحديد النقطة التي سيبدأ عندها الرسم. سيتم تمرير المعاملات x,y للدالة moveTo مع جمع قيمة القطر radius للقيمة y. نبدأ الآن برسم خط مستقيم باستخدام الدالة lineTo وتمرير القيمة x نفسها التي بدأنا عندها الرسم مع قيمة y المضاف إليها طول المستطيل height ليتم رسم خط مستقيم بطول المستطيل وطرح قيمة القطر radius وهكذا ينشأ الضلع الأول للمستطيل. الآن رسم حافة المستطيل باستخدام الدالة quadraticCurveTo وتحديد المعاملات: quadraticCurveTo(x, y + height, x + radius, y + height); ثم رسم الضلع الثاني للمستطيل باستدعاء الدالة lineTo: ctx.lineTo(x + width-radius, y + height); رسم الحافة الثانية للمستطيل: ctx.quadraticCurveTo(x + width, y + height, x + width, y + height-radius); رسم الضلع الثالثة للمستطيل: ctx.lineTo(x + width, y + radius); رسم الحافة الثالثة للمستطيل: ctx.quadraticCurveTo(x + width, y, x + width-radius, y); رسم الضلع الرابعة للمستطيل: ctx.lineTo(x + radius, y); رسم الحافة الرابعة للمستطيل: ctx.quadraticCurveTo(x, y, x, y + radius); أخيرًا استدعاء الدالة stroke لرسم المستطيل بشكل مفرغ: function roundedRect(ctx, x, y, width, height, radius){ ctx.beginPath(); ctx.moveTo(x, y + radius); ctx.lineTo(x, y + height-radius); ctx.quadraticCurveTo(x, y + height, x + radius, y + height); ctx.lineTo(x + width-radius, y + height); ctx.quadraticCurveTo(x + width, y + height, x + width, y + height-radius); ctx.lineTo(x + width, y + radius); ctx.quadraticCurveTo(x + width, y, x + width-radius, y); ctx.lineTo(x + radius, y); ctx.quadraticCurveTo(x, y, x, y + radius); ctx.stroke(); } حان الوقت الآن لاستدعاء الدالة roundedRect ورسم المستطيلات التي ستمثل الحواجز في لعبة pacman. في الدالة draw سيتم استدعاء الدالة roundedRect على عدد المستطيلات (الحواجز) التي ستكون في الشكل. سأقوم بإنشاء جزء من واجهة اللُّعبة (جزء من الإطار الخارجي وعدد من المستطيلات) كما في الشيفرة التالية: function draw() { var canvas = document.getElementById('tutorial'); if (canvas.getContext) { var ctx = canvas.getContext('2d'); roundedRect(ctx, 12, 12, 150, 150, 15); roundedRect(ctx, 19, 19, 150, 150, 9); roundedRect(ctx, 53, 53, 49, 33, 10); roundedRect(ctx, 53, 119, 49, 16, 6); roundedRect(ctx, 135, 53, 49, 33, 10); roundedRect(ctx, 135, 119, 25, 49, 10); } } سينتج الشكل: رسم شكل pacman سنحتاج لرسم شكل pac man إلى استدعاء الدالة arc لرسم الشكل الدائري والدالة lineTo لتحديد الفم: ctx.beginPath(); ctx.arc(37, 37, 13, Math.PI / 7, -Math.PI / 7, false); ctx.lineTo(31, 37); ctx.fill(); رسم مستطيلات صغيرة تمثل طعام pacman سنحتاج إلى حلقات تكرار لإنشاء مستطيلات صغيرة بين الحواجز كما في المثال التالي: for (var i = 0; i < 8; i++) { ctx.fillRect(51 + i * 16, 35, 4, 4); } for (i = 0; i < 6; i++) { ctx.fillRect(115, 51 + i * 16, 4, 4); } for (i = 0; i < 8; i++) { ctx.fillRect(51 + i * 16, 99, 4, 4); } رسم الشبح لرسم هيكل جسم الشبح سنستخدم الدالة bezierCurveTo لعمل الشكل العلوي من الجسم ثم استدعاء الدالة lineTo بإحداثيات مناسبة لعمل المنحنيات السّفلية للجسم: 1- رسم هيكل الشبح ctx.beginPath(); ctx.moveTo(83, 116); ctx.lineTo(83, 102); ctx.bezierCurveTo(83, 94, 89, 88, 97, 88); ctx.bezierCurveTo(105, 88, 111, 94, 111, 102); ctx.lineTo(111, 116); ctx.lineTo(106.333, 111.333); ctx.lineTo(101.666, 116); ctx.lineTo(97, 111.333); ctx.lineTo(92.333, 116); ctx.lineTo(87.666, 111.333); ctx.lineTo(83, 116); ctx.fill(); 2- العينان ctx.fillStyle = "white"; ctx.beginPath(); ctx.moveTo(91, 96); ctx.bezierCurveTo(88, 96, 87, 99, 87, 101); ctx.bezierCurveTo(87, 103, 88, 106, 91, 106); ctx.bezierCurveTo(94, 106, 95, 103, 95, 101); ctx.bezierCurveTo(95, 99, 94, 96, 91, 96); ctx.moveTo(103, 96); ctx.bezierCurveTo(100, 96, 99, 99, 99, 101); ctx.bezierCurveTo(99, 103, 100, 106, 103, 106); ctx.bezierCurveTo(106, 106, 107, 103, 107, 101); ctx.bezierCurveTo(107, 99, 106, 96, 103, 96); ctx.fill(); 3- البؤبؤ الأيمن ctx.fillStyle = "black"; ctx.beginPath(); ctx.arc(101, 102, 2, 0, Math.PI*2, true); ctx.fill(); 4- البؤبؤ الأيسر ctx.beginPath(); ctx.arc(89, 102, 2, 0, Math.PI*2, true); ctx.fill(); يمكنك استعراض المثال على JSFiddle. الكائن Path2D كما لاحظت في المثال السّابق أن كل شكل هو عبارة عن سلسلة من التعليمات التي تنفذ بالترتيب للحصول على المسار المطلوب ولا يوجد ارتباط واضح بين سلسلة التعليمات والشكل الناتج. ما رأيك أن نقوم بعملية تبسيط وتحسين وذلك بتحديد التعليمات الخاصة بكل شكل عن طريق استخدام الكائن Path2D. يقوم المنشئ Constructor عند إنشاء كائن Path2D بإرجاع كائن Path2D. new Path2D(); new Path2D(path); new Path2D(d); جميع الدوال الخاصة بإنشاء المسارات مثل moveTo ،rect ،arc، أو quadraticCurveTo..الخ يمكن استدعاؤها عن طريق الكائن Path2D. يوفّر Path2d API طريقة للجمع بين المسارات باستخدام الدالة addPath ويكون ذلك مفيدًا عندما ترغب في بناء شكل من عدة مكونات. سأقوم بإنشاء مستطيل ودائرة باستخدام الكائن Path2D. كل من المستطيل والدائرة يُخزن ككائن Path2D بحيث تكون متاحة للاستخدام في وقت لاحق. function draw() { var canvas = document.getElementById('canvas'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); var rectangle = new Path2D(); rectangle.rect(10, 10, 50, 50); var circle = new Path2D(); circle.moveTo(125, 35); circle.arc(100, 35, 25, 0, 2 * Math.PI); ctx.stroke(rectangle); ctx.fill(circle); } } لاحظ أنه تم استدعاء الدالتين stroke و fill من خلال السّياق ctx وتمرير الكائنين rectangle و circle من نوع Path2D كمعاملات. وكذلك أصبح واضحًا ما الشكل الذي ترسمه كل سلسلة من التعليمات. الألوان Colors حتى الآن تعرّفنا على الخاصيّة fillStyle والتي تقوم بملأ المسار بلون معين. سنتعرّف أيضًا على الخاصيّة fillStroke والتي تقوم بتلوين المسار المفرّغ (تلوين الحواف). إذًا يوجد خاصيتين أساسيتين لتطبيق الألوان على الأشكال: fillStyle = color strokeStyle = color القيمة الافتراضية لـ color هي اللون الأسود والتي تمثل القيمة #000000، يمكن تمثيل اللون color بعدة طرق. مثلًا تطبيق اللون البرتقالي باستخدام الخاصيّة fillStyle: ctx.fillStyle = "orange"; ctx.fillStyle = "#FFA500"; ctx.fillStyle = "rgb(255, 165, 0)"; ctx.fillStyle = "rgba(255, 165, 0, 1)"; تطبيق الألوان على شكل باستخدام الخاصية FillStyle سأعرض مثالًا لكيفية ملء شكل باستخدام مجموعة مستطيلات بألوان مختلفة ليبدو شكل متعدد الألوان. سيتم إنشاء حلقتي تكرار وذلك لتوليد مجموعة ألوان RGB مختلفة بتغيير قيمة red وgreen باستخدام المتغيرين i و j وترك القيمة blue ثابتة 0 سيبدو لك الشكل وكأنه منشأ باستخدام photoshop. unction draw() { var ctx = document.getElementById('canvas').getContext('2d'); for (var i = 0; i < 6; i++){ for (var j = 0; j < 6; j++){ ctx.fillStyle = 'rgb(' + Math.floor(255-42.5*i) + ',' + Math.floor(255-42.5*j) + ',0)'; ctx.fillRect(j*25, i*25, 25, 25); } } } النتيجة: تطبيق الألوان على شكل باستخدام الخاصية StrokeStyle سيكون المثال التالي مشابهًا للمثال السّابق مع تغيير الخاصيّة fillStyle إلى strokeStyle واستخدام الدالة arc لرسم دوائر داخل مستطيل وتوليد مجموعة ألوان RGB مختلفة بتغيير قيمة green و blue باستخدام المتغيرين i و j وترك القيمة red ثابتة. function draw() { var ctx = document.getElementById('canvas').getContext('2d'); for (var i = 0; i < 6; i++){ for (var j = 0; j < 6; j++){ ctx.strokeStyle = 'rgb(0,' + Math.floor(255-42.5*i) + ',' + Math.floor(255-42.5*j) + ')'; ctx.beginPath(); ctx.arc(12.5+j*25, 12.5+i*25, 10, 0, Math.PI*2,true); ctx.stroke(); } } } النتيجة: الشفافية Transparency بالإضافة لرسم الأشكال الواضحة يمكن أيضًا رسم أشكال شبه شفافة أو شفافة ويتم ذلك إما عن طريق تعيين الخاصيّة globalAlpha أو عن طريق تحديد الشفافية في اللون RGB باستخدام الخاصيّتين StrokeStyle أو FillStyle: globalAlpha = transparencyValue تشبه الدالة ()rgba الدالة ()rgb باختلاف المعامل الأخير والذي يحدد قيمة الشفافية اللَّونية. تأخذ الشفافية قيمتها من 0.0 شفافية مطلقة إلى 1.0 شفافية معدومة. مثال لتحديد الشفافية باستخدام الدالة ()rgba: ctx.strokeStyle = "rgba(255, 0, 0, 0.5)"; ctx.fillStyle = "rgba(255, 0, 0, 0.5)"; تحديد الشفافية باستخدام GlobaAlpha سأقوم بعرض مثال لرسم 4 مربعات متلاصقة وبألوان مختلفة ليتم تشكيل مربع كبير ثم تطبيق شفافية بشكل دوائر متدرجة الأحجام مركزها هي نقطة تلاقي المربعات (مركز المربع) وذلك عن طريق إنشاء حلقة تكرار ورسم الدوائر بقطر متزايد فوق بعضها البعض. function draw() { var ctx = document.getElementById('canvas').getContext('2d'); ctx.fillStyle = '#FD0'; ctx.fillRect(0, 0, 75, 75); ctx.fillStyle = '#6C0'; ctx.fillRect(75, 0, 75, 75); ctx.fillStyle = '#09F'; ctx.fillRect(0, 75, 75, 75); ctx.fillStyle = '#F30'; ctx.fillRect(75, 75, 75, 75); ctx.fillStyle = '#FFF'; ctx.globalAlpha = 0.2; for (i = 0; i < 7; i++){ ctx.beginPath(); ctx.arc(75, 75, 10+10*i, 0, Math.PI*2, true); ctx.fill(); } } تحديد الشفافية باستخدام ()RGBA سأقوم بعرض مثالًا مشابهًا للمثال السّابق ولكن بدلًا من رسم دوائر فوق بعضها بقطر متزايد سأرسم مستطيلات بشفافية متزايدة (زيادة التعتيم) باستخدام ()rgba: function draw() { var ctx = document.getElementById('canvas').getContext('2d'); ctx.fillStyle = 'rgb(255, 221, 0)'; ctx.fillRect(0, 0, 150, 37.5); ctx.fillStyle = 'rgb(102, 204, 0)'; ctx.fillRect(0, 37.5, 150, 37.5); ctx.fillStyle = 'rgb(0, 153, 255)'; ctx.fillRect(0, 75, 150, 37.5); ctx.fillStyle = 'rgb(255, 51, 0)'; ctx.fillRect(0, 112.5, 150, 37.5); for (var i = 0; i < 10; i++){ ctx.fillStyle = 'rgba(255, 255, 255,'+(i+1)/10+')'; for (var j = 0; j < 4; j++){ ctx.fillRect(5+i*14, 5+j*37.5, 14, 27.5); } } } تصاميم وتنسيقات الخطوط يمكنك إنشاء ورسم خطوط بأشكال وتنسيقات مختلفة باستخدام مجموعة من الخصائص: lineWidth = value تحدد سمك الخط المراد رسمه: lineCap = type تحدد مظهر نهاية الخط: lineJoin = type تحدد مظهر الزوايا عند الخطوط المتلاقية: getLineDash() تُرجع مصفوفة لخط من نمط dashes تحوي على أرقام تحدد المسافات لتناوب رسم الخط والمسافة: setLineDash(segments) تحدد الخط الحالي ليأخذ نمط dash: lineDashOffset = value تحدد أين ستبدأ مصفوفة النمط dash على الخط. خاصية lineWidth هذه الخاصيّة تُحدد سمك الخط الحالي وتأخذ قيم موجبة، القيمة الافتراضية لها هي 1.0. عرض الخط هو سمك الحواف Stroke التي تتركز على مسار معين. المثال التالي يعرض 10 خطوط مسقيمة ذات سمك متزايد. function draw() { var ctx = document.getElementById('canvas').getContext('2d'); for (var i = 0; i < 10; i++){ ctx.lineWidth = 1+i; ctx.beginPath(); ctx.moveTo(5+i*14, 5); ctx.lineTo(5+i*14, 140); ctx.stroke(); } } خاصية lineCap تحدد الخاصيّة lineCap كيف ستُرسم النقاط النهائية للخط حيث تأخذ الخاصيّة lineCap ثلاث قيم butt ،round وsquare. القيمة الافتراضية هي butt. butt: تحدد نهايات الخطوط لتكون مربعة. round: تحدد نهايات الخطوط لتكون دائرية. square: تقوم بإنشاء مربع بنفس عرض الخط وارتفاع يساوي نصف سماكة الخط وتضيفه عند نهاية الخط. سأقوم بعرض مثال يرسم ثلاثة خطوط بقيم lineCap مختلفة سيتم تحديد بداية ونهاية الخطوط بواسطة دليلن (خطين أفقيين) لتمييز الفرق بين الخطوط الثلاثة: function draw() { var ctx = document.getElementById(‘canvas’).getContext(‘2d’); var lineCap = [‘butt’,’round’,’square’]; // Draw guides ctx.strokeStyle = ‘#09f’; ctx.beginPath(); ctx.moveTo(10,10); ctx.lineTo(140,10); ctx.moveTo(10,140); ctx.lineTo(140,140); ctx.stroke(); // Draw lines ctx.strokeStyle = ‘black’; for (var i=0;i } كما تلاحظ في الخط اليساري رُسم بقيمة butt. الخط في المنتصف رُسم بقيمة round الخط الأخير رسم بقيمة square والتي تقوم بإنشاء مربع بنفس عرض الخط وارتفاع يساوي نصف سماكة الخط. خاصية lineJoin تحدد الخاصيّة lineJoin كيف لمسارين (خطوط، أقواس، منحنيات) أن يرتبطا معًا أي أنها تحدد شكل نقطة الارتباط بين مسارين. تأخذ الخاصيّة lineJoin ثلاث قيم round ،bevel وmiter. القيمة الافتراضية لـ lineJoin هي miter. Round: تقوم بتدوير زوايا الشكل عن طريق ملئها بقطاعات دائرية نصف قطر هذه الزوايا الدائرية يساوي عرض الخط. Bevel: تقوم بسد المنطقة المثلثية الناتجة من تلاقي خطين بحيث تقوم بحذف المثلث الناتج من تلاقي الخطين. وملأ المساحة المتبقية. Miter: تقوم بملأ المساحة بين نهايتي الخطين المتلاقين لتشكل مثلث. المثال التالي يوضح عمل كل واحد من تلك الخصائص: function draw() { var ctx = document.getElementById('canvas').getContext('2d'); var lineJoin = ['round', 'bevel', 'miter']; ctx.lineWidth = 10; for (var i = 0; i < lineJoin.length; i++){ ctx.lineJoin = lineJoin[i]; ctx.beginPath(); ctx.moveTo(-5, 5+i*40); ctx.lineTo(35, 45+i*40); ctx.lineTo(75, 5+i*40); ctx.lineTo(115, 45+i*40); ctx.lineTo(155, 5+i*40); ctx.stroke(); } } استخدام الشرطات dashes يمكنك تحديد الخط ليأخذ نمط الشرطات dashed باستخدام الدالة setLineDash والخاصيّة lineDashOffset لتحديد نمط الشرطات للخطوط. تأخذ الدالة setLineDash قائمة list من الأرقام التي تحدد المسافات لتناوب رسم الخط والمسافة. الخاصيّة lineDashOffset تحدد القيمة التي سيبدأ عندها النمط. في المثال أدناه سأقوم بإنشاء شكل يشبه تأثير مسيرة النمل مع تأثير حركي عادةً يوجد في أداة التحديد selection tool في برامج الجرافيكس.( سيتم شرح التأثيرات الحركية بالتفصيل لاحقًا) var ctx = document.getElementById('canvas').getContext('2d'); var offset = 0; function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.setLineDash([4, 2]); ctx.lineDashOffset = -offset; ctx.strokeRect(10, 10, 100, 100); } function march() { offset++; if (offset > 16) { offset = 0; } draw(); setTimeout(march, 20); } march(); التدرجات اللونية Gradient يوجد نوعان من التدرّجات اللَّونية في canvas: تدرجات لونية خطية Linear Gradient. وتدرجات لونية شعاعية Radial Gradient. يتم إنشاء تدرُّجات لونية عن طريق إنشاء كائن CanvasGradient باستخدام أحد الدالتين التالييتن ثم نطبق أحد الخاصيّتين fillStyle أو strokeStyle على الكائن. 1- الدالة CreateLinearGradient createLinearGradient(x1, y1, x2, y2) تنشئ كائن من نوع linear gradient حيث تمثل x1, y1 نقطة البداية و x2, y2 نقطة النهاية. 2- الدالة Create RadialGradient createRadialGradient(x1, y1, r1, x2, y2, r2) تنشئ تدرج لوني شعاعي حيث تمثل المعاملات دائرتين x1, y1 مركز الدائرة الأولى ونصف قطرها r1 و x2, y2 مركز الدائرة الثانية ونصف قطرها هو r2. مثال: var lineargradient = ctx.createLinearGradient(0, 0, 150, 150); var radialgradient = ctx.createRadialGradient(75, 75, 0, 75, 75, 100); بعد إنشاء نوع التدرّج اللَّوني يمكنك تطبيق الألوان عليه باستخدام الدالة ()addColorStop: gradient.addColorStop(position, color) المعامل position هو رقم بين 0.0 و 1.0 ويحدد الوضع النسبي للون في الإنحدار. المعامل color يحدد اللون ويجب أن يكون نص string ممثل بـ CSS. يمكن إضافة العديد من نقاط اللّون إلى التدرّج فيما يلي مثال لانحدار خطي بسيط من اللّونين الأبيض والأسود: var lineargradient = ctx.createLinearGradient(0, 0, 150, 150); lineargradient.addColorStop(0, 'white'); lineargradient.addColorStop(1, 'black'); تطبيق تدرج لوني خطي Linear Gradient مع الخاصيتين fillStyle و strokStyle كما ستلاحظ في المثال التالي أن كلا الخاصيّتين fillStyle و strokeStyle تأخذان كائنًا من نوع canvasGradient. function draw() { var ctx = document.getElementById('canvas').getContext('2d'); var lingrad = ctx.createLinearGradient(0, 0, 0, 150); lingrad.addColorStop(0, '#00ABEB'); lingrad.addColorStop(0.5, '#fff'); lingrad.addColorStop(0.5, '#26C000'); lingrad.addColorStop(1, '#fff'); var lingrad2 = ctx.createLinearGradient(0, 50, 0, 95); lingrad2.addColorStop(0.5, '#000'); lingrad2.addColorStop(1, 'rgba(0, 0, 0, 0)'); ctx.fillStyle = lingrad; ctx.strokeStyle = lingrad2; ctx.fillRect(10, 10, 130, 130); ctx.strokeRect(50, 50, 50, 50); } المثال أعلاه يشرح كيفيّة عمل تدرج لوني خطي يمثل لون السماء والأرضية عن طريق إنشاء متغير lingrad ثم استدعاء الدالة ()addColorStop لتطبيق الألوان الأزرق والأبيض ثم الأخضر والأبيض ثم إسنادها للخاصية fillStlye ثم إنشاء تدرج لوني أسود عن طريق إنشاء متغير 2lingrad وتطبيق نقاط لونية باللون الأسود ثم إسناده للخاصية strokeStyle. أخيرًا رسم الأشكال بالإحداثيات المناسبة: تطبيق تدرج لوني شعاعي Radial Gradient مع الخاصيتين fillStyle و strokStyle لفهم كيفية عمل التدرّج اللَّوني الشّعاعي لابد من عرض مثال. المثال أدناه يحدد أربعة تدرجات شعاعية مختلفة حيث سيتم إنشاء تدرّجات شعاعية أكثر تعقيدًا عن التدرّجات الشّعاعية الكلاسيكية. function draw() { var ctx = document.getElementById('canvas').getContext('2d'); var radgrad = ctx.createRadialGradient(45, 45, 10, 52, 50, 30); radgrad.addColorStop(0, '#A7D30C'); radgrad.addColorStop(0.9, '#019F62'); radgrad.addColorStop(1, 'rgba(1,159,98,0)'); var radgrad2 = ctx.createRadialGradient(105, 105, 20, 112, 120, 50); radgrad2.addColorStop(0, '#FF5F98'); radgrad2.addColorStop(0.75, '#FF0188'); radgrad2.addColorStop(1, 'rgba(255,1,136,0)'); var radgrad3 = ctx.createRadialGradient(95, 15, 15, 102, 20, 40); radgrad3.addColorStop(0, '#00C9FF'); radgrad3.addColorStop(0.8, '#00B5E2'); radgrad3.addColorStop(1, 'rgba(0,201,255,0)'); var radgrad4 = ctx.createRadialGradient(0, 150, 50, 0, 140, 90); radgrad4.addColorStop(0, '#F4F201'); radgrad4.addColorStop(0.8, '#E4C700'); radgrad4.addColorStop(1, 'rgba(228,199,0,0)'); ctx.fillStyle = radgrad4; ctx.fillRect(0, 0, 150, 150); ctx.fillStyle = radgrad3; ctx.fillRect(0, 0, 150, 150); ctx.fillStyle = radgrad2; ctx.fillRect(0, 0, 150, 150); ctx.fillStyle = radgrad; ctx.fillRect(0, 0, 150, 150); } كما تلاحظ تم إنشاء 4 تدرجات لونية شعاعية وتحديد إحداثيات ونصف قطر كل من الدائرتين اللَّونيتين لكل تدرج شعاعي. كانت هذه المعلومات بمثابة طرف الخيط الذي يقودك للبدء في تعلُّم رسم الأشكال على Canvas كالمحترفين. يحتاج الأمر منك للكثير من التجريب والتخيل لتتقن العمل على هذه الأداة واكتشاف ميزاتها. المصادر
-
- gradient
- تدرجات لونية
- (و 4 أكثر)