DevOps C++ و «جنگ آشپزخانه»، یا چگونه شروع کردم به نوشتن بازی در حین غذا خوردن

سقراط: می دانم که هیچ چیز نمی دانم

برای چه کسی: برای افراد IT که به همه توسعه دهندگان اهمیتی نمی دهند و می خواهند بازی های آنها را انجام دهند!

در مورد چه چیزی: در مورد نحوه شروع نوشتن بازی ها در C/C++، اگر ناگهان به آن نیاز پیدا کردید!

چرا باید این را بخوانید: توسعه برنامه در زمینه تخصص من نیست، اما سعی می کنم هر هفته کدنویسی کنم. چون من عاشق بازی هستم!

سلام اسم من هست آندری گرانکین، من DevOps در Luxoft هستم. توسعه اپلیکیشن تخصص من نیست، اما سعی می کنم هر هفته کدنویسی کنم. چون من عاشق بازی هستم!

صنعت بازی های رایانه ای بسیار بزرگ است و شایعه شده است که حتی از صنعت سینمای امروز هم بزرگتر است. بازی‌ها از ابتدای پیدایش رایانه‌ها با استفاده از استانداردهای مدرن، روش‌های توسعه پیچیده و اولیه نوشته شده‌اند. با گذشت زمان، موتورهای بازی با گرافیک، فیزیک و صدا از قبل برنامه ریزی شده ظاهر شدند. آنها به شما اجازه می دهند تا روی توسعه خود بازی تمرکز کنید و نگران پایه و اساس آن نباشید. اما همراه با آنها، با موتورها، توسعه دهندگان "کور" می شوند و تنزل می یابند. خود تولید بازی ها روی تسمه نقاله قرار می گیرد. و کمیت محصولات بر کیفیت آن غالب می شود.

در عین حال، هنگام انجام بازی‌های دیگران، ما دائماً توسط مکان‌ها، طرح داستان، شخصیت‌ها و مکانیک‌های بازی که دیگران به آن دست یافته‌اند محدود می‌شویم. بنابراین متوجه شدم که ...

... زمان آن فرا رسیده است که دنیاهای خودم را بسازم که فقط تابع من باشد. دنیاهایی که من پدر، پسر و روح القدس هستم!

و من صمیمانه معتقدم که با نوشتن موتور بازی خود و بازی روی آن، می توانید کفش های خود را در بیاورید، شیشه ها را پاک کنید و کابین خود را ارتقا دهید و به یک برنامه نویس با تجربه و کامل تر تبدیل شوید.

در این مقاله سعی خواهم کرد به شما بگویم که چگونه شروع به نوشتن بازی های کوچک در C/C++ کردم، روند توسعه چگونه است و کجا برای سرگرمی در یک محیط شلوغ وقت پیدا می کنم. ذهنی است و فرآیند شروع فردی را توصیف می کند. مطالبی در مورد جهل و ایمان، در مورد تصویر شخصی من از جهان در حال حاضر. به عبارت دیگر، "دولت مسئول مغز شخصی شما نیست!"

عمل

"دانش بدون تمرین بی فایده است، تمرین بدون دانش خطرناک است" کنفوسیوس

دفترچه من زندگی من است!


بنابراین، در عمل، می توانم بگویم که برای من همه چیز با یک دفترچه یادداشت شروع می شود. من نه تنها کارهای روزانه ام را در آنجا یادداشت می کنم، بلکه طراحی، برنامه ریزی، طراحی فلوچارت و حل مسائل از جمله مسائل ریاضی را نیز انجام می دهم. همیشه از یک دفترچه یادداشت استفاده کنید و فقط با مداد بنویسید. IMHO تمیز، راحت و قابل اعتماد است.

DevOps C++ و «جنگ آشپزخانه»، یا چگونه شروع کردم به نوشتن بازی در حین غذا خوردن
دفترچه من (از قبل پر شده است). این چیزی است که او به نظر می رسد. این شامل وظایف روزمره، ایده ها، نقشه ها، نمودارها، راه حل ها، حسابداری سیاه، کد و غیره است.

در این مرحله، من موفق به تکمیل سه پروژه شدم (این در درک من از "کامل بودن" است، زیرا هر محصولی را می توان نسبتاً بی پایان توسعه داد).

  • پروژه 0: این یک صحنه نمایشی 3D Architect است که با C# و با استفاده از موتور بازی Unity نوشته شده است. برای سیستم عامل های macOS و ویندوز.
  • بازی 1: بازی کنسولی Simple Snake (که همه با نام "Snake" می شناسند) برای ویندوز. نوشته شده در C.
  • بازی 2: بازی کنسولی Crazy Tanks (که برای همه به عنوان "Tanks" شناخته می شود) که در C++ (با استفاده از کلاس ها) و همچنین برای ویندوز نوشته شده است.

پروژه 0. دمو معمار

  • سکو: ویندوز (ویندوز 7، 10)، سیستم عامل مک (OS X El Capitan نسخه 10.11.6)
  • زبان: C#
  • موتور بازی: وحدت
  • الهام: دارین لیل
  • مخزن: GitHub

DevOps C++ و «جنگ آشپزخانه»، یا چگونه شروع کردم به نوشتن بازی در حین غذا خوردن
نسخه ی نمایشی معمار صحنه سه بعدی

پروژه اول نه در C/C++، بلکه در سی شارپ با استفاده از موتور بازی Unity اجرا شد. این موتور به اندازه سخت‌افزار سخت‌افزاری نداشت موتور غیر واقعی، و همچنین نصب و استفاده آسان تر به نظر می رسید. موتورهای دیگر را در نظر نگرفتم.

هدف من در یونیتی توسعه یک بازی نبود. من می خواستم یک صحنه سه بعدی با چند شخصیت بسازم. او یا بهتر بگوییم او (من از دختری که عاشقش بودم الگو گرفتم =) باید حرکت می کرد و با دنیای اطرافش تعامل داشت. مهم این بود که بفهمیم یونیتی چیست، روند توسعه چیست و چقدر تلاش برای ایجاد چیزی لازم است. اینگونه بود که پروژه Architect Demo متولد شد (نام تقریباً از هیچ اختراع شد). برنامه نویسی، مدلسازی، انیمیشن، تکسچرینگ برای من احتمالاً دو ماه کار روزانه طول کشید.

من با فیلم های آموزشی در YouTube در مورد ایجاد مدل های سه بعدی شروع کردم بلندر. Blender یک ابزار رایگان عالی برای مدل سازی سه بعدی (و بیشتر) است که نیازی به نصب ندارد. و اینجا یک شوک در انتظارم بود... معلوم شد که مدلسازی، انیمیشن، تکسچرینگ موضوعات مجزای بزرگی هستند که می توانید در مورد آنها کتاب بنویسید. این به ویژه در مورد شخصیت ها صادق است. برای مدل سازی انگشتان، دندان ها، چشم ها و سایر اعضای بدن، به دانش آناتومی نیاز دارید. ساختار عضلات صورت چگونه است؟ مردم چگونه حرکت می کنند؟ من مجبور شدم استخوان ها را در هر بازو، پا، انگشت، فالانژ انگشتان "قرار دهم"!

استخوان های ترقوه و استخوان های اهرمی اضافی را مدل کنید تا انیمیشن طبیعی به نظر برسد. پس از چنین درس هایی، متوجه می شوید که سازندگان فیلم های انیمیشن چقدر برای ساختن 30 ثانیه ویدئو انجام می دهند. اما فیلم های سه بعدی ساعت ها دوام می آورند! و سپس سینماها را ترک می کنیم و چیزی شبیه این می گوییم: «این یک کارتون/فیلم مزخرف است! می توانستند بهتر از این کار کنند..." احمق ها!

و یک چیز دیگر در مورد برنامه نویسی در این پروژه. همانطور که معلوم شد، برای من جالب ترین قسمت ریاضی بود. اگر صحنه را اجرا کنید (لینک به مخزن در توضیحات پروژه)، متوجه می شوید که دوربین به صورت یک کره به دور شخصیت دختر می چرخد. برای برنامه ریزی چنین چرخشی دوربین، ابتدا باید مختصات نقطه موقعیت روی دایره (2D) و سپس روی کره (3D) را محاسبه می کردم. نکته خنده دار این است که من در مدرسه از ریاضیات متنفر بودم و آن را با C-minus می دانستم. احتمالاً تا حدودی به این دلیل که در مدرسه به شما توضیح نمی دهند که چگونه این ریاضیات در زندگی به کار می رود. اما وقتی در مورد هدف، رویای خود وسواس دارید، ذهن شما پاک می شود و باز می شود! و شما شروع به درک وظایف دشوار به عنوان یک ماجراجویی هیجان انگیز می کنید. و سپس فکر می کنید: "خب، چرا ریاضیدان *مورد علاقه* شما نمی تواند به طور معمول به شما بگوید که کجا می توان این فرمول ها را اعمال کرد؟"

DevOps C++ و «جنگ آشپزخانه»، یا چگونه شروع کردم به نوشتن بازی در حین غذا خوردن
محاسبه فرمول های محاسبه مختصات یک نقطه روی یک دایره و یک کره (از دفترچه یادداشت من)

بازی 1. مار ساده

  • سکو: ویندوز (تست شده روی ویندوز 7، 10)
  • زبان: فکر کنم با C خالص نوشتم
  • موتور بازی: کنسول ویندوز
  • الهام: javidx9
  • مخزن: GitHub

DevOps C++ و «جنگ آشپزخانه»، یا چگونه شروع کردم به نوشتن بازی در حین غذا خوردن
بازی مار ساده

صحنه سه بعدی یک بازی نیست. علاوه بر این، مدل سازی و متحرک سازی اشیاء سه بعدی (به ویژه شخصیت ها) زمان بر و دشوار است. پس از بازی با یونیتی، متوجه شدم که باید ادامه دهم، یا بهتر است بگویم، از اصول اولیه شروع کنم. چیزی ساده و سریع، اما در عین حال جهانی، برای درک ساختار بازی ها.

ساده و سریع چیست؟ درست است، کنسول و دو بعدی. به طور دقیق تر، حتی کنسول و نمادها. دوباره به دنبال الهام گرفتن در اینترنت رفتم (به طور کلی فکر می کنم اینترنت انقلابی ترین و خطرناک ترین اختراع قرن بیست و یکم است). من یک ویدیو از یک برنامه نویس که کنسول تتریس را ساخته بود، پیدا کردم. و در شباهت بازی او تصمیم گرفتم یک "مار" بسازم. از ویدیو در مورد دو چیز اساسی یاد گرفتم - حلقه بازی (با سه عملکرد/بخش اصلی) و خروجی به بافر.

حلقه بازی ممکن است چیزی شبیه به این باشد:

int main()
   {
      Setup();
      // a game loop
      while (!quit)
      {
          Input();
          Logic();
          Draw();
          Sleep(gameSpeed);  // game timing
      }
      return 0;
   }

کد کل تابع main() را به یکباره ارائه می دهد. و چرخه بازی پس از نظر مناسب شروع می شود. سه تابع اصلی در حلقه وجود دارد: Input()، Logic()، Draw(). ابتدا داده های ورودی را وارد می کنیم (عمدتاً کنترل ضربه های کلید)، سپس منطق داده های وارد شده را پردازش می کنیم، سپس خروجی را به صفحه نمایش می دهیم - Draw. و به همین ترتیب در هر قاب. انیمیشن به این صورت ساخته می شود. مثل کارتون هاست به طور معمول، پردازش داده های وارد شده بیشترین زمان را می گیرد و تا آنجا که من می دانم، نرخ فریم بازی را تعیین می کند. اما در اینجا تابع Logic() خیلی سریع اجرا می شود. بنابراین، شما باید با استفاده از تابع Sleep() با پارامتر gameSpeed ​​که این سرعت را تعیین می کند، نرخ فریم را کنترل کنید.

DevOps C++ و «جنگ آشپزخانه»، یا چگونه شروع کردم به نوشتن بازی در حین غذا خوردن
چرخه بازی. برنامه نویسی "مار" در یک دفترچه یادداشت

اگر در حال توسعه یک بازی کنسول مبتنی بر کاراکتر هستید، نمی‌توانید با استفاده از خروجی جریان معمولی «cout» داده‌ها را به صفحه نمایش ارسال کنید - بسیار کند است. بنابراین خروجی باید به بافر صفحه نمایش ارسال شود. این بسیار سریعتر است و بازی بدون اشکال اجرا می شود. صادقانه بگویم، من دقیقاً نمی دانم بافر صفحه نمایش چیست و چگونه کار می کند. اما من در اینجا یک کد مثال می زنم و شاید کسی بتواند در نظرات وضعیت را روشن کند.

دریافت بافر صفحه نمایش (به اصطلاح):

// create screen buffer for drawings
   HANDLE hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0,
 							   NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
   DWORD dwBytesWritten = 0;
   SetConsoleActiveScreenBuffer(hConsole);

نمایش مستقیم یک خط امتیاز رشته خاص (خط نمایش امتیاز):

// draw the score
   WriteConsoleOutputCharacter(hConsole, scoreLine, GAME_WIDTH, {2,3}, &dwBytesWritten);

از نظر تئوری، هیچ چیز پیچیده ای در این بازی وجود ندارد؛ به نظر من یک نمونه ابتدایی خوب است. کد در یک فایل نوشته شده و در چندین تابع فرمت شده است. بدون کلاس، بدون ارث. با رفتن به مخزن در GitHub می توانید همه چیز را در سورس کد بازی مشاهده کنید.

بازی 2. تانک های دیوانه

DevOps C++ و «جنگ آشپزخانه»، یا چگونه شروع کردم به نوشتن بازی در حین غذا خوردن
بازی تانک های دیوانه

چاپ کاراکترها روی کنسول احتمالا ساده ترین چیزی است که می توانید به یک بازی تبدیل کنید. اما پس از آن یک مشکل ظاهر می شود: نمادها ارتفاع و عرض متفاوتی دارند (ارتفاع بیشتر از عرض است). به این ترتیب، همه چیز نامتناسب به نظر می رسد و حرکت به سمت پایین یا بالا بسیار سریعتر از حرکت به چپ یا راست به نظر می رسد. این تاثیر در Snake (بازی 1) بسیار محسوس است. "Tanks" (بازی 2) این اشکال را ندارد، زیرا خروجی در آنجا از طریق رنگ آمیزی پیکسل های صفحه نمایش با رنگ های مختلف سازماندهی می شود. می توان گفت من یک رندر نوشتم. درست است، این کمی پیچیده تر است، اگرچه بسیار جالب تر است.

برای این بازی، توضیح سیستم من برای نمایش پیکسل ها روی صفحه کافی است. من این را بخش اصلی بازی می دانم. و شما می توانید همه چیز را خودتان به دست آورید.

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

DevOps C++ و «جنگ آشپزخانه»، یا چگونه شروع کردم به نوشتن بازی در حین غذا خوردن
مجموعه ای از مستطیل

هر مستطیل با یک ماتریس پر از اعداد نشان داده می شود. به هر حال، من می توانم یک نکته جالب توجه را برجسته کنم - همه ماتریس های بازی به عنوان یک آرایه یک بعدی برنامه ریزی شده اند. نه دو بعدی بلکه تک بعدی! کار با آرایه های یک بعدی بسیار ساده تر و سریعتر است.

DevOps C++ و «جنگ آشپزخانه»، یا چگونه شروع کردم به نوشتن بازی در حین غذا خوردن
نمونه ای از ماتریس مخزن بازی

DevOps C++ و «جنگ آشپزخانه»، یا چگونه شروع کردم به نوشتن بازی در حین غذا خوردن
نمایش ماتریس مخزن بازی به صورت یک آرایه تک بعدی

DevOps C++ و «جنگ آشپزخانه»، یا چگونه شروع کردم به نوشتن بازی در حین غذا خوردن
یک مثال بصری تر از نمایش یک ماتریس به عنوان یک آرایه یک بعدی

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

DevOps C++ و «جنگ آشپزخانه»، یا چگونه شروع کردم به نوشتن بازی در حین غذا خوردن
عبور از یک آرایه یک بعدی در یک حلقه دوتایی. Y - شناسه ردیف، X - شناسه ستون

لطفا توجه داشته باشید: به جای شناسه های ماتریس معمولی i، j، از شناسه های x و y استفاده می کنم. به این ترتیب، به نظر من، برای چشم خوشایندتر و برای مغز قابل درک تر است. علاوه بر این، چنین نمادگذاری این امکان را فراهم می کند که به راحتی ماتریس های مورد استفاده را بر روی محورهای مختصات یک تصویر دو بعدی قرار دهید.

اکنون در مورد پیکسل، رنگ و خروجی صفحه نمایش. تابع StretchDIBits برای خروجی استفاده می شود (Header: windows.h؛ Library: gdi32.lib). این تابع، از جمله موارد زیر را دریافت می کند: دستگاهی که تصویر روی آن نمایش داده می شود (در مورد من، کنسول ویندوز است)، مختصات شروع نمایش تصویر، عرض/ارتفاع آن، و خود تصویر در شکل یک بیت مپ که با آرایه ای از بایت ها نمایش داده می شود. بیت مپ به عنوان یک آرایه بایت!

تابع StretchDIBits() در عمل:

// screen output for game field
   StretchDIBits(
               deviceContext,
               OFFSET_LEFT, OFFSET_TOP,
               PMATRIX_WIDTH, PMATRIX_HEIGHT,
               0, 0,
               PMATRIX_WIDTH, PMATRIX_HEIGHT,
               m_p_bitmapMemory, &bitmapInfo,
               DIB_RGB_COLORS,
               SRCCOPY
               );

حافظه از قبل با استفاده از تابع VirtualAlloc () برای این بیت مپ تخصیص داده می شود. یعنی تعداد مورد نیاز بایت برای ذخیره اطلاعات مربوط به تمام پیکسل ها رزرو می شود که سپس روی صفحه نمایش داده می شود.

ایجاد bitmap m_p_bitmapMemory:

// create bitmap
   int bitmapMemorySize = (PMATRIX_WIDTH * PMATRIX_HEIGHT) * BYTES_PER_PIXEL;
   void* m_p_bitmapMemory = VirtualAlloc(0, bitmapMemorySize, MEM_COMMIT, PAGE_READWRITE);

به طور کلی، یک بیت مپ از مجموعه ای از پیکسل ها تشکیل شده است. هر چهار بایت در آرایه یک پیکسل RGB است. یک بایت به ازای هر مقدار رنگ قرمز، یک بایت به ازای هر مقدار رنگ سبز (G) و یک بایت در هر مقدار رنگ آبی (B). به علاوه یک بایت برای تورفتگی باقی مانده است. این سه رنگ - قرمز/سبز/آبی (RGB) - به نسبت های مختلف با یکدیگر مخلوط می شوند تا رنگ پیکسل حاصل را ایجاد کنند.

اکنون، دوباره، هر مستطیل یا شی بازی، با یک ماتریس عددی نشان داده می شود. همه این اشیاء بازی در یک مجموعه قرار می گیرند. و سپس آنها در زمین بازی قرار می گیرند و یک ماتریس عددی بزرگ را تشکیل می دهند. من هر عدد در ماتریس را با یک رنگ خاص مرتبط کردم. به عنوان مثال، عدد 8 با آبی، عدد 9 به زرد، عدد 10 به خاکستری تیره و غیره مربوط می شود. بنابراین، می توان گفت که ما یک ماتریس از زمین بازی داریم که در آن هر عدد یک رنگ است.

بنابراین، ما یک ماتریس عددی از کل زمین بازی در یک طرف و یک بیت مپ برای نمایش تصویر در طرف دیگر داریم. تا کنون، بیت مپ "خالی" است - هنوز اطلاعاتی در مورد پیکسل های رنگ مورد نظر ندارد. این بدان معنی است که آخرین مرحله پر کردن بیت مپ با اطلاعات مربوط به هر پیکسل بر اساس ماتریس عددی زمین بازی خواهد بود. نمونه بارز چنین تحولی در تصویر زیر است.

DevOps C++ و «جنگ آشپزخانه»، یا چگونه شروع کردم به نوشتن بازی در حین غذا خوردن
نمونه ای از پر کردن یک بیت مپ (ماتریس پیکسل) با اطلاعات مبتنی بر ماتریس دیجیتالی زمین بازی (شاخص های رنگ با شاخص های بازی مطابقت ندارند)

من همچنین یک قطعه کد واقعی از بازی را ارائه خواهم کرد. به متغیر colorIndex در هر تکرار حلقه یک مقدار (شاخص رنگ) از ماتریس عددی زمین بازی (mainDigitalMatrix) اختصاص داده می شود. سپس متغیر رنگ بر اساس شاخص روی خود رنگ تنظیم می شود. سپس رنگ حاصل به نسبت قرمز، سبز و آبی (RGB) تقسیم می شود. و همراه با pixelPadding، این اطلاعات بارها و بارها در پیکسل نوشته می شود و یک تصویر رنگی در بیت مپ تشکیل می دهد.

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

پر کردن بیت مپ با اطلاعات بر اساس ماتریس عددی زمین بازی:

// set pixel map variables
   int colorIndex;
   COLORREF color;
   int pitch;
   uint8_t* p_row;
 
   // arrange pixels for game field
   pitch = PMATRIX_WIDTH * BYTES_PER_PIXEL;     // row size in bytes
   p_row = (uint8_t*)m_p_bitmapMemory;       //cast to uint8 for valid pointer arithmetic
   							(to add by 1 byte (8 bits) at a time)   
   for (int y = 0; y < PMATRIX_HEIGHT; ++y)
   {
       uint32_t* p_pixel = (uint32_t*)p_row;
       for (int x = 0; x < PMATRIX_WIDTH; ++x)
       {
           colorIndex = mainDigitalMatrix[y * PMATRIX_WIDTH + x];
           color = Utils::GetColor(colorIndex);
           uint8_t blue = GetBValue(color);
           uint8_t green = GetGValue(color);
           uint8_t red = GetRValue(color);
           uint8_t pixelPadding = 0;
 
           *p_pixel = ((pixelPadding << 24) | (red << 16) | (green << 8) | blue);
           ++p_pixel;
       }
       p_row += pitch;
   }

با توجه به روشی که در بالا توضیح داده شد، در بازی Crazy Tanks یک تصویر (فریم) در تابع Draw() تشکیل شده و بر روی صفحه نمایش داده می شود. پس از ثبت ضربات کلید در تابع Input() و پردازش بعدی آنها در تابع Logic() یک تصویر (فریم) جدید تشکیل می شود. درست است، اشیاء بازی ممکن است در حال حاضر موقعیت متفاوتی در زمین بازی داشته باشند و بر این اساس، در مکان دیگری کشیده شوند. به این ترتیب انیمیشن (حرکت) اتفاق می افتد.

در تئوری (اگر چیزی را فراموش نکرده باشم)، درک حلقه بازی از بازی اول ("Snake") و سیستم نمایش پیکسل ها روی صفحه نمایش از بازی دوم ("Tanks") تنها چیزی است که برای نوشتن نیاز دارید. از بازی های دو بعدی شما تحت ویندوز. بی صدا! 😉 مابقی قسمت ها فقط یک پرواز خیالی است.

البته بازی "Tanks" بسیار پیچیده تر از "Snake" است. من قبلا از زبان C++ استفاده کردم، یعنی اشیاء مختلف بازی را با کلاس ها توصیف کردم. من مجموعه خود را ایجاد کردم - کد را می توان در headers/Box.h مشاهده کرد. به هر حال، مجموعه به احتمال زیاد دارای نشت حافظه است. اشاره گرهای استفاده شده با حافظه کار کرد باید بگویم که کتاب خیلی به من کمک کرد شروع C++ از طریق برنامه نویسی بازی. این یک شروع عالی برای مبتدیان در C++ است. کوچک، جالب و به خوبی سازماندهی شده است.

ساخت این بازی حدود شش ماه طول کشید. من عمدتا در هنگام ناهار و میان وعده در محل کار می نوشتم. او در آشپزخانه دفتر نشست، غذا را زیر پا گذاشت و کد نوشت. یا هنگام شام در خانه. بنابراین من با این "جنگ های آشپزخانه" به پایان رسیدم. مثل همیشه، من فعالانه از یک دفترچه استفاده کردم و همه چیزهای مفهومی در آن متولد شدند.

برای تکمیل قسمت عملی، چند اسکن از نوت بوکم می گیرم. برای اینکه نشان دهم دقیقا چه چیزی را یادداشت کردم، ترسیم کردم، شمردم، طراحی کردم...

DevOps C++ و «جنگ آشپزخانه»، یا چگونه شروع کردم به نوشتن بازی در حین غذا خوردن
طراحی تصاویر تانک. و تعیین اینکه هر مخزن چند پیکسل روی صفحه باید اشغال کند

DevOps C++ و «جنگ آشپزخانه»، یا چگونه شروع کردم به نوشتن بازی در حین غذا خوردن
محاسبه الگوریتم و فرمول چرخش مخزن حول محور آن

DevOps C++ و «جنگ آشپزخانه»، یا چگونه شروع کردم به نوشتن بازی در حین غذا خوردن
طرح مجموعه من (به احتمال زیاد، طرحی که در آن نشت حافظه وجود دارد). مجموعه بر اساس نوع لیست پیوندی ایجاد می شود

DevOps C++ و «جنگ آشپزخانه»، یا چگونه شروع کردم به نوشتن بازی در حین غذا خوردن
و اینها تلاش های بیهوده ای برای پیوستن هوش مصنوعی به بازی است

Теория

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

از عمل به تئوری برویم! چگونه برای سرگرمی خود وقت پیدا کنیم؟

  1. تعیین کنید که واقعاً چه می خواهید (افسوس، این سخت ترین قسمت است).
  2. اولویت ها را تعیین کنید.
  3. همه چیز "اضافی" را به خاطر اولویت های بالاتر قربانی کنید.
  4. هر روز به سمت اهداف حرکت کنید.
  5. انتظار نداشته باشید دو یا سه ساعت وقت آزاد خود را صرف یک سرگرمی کنید.

از یک طرف، باید تعیین کنید که چه چیزی می خواهید و اولویت بندی کنید. از سوی دیگر، می توان برخی از فعالیت ها/پروژه ها را به نفع این اولویت ها کنار گذاشت. به عبارت دیگر، شما باید همه چیز "اضافی" را قربانی کنید. جایی شنیدم که در زندگی باید حداکثر سه فعالیت اصلی وجود داشته باشد. سپس می توانید آنها را با بالاترین کیفیت انجام دهید. و پروژه‌ها/جهت‌های اضافی به سادگی شروع به بارگیری خواهند کرد. اما همه اینها احتمالاً ذهنی و فردی است.

یک قانون طلایی وجود دارد: هرگز یک روز 0% نداشته باشید! من در مورد آن در مقاله ای توسط یک توسعه دهنده مستقل یاد گرفتم. اگر روی پروژه ای کار می کنید، هر روز کاری در مورد آن انجام دهید. و مهم نیست که چقدر انجام می دهید. یک کلمه یا یک خط کد بنویسید، یک ویدیوی آموزشی تماشا کنید یا یک میخ را به تخته بکوبید - فقط کاری انجام دهید. سخت ترین کار شروع کردن است. پس از شروع، احتمالاً در نهایت کمی بیشتر از آنچه می خواستید انجام خواهید داد. به این ترتیب مدام به سمت هدف خود و باور کنید خیلی سریع حرکت خواهید کرد. به هر حال، مانع اصلی همه کارها به تعویق انداختن کار است.

و مهم است که به یاد داشته باشید که نباید "خاک اره" رایگان زمان 5، 10، 15 دقیقه را دست کم بگیرید و نادیده بگیرید، منتظر چند "الوار" بزرگ باشید که یک یا دو ساعت طول می کشد. آیا در صف ایستاده اید؟ به چیزی برای پروژه خود فکر کنید. سوار شدن به پله برقی؟ چیزی را در دفترچه یادداشت بنویسید. آیا با اتوبوس سفر می کنید؟ عالی، یک مقاله بخوانید از هر فرصتی استفاده کنید. تماشای سگ‌ها و گربه‌ها را در YouTube متوقف کنید! مغزتان را آلوده نکنید!

و یک چیز آخر اگر پس از خواندن این مقاله، ایده ساخت بازی بدون استفاده از موتورهای بازی را دوست داشتید، نام کیسی موراتوری را به خاطر بسپارید. این پسر دارد سایت اینترنتی. در بخش "تماشا -> قسمت های قبلی" آموزش های ویدیویی رایگان فوق العاده ای در مورد ایجاد یک بازی حرفه ای از ابتدا پیدا خواهید کرد. در پنج درس Intro to C for Windows احتمالاً بیشتر از پنج سال تحصیل در دانشگاه خواهید آموخت (کسی در این مورد در نظرات زیر ویدیو نوشته است).

کیسی همچنین توضیح می دهد که با توسعه موتور بازی خود، درک بهتری از موتورهای موجود خواهید داشت. در دنیایی از چارچوب‌هایی که همه در تلاش برای خودکارسازی هستند، شما یاد می‌گیرید به جای استفاده، ایجاد کنید. شما ماهیت کامپیوترها را درک می کنید. و همچنین به یک برنامه نویس بسیار باهوش تر و بالغ تبدیل خواهید شد - یک حرفه ای.

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

نویسنده: گرانکین آندری، DevOps



منبع: www.habr.com