Advertisement
  1. Game Development
  2. Artificial Intelligence

إنشاء لعبة هوكي منظمة العفو الدولية باستخدام توجيه السلوكيات: لعبة ميكانيكا

Scroll to top
Read Time: 12 min
This post is part of a series called Create AI for a Hockey Game Using Steering Behaviors.
Create a Hockey Game AI Using Steering Behaviors: Defense

Arabic (العربية/عربي) translation by Wasmia Mia (you can also view the original English article)

في المقالات السابقة في هذه السلسلة ، ركزنا على المفاهيم الكامنة وراء الذكاء الاصطناعي الذي كنا نتعلم عنه. في هذا الجزء ، سنقوم بتغليف جميع التطبيقات في لعبة هوكي قابلة للعب بالكامل. سوف تتعلم كيفية إضافة القطع المفقودة المطلوبة لتحويل هذا إلى لعبة ، مثل النتيجة ، وشكا من السلطة ، وقليلا من تصميم اللعبة.

النتيجة النهائية

أدناه هو اللعبة التي سيتم تنفيذها باستخدام جميع العناصر المذكورة في هذا البرنامج التعليمي.

تصميم لعبة التفكير

الأجزاء السابقة من هذه السلسلة تركز على شرح كيفية عمل منظمة العفو الدولية لعبة. كل جزء بالتفصيل جانبا خاصا من اللعبة، مثل كيفية نقل الرياضيين وكيفية تنفيذ الهجوم والدفاع. كانت تستند إلى مفاهيم مثل سلوكيات القيادة وآلات الحالة المحدودة القائمة على المكدس.

من أجل جعل لعبة للعب بشكل كامل ، ومع ذلك ، يجب أن تكون ملفوفة كل هذه الجوانب في ميكانيكي اللعبة الأساسية. الخيار الأكثر وضوحًا هو تنفيذ جميع القواعد الرسمية لمباراة هوكي رسمية ، لكن ذلك يتطلب الكثير من العمل والوقت. دعونا نأخذ نهج خيالي أبسط بدلا من ذلك.

سيتم استبدال جميع قواعد الهوكي بواحد: إذا كنت تحمل بطلاً وتمس من قبل خصم ، فإنك تتجمد وتتحطم إلى مليون قطعة! سيجعل اللعبة أبسط للعب والمرح لكلا اللاعبين: واحد يحمل عفريت واحد يحاول استردادها.

من أجل تعزيز هذا الميكانيكي ، سنقوم بإضافة بعض شكا من السلطة. سيساعدون اللاعب على التسجيل وجعل اللعبة أكثر ديناميكية.

إضافة القدرة على نقاط

دعونا نبدأ بنظام التسجيل ، المسؤول عن تحديد من يفوز أو يخسر. الفريق يسجل في كل مرة تدخل فيها كرة القفزة هدف الخصم.

أن أسهل طريقة لتنفيذ ذلك استخدام مستطيلات المتراكبة اثنين:

Overlapped rectangles describing the goal area If the puck collides with the red rectangle the team scoresOverlapped rectangles describing the goal area If the puck collides with the red rectangle the team scoresOverlapped rectangles describing the goal area If the puck collides with the red rectangle the team scores
مستطيلات متراكبة تصف منطقة الهدف. إذا اصطدم العفريت بالمستطيل الأحمر ، يسجل الفريق.

يمثل المستطيل الأخضر المساحة التي يشغلها هيكل الهدف (الإطار والشبكة). إنه يعمل مثل كتلة صلبة ، لذا لن يتمكن البطة والرياضيون من التحرك من خلالها ؛ سوف ترتد.

المستطيل الأحمر الذي يمثل منطقة "نقاط". إذا عفريت يتداخل هذا المستطيل، فهذا يعني فريق سجل فقط.

المستطيل الأحمر أصغر من واحدة خضراء، ووضعت أمامه، حتى إذا عفريت تلامس الهدف على أي جانب ولكن الجبهة، أنها سوف ترتد مرة أخرى وسيتم إضافة لا نقاط:

A few examples of how the puck would behave if it touched the rectangles while movingA few examples of how the puck would behave if it touched the rectangles while movingA few examples of how the puck would behave if it touched the rectangles while moving
بعض الأمثلة على كيف تتصرف عفريت إذا لمست المستطيلات أثناء التحرك.

تنظيم كل شيء بعد درجات شخص ما

بعد عشرات فريق، يجب أن يعود جميع الرياضيين لموقفها المبدئي وعفريت يجب أن توضع في وسط حلبة مرة أخرى. وبعد هذه العملية، ويمكن أن تستمر المباراة.

نقل الرياضيين إلى موقعهم الأولي

كما هو موضح في الجزء الأول من هذه السلسلة ، فإن جميع الرياضيين لديهم حالة من الذكاء الاصطناعي تسمى prepareForMatch التي ستحركهم نحو الوضع الأولي ، وتؤدي إلى توقفهم بشكل سلس.

عندما عفريت يتراكب مع واحدة من "المناطق نقاط"، تتم إزالة أي دولة منظمة العفو الدولية النشطة حاليا لكل رياضي وهو الضغط بريباريفورماتش في المخ. أينما الرياضيين، أنهم سيعودون إلى مواقعها الأولية بعد بضع ثوان:

تتحرك الكاميرا نحو مركز حلبة

منذ الكاميرا دائماً يتبع عفريت، إذا أنها مباشرة teleported إلى مركز حلبة بعد شخص العشرات، طريقة العرض الحالية سوف تتغير فجأة، الذي سيكون مربكاً والقبيح.

أفضل طريقة للقيام بذلك هي نقل عفريت على نحو سلس نحو مركز الحلبة. نظرًا لأن الكاميرا تلتقط الصولجان ، فسيؤدي ذلك إلى تحريك المشهد من الهدف إلى مركز التزحلق.

يمكن تحقيق هذا عن طريق تغيير ناقل السرعة في عفريت بعد أن يضرب أي منطقة الهدف. ناقل السرعة الجديد يجب أن "دفع" عفريت نحو مركز حلبة، حيث أنها يمكن أن تحسب ك:

1
var c :Vector3D = getRinkCenter();
2
var p :Vector3D = puck.position;
3
4
var v :Vector3D = c - p;
5
v = normalize(v) * 100;
6
7
puck.velocity = v;

عن طريق طرح مركز مركز الحلبة من الوضع الحالي للقفز ، من الممكن حساب المتجه الذي يشير مباشرة نحو مركز الحلبة.

بعد تطبيع هذه القوة الموجهة، يمكن تحجيمه بأي قيمة، مثل 100، الذي يتحكم في مدى سرعة عفريت يتحرك نحو وسط حلبة.

أدناه صورة مع وجود تمثيل لناقل السرعة الجديد:

Calculation of a new velocity vector that will move the puck towards the rink centerCalculation of a new velocity vector that will move the puck towards the rink centerCalculation of a new velocity vector that will move the puck towards the rink center
حساب ناقل السرعة الجديد الذي سيحرك العجلة نحو مركز الحلبة.

هذا متجه V كناقل السرعة في عفريت، حيث عفريت سينتقل نحو مركز للتزلج على النحو المنشود.

لمنع أي سلوك غريب حين عفريت تتجه نحو وسط حلبة، مثل تفاعل مع رياضي، يتم إلغاء تنشيط عفريت أثناء العملية. نتيجة لذلك، فإنه يتوقف عن التفاعل مع الرياضيين، وتم وضع علامة كغير مرئية. اللاعب لن ترى عفريت تتحرك، ولكن سوف لا تزال تتبع من قبل الكاميرا.

لتقرر ما إذا كان عفريت بالفعل في الموقف، يحسب المسافة بين ذلك ووسط حلبة أثناء الحركة. إذا كان أقل من 10، على سبيل المثال، ما يكفي لتكون وضعت في وسط حلبة مباشرة وإعادة تنشيط يتسنى مواصلة المباراة وثيقة عفريت.

إضافة شكا من السلطة

الفكرة وراء شكا من السلطة هو مساعدة اللاعب على تحقيق الهدف الأساسي للعبة ، وهو التسجيل عن طريق تحمل عفريت لهدف الخصم.

من أجل النطاق ، سيكون لدينا لعبة اثنين فقط من شكا من السلطة: Ghost Help and Fear The Puck. ويضيف اللاعب السابق ثلاثة لاعبين إضافيين إلى فريق اللاعب لبعض الوقت ، في حين أن الأخير يجعل المعارضين يفرون من الصولجان لبضع ثوان.

تضاف السلطة الناشئة لكلا الفريقين عندما يسجل أي شخص.

تنفيذ السلطة "شبح تعليمات" إلى أعلى

نظرًا لأن جميع الرياضيين الذين تتم إضافتهم من خلال Ghost Help up-up مؤقتة ، يجب تعديل فئة الرياضي للسماح للرياضي بتمييزه كـ "ghost". إذا كان أحد الرياضيين شبحًا ، فسيزيل نفسه من اللعبة بعد بضع ثوانٍ.

أدناه هو فئة الرياضي، ويبرز فقط في إضافات لاستيعاب وظيفة الأشباح:

1
public class Athlete
2
{
3
    // (...)

4
  private var mGhost :Boolean;        // tells if the athlete is a ghost (a powerup that adds new athletes to help steal the puck).

5
	private var mGhostCounter :Number;  // counts the time a ghost will remain active

6
	
7
	public function Athlete(thePosX :Number, thePosY :Number, theTotalMass :Number) {
8
		// (...)

9
		mGhost = false;
10
		mGhostCounter = 0;
11
		
12
		// (...)

13
	}
14
    
15
    public function setGhost(theStatus :Boolean, theDuration :Number) :void {
16
		mGhost = theStatus;
17
		mGhostCounter = theDuration;
18
	}
19
	
20
	public function amIAGhost() :Boolean {
21
		return mGhost;
22
	}
23
	
24
	public function update() :void {
25
		// (...)

26
		
27
		// Update powerup counters and stuff

28
		updatePowerups();
29
		
30
		// (...)

31
	}
32
    
33
    public function updatePowerups() :void {
34
        // TODO.

35
    }
36
}

الخاصية mGhost هي منطقية تحكي ما إذا كان الرياضي شبحًا أم لا ، بينما يحتوي mGhostCounter على عدد الثواني التي يجب أن ينتظرها اللاعب قبل أن يزيل نفسه من اللعبة.

يتم استخدام هاتين الخاصيتين بواسطة أسلوب updatePowerups ():

1
private function updatePowerups():void {		
2
	// If the athlete is a ghost, it has a counter that controls

3
	// when it must be removed.

4
	if (amIAGhost()) {
5
		mGhostCounter -= time_elapsed;
6
		
7
		if (mGhostCounter <= 2) {
8
			// Make athlete flicker when it is about to be removed.

9
			flicker(0.5);
10
		}
11
		
12
		if (mGhostCounter <= 0) {
13
			// Time to leave this world! (again)

14
			kill();
15
		}
16
	}
17
}

ستقوم طريقة updatePowerups () ، التي يتم استدعاؤها في روتين التحديث الخاص بـ () ، بمعالجة جميع عمليات التزويد بالطاقة في الرياضي. الآن كل ما يفعله هو التحقق ما إذا كان الرياضي الحالي هو أشباح أم لا. إذا كان كذلك ، يتم تقليل الخاصية mGhostCounter بمقدار الوقت المنقضي منذ آخر تحديث.

عندما تصل قيمة مغوستكونتير إلى الصفر، فهذا يعني أن تنشط الرياضي مؤقتة لفترة طويلة كافية، ولذلك فإنه يجب إزالة نفسه من اللعبة. لجعل اللاعب يدرك أن الرياضي سوف تبدأ الخفقان الأخيرة اثنين ثانية قبل أن تختفي.

وأخيراً، حان الوقت لتنفيذ عملية إضافة الرياضيين مؤقتة عندما يتم تنشيط السلطة حتى. التي تتم في أسلوب powerupGhostHelp()، متاح في منطق اللعبة الرئيسية:

1
private function powerupGhostHelp() :void {
2
	var aAthlete :Athlete;	
3
	
4
	for (var i:int = 0; i < 3; i++) {
5
        // Add the new athlete to the list of athletes

6
		aAthlete = addAthlete(RINK_WIDTH / 2, RINK_HEIGHT - 100);
7
        
8
        // Mark the athlete as a ghost which will be removed after 10 seconds.

9
		aAthlete.setGhost(true, 10);
10
	}
11
}

بتكرار هذا الأسلوب على حلقة يتوافق مع مقدار الرياضيين مؤقتة يتم إضافتها. كل رياضي جديد يضاف إلى الجزء السفلي من الحلبة ووضع علامة كشبح.

كما هو موضح سابقًا ، سيزيل الرياضيون الأشباح أنفسهم من اللعبة.

تنفيذ قوة "الخوف"

عفريت الخوف السلطة حتى يجعل جميع المعارضين الفرار عفريت لبضع ثوان.

تماما مثل القوة "مساعدة شبح"-الأعلى، يجب أن يتم تعديل فئة الرياضي لاستيعاب هذه الوظيفة:

1
public class Athlete
2
{
3
    // (...)

4
    private var mFearCounter :Number; // counts the time the athlete should evade from puck (when fear powerup is active).

5
6
	
7
	public function Athlete(thePosX :Number, thePosY :Number, theTotalMass :Number) {
8
		// (...)

9
		mFearCounter = 0;
10
		
11
		// (...)

12
	}
13
    
14
	public function fearPuck(theDuration: Number = 2) :void {
15
		mFearCounter = theDuration;
16
	}
17
	
18
    // Returns true if the mFearCounter has a value and the athlete

19
    // is not idle or preparing for a match.

20
	private function shouldIEvadeFromPuck() :Boolean {
21
		return mFearCounter > 0 && mBrain.getCurrentState() != idle && mBrain.getCurrentState() != prepareForMatch;
22
	}
23
    
24
    private function updatePowerups():void {
25
    	if(mFearCounter > 0) {
26
			mFearCounter -= elapsed_time;
27
		}
28
		
29
		// (...)

30
	}
31
	
32
	public function update() :void {
33
		// (...)

34
		
35
		// Update powerup counters and stuff

36
		updatePowerups();
37
        
38
		// If the athlete is an AI-controlled opponent

39
		if (amIAnAiControlledOpponent()) {
40
			// Check if "fear of the puck" power-up is active.

41
            // If that's true, evade from puck.

42
			if(shouldIEvadeFromPuck()) {
43
				evadeFromPuck();
44
			}
45
        }			
46
		
47
		// (...)

48
	}
49
    
50
    public function evadeFromPuck() :void {
51
        // TODO

52
    }
53
}

أولاً يتم تغيير الأسلوب updatePowerups () إلى decrement الخاصية mFearCounter ، الذي يحتوي على مقدار الوقت يجب على الرياضي تجنب عفريت. يتم تغيير الخاصية mFearCounter في كل مرة يتم استدعاء الأسلوب fearPuck ().

في طريقة التحديث الخاص بـ Athlete () ، تتم إضافة اختبار للتحقق مما إذا كان يجب أن تتم عملية التشغيل. إذا كان الرياضي هو خصم تسيطر عليه AI (amIAnAiControlledOpponent () بإرجاع true) ويجب على الرياضي تجنب العبث (يجب أن يتم إرجاع trueIpeadeFromPuck () أيضاً) ، يتم استدعاء أسلوب evadeFromPuck ().

يستخدم الأسلوب evadeFromPuck() السلوك تهرب، الأمر الذي يجعل كيان تجنب أي كائن ومساره تماما:

1
private function evadeFromPuck() :void {
2
	mBoid.steering = mBoid.steering + mBoid.evade(getPuck().getBoid());
3
}

كل أسلوب evadeFromPuck() لا إضافة قوة تهرب إلى الرياضي الحالي توجيه القوة. فإنه يجعل منه تهرب عفريت دون تجاهل قوي التوجيهي المضافة مسبقاً، مثل تلك التي تم إنشاؤها بواسطة الدولة منظمة العفو الدولية النشطة حاليا.

ولكي تكون افادابل، عفريت يجب أن تسلك بويد، كما تفعل جميع الرياضيين (مزيد من المعلومات عن هذا الموضوع في الجزء الأول من هذه السلسلة). نتيجة لذلك، يجب إضافة خاصية بويد، الذي يتضمن الموقف الحالي للصولجان والسرعة، إلى فئة عفريت:

1
class Puck {
2
    // (...)

3
    private var mBoid :Boid;
4
    
5
    // (...)

6
    
7
    public function update() {
8
        // (...)

9
        mBoid.update();
10
    }
11
    
12
    public function getBoid() :Boid {
13
        return mBoid;
14
    }
15
    
16
    // (...)

17
}

وأخيراً، سنقوم بتحديث منطق اللعبة الرئيسية لجعل المعارضين يخشون عفريت عندما يتم تنشيط السلطة حتى:

1
private function powerupFearPuck() :void {
2
	var i           :uint,
3
		athletes    :Array  = rightTeam.members,
4
		size        :uint   = athletes.length;
5
			
6
	for (i = 0; i < size; i++) {
7
		if (athletes[i] != null) {
8
            // Make athlete fear the puck for 3 seconds.

9
			athletes[i].fearPuck(3);
10
		}
11
	}
12
}

الأسلوب بالتكرار عبر كافة الرياضيين الخصم (الفريق المناسب، في هذه الحالة)، استدعاء الأسلوب fearkPuck() لكل واحد منهم. وهذا سوف يؤدي إلى المنطق الذي يجعل الرياضيين الخوف عفريت خلال ثوان قليلة، كما سبق وشرح.

التجميد والتحطم

الماضي، بالإضافة إلى اللعبة هو الجزء الخاص بتجميد وتحطيم. أنها تتم في منطق اللعبة الرئيسية، حيث يتحقق روتين سواء رياضيين فريق اليسار هي متداخلة مع رياضيين الفريق الصحيح.

يتم إجراء هذا الفحص المتداخل تلقائيًا بواسطة محرك اللعبة Flixel ، والذي يستدعي معاودة الاتصال في كل مرة يتم فيها العثور على تراكب:

1
private function athletesOverlapped(theLeftAthlete :Athlete, theRightAthlete :Athlete) :void {
2
    // Does the puck have an owner?	

3
	if (mPuck.owner != null) {
4
        // Yes, it does.

5
		if (mPuck.owner == theLeftAthlete) {
6
            //Puck's owner is the left athlete

7
			theLeftAthlete.shatter();
8
			mPuck.setOwner(theRightAthlete);
9
10
		} else if (mPuck.owner == theRightAthlete) {
11
            //Puck's owner is the right athlete

12
			theRightAthlete.shatter();
13
			mPuck.setOwner(theLeftAthlete);
14
		}
15
	}
16
}

ويتلقى هذا الاستدعاء كمعلمات الرياضيين من كل فريق أن تتداخل. اختبار التحقق من إذا لم يكن المالك عفريت فارغة، مما يعني أنه يتم بشخص ما.

في هذه الحالة ، تتم مقارنة مالك الصولجان بالرياضيين المتراكبين. إذا كان واحد منهم يحمل عفريت (لذلك فهو مالك البطة) ، هو محطم وممتلكات عفريت يمر إلى الرياضي الآخر.

ستحدد طريقة التحطيم في فئة الرياضي الرياضي غير نشط وتضعه في أسفل الحلبة بعد بضع ثوان. كما أنه سيطلق العديد من الجسيمات التي تمثل قطع الجليد ، ولكن سيتم تغطية هذا الموضوع في وظيفة أخرى.

الاستنتاج

في هذا البرنامج التعليمي، قمنا بتنفيذ بعض العناصر المطلوبة لتحويل لدينا نموذج الهوكي لعبة تماما لعب. أنا وضعت عمدا التركيز على المفاهيم وراء كل عنصر من تلك العناصر، بدلاً من كيفية تنفيذها فعلا في محرك اللعبة X أو Y.

قد يبدو النهج تجميد وتحطيم المستخدمة اللعبة خيالية جداً، ولكنه يساعد إبقاء المشروع يمكن التحكم فيها. الرياضة قواعد محددة جداً، وتنفيذها يمكن أن تكون خادعة.

من خلال إضافة بعض الشاشات وبعض عناصر HUD ، يمكنك إنشاء لعبة الهوكي الخاصة بك بالكامل من هذا العرض التوضيحي!

المراجع

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Game Development tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.