TheIslamFalcon
31-12-2007, 11:23 PM
السلام عليكم ورحمة الله وبركاته
ما سنراه هنا سيكون بداية لتسهيل التعامل مع مكتبة تعتمد في الأساس إلى المحرك irrlichtCP في استعمالها للمحرك واذا تكلمنا عن الفرق فسيكون الفرق بين هذا المحرك والمحرك الرسمي الذي تحدثنا عنه سابقا
لكننا لن نتحدث كثيرا عن الفروق هذه المرة لان المتتبع سيلاحظ فروق بسيطة
irrlichtCP جاءت لتدعم المحرك على جميع المنصات باستعمال لغات الدوت نت بينما المكتبة التي سنراها ورغم انها انطلقت من كود المحرك إلا أنها لا تهدف إلا العمل على جميع المنصات وانما وضع اطار عمل سهل لمبرمجي الألعاب على الدوت نت بادراج مكتبة فيزياء محترمة (newton) + مكتبة صوت قوية (openal)
لذلك سنرى اليوم التنظيم الذي جاءت به هذه المكتبة والتسهيل أيضا
عند إدراجنا لمرجع المكتبة سنرى أنها تحمل 5 فضاءات للأسماء
فضائين موجودين أصلا في المحرك irrlichtCP و وفضائي الصوت والفيزياء وفضاء للإطار المشترك بينهم
يوفر فضاء الإطار المشترك Framework (ليس هو الفريمورك للدوت نت http://www.arabteam2000-forum.com/style_emoticons/default/regular_smile.gif ) فئات مشتركة خصوصا فئات الأحداثيات التي تغنينا عن التحويل لتوحيد معايير القياس بين فضاءات الأسماء الأخرى وفئين خاصين وفرهما صاحب المكتبة لتسهيل الكود وللاستفادة من مميزات الوراثة هما game و entity
الفئة Game : وتحمل جميع متغيرات اللعبة وهي قابلة للوراثة
الفئة Entity : تقوم بتحميل كل كيانات داخل اللعبة وهي عبارة عن collection
طيب لقد أطلنا الكلام هذه المرة لنرى كيف يمكننا البدأ بالتطبيق
بعد اداراج المرجع الخاص بالمكتبة للمشروع المنشئ وليكن console
نضيف للمشروع كلاس ونسميها مثلا myGame
لكي نرى فائدة وجود الفئة Game نقوم بعمل توريث لها لفئتنا myGame
كود:
-----
Public Class myGame
Inherits Framework.Game
End Class
الآن يمكن استدعاء دوال الفئة بعد وراثتها
الآن يمكننا تجهيز لعبتنا انطلاقا من هذه الفئة علينا فقط إدراج الأمر للتشغيل عند انشاء هذه الفئة لذلك يجب اضافة new
كود:
-----
Public Sub New()
Run()
End Sub
فقط بكتابة هذا الأمر فان المحرك قد تم تجهيزه للعمل انطلاقا من هذه الفئة :shock:
لم تصدق :!:
تعال واكتب في الmain لمشروعك كود انشاء نسخة من الفئة mygame
كود:
-----
Dim test As myGame = New myGame
شغل البرنامج فقط وسترى
لقد كتبنا 3 أسطر فقط
الآن نريد أن نضيف كائن داخل اللعبة بعد اضافة كاميرا وهنا نريد الاستفادة من الفئة Entity والتي يجب توريثها مثلها مثل الفئة Game
مثلا نريد اضافة مكعب داخل اللعبة لذلك نقوم باضافة class جديدة لبرنامجنا ولنسميها مثلا mBox
كود:
-----
Imports Framework
Imports Framework.Irrlicht
Public Class mBox
Inherits Framework.Entity
Private m_node As SceneNode = Nothing
Public Sub New(ByVal mgame As Game)
MyBase.New(mgame)
Dim texture As Texture = Game.VideoDriver.GetTexture("box.png")
m_node = mgame.IrrlichtDevice.SceneManager.AddCubeSceneNode(19, Nothing, -1)
m_node.SetMaterialFlag(MaterialFlag.Lighting, False)
m_node.SetMaterialTexture(0, texture)
m_node.Position = New Vector3D(10, -10, 70)
End Sub
End Class
ماقمنا بعمله هو فقط انشاء مكعب داخل اللعبة ولو لاحظتم أن عند الانشاء في الإجراء New توجب علينا ادراج متغير من النوع Game لكي يتم اضافتها داخل اطار اللعبة المنشئة طبعا
نرجع إالى فئتنا myGame لكي نرى كيف نضيف هذا الكيان للعبة
طبعا قبل اضافته نضيف كاميرا أولا ثم نستعمل الخاصية Entities والتي هي مجموع الكيانات المحتواة داخل اللعبة لاضافة الكيان الجديد mBox الذي انشئناه
كود:
-----
SceneManager.AddCameraSceneNodeFPS(Nothing, 300, 300, False)
Entities.Add(New mBox(Me))
ثم نشغل اللعبة Run
هذا كل شئ فقط هناك ملاحظة
عند تشغيل اللعبة باستدعاء الأجراء New في الفئة myGame لم نحدد خصائصها لذلك يتم التشغيل بالخصائص الافتراضية والتي هي OpenGL و أبعاد (640, 480) يمكننا تغيير هذه الخصائص باعادة صياغة الفئة باضافة
تعديل بسيط
كود:
-----
Public Sub New(ByVal dtype As DriverType)
MyBase.New(dtype, New Dimension2D(640, 480), 32, False, False, False, False)
SceneManager.AddCameraSceneNodeFPS(Nothing, 300, 300, False)
Entities.Add(New mBox(Me))
Run()
End Sub
هنا يجب اعادة كتابة انشاء الفئة بتحديد نوع drivetype
كود:
-----
Dim test As myGame = New myGame(Framework.Irrlicht.DriverType.Direct3D9)
مرفق مثال لتطبيق الدرس
http://www.arabteam2000-forum.com/style_images/ip.boardpr/folder_mime_types/zip.gif (http://www.arabteam2000-forum.com/index.php?act=attach&type=post&id=53173) Tut_irrlichtFramwork1.zip (http://www.arabteam2000-forum.com/index.php?act=attach&type=post&id=53173) ( 997.62k )
الدروس عبارة عن تبسيط فقط للتعامل وليس للاحتراف http://www.arabteam2000-forum.com/style_emoticons/default/regular_smile.gif
بالنسبة لمستعملي المكتبة الرسمية فقد يلاحظون أن الأسماء تغيرت فقد أصبح مثلا :
ISceneNode يسمى SceneNode
ومعظم المتغيرات والفئات أصبحت تسميتها تتبع نفس المنهاج يعني حذف ال I
من جهة تغيرت طريقة استعمال الأحداث داخل المحرك
فمثلا لو أردنا أن نضيف حدث OnEvent فقط علينا ربطه مباشرة باستدعاء الحدث والذي أصبح عبارة عن كائن داخل الdevice للمحرك
كود:
----
AddHandler IrrlichtDevice.OnEvent, AddressOf OnEvent
طبعا الكتابة لا تختلف كثيرا في تسيير متغيرات الأحداث فهي نفسها وقد رأيناها سابقا في الموضوع الأول
كود:
----
Private Function OnEvent(ByVal ev As [Event]) As Boolean
If ev.Type = EventType.KeyInputEvent And ev.KeyCode = KeyCode.Escape Then
IrrlichtDevice.Close()
End If
End Function
ربما يرى البعض أنه يوجد إختلاف بين هذه الأكواد نضيفها لفئتنا التي أنشأناها myGame في المثال السابق لكي يتم اغلاق اللعبة عند الضغط على Escape
المكتبة والتي لا أحب أن أسميها محرك لأنها لم تأتي بشئ جديد سوى تجميع للمحركات الثلاثة بشكل يبسط أكثر استعمالها في انشاء لعبة
طيب سنحاول بالتدريج مراجعة دروس المحرك irrlicht هنا لكي نحاول تطبيقها باستعمال هذه المكتبة
نبدأ بانشاء مشهد الquake3 :
الشئ الجديد هنا أو لنقل الخاصية الجديدة التي سنلاحظ وجودها هو أنه أصبح بالإمكان تحديد مكان العمل على الملفات يعني ال WorkingDirectory للفئة FileSystem
طبعا بعد اضافة المرجع الخاص للمكتبة والملفات الضرورية
ننشئ كيان جديد Entity (حتى نستفيد من خصائص التي تقدمها المكتبة) نحمل فيه مشهد الquake3
أول خطوة طبعا نضيف كلاس جديدة وليكن اسمها مثلا quake3 مووروثة من الفئة Entity
طبعا يجب اضافة كود الانشاء للكلاس في New لكن مع مراعاة اسناده للفئة الأساسية التي تم توريثها منها باستعمال mybase
يجب أن تكون الكلاس الناتجة على الشكل التالي :
كود:
----
Imports Framework
Imports Framework.Irrlicht
Public Class Quake3
Inherits Entity
Public Sub New(ByVal myGame As Game)
MyBase.New(myGame)
Dim GameDevice As IrrlichtDevice = myGame.IrrlichtDevice
GameDevice.FileSystem.WorkingDirectory = "C:\irrlicht-1.3.1\media\"
GameDevice.FileSystem.AddZipFileArchive("map-20kdm2.pk3", True, True)
Dim mesh As AnimatedMesh = GameDevice.SceneManager.GetMesh("20kdm2.bsp")
Dim node As SceneNode = GameDevice.SceneManager.AddOctTreeSceneNode(mesh.GetMesh(0), _
Nothing, 0, 128)
End Sub
End Class
بنفس الطريقة ننشئ كيان يقوم اضافة الكاميرا إلى المشهد ونسمي الكلاس المنشئة مثلا: GameCam
كود:
----
Imports Framework
Imports Framework.Irrlicht
Public Class GameCam
Inherits Entity
Public Sub New(ByVal myGame As Game)
MyBase.New(myGame)
Dim cam As CameraSceneNode = myGame.SceneManager.AddCameraSceneNodeFPS(Nothing _
, 250, 250, False)
cam.Position = New Vector3D(200, 850, 0)
cam.Rotation = New Vector3D(30, 50, 0)
End Sub
End Class
لاضافة الكائنين داخل اللعبة طبعا يجب أن تكون هناك فئة مووروثة من الكائن Game كما رأينا في السابق
كود:
----
Imports Framework
Imports Framework.Irrlicht
Public Class Program1
Inherits Game
Public Sub New()
IrrlichtDevice.WindowCaption = "Quake 3 Level Sample With IrrlichtFramework"
Dim quakeLevel As New Quake3(Me)
Dim myCamera As New GameCam(Me)
Entities.Add(quakeLevel)
Entities.Add(myCamera)
Run()
End Sub
End Class
ملاحظة :
على مبرمج الألعاب أن يكون كود اللعبة مفهوم ومرتب والمكتبة هذه تساعد المبرمج على فعل ذلك
فهنا عندما تكبر لعبتك تدريجيا وتريد التغيير في شئ ستعرف إلى أين تتجه دون البحث كثيرا داخل الكود
يمكن تطبيق المثال مباشرة دون استعمال كل هذه الفئات لكن ماحرصت عليه هنا أكثر هو أن نتعلم كيف ننظم عملنا باستعمال هذه المكتبة والإستفادة أكثر منها
مثال التطبيق
http://www.arabteam2000-forum.com/style_images/ip.boardpr/folder_mime_types/zip.gif (http://www.arabteam2000-forum.com/index.php?act=attach&type=post&id=53476) sample.zip (http://www.arabteam2000-forum.com/index.php?act=attach&type=post&id=53476) ( 1.02mb )
-------------------------------------------------
نتطرق في هذه العجالة للحديث عن الفيزياء باستعمال هذه المكتبة باستعمال Newton
في المحركات الفيزيائية عامة يلزمنا 3 أشياء أساسية
تكوين عالم يدعى في الغالب العالم الفيزيائي والذي يكون محدود
إضافة الأجسام داخل العالم الفيزيائي بتحديد خصائصها
تطبيق القوى على الأجسام أو الكيانات المنشئة
الناتج طبعا يكون المصفوفة التي ستتيح لنا تحديد مكان تواجد الجسم بعد تطبيق القوى اللازمة عليه
كيف يجري كل هذا في مكتبتنا؟
تكوين العالم الفيزيائي :
المكتبة التي نعمل عليها تحضر المكتبة الفيزيائية بمجرد انشاء نسخة جديدة من كلاس مورثة من الفئة Game
نمر لتحديد أبعاد العالم الفيزيائي المنشئ
كود:
----
NewtonWorld.WorldSize(New Vector3D(-1000.0F, -1000.0F, -1000.0F), New Vector3D(1000.0F, 1000.0F, 1000.0F))
إنشاء الأجسام المتصادمة داخل العالم الفيزيائي :
في المثال الذي نتحدث عنه نقوم بانشاء صندوق
كود:
----
Dim collision As Box = New Box(game.NewtonWorld, New Vector3D(19, 19, 19), New Matrix4())
ثم نضيفه داخل العالم الفيزيائي المنشئ بتعريف RigidBody
كود:
----
Private m_body As RigidBody = Nothing
كود:
----
m_body = New RigidBody(game.NewtonWorld, collision)
بعدها نحدد مصفوفة الكتلة للشكل المضاف بتحديد MassMatrix لل RigidBody
تطبيق القوى على الأجسام أو الكيانات المنشئة :
نربط الحدث Transform لل RigidBody والذي مكان تواجد الجسم وزاوية دورانه انطلاقا من المصوفة التي تم حسابها عن طريق المكتبة الفيزيائية
كود:
----
AddHandler m_body.Transform, AddressOf mTransform
ولتطبيق القوى نربط الحدث ApplyForceAndTorque لل RigidBody
كود:
----
AddHandler m_body.ApplyForceAndTorque, AddressOf mApplyForceAndTorque
الحدث mTransform
كود:
----
Overridable Sub mTransform(ByVal body As RigidBody, ByVal matrix As Matrix4)
m_node.Position = matrix.Translation
m_node.Rotation = matrix.RotationDegrees
End Sub
ويكون الحدث mApplyForceAndTorque
كود:
----
Overridable Sub mApplyForceAndTorque(ByVal body As RigidBody)
body.AddForce(New Vector3D(0, Gravity * Mass, 0))
End Sub
طبعا يجب تحديد قيم الجاذبية والكتلة للجسم مسبقا وهي قيم ثابتة طبعا
مثال تطبيقي لاستعمال الفيزياء على هذه المكتبة
http://www.arabteam2000-forum.com/uploads/monthly_11_2007/post-23361-1195579760.jpg
في المثال نستخدم جسم ثابت وآخر متحرك عبارة عن صندوق كما في الصورة
الكود للمثال http://www.arabteam2000-forum.com/style_images/ip.boardpr/folder_mime_types/zip.gif (http://www.arabteam2000-forum.com/index.php?act=attach&type=post&id=54453) Tut01.rar (http://www.arabteam2000-forum.com/index.php?act=attach&type=post&id=54453) ( 209.87k )
---------------------------------------------------------------
بالنسبة لعميلة رسم النار أو الدخان فتتم بنفس الطريقة باستخدام particles system
ومن أجل هذا الغرض فهناك فئة خاصة بذلك تسمى ParticleSystemSceneNode
ننشئ الجسم الذي سنضيف له باعث إما للنار أو للدخان (حسب الtexture المستعمل )
كود:
Dim particles As ParticleSystemSceneNode = SceneManager.AddParticleSystemSceneNode(False, Nothing, -1)
ثم نقوم بتحديد الجسم الباعث بانشائه داخل مكعب
كود:
Dim em As ParticleEmitter = particles.CreateBoxEmitter(New Box3D(-4, 0, -4, 4, 1, 4), _
New Vector3D(0, 0.03, 0), 10, 100, New Color(0, 255, 255, 255), _
New Color(0, 255, 255, 255), 800, 2000, -1)
كود الانشاء يحدد عدة خصائص منها
أبعاد الصندوق الذي يحتوي الجسم الباعث
اتجاه الانبعاث
minPPS أقل عدد من الجسيمات انبعاثا في الثانية
maxPPS أكبر عدد من الجسيمات انبعاثا في الثانية
وأقل لون و أقصى لون
وأقل وأقصى مدة حياة الجسيم المنبعث minLT و maxLT
ثم نضيف الجسم الباعث للكائن particle
كود:
particles.SetEmitter(em)
ثم بعدها نحدد الtexture والأشياء الضرورية الأخرى
كود:
particles.SetMaterialTexture(0, VideoDriver.GetTexture("fire.bmp"))
particles.SetMaterialType(MaterialType.TransparentAddColor)
particles.SetMaterialFlag(MaterialFlag.Lighting, False)
particles.ParticleSize = New Dimension2Df(10, 10)
وبالتوفيق دائما للجميع
ما سنراه هنا سيكون بداية لتسهيل التعامل مع مكتبة تعتمد في الأساس إلى المحرك irrlichtCP في استعمالها للمحرك واذا تكلمنا عن الفرق فسيكون الفرق بين هذا المحرك والمحرك الرسمي الذي تحدثنا عنه سابقا
لكننا لن نتحدث كثيرا عن الفروق هذه المرة لان المتتبع سيلاحظ فروق بسيطة
irrlichtCP جاءت لتدعم المحرك على جميع المنصات باستعمال لغات الدوت نت بينما المكتبة التي سنراها ورغم انها انطلقت من كود المحرك إلا أنها لا تهدف إلا العمل على جميع المنصات وانما وضع اطار عمل سهل لمبرمجي الألعاب على الدوت نت بادراج مكتبة فيزياء محترمة (newton) + مكتبة صوت قوية (openal)
لذلك سنرى اليوم التنظيم الذي جاءت به هذه المكتبة والتسهيل أيضا
عند إدراجنا لمرجع المكتبة سنرى أنها تحمل 5 فضاءات للأسماء
فضائين موجودين أصلا في المحرك irrlichtCP و وفضائي الصوت والفيزياء وفضاء للإطار المشترك بينهم
يوفر فضاء الإطار المشترك Framework (ليس هو الفريمورك للدوت نت http://www.arabteam2000-forum.com/style_emoticons/default/regular_smile.gif ) فئات مشتركة خصوصا فئات الأحداثيات التي تغنينا عن التحويل لتوحيد معايير القياس بين فضاءات الأسماء الأخرى وفئين خاصين وفرهما صاحب المكتبة لتسهيل الكود وللاستفادة من مميزات الوراثة هما game و entity
الفئة Game : وتحمل جميع متغيرات اللعبة وهي قابلة للوراثة
الفئة Entity : تقوم بتحميل كل كيانات داخل اللعبة وهي عبارة عن collection
طيب لقد أطلنا الكلام هذه المرة لنرى كيف يمكننا البدأ بالتطبيق
بعد اداراج المرجع الخاص بالمكتبة للمشروع المنشئ وليكن console
نضيف للمشروع كلاس ونسميها مثلا myGame
لكي نرى فائدة وجود الفئة Game نقوم بعمل توريث لها لفئتنا myGame
كود:
-----
Public Class myGame
Inherits Framework.Game
End Class
الآن يمكن استدعاء دوال الفئة بعد وراثتها
الآن يمكننا تجهيز لعبتنا انطلاقا من هذه الفئة علينا فقط إدراج الأمر للتشغيل عند انشاء هذه الفئة لذلك يجب اضافة new
كود:
-----
Public Sub New()
Run()
End Sub
فقط بكتابة هذا الأمر فان المحرك قد تم تجهيزه للعمل انطلاقا من هذه الفئة :shock:
لم تصدق :!:
تعال واكتب في الmain لمشروعك كود انشاء نسخة من الفئة mygame
كود:
-----
Dim test As myGame = New myGame
شغل البرنامج فقط وسترى
لقد كتبنا 3 أسطر فقط
الآن نريد أن نضيف كائن داخل اللعبة بعد اضافة كاميرا وهنا نريد الاستفادة من الفئة Entity والتي يجب توريثها مثلها مثل الفئة Game
مثلا نريد اضافة مكعب داخل اللعبة لذلك نقوم باضافة class جديدة لبرنامجنا ولنسميها مثلا mBox
كود:
-----
Imports Framework
Imports Framework.Irrlicht
Public Class mBox
Inherits Framework.Entity
Private m_node As SceneNode = Nothing
Public Sub New(ByVal mgame As Game)
MyBase.New(mgame)
Dim texture As Texture = Game.VideoDriver.GetTexture("box.png")
m_node = mgame.IrrlichtDevice.SceneManager.AddCubeSceneNode(19, Nothing, -1)
m_node.SetMaterialFlag(MaterialFlag.Lighting, False)
m_node.SetMaterialTexture(0, texture)
m_node.Position = New Vector3D(10, -10, 70)
End Sub
End Class
ماقمنا بعمله هو فقط انشاء مكعب داخل اللعبة ولو لاحظتم أن عند الانشاء في الإجراء New توجب علينا ادراج متغير من النوع Game لكي يتم اضافتها داخل اطار اللعبة المنشئة طبعا
نرجع إالى فئتنا myGame لكي نرى كيف نضيف هذا الكيان للعبة
طبعا قبل اضافته نضيف كاميرا أولا ثم نستعمل الخاصية Entities والتي هي مجموع الكيانات المحتواة داخل اللعبة لاضافة الكيان الجديد mBox الذي انشئناه
كود:
-----
SceneManager.AddCameraSceneNodeFPS(Nothing, 300, 300, False)
Entities.Add(New mBox(Me))
ثم نشغل اللعبة Run
هذا كل شئ فقط هناك ملاحظة
عند تشغيل اللعبة باستدعاء الأجراء New في الفئة myGame لم نحدد خصائصها لذلك يتم التشغيل بالخصائص الافتراضية والتي هي OpenGL و أبعاد (640, 480) يمكننا تغيير هذه الخصائص باعادة صياغة الفئة باضافة
تعديل بسيط
كود:
-----
Public Sub New(ByVal dtype As DriverType)
MyBase.New(dtype, New Dimension2D(640, 480), 32, False, False, False, False)
SceneManager.AddCameraSceneNodeFPS(Nothing, 300, 300, False)
Entities.Add(New mBox(Me))
Run()
End Sub
هنا يجب اعادة كتابة انشاء الفئة بتحديد نوع drivetype
كود:
-----
Dim test As myGame = New myGame(Framework.Irrlicht.DriverType.Direct3D9)
مرفق مثال لتطبيق الدرس
http://www.arabteam2000-forum.com/style_images/ip.boardpr/folder_mime_types/zip.gif (http://www.arabteam2000-forum.com/index.php?act=attach&type=post&id=53173) Tut_irrlichtFramwork1.zip (http://www.arabteam2000-forum.com/index.php?act=attach&type=post&id=53173) ( 997.62k )
الدروس عبارة عن تبسيط فقط للتعامل وليس للاحتراف http://www.arabteam2000-forum.com/style_emoticons/default/regular_smile.gif
بالنسبة لمستعملي المكتبة الرسمية فقد يلاحظون أن الأسماء تغيرت فقد أصبح مثلا :
ISceneNode يسمى SceneNode
ومعظم المتغيرات والفئات أصبحت تسميتها تتبع نفس المنهاج يعني حذف ال I
من جهة تغيرت طريقة استعمال الأحداث داخل المحرك
فمثلا لو أردنا أن نضيف حدث OnEvent فقط علينا ربطه مباشرة باستدعاء الحدث والذي أصبح عبارة عن كائن داخل الdevice للمحرك
كود:
----
AddHandler IrrlichtDevice.OnEvent, AddressOf OnEvent
طبعا الكتابة لا تختلف كثيرا في تسيير متغيرات الأحداث فهي نفسها وقد رأيناها سابقا في الموضوع الأول
كود:
----
Private Function OnEvent(ByVal ev As [Event]) As Boolean
If ev.Type = EventType.KeyInputEvent And ev.KeyCode = KeyCode.Escape Then
IrrlichtDevice.Close()
End If
End Function
ربما يرى البعض أنه يوجد إختلاف بين هذه الأكواد نضيفها لفئتنا التي أنشأناها myGame في المثال السابق لكي يتم اغلاق اللعبة عند الضغط على Escape
المكتبة والتي لا أحب أن أسميها محرك لأنها لم تأتي بشئ جديد سوى تجميع للمحركات الثلاثة بشكل يبسط أكثر استعمالها في انشاء لعبة
طيب سنحاول بالتدريج مراجعة دروس المحرك irrlicht هنا لكي نحاول تطبيقها باستعمال هذه المكتبة
نبدأ بانشاء مشهد الquake3 :
الشئ الجديد هنا أو لنقل الخاصية الجديدة التي سنلاحظ وجودها هو أنه أصبح بالإمكان تحديد مكان العمل على الملفات يعني ال WorkingDirectory للفئة FileSystem
طبعا بعد اضافة المرجع الخاص للمكتبة والملفات الضرورية
ننشئ كيان جديد Entity (حتى نستفيد من خصائص التي تقدمها المكتبة) نحمل فيه مشهد الquake3
أول خطوة طبعا نضيف كلاس جديدة وليكن اسمها مثلا quake3 مووروثة من الفئة Entity
طبعا يجب اضافة كود الانشاء للكلاس في New لكن مع مراعاة اسناده للفئة الأساسية التي تم توريثها منها باستعمال mybase
يجب أن تكون الكلاس الناتجة على الشكل التالي :
كود:
----
Imports Framework
Imports Framework.Irrlicht
Public Class Quake3
Inherits Entity
Public Sub New(ByVal myGame As Game)
MyBase.New(myGame)
Dim GameDevice As IrrlichtDevice = myGame.IrrlichtDevice
GameDevice.FileSystem.WorkingDirectory = "C:\irrlicht-1.3.1\media\"
GameDevice.FileSystem.AddZipFileArchive("map-20kdm2.pk3", True, True)
Dim mesh As AnimatedMesh = GameDevice.SceneManager.GetMesh("20kdm2.bsp")
Dim node As SceneNode = GameDevice.SceneManager.AddOctTreeSceneNode(mesh.GetMesh(0), _
Nothing, 0, 128)
End Sub
End Class
بنفس الطريقة ننشئ كيان يقوم اضافة الكاميرا إلى المشهد ونسمي الكلاس المنشئة مثلا: GameCam
كود:
----
Imports Framework
Imports Framework.Irrlicht
Public Class GameCam
Inherits Entity
Public Sub New(ByVal myGame As Game)
MyBase.New(myGame)
Dim cam As CameraSceneNode = myGame.SceneManager.AddCameraSceneNodeFPS(Nothing _
, 250, 250, False)
cam.Position = New Vector3D(200, 850, 0)
cam.Rotation = New Vector3D(30, 50, 0)
End Sub
End Class
لاضافة الكائنين داخل اللعبة طبعا يجب أن تكون هناك فئة مووروثة من الكائن Game كما رأينا في السابق
كود:
----
Imports Framework
Imports Framework.Irrlicht
Public Class Program1
Inherits Game
Public Sub New()
IrrlichtDevice.WindowCaption = "Quake 3 Level Sample With IrrlichtFramework"
Dim quakeLevel As New Quake3(Me)
Dim myCamera As New GameCam(Me)
Entities.Add(quakeLevel)
Entities.Add(myCamera)
Run()
End Sub
End Class
ملاحظة :
على مبرمج الألعاب أن يكون كود اللعبة مفهوم ومرتب والمكتبة هذه تساعد المبرمج على فعل ذلك
فهنا عندما تكبر لعبتك تدريجيا وتريد التغيير في شئ ستعرف إلى أين تتجه دون البحث كثيرا داخل الكود
يمكن تطبيق المثال مباشرة دون استعمال كل هذه الفئات لكن ماحرصت عليه هنا أكثر هو أن نتعلم كيف ننظم عملنا باستعمال هذه المكتبة والإستفادة أكثر منها
مثال التطبيق
http://www.arabteam2000-forum.com/style_images/ip.boardpr/folder_mime_types/zip.gif (http://www.arabteam2000-forum.com/index.php?act=attach&type=post&id=53476) sample.zip (http://www.arabteam2000-forum.com/index.php?act=attach&type=post&id=53476) ( 1.02mb )
-------------------------------------------------
نتطرق في هذه العجالة للحديث عن الفيزياء باستعمال هذه المكتبة باستعمال Newton
في المحركات الفيزيائية عامة يلزمنا 3 أشياء أساسية
تكوين عالم يدعى في الغالب العالم الفيزيائي والذي يكون محدود
إضافة الأجسام داخل العالم الفيزيائي بتحديد خصائصها
تطبيق القوى على الأجسام أو الكيانات المنشئة
الناتج طبعا يكون المصفوفة التي ستتيح لنا تحديد مكان تواجد الجسم بعد تطبيق القوى اللازمة عليه
كيف يجري كل هذا في مكتبتنا؟
تكوين العالم الفيزيائي :
المكتبة التي نعمل عليها تحضر المكتبة الفيزيائية بمجرد انشاء نسخة جديدة من كلاس مورثة من الفئة Game
نمر لتحديد أبعاد العالم الفيزيائي المنشئ
كود:
----
NewtonWorld.WorldSize(New Vector3D(-1000.0F, -1000.0F, -1000.0F), New Vector3D(1000.0F, 1000.0F, 1000.0F))
إنشاء الأجسام المتصادمة داخل العالم الفيزيائي :
في المثال الذي نتحدث عنه نقوم بانشاء صندوق
كود:
----
Dim collision As Box = New Box(game.NewtonWorld, New Vector3D(19, 19, 19), New Matrix4())
ثم نضيفه داخل العالم الفيزيائي المنشئ بتعريف RigidBody
كود:
----
Private m_body As RigidBody = Nothing
كود:
----
m_body = New RigidBody(game.NewtonWorld, collision)
بعدها نحدد مصفوفة الكتلة للشكل المضاف بتحديد MassMatrix لل RigidBody
تطبيق القوى على الأجسام أو الكيانات المنشئة :
نربط الحدث Transform لل RigidBody والذي مكان تواجد الجسم وزاوية دورانه انطلاقا من المصوفة التي تم حسابها عن طريق المكتبة الفيزيائية
كود:
----
AddHandler m_body.Transform, AddressOf mTransform
ولتطبيق القوى نربط الحدث ApplyForceAndTorque لل RigidBody
كود:
----
AddHandler m_body.ApplyForceAndTorque, AddressOf mApplyForceAndTorque
الحدث mTransform
كود:
----
Overridable Sub mTransform(ByVal body As RigidBody, ByVal matrix As Matrix4)
m_node.Position = matrix.Translation
m_node.Rotation = matrix.RotationDegrees
End Sub
ويكون الحدث mApplyForceAndTorque
كود:
----
Overridable Sub mApplyForceAndTorque(ByVal body As RigidBody)
body.AddForce(New Vector3D(0, Gravity * Mass, 0))
End Sub
طبعا يجب تحديد قيم الجاذبية والكتلة للجسم مسبقا وهي قيم ثابتة طبعا
مثال تطبيقي لاستعمال الفيزياء على هذه المكتبة
http://www.arabteam2000-forum.com/uploads/monthly_11_2007/post-23361-1195579760.jpg
في المثال نستخدم جسم ثابت وآخر متحرك عبارة عن صندوق كما في الصورة
الكود للمثال http://www.arabteam2000-forum.com/style_images/ip.boardpr/folder_mime_types/zip.gif (http://www.arabteam2000-forum.com/index.php?act=attach&type=post&id=54453) Tut01.rar (http://www.arabteam2000-forum.com/index.php?act=attach&type=post&id=54453) ( 209.87k )
---------------------------------------------------------------
بالنسبة لعميلة رسم النار أو الدخان فتتم بنفس الطريقة باستخدام particles system
ومن أجل هذا الغرض فهناك فئة خاصة بذلك تسمى ParticleSystemSceneNode
ننشئ الجسم الذي سنضيف له باعث إما للنار أو للدخان (حسب الtexture المستعمل )
كود:
Dim particles As ParticleSystemSceneNode = SceneManager.AddParticleSystemSceneNode(False, Nothing, -1)
ثم نقوم بتحديد الجسم الباعث بانشائه داخل مكعب
كود:
Dim em As ParticleEmitter = particles.CreateBoxEmitter(New Box3D(-4, 0, -4, 4, 1, 4), _
New Vector3D(0, 0.03, 0), 10, 100, New Color(0, 255, 255, 255), _
New Color(0, 255, 255, 255), 800, 2000, -1)
كود الانشاء يحدد عدة خصائص منها
أبعاد الصندوق الذي يحتوي الجسم الباعث
اتجاه الانبعاث
minPPS أقل عدد من الجسيمات انبعاثا في الثانية
maxPPS أكبر عدد من الجسيمات انبعاثا في الثانية
وأقل لون و أقصى لون
وأقل وأقصى مدة حياة الجسيم المنبعث minLT و maxLT
ثم نضيف الجسم الباعث للكائن particle
كود:
particles.SetEmitter(em)
ثم بعدها نحدد الtexture والأشياء الضرورية الأخرى
كود:
particles.SetMaterialTexture(0, VideoDriver.GetTexture("fire.bmp"))
particles.SetMaterialType(MaterialType.TransparentAddColor)
particles.SetMaterialFlag(MaterialFlag.Lighting, False)
particles.ParticleSize = New Dimension2Df(10, 10)
وبالتوفيق دائما للجميع