פרוייקט משחק בחודש #1: קוד


(Itzik Arzoni) #1

ממשיך את הדיון מ פרוייקט משחק בחודש:

###אוקי, אני רוצה להתחיל כבר לתכנת.

בגלל הזמן המועט שיש לי אחרי העבודה, הפרוייקט הזה נמשך כבר יותר מחודש. אז רציתי לקפוץ ישר לקוד.
כאשר מדובר בפיתוח משחק, שלב התכנות הוא מאוד חשוב. אבל… נו מדגדג לי כבר לגעת בקוד. :slight_smile:

####HaxeFlixel
בדרך כלל אני הייתי מעדיף פשוט לפתוח פלאש ולעשות את מה שצריך. אבל זו נשמעת כמו הזדמנות מצויינת ללמוד את אחת מהספריות היותר ותיקות (עוד מימי פלאש) וגם אחת היותר כיפיות, Flixel שעברה המרה מלאה להקס, עד כדי כך שהיא מנצלת עד תומם את כל יכולות השפה (בניגוד להמרה שטחית מפלאש, שם פשוט מעתיקים את המחלקות ומשנים כמה שמות).

####איך מתחילים?
תהליך ההתקנה הוא מאוד פשוט. פותחים את CMD וכותבים שם:

haxelib install haxeflixel

מי שרוצה יכול להוריד גם את ספריית ההדגמות שלהם, שמכילה פרוייקטים מוכנים להתחיל מהם וללמוד, או כל מיני ספריות עזר נוספות, שאולי נתייחס אליהן בהמשך. אפשר לקרוא עליהן עוד באתר של הקס פליקסל.

לאחר ההתקנה של הספריה הזו, יצרתי פרוייקט חדש מסוג OpenFl ב FlashDevelop.
הפרוייקט יצר מבנה כמעט ריק של תיקיות והגדרות מינימליות של שמאפשרות להפעיל את הפרוייקט. OpenFl, כזכור, זה “פלאש בתוך הקס”, ככה שאם הייתי רוצה לעשות פרוייקט “פלאש” זה היה מספיק. אבל אני רוצה לעלות כיתה להקס פליקסל, וזה דורש הגדרות נוספות.

כדי להוסיף את ההגדרות הנוספות, צריך לפתוח את הקובץ Project.xml. שם יש את כל הגדרות הפרוייקט.
הוספתי אליו את ההגדרות האלו, שמאפשרות לי לפתח בהקס פליקסל:

מייבא את ספריית פליקסל:

<haxelib name="flixel"/>

מגדיר לו פרילואדר, וגם אומר לו מה הגרסא המינימלית של פלאש לייצא אליה. אל דאגה, אם התוצר שלכם יהיה HTML או כל דבר אחר, לשורה הזו אין משמעות. אבל אני אוהב לעשות את זה בפלאש, אולי מתוך הרגל, אולי כי זה הכי יציב בעיני כרגע. לשנות את זה, זה פשוט לפתוח את תיבת הקומבו עם המילה Flash ולבחור שם HTML5.

  <app preloader="flixel.system.FlxPreloader" />
  <set name="SWF_VERSION" value="11.8" />

ועוד כמה פרמטרים שהם פנימיים של פליקסל:

<haxedef name="FLX_NO_GAMEPAD" />
<haxedef name="FLX_NO_MOUSE_ADVANCED" />
<!--Disable the Flixel core debugger. Automatically gets set whenever you compile in release mode!-->
<haxedef name="FLX_NO_DEBUG" unless="debug" />
<!--Enable this for Nape release builds for a serious peformance improvement-->
<haxedef name="NAPE_RELEASE_BUILD" unless="debug" />

אל דאגה! לפליקסל יש אפשרות ליצור פרוייקט משל עצמה עבור FlashDevelop. הצעדים לשם כך כתובים באתר.

####מה עושים עם זה?
למשחק של פליקסל יש מבנה קבוע ומאוד מסודר. כל מסך נקרא FlxState, ושם מרכזים את כל הכפתורים, רקעים, שחקנים, אוייבים ומה שצריך באותו המסך. לפעמים במסך אחד ישנם שני State, כאשר הראשון הוא המשחק ומעליו המצא תפריט (נניח כשעשיתם Pause ).
לכל State כזה יש שלוש פונקציות שצריך למלא בתוכן: create, update, destroy אשר עושות מה ששמן מרמז. ובין הStates מעבירים באמצעות הפקודה:

FlxG.switchState(new PlayState());

####בתוך ה State

בפונקציה Create של ה PlayState כתבתי את הפקודות הבאות:

	_player = new Player(0, 0);
	_player.screenCenter();
	add (_player);

בינתיים זה הכי פשוט שיש, רק כדי ללמוד את היסודות של פליקסל. לא ציינתי שאת _player הגדרתי כמשתנה פרטי של המחלקה. כל מה שפקודות אלו עושות, זה להגדיר את Player (מחלקה נוספת) ולהוסיף אותו לבמה.

בתוך המחלקה של שחקן

גם בתוך מחלקת Player ישנם בדיוק אותן הפקודות create,update,destroy שיש ל State. זה יוצר אחידות. במחלקה זו צירתי ריבוע פשוט וכחול שמסמל את מה שיהיה מתישהו הגרפיקה של השחקן. הגדרתי כמה הגדרות בסיסיות למהירות השחקן.

	makeGraphic(16, 16, FlxColor.BLUE);
	drag.x = drag.y = 10;
	_speed = 200;

בפונקציה Update הוספתי את הטיפול בתנועה. זה באמת קטע הקוד הכי ארוך שיצא לי לכתוב:

	var _up    = FlxG.keys.anyPressed(["UP"   , "W"]) ? 1  : 0 ;
	var _down  = FlxG.keys.anyPressed(["DOWN" , "S"]) ? -1 : 0 ;
	var _left  = FlxG.keys.anyPressed(["LEFT" , "A"]) ? 1  : 0 ;
	var _right = FlxG.keys.anyPressed(["RIGHT", "D"]) ? -1 : 0 ;

	var mA:Float = 0;
	 if (_up != 0)
	 {
		 mA = -90;
		 if (_left != 0)
			 mA -= 45;
		 else if (_right != 0)
			 mA += 45;
	 }
	 else if (_down != 0)
	 {
		 mA = 90;
		 if (_left != 0)
			 mA += 45;
		 else if (_right != 0)
			 mA -= 45;
	 }
	 else if (_left != 0)
		 mA = 180;
	 else if (_right != 0)
		 mA = 0;

	var speed:Float  = 0;
	if ( _up * _down * _left * _right != 0) {
		speed = _speed;
		velocity.x = speed;
		velocity.y = speed;
	}

	FlxAngle.rotatePoint(speed, 0, 0, 0, mA, velocity);

סה"כ, זה נראה פשוט מאוד. עד הפעם הבאה, אז אוסיף קצת יותר אפשרויות, שלב וגרפיקה.