سفارش ساخت بازی
سطح بازی مورد نظر خود را انتخاب نمایید
موتور بازی سازی مورد نظر خود را انتخاب نمایید
سبك بازی را انتخاب نمایید
نام:
نام خانوادگی:
نام مدرسه:
نام معلم:
تلفن تماس:
آی تلگرام:
توضیحات :
مدت زمان تولید دو روز كاری
هزینه تولید پروژه 300.000 تومان

موتور بازی سازی مورد نظر خود را انتخاب نمایید
سبك بازی را انتخاب نمایید
نام:
نام خانوادگی:
نام دانشگاه:
نام استاد:
تلفن تماس:
آی تلگرام:
توضیحات :
مدت زمان تولید پنج روز كاری
هزینه تولید پروژه 600.000 تومان

موتور بازی سازی مورد نظر خود را انتخاب نمایید
سبك بازی را انتخاب نمایید
نام:
نام خانوادگی:
نام دانشگاه:
نام استاد:
تلفن تماس:
آی تلگرام:
توضیحات :
مدت زمان تولید پانزده روز كاری
هزینه تولید پروژه 2.000.000 تومان

برای ساخت بازی و مشاوره رایگان با آی دی تلگرام زیر تماس بگیرید: Tfh1368
برای ساخت بازی و مشاوره رایگان با آی دی تلگرام زیر تماس بگیرید: Tfh1368


بازی های سبك پلتفرم (ساده)


بازی‌کننده در این نوع بازی مجبور به پرش از روی موانع مختلف یا بالا رفتن از سدهای فیزیکی است، مانند بازی سوپر ماریو یا بازی سونیك

گرافیك آماده
تعداد مراحل 2
منوی ورود ساده
حركات حركت به طرفین- پرش- دشمن ثابت
سورس كد
خروجی ویندوز
خروجی اندروید
صدا گذاری
درج اطلاعات شما در بازی
درج اطلاعات درخواستی


بازی های سبك پلتفرم (متوسط)


بازی‌کننده در این نوع بازی مجبور به پرش از روی موانع مختلف یا بالا رفتن از سدهای فیزیکی است، مانند بازی سوپر ماریو یا بازی سونیك

گرافیك آماده
تعداد مراحل 5
منوی ورود نیمه حرفه ای
حركات حركت به طرفین- پرش- شلیك- دشمنان متحرك
سورس كد
خروجی ویندوز
خروجی اندروید
صدا گذاری
درج اطلاعات شما در بازی
درج اطلاعات درخواستی


بازی های سبك پلتفرم (حرفه ای)


بازی‌کننده در این نوع بازی مجبور به پرش از روی موانع مختلف یا بالا رفتن از سدهای فیزیکی است، مانند بازی سوپر ماریو یا بازی سونیك

گرافیك آماده-حرفه ای
تعداد مراحل 10
منوی ورود حرفه ای
حركات حركت به طرفین- پرش- شلیك- دشمنان متحرك- دشمن تیر انداز- دشمن دارای هوش مصنوعی- حركات خاص كاراكتر- تغییر اصلحه
سورس كد
خروجی ویندوز
خروجی اندروید
صدا گذاری
درج اطلاعات شما در بازی
درج اطلاعات درخواستی


بازی های جنگی (ساده)


محوریت اصلی این نوع بازی ها بر روی پیروزی در جنگ استوار است و شما باید با غلبه بر دشمنان مراحل را به پایان برسانید. مانند جنگ هوایی یا جنگ تانكی

گرافیك آماده
تعداد مراحل 2
منوی ورود ساده
حركات حركت به طرفین- شلیك- دشمن ثابت
سورس كد
خروجی ویندوز
خروجی اندروید
صدا گذاری
درج اطلاعات شما در بازی
درج اطلاعات درخواستی


بازی های جنگی (متوسط)


محوریت اصلی این نوع بازی ها بر روی پیروزی در جنگ استوار است و شما باید با غلبه بر دشمنان مراحل را به پایان برسانید. مانند جنگ هوایی یا جنگ تانكی

گرافیك آماده
تعداد مراحل 5
منوی ورود نیمه حرفه ای
حركات حركت به طرفین-  شلیك- دشمنان متحرك- جوایز حین جنگ
سورس كد
خروجی ویندوز
خروجی اندروید
صدا گذاری
درج اطلاعات شما در بازی
درج اطلاعات درخواستی


بازی های جنگی (حرفه ای)


محوریت اصلی این نوع بازی ها بر روی پیروزی در جنگ استوار است و شما باید با غلبه بر دشمنان مراحل را به پایان برسانید. مانند جنگ هوایی یا جنگ تانكی

گرافیك آماده-حرفه ای
تعداد مراحل 10
منوی ورود حرفه ای
حركات حركت به طرفین-  شلیك- دشمنان متحرك- دشمنان ثابت- هوش مصنوعی- جوایز حین جنگ- ارتقا- تغییر صلاح
سورس كد
خروجی ویندوز
خروجی اندروید
صدا گذاری
درج اطلاعات شما در بازی
درج اطلاعات درخواستی


بازی های مسابقه ای (متوسط)


محوریت اصلی این نوع بازی ها پیروزی بر رقبا در مسابقات است معمولا مسابقات با وسایل نقلیه انجام میپذیرد.

گرافیك آماده
تعداد مراحل 5
منوی ورود نیمه حرفه ای
حركات حركت- مسابقه با رقبای كامپیوتری-
سورس كد
خروجی ویندوز
خروجی اندروید
صدا گذاری
درج اطلاعات شما در بازی
درج اطلاعات درخواستی


بازی های مسابقه ای (حرفه ای)


محوریت اصلی این نوع بازی ها پیروزی بر رقبا در مسابقات است معمولا مسابقات با وسایل نقلیه انجام میپذیرد.

گرافیك آماده-حرفه ای
تعداد مراحل 10
منوی ورود حرفه ای
حركات حركت- مسابقه با رقبای كامپیوتری- ماژول های خاص در حین مسابقه- ارتقا و شخصی سازی وسیله
سورس كد
خروجی ویندوز
خروجی اندروید
صدا گذاری
درج اطلاعات شما در بازی
درج اطلاعات درخواستی


بازی های آموزشی ای (متوسط)


محوریت اصلی این نوع بازی ها آموزش است. مانند آموزش الفبا فارسی یا انگلیسی و آموزش ریاضی

گرافیك آماده
تعداد مراحل 0
منوی ورود نیمه حرفه ای
حركات آموزش جزئی بحث
سورس كد
خروجی ویندوز
خروجی اندروید
صدا گذاری
درج اطلاعات شما در بازی
درج اطلاعات درخواستی


بازی های آموزشی ای (حرفه ای)


محوریت اصلی این نوع بازی ها آموزش است. مانند آموزش الفبا فارسی یا انگلیسی و آموزش ریاضی

گرافیك آماده-حرفه ای
تعداد مراحل 0
منوی ورود حرفه ای
حركات آموزش كلی- ثبت امتیاز
سورس كد
خروجی ویندوز
خروجی اندروید
صدا گذاری
درج اطلاعات شما در بازی
درج اطلاعات درخواستی

دسته بندی

آموزشهای تخصصی
ساخت چت روم با سی شارپ: قسمت دوم ساخت چت روم با سی شارپ: قسمت دوم ساخت چت روم با سی شارپ: قسمت دوم


ساخت چت روم با سی شارپ: قسمت دوم


در قسمت قبل آموزش ما یک سرور را در حالت listening قرار دادیم و همچنین بسته های دریافتی را تفکیک کردیم و آنها را به تابعی با نام handle_packet ارسال کردیم. در این بخش از آموزش ما بسته های مورد استفاده را تعریف میکنیم. ما به دو بسته نیاز داریم که به شکل زیر آنها را تعریف میکنیم.

بسته با شناسه 1

نوع بسته: کلاینت به سرور

مقادیر بازگشتی: ندارد

مقادیر ارسالی: متن چت همراه با نام ارسال کننده (از نوع رشته)

وظیفه: ارسال چت های کاربر به سرور

بسته با شناسه 2

نوع بسته: سرور به کلاینت

مقادیر بازگشتی: ندارد

مقادیر ارسالی: متن چت های سایر کاربران(از نوع رشته)

وظیفه : ارسال چت های سایر کاربران به کاربر

ممکن است در نگاه اول تعاریف بالا کمی ترسناک به نظر بیایند، پس بیایید تک تک اصطلاحات آن را بشکافیم. در تعاریف بالا نوع بسته جهت بسته را نشان میدهد که بسته با شناسه یک به دلیل این که باید داده ای را از کلاینت(کاربر) به سرور منتقل کند به عنوان کلاینت به سرور در نظر گرفته می شود.

در ادامه اگر بسته ای که به سرور ارسال می شود با همان شناسه باید داده ای را برگرداند میگوییم که بسته مقدار بازگشتی دارد، به عنوان مثال بسته مربوط به ورود(لوگین) با شناسه 5 ، هنگامی که داده ها به سرور ارسال می شوند باید نتیجه آن با همان شناسه 5 بازگردد، البته در بسته هایی که ما در اینجا تعریف کرده ایم هیچکدام مقدار بازگشتی ندارند.

مقادیر ارسالی داده هایی هستند که بسته باید به مقصد برساند تعریف نوع و ترتیب داده ها بسیار مهم است به عنوان مثال برای نام از String و برای امتیاز از int استفاده می کنیم. و در نهایت وظیفه بسته که شامل تعیین دقیق کاری که بسته باید انجام دهد است.

حالا وقت آن است تا کدهای مربوط به دریافت چت و ارسال آن برای سایر کاربران را بنویسیم

 

try

            {

               

                using (BinaryReader reader = new BinaryReader(new MemoryStream(data)))

                {

                    int packet_id = reader.ReadUInt16();

                   

                    switch (packet_id)

                    {

                        case 1:

 

                            UInt16 chat_len = reader.ReadUInt16();

                            string chat_data = Encoding.UTF8.GetString(reader.ReadBytes(chat_len));

                           

                            using (BinaryWriter writer = new BinaryWriter(new MemoryStream()))

                            {

                                //packet data

                                writer.Write((ushort)0);

                                writer.Write((ushort)2);

                                writer.Write((ushort)chat_data.Length);

                                writer.Write(chat_data);

 

                                // write packet len at begining

                                writer.Seek(0, SeekOrigin.Begin);

                                writer.Write((ushort)writer.BaseStream.Length);

 

 

                                byte[] raw_data = ((MemoryStream)writer.BaseStream).ToArray();

 

                                for (int i = 0; i < list_users.Count-1; i++)

                                {

                                    if (list_users[i] != client) { send_packet(raw_data, list_users[i]); }

                                }

                            }

                            break;

                    }

 

                }

            }

            catch (Exception)

            {

 

               

          }

کد های بالا در تابع handle_packet قرار دارند همانطور که میدانید این تابع دو پارامتر دارد اولی داده های تفکیک شده و دوم کلاینتی که داده ها را ارسال کرده است، داخل این تابع ابتدا از try catch استفاده کرده ایم تا در صورت بروز هر گونه خطا در هنگام خواندن داده ها و یا ارسال آنها برنامه سرور ما بسته نشود. در ادامه از binaryreader برای خواندن داده ها استفاده کرده ایم، داخل بلاک binaryreader ابتدا شناسه پکت را که از نوع uint16  وارد کرده بودیم را میخوانیم سپس با استفاده از یک switch وظیفه بسته آمده را انجام میدهیم. در کد های بالا پیامی که از سمت کاربر به سرور ارسال می شود با شناسه یک است که باید برای سایر کلاینت ها ارسال شود، بنابراین ما در کیس 1 ، ابتدا طول چت کاربر و سپس متن چت را استخراج میکنیم(ما قبلا طول چت را در سمت کلاینت وارد کرده ایم که در جلسه بعد کامل شرح داده می شود) برای تبدیل بایت ها به رشته از کلاس encoding استفاده کرده ایم که بسته به نوع encoding (در اینجا utf8) داده ها را استخراج کرده ایم .

حالا باید داده های دریافت شده را به سایر کاربران ارسال کنیم پس یک binarywirter ایجاد میکنیم. در ابتدا چون طول بسته را نمیدانیم چقدر است یک مقدار 0 از نوع Ushort (با Uint16 برابر است) وارد میکنیم سپس شناسه بسته که 2 است و در ادامه طول پیام و در نهایت متن پیام، برای این که کلاینت بتواند بسته ها را از یک دیگر تفکیک کند باید طول بسته را در ابتدای بسته قرار دهیم ، از انجایی که ما در ابتدا طول بسته را 0 قرار دادیم باید آن را دوباره مقدار دهی کنیم(به دلیل اینکه ما در ابتدا نمیدانستیم طول بسته چقدر است اما حالا میدانیم). برای تغییر مقداری که در ابتدای بسته قرار داده ایم باید موقعیت فعلی رایتر را به ابتدای بسته تغییر دهیم برای اینکار از کد wirter.seek استفاده کرده ایم در پارامتر اول این تابع افست و در پارامتر دوم محل افست تعریف شده است که چون ما در اینجا قصد داریم به ابتدای بسته برویم افست ان را 0 و محل آن را از ابتدا در نظر گرفته ایم(اگر seekorigin را end قرار دهیم افست را از اخر بسته در نظر میگیرد)، در خط بعد ما طول بسته را باز نویسی کرده ایم.

حالا نوبت آن است تا بایت هایی که نوشته ایم را از  wirter بگیریم، برای این کار بیس استریم را به memorystream کَست میکنیم و از شی تبدیل شده تابع toarray را فراخوانی میکنیم تا داده ها را به صورت ارایه ای از بایت به ما تحویل دهد. برای ارسال داده ها به تمام کاربران یک حلقه ایجاد میکنیم و در درون حلقه از لیست کلاینت ها برای ارسال داده ها استفاده میکنیم، همانطور که مشاهده میکنید ما بررسی کرده ایم اگر کلاینتی که داخل لیست است با کلاینتی که پیام را ارسال کرده است برابر است پیام را برای او ارسال نکند.

نکته: این ابتدایی ترین حالت ارسال و دریافت است و ما در اینجا مسائل امنیتی و چند گره ای را در نظر نگرفته ایم.

نکته 2: برای درک بهتر binaryreader و  binarywriter توصیه میشود حتما رفرنس های مایکروسافت را مطالعه کنید.

نکته3: از انجایی که نوع داده ای مانند int16،int32،float و مانند آن طول ثابت دارند ما نیازی به وارد کردن طول آنها قبل از مقدار آنها نداریم، در کد های بالا ما برای ارسال و دریافت رشته (که هیچ طول ثابتی ندارد) ابتدا طول رشته را در یک نوع  ushort قرارداده ایم و سپس متن رشته را (در ارسال رشته بین سی شارپ و گیم میکر باید از این راه استفاده شود)، همچنین باید به خاطر داشته باشید ما در اینجا متن های انگلیسی را جابه جا میکنیم که طول هر کاراکتر آن 1 بایت است اما متن های فارسی و سایر زبان ها طولشان 2 بایت است که باید از encoding از نوع  utf8 استفاده شود.

در قسمت بعد نوشتن کلاینت را توضیح خواهیم داد.

 

 



نویسنده:

hadi eb





نظرات


نام: cloner

4 آذر 1397
salam khaste nabashid key in client ro minevisid?? mn vaghean lazemesh daram
نام: hadi eb

4 آذر 1397
با سلام خوشحالم که آموزش ها براتون مفید بوده انشالله تا اخر این ماه آماده میشه بلکه هر چه زودتر

نام: zanous

5 بهمن 1397
سلام میشه یه آموزش کامل درمورد خروجی گیم میکر استادیو 2 بزارید برای اندروید بزارید ممنون .
نام: tohid Fh

3 فروردین 1398
آقای عبادت زحمتشو کشیدن https://goo.gl/ZoDTof

نام: MAHDI

5 فروردین 1398
سلام من توی گیم میکر استدیو هر نوع اسکریپتی رو که مینویسم بهم ارور میده به عبارت دیگه نمیتونم تو گیم میکر استدیو اسکریپت نویسی کنم:(