The_source
08-10-2008, 09:11 AM
السلام عليكم ورحمة الله وبركاته
ملاحظه:
يجب تجاهل هذا الكود في نافذة الأكواد
أرفع اليوم هذا المثال التفاعلي الذي بيوضح تفاعل كلاً من
For...loop + Global + Type + Array
مع شرح المثال سطراً سطراً..... (المثال موجود في الملفات المرفقــــه...يجب التجربه لمشاهدة الناتج)
في الواقع هذا المثال يعطيك لمحه سريعه عن عمل لعبه بسيطه المضمون ولكن من عبر الكود الموجود فيها يمكنك إستنتاج أفكار خاصه بك لعمل ألعابها (هذا الكود لاشيء بالمقارنه مع الألعاب الأخرى وإنما لإكتساب الأفكار فقط).
والأن لنبداء...
[left]sync on
sync rate 60
color backdrop rgb(0,0,0)
autocam off
Type Attacking
Nemisis As integer
Zombi As integer
Count As integer
Endtype
global x# As float
global y# As float
global z# As float
dim a(1)as Attacking
a(1).Count=1
For Nemisis = 2 to 3
a(1).Count=a(1).Count+50
make object Cube Nemisis,5
position object Nemisis,10+a(1).Count,0.5,150
color object Nemisis,RGB(0,0,0)
next Nemisis
make object cube 1,5
position object 1,0,0.5,20
make matrix 1,150,150,10,10
load image "555.jpg",1
prepare matrix texture 1,1,1,1
position matrix 1,0,-2,10
set object collision on 1
do
x#=object position x(1)
y#=object position y(1)
z#=object position z(1)
For Nemisis = 2 to 3
x2#=object position x(Nemisis)
y2#=object position y(Nemisis)
z2#=object position z(Nemisis)
farx#=x2#-x#
farz#=z2#-z#
long#=sqrt(farx#*farx#)+sqrt(farz#*farz)
if long#<20
point object Nemisis,x#,y#,z#
move object Nemisis,0.3
endif
if object collision(1,Nemisis)>0
END
endif
next Nemisis
Rem this function for move
Movement()
Rem make camera tracking main object by simple function
camera()
sync
loop
function Movement()
if upkey()=1
move object 1,0.5
endif
if downkey()=1
move object 1,-0.5
endif
if rightkey()=1
yrotate object 1,object angle y(1)+2
endif
if leftkey()=1
yrotate object 1,object angle y(1)-2
endif
endfunction
function camera()
set camera to follow x#,y#,z#,30,20,3,50,1
endfunction
السطر الأول:نقوم بتحفيز خاصية تحديث المشهد أو كما يُعرف عند البعض بالرندره(Render)
السطر الثاني:هذا الأمر متصل بما قبله ووظيفته وضع قيمه من شأنها عمل تحديث لإطار العمل عند التنفيذ في كم جزء من الثانيه بحسب ماتريد
وذلك لتعديل سرعة الأحداث الحاصله عند التنفذ مع حركه ناعمه وسلسه
السطر الثالث:نقوم بإعطاء لون ليمثل الفضاء الثلاثي الأبعاد(البيئه المحيطه بك عند التنفيذ)ونلاحظ إننا أتبعنا الأمر بالداله RGB والأحرف الذي تمثلها الداله
هي عباره عن إسم لكل من الألوان الثلاثه الرئيسيه الذي تشتق منها الألوان كافه...عندها نقوم بوضع القيم من النوع العددي لكل خانه من هذه الثلاثه الألوان
فمثلاً أنا أعطيت الرقم صفر لكل خانه مما يعني إنه اللون المتبع بهذا التطبيق هو الأســـــــود
السطر الرابع:وظيفته هي جعل الكاميرا تركز على أخر مجسم (Object)تم إستدعائه متجاهلتاً للبقيه
إلى هنا أنهينا الأعدادات الذي تهيىء لنا جو العمل والأن سنقوم بكتابة الجزء الأخر من الكود وهو الذي فيه سنقوم بإنشاء المجسمات والأشياء الذي تساعدنا في إتمام عملنا
السطر الخامس:نقوم بعمل حزمه من المتغيرات بواسطة التعليمه Type تحت إسم Attacking السطور 6,7,8 وفي السطر 9 ننهي التعليمه Type
السطر 10 إلى 12: نقوم بالتصريح عن ثلاثه متغيرات والذي ستمثل إحداثيات المجسم المتحرك فيما بعد(قمنا بالتصريح عنها بواسطة الــGlobal)
السطر 13 إلى 14:نقوم بعمل مصفوفه من بعد واحد وأسندناها إلى التعليمه tybe ولكن هنا أستخدمنا المتغير Count من التعليمه type فيها وجعلنا قيمة الــIndex هي 1
لإنني أردتها أن تكون محدودة الأستخدام(ملاحظه:يمكنك زيادتها كيفما شأت ولكن مع مراعاة القيم المدخله )كما في هذه الصوره
dim a(1)as Attacking
a(1).Count=1
السطر 15 إلى 20:هنا ننشىء حلقه تكراريه من النوع For...Next وأعطيناها إحدى متغيرات التعليمه Type وهو Nemisis وزايدناه بمتغيرين كما في هذه الصوره من الكود
For Nemisis = 2 to 3
ملاحظه :
كتبنا في الحلقه التكراريه القيم من 2 إلى 3 ولم نقول من 1 إلى2 مثلاً ...والسبب هو إنه القيمه 1 جعلتها محجوزه لعنوان مجسم أخر أود إنشائه لاحقاً(ممكن تكون القيمه كيفما تريد ولكن لاتجعلها ضمن قيم تم حجرها لمجسمات أخرى)
لنتابع شرح ماهو موجود في جملة التكرار
السطر السادس عشر:قمنا بزيادة متغير المصفوفه 50 كما في الصوره التاليه a(1).Count=a(1).Count+50 (أبقي هذا الكود في الحسبان)
السطر السابع عشر: قمنا بعمل مجسم مكعب الشكل بواسطة الأمر Make object cube ونلاحظ إنه هذا الأمر بيطلب رقم ليتم التعامل معه في شتى من الأوامر وهذا الراقم سيكون كبطاقة تعريف له ونحن وضعنا فيه المتغير Nemisis
لإنه يحتوي على القيمتين الذي قد قمنا بشحنها داخل المتغير (Nemisis) أنظر:(For Nemisis = 2 to 3)مما يعني إنه سوف ينشىء مجسمين مرتاً واحده وأي أمر أخر متعلق بنفس المجسمين يتم إضافته داخل هذه الحلقه فهو بينطبق عليها بسطر واحد من الكود(كما هو مبين في السطر الذي يليه)
دون الحاجه إلى عمل كل مجسم على حدى ....موضوع روعه ويقلل الجهد ولكن لايمكن إعطاء كل مجسم داخل هذه الحلقه خصائص تختلف عن الأخر بمعنى أخر هذه الجمله التكراريه بتنفع بشكل كبير في حال أردت عمل جوهرات أو أشياء تلتقطها أثناء اللعبه لإنها تتشابه في الشكل والوظيفه
السطر الثامن عشر:ركزوا معي هنا ...قمنا بعمل الأمر position object وهو بيطلب رقم التعريف للمجسم مع الأحداثيات ليتم تحديد موضعه في العالم الثلاثي الأبعاد طبعاً قد قمنا مسبقاً بعمل متغير من النوع الرقمي (Nemisis)ستلاحظ عند التنفيذ إنه هناك مجسم واحد فقط على الرغم من إننا أنشئنا إثنين ...بتعرف لماذا؟
بحكم إنهم مجسمين بيتشاركوا كل شيء بيطرء عليها هذا يعني إنهم في نفس الأحداثي(متداخلين معاً وكإنهم مجسم واحد)...ستقول لي:"وكيف أقوم بفصلهم طالما إنهم بيتشارك في موضعهم" سأقول الأمر سهل جداً...هل تذكر الكود الموجود في السطر 16 والذي طلبت منك إبقئه في الحسبان a(1).Count=a(1).Count+50
الأن سنستخدمه وسوف نضع المتغير الموجود فيه في الطرف الأيسر وليس كاملاً وذكرنا من قبل بإنه يقوم بالمزايده بمقدار 50 في هذه الحال سنجمعه مع الأحداثي الذي يمثل z
إن أردت رصف المجسمين بشكل أفقي كما هو موضح في الكود
position object Nemisis,10+a(1).Count,0.5,150
في حال أردتهم في شكل رأسي فستجمع المتغير a(1).Count بالمتغير الذي يمثل المحور x ليصير الكود بهذا الشكل
position object Nemisis,10,0.5,150+a(1).Count
معناه إنه ستكون المسافه بين كلاً منهما 50 في البعد X أو z كما تريد
السطر التاسع عشر: قمنا بعمل لون للمجسمات(العــــدو) المُنشائه وذلك بالداله RGB وأعطيناها اللون الأســــود
السطر العشرون: نغلق الحلقه التكراريه بواسطة Next متبوعه بإسم المتغير الذي بدأنا بعمل الحلقه التكراريه به(Nemisis).
السطر الواحد والعشرون: نقوم بعمل مجسم وهو الشخصيه الذي سنتحكم بها أثناء التنفيذ... لاحظ ماكتب في السطر من 15 إلى 20 وستعرف السبب.
السطر الثاني والعشرون: نعطي الأحداثيات للمجسم الرئيسي
السطر الثالث والعشرون: هنا سنتعرف عن شيء جديد ....وهو المصفوفات أو القالب (Matrix) هناك من سيتسائل ويقول" المصفوفات هي ضمن أوامر " ولكنها كذالك أمر في الواقع وسمي بذلك لإنه يتم تقسيم المسطح المُنشىء بها بواسطة المدخلات الذي تحددها وسنناقشها الأن
الأمر Make matrix بيطلب منك إدخال خمس قيم في هذه الأمر وهي
Matrix Num:هنا سنعطي رقم وسيكون بمثابة تعريف للمصفوفه ليتم التعامل معها في كافة الأوامر الخاصه بها وأعطيتها الرقم واحــــــد (لاحظوا...منكم سيقول الرقم واحد محجوز للمجسم الرئيسي)المجسمات أرقام تعريفها ليس لها علاقه بالمصفوفات(القوالب)لذا يمكنك أن ترتاح الأن ^^
Width: سيمثل عرض المصفوفه(القالب)
Height:سيمثل الأرتفاع لــــها
ْْْXsegments:سيمثل عدد صفوف المصفوفه(القالب)في المحور السيني x وسيقوم بعمليه حسابيه لترتيبها حتى تتناسب مع العرض وهذا بينطبق على البعد z.
Zsegments:سيمثل عدد صفوف المصفوفه(القالب)في المحور الأفقي z
وهنا صوره توضح الفكره بشكل أفضل
http://www8.0zz0.com/2008/10/08/05/962616844.jpg
نلاحظ إنه في المحور x ثلاثه مربعات مكونه من صف لتشكل عرض القالب و مربعين في الأحداثي z ليشكل طوله أو بعده المصطلح الأنسب في العالم الثلاثي الأبعاد
لكن في هذا المثال أنا أعطيت القيمه150 لكلاً من x,z ...يعني تصور كم عدد المربعات الذي سيتم تكوينها في هذه المصفوفه(القالب)والسبب في زيادتها هو لإعطاء دقه عاليه لإكسائها(الصوره الذي سيتم إحاطتها بالمصفوفه...سننقاش هذا الأمر بالسطر التالي)
إن سألتم السبب سأقول
لاحظوا عند عرض صوره بمستعرض الصور...عندما نقوم بتكبيرها كثيراً فإنها تقل جودتها ولكن عند تصغيرها بشكل معقول ستلاحظ إن ال pixels للصوره تجمعت مُعطيه دقه أكبر للصوره وهذا الأمر بيحصل كمان في المصفوفات(القوالب)
عندما تزيد من عدد المربعات في القالب فإن الصوره الذي تحملها ستوضع لكل مربع من مربعات القالب بشكل مستقل لكن إن عملت العكس x_x جرب أن تتلاعب بالقيم إلى الأنقص وستعرف ما أعني.
السطر الرابع والعشرون: سنقوم بتحميل صوره بواسطة الأمر load image وتأكد إن رقم التعريف للصوره ليس محجوز ظمن صوره أخرى
السطر الخامس والعشرون: هنا أمر إكساء المصفوفه(القالب) prepare matrix texture وهو بيطلب إدخال قيم بالترتيب
Matrix Num:وهو رقم تعريف المصفوفه الذي أنشئناها في الأمر Make matrix سابقاً
Image Num:رقم التعريف الخاص بالصوره الذي قمنا بتحميلها سابقا
ملاحظه:
يجب إنشاء أمر load image قبل أمر prepare matrix texture حتى يتم إستدعاء الصوره بشكل جيد لإنه الــCompiler بيقراء من الأعلى... في حال لم يجد الأمر load image قبل الأمر prepare matrix texture
فلن يتم تحميل الصوره إلى القالب بشكل صحيح.
Across:هذا المتغير بيطلب كم عدد المرات الذي سيتم تكرار الصوره في المربع الواحد من المصفوفه (في المحور x)
Down:هذا المتغير بيطلب كم عدد المرات الذي سيتم تكرار الصوره في المربع الواحد من المصفوفه (في المحور z)
وأنا أعطيت القيمه 1 إي إنه لكل مربع صوره واحده يتم إكسائها به فقط أما في حال الزياده ستظهر بعض العيوب مثل كثرة تركيز الــPixels معا بعضها وإعطاء لون حاد وستتداخل تفاصيل الأكساء بسبب
كثرة الصور في المربع الواحد
السطر السادس والعشرون: وهنا نضع مكان المصفوفه في الفضاء الثلاثي الأبعاد(الأمر الذي يقابله في العمل Position object)
السطر السابع والعشرون: نقوم بتحفيز كشف التصادم بالنسبه للمجسم رقم واحد(الرئيسي).
إلى هنا نكون أنهينا الجزء المتعلق بإستدعاء المجسمات وتجهيز بعض المتغيرات وما إلى ذلك للعمل....الجزء التالي سنتطرق إلى جعل هذه المجسمات مُفعمه بالحيويه(يمكن اللعب بها أثناء التنفيذ)
عن طريق الحلقه التكراريه Do...loop لــــــذا أرجو التركيز معي ....
السطر الثامن والعشرون: سنضع حلقه تكراريه لانهائيه Do...loop الذي سيتم فيها إدارة المجسمات والأحداث.
السطر 29 إلى 31: نلاحظ هنا إنه تم كتابة هذه الدوال ()Object position x(),Object position y(),Object position z
وهي تُعيد قيمة مكان المجسم في الواقع ثلاثي الأبعاد وهي تطلب رقم المجسم بين القوسين ليتسنى إعادة القيمه المختصه بمكانه عند الحركه
للعلم إنه يجب أن يتم خزنها في متغيرات ليتم التعامل معها بسهوله في التطبيق ونحن خزناها في هذه المتغيرات#x#,y#,z
لتكون النتيجه بالشكل التالي
x#=object position x(1)
y#=object position y(1)
z#=object position z(1)
السطر 32 : سنعمل حلقه تكراريه من نوع For...next
ملاحظه:
عندما تنشىء مجسمات بواسطة حلقه تكراريه من النوع For...next يجب أن تضع في الحسبان إنك سوف تتعامل معها بهذا الشكل في كل مره داخل التطبيق نفسه(أي إنك ستنشئها أكثر من مره لعمل وظائف أخرى)
السطر ,35,34,33: بما إننا أنشئنا دوال إعادة قيمة مكان المجسم للشخصيه الرئيسيه فيجب أيضاً إنشاء نفس الدوال للمجسمات المحجوزه للمتغير Nemisis لتصير بهذا الشكل
x2#=object position x(Nemisis)
y2#=object position y(Nemisis)
z2#=object position z(Nemisis)
السطر 38,37,36: هنا عملنا معادله بسيطه ولها دور كبير بعمل ذكاء إصطناعي بسيط (يمكن تطويره)
أردنا أن نحسب المسافه بين المجسم الرئيسي والمجسمات المحجوزه للمتغير Nemisis وإنه في حال تعدينا مسافه معينه سيتم مهاجمة المجسم الرئيسي من قِبل المجسمات الأخرى
لذا لحساب المسافه نطرح الأحداثي x للمجسم الرئيسي من الأحداثي x للمجسمات الأخرى(Nemisis) ونخزن النواتج في متغيرات أخرى وهذا بينطبق على كافة الأحداثيات Y,Z ليصير الكود بالشكل التالي
#farx#=x2#-x
#farz#=z2#-z
وهنا حسبنا المتغير x والمتغير z ولم نحسب المتغير y لإننا لسنا بحاجه إليه بهذا المثال
وأخيراً لجعل العمليه أكثر فعاليه سنجعل المجسمات الأخرى حساسه لإقتراب المجسم الرئيسي من جهه كانت من الأمام أم الخلف أو الجوانب بواسطة هذا الكود
long#=sqrt(farx#*farx#)+sqrt(farz#*farz)
وفيه عملنا دالة الجدر التربيعي وكتبنا داخل القوس(القيمه الذي سيجعلها مربعه)وهي ناتج طرح الأحداثي x وضربه في نفسه داخل القوس وهذا بينطبق على الأحداثي z ومن ثم نجعل نواتج القيمه المربعه مخزونه في المتغير #long كما هو مبين في الكود أعلاه
بهذه الطريقه نكون قد عملنا حدود للمجسمات المحجوزه للمتغير Nemisis في حال تخطيها سيتم عمل حدث معين كما تريد أنت وأنا أردت أن يتم ملاحقة المجسم الرئيسي من المجسمات الأخرى بالكود الموجود في السطور التاليه
السطر 42,41,40,39: أول سطر عملنا شرط في حال كانت المسافه بين المجسم الرئيسي والمجسمات الأخرى المخزونه في المتغير #long أصغر من العشرين
عندها سيتم تركيز المجسمات الأخرى على المجسم الرئيسي بواسطة هذا الأمر Point object وهذا الأمر بيطلب رقم المجسم (Nemisis) وسيطلب الأحداثيات المراد التركيز عليها وسنضع إحداثيات المجسم الرئيسي لإننا نريد أن نجعله يركز على المجسم الرئيسي حالما يتجاوز الشرط
أي إنه سيلتف بإتجاه المجسم الرئيسي بكافة الجهات بحسب حركة المجسم الرئيسي ليصبح الكود بالشكل التالي
#point object Nemisis,x#,y#,z
طالما إنه التركيز عليه لذا سنضيف أمر بسيط ليتحركوا المجسمات بإتجاه المجسم الرئيسي وهو الأمر Move object وسنعطيه الأرقام المحجوزه في المتغير Nemisis لينطبق الأمر على المجسمات كامله عدا الرئيسي
وسنعطيه قيمه والتي من شأنها أن تحرك المجسم في حال كانت أكبر قيمه غير الصفر وأعطيناه القيمه 3.0 لإنه الأمر يقبل النوع Float من القيم
وأخيراً نغلق الجمله الشرطيه بــEndif
السطر 46,45,44,43: في هذه السطور عملنا شرط إنه في حال حدث إصطدام مع المجسم الرئيسي من قِبل المجسمات الأخرى عندها سيتم الخروج من اللعبه
وبعدها قمنا بإغلاق الشرط وأغلقنا الحلقه التكراريه for...next لتصبح صورة الكود المختص بالذكاء الأصطناعي بهذه الشكل(الكود شرحه من السطر 32 إلى 46)
For Nemisis = 2 to 3
x2#=object position x(Nemisis)
y2#=object position y(Nemisis)
z2#=object position z(Nemisis)
farx#=x2#-x#
farz#=z2#-z#
long#=sqrt(farx#*farx#)+sqrt(farz#*farz)
if long#<20
point object Nemisis,x#,y#,z#
move object Nemisis,0.3
endif
if object collision(1,Nemisis)>0
END
endif
next Nemisis
السطر 47:عملنا فيه داله وجعلنا إسمها يدل على وظيفتها ()movement أي الحركه وهي مختصه بتحريك الشخصيه الرئيسيه ونلاحظ إنه أنشئناها خارج الحلقه التكراريه do..loop تحسباً من وقوع المشاكل في القيم المخرجه عند التنفيذ
فالسطور البرمجيه لهذه الداله ليست صعبه كما ترى وكلها مكونه من شروط
منها
في حال تم الضغط على السهم بإتجاه الأعلى سيتحرك المجسم إلى الأعلى وهذا بينطبق إلى الأسفل ولكن هناك ملاحظه بسيطه وهي
القيمه الموجبه ستحركه إلى الأعلى والسالبه إلى الأسفل
أما بالنسبه للألتفاف ...عند الضغط على الزر الأيمن سيتم إلتفاف المجسم إلى اليمين بشكل مقبول أما إن زادت القيمه سيلتف بسرعه كبيره وهذا بينطبق على الألتفاف إلى اليسار
وهذا الكود الخاص بالألتفاف
yrotate object
وهو بيطلب رقم المجسم المراد إلتفافه بالأضافه قيمة الألتفاف ولكن هنا أستعضنا عن قيمة الألتفاف بداله تعيد القيم حتى يتم الألتفاف مع كل نقرة زر طالما إنه في الحلقه التكراريه Do...loop
والداله هي
object angle y(1)+2
فهي تطلب رقم المجسم المراد تحريكه ونزايده بإثنين ليستدير المجسم إلى اليمين في حال أردناه إلى اليسار سنجعله بهذه الصوره
object angle y(1)-2
ملاحظه:
الأشارات لها دور كبير في الألتفاف ....إن كان إلى اليمين نستخدم القيم الموجبه واليسار القيم السالبه
السطر 48:هنا داله بسيطه جداً وهي مكونه من سطر على عكس الأولى وفي الواقع هي عباره عن أمر يجعل الكاميرا تتبع المجسم حيث ماذهب ولكنها تحتوي عيوب كبيره ...وضعتها لتوضيح مثال فقط
كما إنه يمكن عملها من دون حجزها في داله ولكنني أردت أن أريك فائدة المتغيرات من النوع Global فقط
الأمر Set camera to follow: بيطلب ثمان قيم مُدخله
أول ثلاث قيم هي مختصه بإحداثي المجسم الذي نود أن نجعل الكاميرا تحملق به ويفضل أن نضع المتغيرات المعبره عن ذلك #X#,Y#,Z
بعدها بيطلب زاوية الكاميرا (أي من أي زاويه تريدها أن تكون مسلطه على المجسم)
بعدها بيطلب المسافه (بعد الكاميرا عن المجسم الرئيسي)
القيمه التاليه بتطلب إرتفاع الكاميرا بالنسبه للمجسم الرئيسي
التالي...ستوفر القيمه المدخله حركه ناعمه للكاميرا
وبعدها سيطلب قيمه لكشف التصادم ....إن قمت بعمل واحد لن يتم تحفيزه لإنه يقبل التصادم من نوع static boxes
ملاحظه:
جرب أن تزيل المتغيرات الذي صرحنا عنها من النوع Global في بداية السطور ...ماذا ستلاحظ؟
سنلاحظ إن الكاميرا أصبحت ثابته ولاتتحرك
أما إن قمنا بعمل هذا الكود داخل الداله دون التصريح عن المتغيرات بواسطة Global ستعمل الكاميرا بشكل سليم
function camera()
x#=object position x(1)
y#=object position y(1)
z#=object position z(1)
set camera to follow x#,y#,z#,30,20,3,50,1
endfunction
أعتقد إنه هنا فهمتم ماهي الglobal ...إنها تجعلك توفر سطور برمجيه قليله وذلك لإنها تتعامل مع القيم المصرحه بها من كافة المشروع دون الحاجه إلى كتابة دوال وزيادة عدد السطور لتصير صورة الكود بهذا الشكل
()function camera
set camera to follow x#,y#,z#,30,20,3,50,1
endfunction
طبعاً... طالما إنه المتغيرات المستخدمه في الأمر مصرح عنها بواسطة الــGlobal في بداية الكود وخارج الحلقه التكراريه
لاحظوا إنه الكود الثاني يوفر أسطر على غرار الأول...
إلى هنا أنتهينا وأعتقد إنه هذا الدرس كافي لجعل البعض يبدأو بالعمل في مجال برمجة الألعاب بشكل بسيط
:biggthump
ملاحظه:
يجب تجاهل هذا الكود في نافذة الأكواد
أرفع اليوم هذا المثال التفاعلي الذي بيوضح تفاعل كلاً من
For...loop + Global + Type + Array
مع شرح المثال سطراً سطراً..... (المثال موجود في الملفات المرفقــــه...يجب التجربه لمشاهدة الناتج)
في الواقع هذا المثال يعطيك لمحه سريعه عن عمل لعبه بسيطه المضمون ولكن من عبر الكود الموجود فيها يمكنك إستنتاج أفكار خاصه بك لعمل ألعابها (هذا الكود لاشيء بالمقارنه مع الألعاب الأخرى وإنما لإكتساب الأفكار فقط).
والأن لنبداء...
[left]sync on
sync rate 60
color backdrop rgb(0,0,0)
autocam off
Type Attacking
Nemisis As integer
Zombi As integer
Count As integer
Endtype
global x# As float
global y# As float
global z# As float
dim a(1)as Attacking
a(1).Count=1
For Nemisis = 2 to 3
a(1).Count=a(1).Count+50
make object Cube Nemisis,5
position object Nemisis,10+a(1).Count,0.5,150
color object Nemisis,RGB(0,0,0)
next Nemisis
make object cube 1,5
position object 1,0,0.5,20
make matrix 1,150,150,10,10
load image "555.jpg",1
prepare matrix texture 1,1,1,1
position matrix 1,0,-2,10
set object collision on 1
do
x#=object position x(1)
y#=object position y(1)
z#=object position z(1)
For Nemisis = 2 to 3
x2#=object position x(Nemisis)
y2#=object position y(Nemisis)
z2#=object position z(Nemisis)
farx#=x2#-x#
farz#=z2#-z#
long#=sqrt(farx#*farx#)+sqrt(farz#*farz)
if long#<20
point object Nemisis,x#,y#,z#
move object Nemisis,0.3
endif
if object collision(1,Nemisis)>0
END
endif
next Nemisis
Rem this function for move
Movement()
Rem make camera tracking main object by simple function
camera()
sync
loop
function Movement()
if upkey()=1
move object 1,0.5
endif
if downkey()=1
move object 1,-0.5
endif
if rightkey()=1
yrotate object 1,object angle y(1)+2
endif
if leftkey()=1
yrotate object 1,object angle y(1)-2
endif
endfunction
function camera()
set camera to follow x#,y#,z#,30,20,3,50,1
endfunction
السطر الأول:نقوم بتحفيز خاصية تحديث المشهد أو كما يُعرف عند البعض بالرندره(Render)
السطر الثاني:هذا الأمر متصل بما قبله ووظيفته وضع قيمه من شأنها عمل تحديث لإطار العمل عند التنفيذ في كم جزء من الثانيه بحسب ماتريد
وذلك لتعديل سرعة الأحداث الحاصله عند التنفذ مع حركه ناعمه وسلسه
السطر الثالث:نقوم بإعطاء لون ليمثل الفضاء الثلاثي الأبعاد(البيئه المحيطه بك عند التنفيذ)ونلاحظ إننا أتبعنا الأمر بالداله RGB والأحرف الذي تمثلها الداله
هي عباره عن إسم لكل من الألوان الثلاثه الرئيسيه الذي تشتق منها الألوان كافه...عندها نقوم بوضع القيم من النوع العددي لكل خانه من هذه الثلاثه الألوان
فمثلاً أنا أعطيت الرقم صفر لكل خانه مما يعني إنه اللون المتبع بهذا التطبيق هو الأســـــــود
السطر الرابع:وظيفته هي جعل الكاميرا تركز على أخر مجسم (Object)تم إستدعائه متجاهلتاً للبقيه
إلى هنا أنهينا الأعدادات الذي تهيىء لنا جو العمل والأن سنقوم بكتابة الجزء الأخر من الكود وهو الذي فيه سنقوم بإنشاء المجسمات والأشياء الذي تساعدنا في إتمام عملنا
السطر الخامس:نقوم بعمل حزمه من المتغيرات بواسطة التعليمه Type تحت إسم Attacking السطور 6,7,8 وفي السطر 9 ننهي التعليمه Type
السطر 10 إلى 12: نقوم بالتصريح عن ثلاثه متغيرات والذي ستمثل إحداثيات المجسم المتحرك فيما بعد(قمنا بالتصريح عنها بواسطة الــGlobal)
السطر 13 إلى 14:نقوم بعمل مصفوفه من بعد واحد وأسندناها إلى التعليمه tybe ولكن هنا أستخدمنا المتغير Count من التعليمه type فيها وجعلنا قيمة الــIndex هي 1
لإنني أردتها أن تكون محدودة الأستخدام(ملاحظه:يمكنك زيادتها كيفما شأت ولكن مع مراعاة القيم المدخله )كما في هذه الصوره
dim a(1)as Attacking
a(1).Count=1
السطر 15 إلى 20:هنا ننشىء حلقه تكراريه من النوع For...Next وأعطيناها إحدى متغيرات التعليمه Type وهو Nemisis وزايدناه بمتغيرين كما في هذه الصوره من الكود
For Nemisis = 2 to 3
ملاحظه :
كتبنا في الحلقه التكراريه القيم من 2 إلى 3 ولم نقول من 1 إلى2 مثلاً ...والسبب هو إنه القيمه 1 جعلتها محجوزه لعنوان مجسم أخر أود إنشائه لاحقاً(ممكن تكون القيمه كيفما تريد ولكن لاتجعلها ضمن قيم تم حجرها لمجسمات أخرى)
لنتابع شرح ماهو موجود في جملة التكرار
السطر السادس عشر:قمنا بزيادة متغير المصفوفه 50 كما في الصوره التاليه a(1).Count=a(1).Count+50 (أبقي هذا الكود في الحسبان)
السطر السابع عشر: قمنا بعمل مجسم مكعب الشكل بواسطة الأمر Make object cube ونلاحظ إنه هذا الأمر بيطلب رقم ليتم التعامل معه في شتى من الأوامر وهذا الراقم سيكون كبطاقة تعريف له ونحن وضعنا فيه المتغير Nemisis
لإنه يحتوي على القيمتين الذي قد قمنا بشحنها داخل المتغير (Nemisis) أنظر:(For Nemisis = 2 to 3)مما يعني إنه سوف ينشىء مجسمين مرتاً واحده وأي أمر أخر متعلق بنفس المجسمين يتم إضافته داخل هذه الحلقه فهو بينطبق عليها بسطر واحد من الكود(كما هو مبين في السطر الذي يليه)
دون الحاجه إلى عمل كل مجسم على حدى ....موضوع روعه ويقلل الجهد ولكن لايمكن إعطاء كل مجسم داخل هذه الحلقه خصائص تختلف عن الأخر بمعنى أخر هذه الجمله التكراريه بتنفع بشكل كبير في حال أردت عمل جوهرات أو أشياء تلتقطها أثناء اللعبه لإنها تتشابه في الشكل والوظيفه
السطر الثامن عشر:ركزوا معي هنا ...قمنا بعمل الأمر position object وهو بيطلب رقم التعريف للمجسم مع الأحداثيات ليتم تحديد موضعه في العالم الثلاثي الأبعاد طبعاً قد قمنا مسبقاً بعمل متغير من النوع الرقمي (Nemisis)ستلاحظ عند التنفيذ إنه هناك مجسم واحد فقط على الرغم من إننا أنشئنا إثنين ...بتعرف لماذا؟
بحكم إنهم مجسمين بيتشاركوا كل شيء بيطرء عليها هذا يعني إنهم في نفس الأحداثي(متداخلين معاً وكإنهم مجسم واحد)...ستقول لي:"وكيف أقوم بفصلهم طالما إنهم بيتشارك في موضعهم" سأقول الأمر سهل جداً...هل تذكر الكود الموجود في السطر 16 والذي طلبت منك إبقئه في الحسبان a(1).Count=a(1).Count+50
الأن سنستخدمه وسوف نضع المتغير الموجود فيه في الطرف الأيسر وليس كاملاً وذكرنا من قبل بإنه يقوم بالمزايده بمقدار 50 في هذه الحال سنجمعه مع الأحداثي الذي يمثل z
إن أردت رصف المجسمين بشكل أفقي كما هو موضح في الكود
position object Nemisis,10+a(1).Count,0.5,150
في حال أردتهم في شكل رأسي فستجمع المتغير a(1).Count بالمتغير الذي يمثل المحور x ليصير الكود بهذا الشكل
position object Nemisis,10,0.5,150+a(1).Count
معناه إنه ستكون المسافه بين كلاً منهما 50 في البعد X أو z كما تريد
السطر التاسع عشر: قمنا بعمل لون للمجسمات(العــــدو) المُنشائه وذلك بالداله RGB وأعطيناها اللون الأســــود
السطر العشرون: نغلق الحلقه التكراريه بواسطة Next متبوعه بإسم المتغير الذي بدأنا بعمل الحلقه التكراريه به(Nemisis).
السطر الواحد والعشرون: نقوم بعمل مجسم وهو الشخصيه الذي سنتحكم بها أثناء التنفيذ... لاحظ ماكتب في السطر من 15 إلى 20 وستعرف السبب.
السطر الثاني والعشرون: نعطي الأحداثيات للمجسم الرئيسي
السطر الثالث والعشرون: هنا سنتعرف عن شيء جديد ....وهو المصفوفات أو القالب (Matrix) هناك من سيتسائل ويقول" المصفوفات هي ضمن أوامر " ولكنها كذالك أمر في الواقع وسمي بذلك لإنه يتم تقسيم المسطح المُنشىء بها بواسطة المدخلات الذي تحددها وسنناقشها الأن
الأمر Make matrix بيطلب منك إدخال خمس قيم في هذه الأمر وهي
Matrix Num:هنا سنعطي رقم وسيكون بمثابة تعريف للمصفوفه ليتم التعامل معها في كافة الأوامر الخاصه بها وأعطيتها الرقم واحــــــد (لاحظوا...منكم سيقول الرقم واحد محجوز للمجسم الرئيسي)المجسمات أرقام تعريفها ليس لها علاقه بالمصفوفات(القوالب)لذا يمكنك أن ترتاح الأن ^^
Width: سيمثل عرض المصفوفه(القالب)
Height:سيمثل الأرتفاع لــــها
ْْْXsegments:سيمثل عدد صفوف المصفوفه(القالب)في المحور السيني x وسيقوم بعمليه حسابيه لترتيبها حتى تتناسب مع العرض وهذا بينطبق على البعد z.
Zsegments:سيمثل عدد صفوف المصفوفه(القالب)في المحور الأفقي z
وهنا صوره توضح الفكره بشكل أفضل
http://www8.0zz0.com/2008/10/08/05/962616844.jpg
نلاحظ إنه في المحور x ثلاثه مربعات مكونه من صف لتشكل عرض القالب و مربعين في الأحداثي z ليشكل طوله أو بعده المصطلح الأنسب في العالم الثلاثي الأبعاد
لكن في هذا المثال أنا أعطيت القيمه150 لكلاً من x,z ...يعني تصور كم عدد المربعات الذي سيتم تكوينها في هذه المصفوفه(القالب)والسبب في زيادتها هو لإعطاء دقه عاليه لإكسائها(الصوره الذي سيتم إحاطتها بالمصفوفه...سننقاش هذا الأمر بالسطر التالي)
إن سألتم السبب سأقول
لاحظوا عند عرض صوره بمستعرض الصور...عندما نقوم بتكبيرها كثيراً فإنها تقل جودتها ولكن عند تصغيرها بشكل معقول ستلاحظ إن ال pixels للصوره تجمعت مُعطيه دقه أكبر للصوره وهذا الأمر بيحصل كمان في المصفوفات(القوالب)
عندما تزيد من عدد المربعات في القالب فإن الصوره الذي تحملها ستوضع لكل مربع من مربعات القالب بشكل مستقل لكن إن عملت العكس x_x جرب أن تتلاعب بالقيم إلى الأنقص وستعرف ما أعني.
السطر الرابع والعشرون: سنقوم بتحميل صوره بواسطة الأمر load image وتأكد إن رقم التعريف للصوره ليس محجوز ظمن صوره أخرى
السطر الخامس والعشرون: هنا أمر إكساء المصفوفه(القالب) prepare matrix texture وهو بيطلب إدخال قيم بالترتيب
Matrix Num:وهو رقم تعريف المصفوفه الذي أنشئناها في الأمر Make matrix سابقاً
Image Num:رقم التعريف الخاص بالصوره الذي قمنا بتحميلها سابقا
ملاحظه:
يجب إنشاء أمر load image قبل أمر prepare matrix texture حتى يتم إستدعاء الصوره بشكل جيد لإنه الــCompiler بيقراء من الأعلى... في حال لم يجد الأمر load image قبل الأمر prepare matrix texture
فلن يتم تحميل الصوره إلى القالب بشكل صحيح.
Across:هذا المتغير بيطلب كم عدد المرات الذي سيتم تكرار الصوره في المربع الواحد من المصفوفه (في المحور x)
Down:هذا المتغير بيطلب كم عدد المرات الذي سيتم تكرار الصوره في المربع الواحد من المصفوفه (في المحور z)
وأنا أعطيت القيمه 1 إي إنه لكل مربع صوره واحده يتم إكسائها به فقط أما في حال الزياده ستظهر بعض العيوب مثل كثرة تركيز الــPixels معا بعضها وإعطاء لون حاد وستتداخل تفاصيل الأكساء بسبب
كثرة الصور في المربع الواحد
السطر السادس والعشرون: وهنا نضع مكان المصفوفه في الفضاء الثلاثي الأبعاد(الأمر الذي يقابله في العمل Position object)
السطر السابع والعشرون: نقوم بتحفيز كشف التصادم بالنسبه للمجسم رقم واحد(الرئيسي).
إلى هنا نكون أنهينا الجزء المتعلق بإستدعاء المجسمات وتجهيز بعض المتغيرات وما إلى ذلك للعمل....الجزء التالي سنتطرق إلى جعل هذه المجسمات مُفعمه بالحيويه(يمكن اللعب بها أثناء التنفيذ)
عن طريق الحلقه التكراريه Do...loop لــــــذا أرجو التركيز معي ....
السطر الثامن والعشرون: سنضع حلقه تكراريه لانهائيه Do...loop الذي سيتم فيها إدارة المجسمات والأحداث.
السطر 29 إلى 31: نلاحظ هنا إنه تم كتابة هذه الدوال ()Object position x(),Object position y(),Object position z
وهي تُعيد قيمة مكان المجسم في الواقع ثلاثي الأبعاد وهي تطلب رقم المجسم بين القوسين ليتسنى إعادة القيمه المختصه بمكانه عند الحركه
للعلم إنه يجب أن يتم خزنها في متغيرات ليتم التعامل معها بسهوله في التطبيق ونحن خزناها في هذه المتغيرات#x#,y#,z
لتكون النتيجه بالشكل التالي
x#=object position x(1)
y#=object position y(1)
z#=object position z(1)
السطر 32 : سنعمل حلقه تكراريه من نوع For...next
ملاحظه:
عندما تنشىء مجسمات بواسطة حلقه تكراريه من النوع For...next يجب أن تضع في الحسبان إنك سوف تتعامل معها بهذا الشكل في كل مره داخل التطبيق نفسه(أي إنك ستنشئها أكثر من مره لعمل وظائف أخرى)
السطر ,35,34,33: بما إننا أنشئنا دوال إعادة قيمة مكان المجسم للشخصيه الرئيسيه فيجب أيضاً إنشاء نفس الدوال للمجسمات المحجوزه للمتغير Nemisis لتصير بهذا الشكل
x2#=object position x(Nemisis)
y2#=object position y(Nemisis)
z2#=object position z(Nemisis)
السطر 38,37,36: هنا عملنا معادله بسيطه ولها دور كبير بعمل ذكاء إصطناعي بسيط (يمكن تطويره)
أردنا أن نحسب المسافه بين المجسم الرئيسي والمجسمات المحجوزه للمتغير Nemisis وإنه في حال تعدينا مسافه معينه سيتم مهاجمة المجسم الرئيسي من قِبل المجسمات الأخرى
لذا لحساب المسافه نطرح الأحداثي x للمجسم الرئيسي من الأحداثي x للمجسمات الأخرى(Nemisis) ونخزن النواتج في متغيرات أخرى وهذا بينطبق على كافة الأحداثيات Y,Z ليصير الكود بالشكل التالي
#farx#=x2#-x
#farz#=z2#-z
وهنا حسبنا المتغير x والمتغير z ولم نحسب المتغير y لإننا لسنا بحاجه إليه بهذا المثال
وأخيراً لجعل العمليه أكثر فعاليه سنجعل المجسمات الأخرى حساسه لإقتراب المجسم الرئيسي من جهه كانت من الأمام أم الخلف أو الجوانب بواسطة هذا الكود
long#=sqrt(farx#*farx#)+sqrt(farz#*farz)
وفيه عملنا دالة الجدر التربيعي وكتبنا داخل القوس(القيمه الذي سيجعلها مربعه)وهي ناتج طرح الأحداثي x وضربه في نفسه داخل القوس وهذا بينطبق على الأحداثي z ومن ثم نجعل نواتج القيمه المربعه مخزونه في المتغير #long كما هو مبين في الكود أعلاه
بهذه الطريقه نكون قد عملنا حدود للمجسمات المحجوزه للمتغير Nemisis في حال تخطيها سيتم عمل حدث معين كما تريد أنت وأنا أردت أن يتم ملاحقة المجسم الرئيسي من المجسمات الأخرى بالكود الموجود في السطور التاليه
السطر 42,41,40,39: أول سطر عملنا شرط في حال كانت المسافه بين المجسم الرئيسي والمجسمات الأخرى المخزونه في المتغير #long أصغر من العشرين
عندها سيتم تركيز المجسمات الأخرى على المجسم الرئيسي بواسطة هذا الأمر Point object وهذا الأمر بيطلب رقم المجسم (Nemisis) وسيطلب الأحداثيات المراد التركيز عليها وسنضع إحداثيات المجسم الرئيسي لإننا نريد أن نجعله يركز على المجسم الرئيسي حالما يتجاوز الشرط
أي إنه سيلتف بإتجاه المجسم الرئيسي بكافة الجهات بحسب حركة المجسم الرئيسي ليصبح الكود بالشكل التالي
#point object Nemisis,x#,y#,z
طالما إنه التركيز عليه لذا سنضيف أمر بسيط ليتحركوا المجسمات بإتجاه المجسم الرئيسي وهو الأمر Move object وسنعطيه الأرقام المحجوزه في المتغير Nemisis لينطبق الأمر على المجسمات كامله عدا الرئيسي
وسنعطيه قيمه والتي من شأنها أن تحرك المجسم في حال كانت أكبر قيمه غير الصفر وأعطيناه القيمه 3.0 لإنه الأمر يقبل النوع Float من القيم
وأخيراً نغلق الجمله الشرطيه بــEndif
السطر 46,45,44,43: في هذه السطور عملنا شرط إنه في حال حدث إصطدام مع المجسم الرئيسي من قِبل المجسمات الأخرى عندها سيتم الخروج من اللعبه
وبعدها قمنا بإغلاق الشرط وأغلقنا الحلقه التكراريه for...next لتصبح صورة الكود المختص بالذكاء الأصطناعي بهذه الشكل(الكود شرحه من السطر 32 إلى 46)
For Nemisis = 2 to 3
x2#=object position x(Nemisis)
y2#=object position y(Nemisis)
z2#=object position z(Nemisis)
farx#=x2#-x#
farz#=z2#-z#
long#=sqrt(farx#*farx#)+sqrt(farz#*farz)
if long#<20
point object Nemisis,x#,y#,z#
move object Nemisis,0.3
endif
if object collision(1,Nemisis)>0
END
endif
next Nemisis
السطر 47:عملنا فيه داله وجعلنا إسمها يدل على وظيفتها ()movement أي الحركه وهي مختصه بتحريك الشخصيه الرئيسيه ونلاحظ إنه أنشئناها خارج الحلقه التكراريه do..loop تحسباً من وقوع المشاكل في القيم المخرجه عند التنفيذ
فالسطور البرمجيه لهذه الداله ليست صعبه كما ترى وكلها مكونه من شروط
منها
في حال تم الضغط على السهم بإتجاه الأعلى سيتحرك المجسم إلى الأعلى وهذا بينطبق إلى الأسفل ولكن هناك ملاحظه بسيطه وهي
القيمه الموجبه ستحركه إلى الأعلى والسالبه إلى الأسفل
أما بالنسبه للألتفاف ...عند الضغط على الزر الأيمن سيتم إلتفاف المجسم إلى اليمين بشكل مقبول أما إن زادت القيمه سيلتف بسرعه كبيره وهذا بينطبق على الألتفاف إلى اليسار
وهذا الكود الخاص بالألتفاف
yrotate object
وهو بيطلب رقم المجسم المراد إلتفافه بالأضافه قيمة الألتفاف ولكن هنا أستعضنا عن قيمة الألتفاف بداله تعيد القيم حتى يتم الألتفاف مع كل نقرة زر طالما إنه في الحلقه التكراريه Do...loop
والداله هي
object angle y(1)+2
فهي تطلب رقم المجسم المراد تحريكه ونزايده بإثنين ليستدير المجسم إلى اليمين في حال أردناه إلى اليسار سنجعله بهذه الصوره
object angle y(1)-2
ملاحظه:
الأشارات لها دور كبير في الألتفاف ....إن كان إلى اليمين نستخدم القيم الموجبه واليسار القيم السالبه
السطر 48:هنا داله بسيطه جداً وهي مكونه من سطر على عكس الأولى وفي الواقع هي عباره عن أمر يجعل الكاميرا تتبع المجسم حيث ماذهب ولكنها تحتوي عيوب كبيره ...وضعتها لتوضيح مثال فقط
كما إنه يمكن عملها من دون حجزها في داله ولكنني أردت أن أريك فائدة المتغيرات من النوع Global فقط
الأمر Set camera to follow: بيطلب ثمان قيم مُدخله
أول ثلاث قيم هي مختصه بإحداثي المجسم الذي نود أن نجعل الكاميرا تحملق به ويفضل أن نضع المتغيرات المعبره عن ذلك #X#,Y#,Z
بعدها بيطلب زاوية الكاميرا (أي من أي زاويه تريدها أن تكون مسلطه على المجسم)
بعدها بيطلب المسافه (بعد الكاميرا عن المجسم الرئيسي)
القيمه التاليه بتطلب إرتفاع الكاميرا بالنسبه للمجسم الرئيسي
التالي...ستوفر القيمه المدخله حركه ناعمه للكاميرا
وبعدها سيطلب قيمه لكشف التصادم ....إن قمت بعمل واحد لن يتم تحفيزه لإنه يقبل التصادم من نوع static boxes
ملاحظه:
جرب أن تزيل المتغيرات الذي صرحنا عنها من النوع Global في بداية السطور ...ماذا ستلاحظ؟
سنلاحظ إن الكاميرا أصبحت ثابته ولاتتحرك
أما إن قمنا بعمل هذا الكود داخل الداله دون التصريح عن المتغيرات بواسطة Global ستعمل الكاميرا بشكل سليم
function camera()
x#=object position x(1)
y#=object position y(1)
z#=object position z(1)
set camera to follow x#,y#,z#,30,20,3,50,1
endfunction
أعتقد إنه هنا فهمتم ماهي الglobal ...إنها تجعلك توفر سطور برمجيه قليله وذلك لإنها تتعامل مع القيم المصرحه بها من كافة المشروع دون الحاجه إلى كتابة دوال وزيادة عدد السطور لتصير صورة الكود بهذا الشكل
()function camera
set camera to follow x#,y#,z#,30,20,3,50,1
endfunction
طبعاً... طالما إنه المتغيرات المستخدمه في الأمر مصرح عنها بواسطة الــGlobal في بداية الكود وخارج الحلقه التكراريه
لاحظوا إنه الكود الثاني يوفر أسطر على غرار الأول...
إلى هنا أنتهينا وأعتقد إنه هذا الدرس كافي لجعل البعض يبدأو بالعمل في مجال برمجة الألعاب بشكل بسيط
:biggthump