DevOps C++ và "cuộc chiến nhà bếp" hay Tôi đã bắt đầu viết game trong khi ăn như thế nào

“Tôi biết rằng tôi không biết gì cả” Socrates

Dành cho ai: dành cho dân CNTT không quan tâm đến tất cả các nhà phát triển và muốn chơi trò chơi của họ!

Về cái gì: về cách bắt đầu viết trò chơi bằng C/C++, nếu bạn đột nhiên cần đến nó!

Tại sao bạn nên đọc cái này: Phát triển ứng dụng không phải là lĩnh vực chuyên môn của tôi nhưng tôi cố gắng viết mã mỗi tuần. Vì tôi yêu game!

xin chao tên tôi la Andrey Grankin, Tôi là DevOps tại Luxoft. Phát triển ứng dụng không phải là chuyên môn của tôi nhưng tôi cố gắng viết mã hàng tuần. Vì tôi yêu game!

Ngành công nghiệp game trên máy tính rất lớn, được đồn đại là còn lớn hơn cả ngành điện ảnh ngày nay. Trò chơi đã được viết từ buổi bình minh của máy tính, sử dụng các phương pháp phát triển cơ bản và phức tạp theo tiêu chuẩn hiện đại. Theo thời gian, các công cụ trò chơi với đồ họa, vật lý và âm thanh đã được lập trình sẵn bắt đầu xuất hiện. Chúng cho phép bạn tập trung vào việc phát triển trò chơi và không phải lo lắng về nền tảng của nó. Nhưng cùng với chúng, với động cơ, các nhà phát triển “mù quáng” và xuống cấp. Bản thân việc sản xuất trò chơi được đưa lên băng chuyền. Và số lượng sản phẩm bắt đầu chiếm ưu thế hơn chất lượng của nó.

Đồng thời, khi chơi trò chơi của người khác, chúng ta liên tục bị giới hạn bởi địa điểm, cốt truyện, nhân vật và cơ chế trò chơi mà người khác nghĩ ra. Thế là tôi nhận ra rằng...

... đã đến lúc tạo ra thế giới của riêng tôi, chỉ thuộc về tôi. Những thế giới nơi Ta là Chúa Cha, Chúa Con và Chúa Thánh Thần!

Và tôi chân thành tin rằng bằng cách viết game engine của riêng mình và chơi trên đó, bạn sẽ có thể cởi giày, lau cửa sổ và nâng cấp cabin của mình, trở thành một lập trình viên giàu kinh nghiệm và hoàn thiện hơn.

Trong bài viết này, tôi sẽ cố gắng kể cho bạn biết tôi đã bắt đầu viết các trò chơi nhỏ bằng C/C++ như thế nào, quá trình phát triển diễn ra như thế nào và tôi tìm thấy thời gian cho sở thích ở đâu trong một môi trường bận rộn. Nó mang tính chủ quan và mô tả quá trình khởi đầu của một cá nhân. Tài liệu về sự ngu dốt và niềm tin, về bức tranh cá nhân của tôi về thế giới lúc này. Nói cách khác, "Chính quyền không chịu trách nhiệm về bộ não cá nhân của bạn!"

Tập luyện

“Biết mà không hành thì vô ích, hành mà không biết thì nguy hiểm” Khổng Tử

Cuốn sổ của tôi là cuộc sống của tôi!


Vì vậy, trong thực tế, tôi có thể nói rằng đối với tôi mọi thứ đều bắt đầu bằng một cuốn sổ ghi chú. Tôi không chỉ viết ra các công việc hàng ngày của mình ở đó mà còn vẽ, lập trình, thiết kế sơ đồ và giải quyết các vấn đề, bao gồm cả các vấn đề toán học. Luôn sử dụng sổ ghi chú và chỉ viết bằng bút chì. Nó sạch sẽ, tiện lợi và đáng tin cậy, IMHO.

DevOps C++ và "cuộc chiến nhà bếp" hay Tôi đã bắt đầu viết game trong khi ăn như thế nào
Sổ ghi chép (đã đầy) của tôi. Đây là những gì anh ấy trông giống như. Nó chứa các công việc hàng ngày, ý tưởng, bản vẽ, sơ đồ, giải pháp, sổ sách đen, mã, v.v.

Ở giai đoạn này, tôi đã hoàn thành được ba dự án (theo hiểu biết của tôi về “sự hoàn thiện”, bởi vì bất kỳ sản phẩm nào cũng có thể được phát triển tương đối vô tận).

  • Dự án 0: Đây là cảnh Demo Kiến trúc sư 3D được viết bằng C# bằng công cụ trò chơi Unity. Dành cho nền tảng macOS và Windows.
  • Trò chơi 1: trò chơi console Simple Snake (được mọi người gọi là “Snake”) dành cho Windows. Viết bằng C
  • Trò chơi 2: trò chơi console Crazy Tanks (được mọi người gọi là “Tanks”), được viết bằng C++ (sử dụng các lớp) và cả cho Windows.

Dự án 0. Demo kiến ​​trúc sư

  • Nền tảng: Windows (Windows 7, 10), Mac OS (OS X El Capitan v. 10.11.6)
  • Lưỡi: C#
  • Công cụ trò chơi: Unity
  • Nguồn cảm hứng: Darrin Lile
  • Kho: GitHub

DevOps C++ và "cuộc chiến nhà bếp" hay Tôi đã bắt đầu viết game trong khi ăn như thế nào
Bản trình diễn kiến ​​trúc cảnh 3D

Dự án đầu tiên được triển khai không phải bằng C/C++ mà bằng C# bằng cách sử dụng công cụ trò chơi Unity. Công cụ này không đòi hỏi nhiều về phần cứng như Unreal Enginevà dường như cũng dễ cài đặt và sử dụng hơn. Tôi đã không xem xét các động cơ khác.

Mục tiêu của tôi ở Unity không phải là phát triển trò chơi. Tôi muốn tạo một cảnh 3D với một số nhân vật. Anh ấy, hay đúng hơn là Cô ấy (tôi làm mẫu cho cô gái tôi yêu =) phải di chuyển và tương tác với thế giới xung quanh. Điều quan trọng là phải hiểu Unity là gì, quá trình phát triển là gì và cần bao nhiêu nỗ lực để tạo ra thứ gì đó. Đây là cách dự án Architect Demo ra đời (cái tên gần như được phát minh ra một cách bất ngờ). Việc lập trình, tạo mô hình, hoạt hình, tạo họa tiết có lẽ khiến tôi mất hai tháng làm việc hàng ngày.

Tôi bắt đầu với các video hướng dẫn trên YouTube về cách tạo mô hình 3D trong Máy xay sinh tố. Blender là một công cụ miễn phí tuyệt vời để tạo mô hình 3D (và hơn thế nữa) mà không cần cài đặt. Và ở đây một cú sốc đang chờ đợi tôi... Hóa ra mô hình hóa, hoạt hình, kết cấu là những chủ đề riêng biệt lớn mà bạn có thể viết sách. Điều này đặc biệt đúng với các nhân vật. Để tạo mô hình ngón tay, răng, mắt và các bộ phận cơ thể khác, bạn sẽ cần kiến ​​thức về giải phẫu. Các cơ mặt có cấu tạo như thế nào? Mọi người di chuyển bằng cách nào? Tôi đã phải “nhét” xương vào từng cánh tay, chân, ngón tay, đốt ngón tay!

Mô hình hóa xương đòn và xương đòn bổ sung để làm cho hoạt ảnh trông tự nhiên. Sau những bài học như vậy, bạn nhận ra rằng những người sáng tạo phim hoạt hình đã phải làm bao nhiêu công việc chỉ để tạo ra một đoạn video dài 30 giây. Nhưng phim 3D kéo dài hàng giờ! Và sau đó chúng tôi rời rạp chiếu phim và nói những điều như: “Đó là một bộ phim hoạt hình/phim tào lao! Lẽ ra họ có thể làm tốt hơn..." Đồ ngu!

Và một điều nữa liên quan đến lập trình trong dự án này. Hóa ra, phần thú vị nhất đối với tôi là phần toán học. Nếu bạn chạy cảnh (liên kết đến kho lưu trữ trong mô tả dự án), bạn sẽ nhận thấy rằng camera quay xung quanh nhân vật cô gái trong một quả cầu. Để lập trình cách quay camera như vậy, trước tiên tôi phải tính tọa độ của điểm vị trí trên hình tròn (2D), sau đó trên hình cầu (3D). Điều buồn cười là ở trường tôi ghét môn toán và chỉ biết môn này với điểm C trừ. Có lẽ một phần là vì ở trường họ không giải thích cho bạn cách áp dụng phép toán này vào cuộc sống. Nhưng khi bạn bị ám ảnh bởi mục tiêu, ước mơ của mình, tâm trí bạn sẽ sáng suốt và rộng mở hơn! Và bạn bắt đầu cảm nhận những nhiệm vụ khó khăn như một cuộc phiêu lưu thú vị. Và sau đó bạn nghĩ: “Chà, tại sao nhà toán học *yêu thích* của bạn không thể nói cho bạn biết những công thức này có thể được áp dụng ở đâu một cách bình thường?”

DevOps C++ và "cuộc chiến nhà bếp" hay Tôi đã bắt đầu viết game trong khi ăn như thế nào
Tính công thức tính tọa độ của một điểm trên đường tròn và trên hình cầu (từ sổ tay của tôi)

Trò chơi 1. Rắn đơn giản

  • Nền tảng: Windows (đã thử nghiệm trên Windows 7, 10)
  • Lưỡi: Tôi nghĩ tôi đã viết nó bằng C thuần túy
  • Công cụ trò chơi: Bảng điều khiển Windows
  • Nguồn cảm hứng: javidx9
  • Kho: GitHub

DevOps C++ và "cuộc chiến nhà bếp" hay Tôi đã bắt đầu viết game trong khi ăn như thế nào
Trò chơi rắn đơn giản

Cảnh 3D không phải là trò chơi. Ngoài ra, việc tạo mô hình và tạo hoạt ảnh cho các vật thể 3D (đặc biệt là các nhân vật) rất tốn thời gian và khó khăn. Sau khi thử nghiệm với Unity, tôi nhận ra rằng mình cần phải tiếp tục, hay đúng hơn là bắt đầu, từ những điều cơ bản. Một cái gì đó đơn giản và nhanh chóng, nhưng đồng thời mang tính toàn cầu, để hiểu chính cấu trúc của trò chơi.

Thế nào là đơn giản và nhanh chóng? Đúng vậy, console và 2D. Chính xác hơn là ngay cả bảng điều khiển và các biểu tượng. Một lần nữa tôi lại đi tìm cảm hứng trên Internet (nói chung, tôi nghĩ Internet là phát minh mang tính cách mạng và nguy hiểm nhất thế kỷ XNUMX). Tôi tìm được một đoạn video về một lập trình viên đã tạo ra bảng điều khiển Tetris. Và để giống với trò chơi của anh ấy, tôi quyết định làm một con “con rắn”. Từ video, tôi đã học được hai điều cơ bản - vòng lặp trò chơi (với ba chức năng/phần cơ bản) và đầu ra tới bộ đệm.

Vòng lặp trò chơi có thể trông giống như thế này:

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

Mã trình bày toàn bộ hàm main() cùng một lúc. Và chu kỳ trò chơi bắt đầu sau nhận xét thích hợp. Có ba hàm cơ bản trong vòng lặp: input(), logic(), draw(). Đầu tiên là nhập dữ liệu vào (chủ yếu là điều khiển thao tác gõ phím), sau đó xử lý dữ liệu nhập vào Logic, sau đó xuất ra màn hình - Draw. Và như vậy trên mọi khung hình. Đây là cách hoạt hình được tạo ra. Nó giống như trong phim hoạt hình. Thông thường, việc xử lý dữ liệu đã nhập mất nhiều thời gian nhất và theo như tôi biết, nó quyết định tốc độ khung hình của trò chơi. Nhưng ở đây hàm Logic() thực thi rất nhanh. Do đó, bạn phải kiểm soát tốc độ khung hình bằng hàm Sleep() với tham số gameSpeed, thông số này xác định tốc độ này.

DevOps C++ và "cuộc chiến nhà bếp" hay Tôi đã bắt đầu viết game trong khi ăn như thế nào
Chu kỳ trò chơi. Lập trình “con rắn” trong notepad

Nếu bạn đang phát triển trò chơi console dựa trên nhân vật, bạn sẽ không thể xuất dữ liệu ra màn hình bằng đầu ra luồng 'cout' thông thường - tốc độ rất chậm. Vì vậy, đầu ra phải được gửi đến bộ đệm màn hình. Điều này nhanh hơn nhiều và trò chơi sẽ chạy mà không gặp trục trặc. Thành thật mà nói, tôi hoàn toàn không hiểu bộ đệm màn hình là gì và nó hoạt động như thế nào. Nhưng tôi sẽ đưa ra một ví dụ về mã ở đây và có lẽ ai đó có thể làm rõ tình huống này trong phần bình luận.

Lấy bộ đệm màn hình (có thể nói):

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

Hiển thị trực tiếp một chuỗi nhất định ScoreLine (dòng hiển thị điểm):

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

Về lý thuyết, trò chơi này không có gì phức tạp; tôi nghĩ đây là một ví dụ hay dành cho người mới bắt đầu. Mã được viết trong một tệp và được định dạng theo một số chức năng. Không có lớp học, không có sự kế thừa. Bạn có thể tự mình xem mọi thứ trong mã nguồn của trò chơi bằng cách truy cập kho lưu trữ trên GitHub.

Trò chơi 2. Xe tăng điên

DevOps C++ và "cuộc chiến nhà bếp" hay Tôi đã bắt đầu viết game trong khi ăn như thế nào
trò chơi Xe tăng điên

In các ký tự ra bảng điều khiển có lẽ là điều đơn giản nhất bạn có thể biến thành một trò chơi. Nhưng sau đó một vấn đề xuất hiện: các biểu tượng có chiều cao và chiều rộng khác nhau (chiều cao lớn hơn chiều rộng). Bằng cách này, mọi thứ sẽ trông không cân xứng và việc di chuyển xuống hoặc lên sẽ xuất hiện nhanh hơn nhiều so với di chuyển sang trái hoặc phải. Hiệu ứng này rất dễ nhận thấy trong Snake (Game 1). “Xe tăng” (Trò chơi 2) không có nhược điểm này, vì đầu ra ở đó được sắp xếp thông qua việc vẽ các pixel màn hình bằng các màu khác nhau. Bạn có thể nói tôi đã viết một trình kết xuất. Đúng, điều này phức tạp hơn một chút, mặc dù thú vị hơn nhiều.

Đối với trò chơi này, chỉ cần mô tả hệ thống hiển thị pixel trên màn hình của tôi là đủ. Tôi coi đây là phần chính của trò chơi. Và bạn có thể tự mình nghĩ ra mọi thứ khác.

Vì vậy, những gì bạn nhìn thấy trên màn hình chỉ là một tập hợp các hình chữ nhật nhiều màu chuyển động.

DevOps C++ và "cuộc chiến nhà bếp" hay Tôi đã bắt đầu viết game trong khi ăn như thế nào
Bộ hình chữ nhật

Mỗi hình chữ nhật được biểu diễn bằng một ma trận chứa đầy các số. Nhân tiện, tôi có thể làm nổi bật một sắc thái thú vị - tất cả các ma trận trong trò chơi đều được lập trình dưới dạng mảng một chiều. Không phải hai chiều, mà là một chiều! Mảng một chiều làm việc dễ dàng và nhanh hơn nhiều.

DevOps C++ và "cuộc chiến nhà bếp" hay Tôi đã bắt đầu viết game trong khi ăn như thế nào
Ví dụ về ma trận xe tăng trò chơi

DevOps C++ và "cuộc chiến nhà bếp" hay Tôi đã bắt đầu viết game trong khi ăn như thế nào
Biểu diễn ma trận xe tăng trò chơi dưới dạng mảng một chiều

DevOps C++ và "cuộc chiến nhà bếp" hay Tôi đã bắt đầu viết game trong khi ăn như thế nào
Một ví dụ trực quan hơn về việc biểu diễn ma trận dưới dạng mảng một chiều

Nhưng việc truy cập vào các phần tử của mảng xảy ra theo một vòng lặp kép, như thể đó không phải là mảng một chiều mà là mảng hai chiều. Điều này được thực hiện bởi vì chúng ta vẫn làm việc với ma trận.

DevOps C++ và "cuộc chiến nhà bếp" hay Tôi đã bắt đầu viết game trong khi ăn như thế nào
Duyệt mảng một chiều bằng vòng lặp kép. Y - mã định danh hàng, X - mã định danh cột

Xin lưu ý: thay vì các định danh ma trận thông thường i, j, tôi sử dụng các định danh x và y. Theo tôi, cách này có vẻ dễ chịu hơn và dễ hiểu hơn đối với não. Ngoài ra, ký hiệu như vậy giúp có thể chiếu các ma trận được sử dụng lên các trục tọa độ của hình ảnh hai chiều một cách thuận tiện.

Bây giờ về pixel, màu sắc và đầu ra màn hình. Hàm StretchDIBits được sử dụng cho đầu ra (Tiêu đề: windows.h; Thư viện: gdi32.lib). Chức năng này, trong số những thứ khác, nhận được những thông tin sau: thiết bị hiển thị hình ảnh (trong trường hợp của tôi, đó là bảng điều khiển Windows), tọa độ bắt đầu của màn hình hiển thị hình ảnh, chiều rộng/chiều cao của nó và chính hình ảnh đó trong dạng bitmap, được biểu thị bằng một mảng byte. Bitmap dưới dạng mảng byte!

Chức năng StretchDIBits() đang hoạt động:

// 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
               );

Bộ nhớ được phân bổ trước cho bitmap này bằng hàm VirtualAlloc(). Nghĩa là, số byte cần thiết được dành riêng để lưu trữ thông tin về tất cả các pixel, sau đó sẽ được hiển thị trên màn hình.

Tạo 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);

Nói một cách đại khái, một bitmap bao gồm một tập hợp các pixel. Cứ bốn byte trong mảng là một pixel RGB. Một byte cho mỗi giá trị màu đỏ, một byte cho mỗi giá trị màu xanh lục (G) và một byte cho mỗi giá trị màu xanh lam (B). Ngoài ra còn một byte để thụt lề. Ba màu này - Đỏ/Xanh lục/Xanh lam (RGB) - được trộn với nhau theo các tỷ lệ khác nhau để tạo ra màu pixel thu được.

Bây giờ, một lần nữa, mỗi hình chữ nhật hoặc đối tượng trò chơi được biểu thị bằng một ma trận số. Tất cả các đối tượng trò chơi này được đặt trong một bộ sưu tập. Và sau đó chúng được đặt trên sân chơi, tạo thành một ma trận số lớn. Tôi liên kết mỗi số trong ma trận với một màu cụ thể. Ví dụ: số 8 tương ứng với màu xanh lam, số 9 tương ứng với màu vàng, số 10 tương ứng với màu xám đậm, v.v. Vì vậy, chúng ta có thể nói rằng chúng ta có một ma trận sân chơi, trong đó mỗi số là một màu.

Vì vậy, chúng ta có một ma trận số của toàn bộ sân chơi ở một bên và một bitmap để hiển thị hình ảnh ở bên kia. Cho đến nay, bitmap vẫn "trống" - nó chưa chứa thông tin về các pixel có màu mong muốn. Điều này có nghĩa là bước cuối cùng sẽ là điền vào bitmap thông tin về từng pixel dựa trên ma trận số của sân chơi. Một ví dụ rõ ràng về sự chuyển đổi như vậy là trong hình dưới đây.

DevOps C++ và "cuộc chiến nhà bếp" hay Tôi đã bắt đầu viết game trong khi ăn như thế nào
Ví dụ về điền thông tin vào bitmap (Ma trận Pixel) dựa trên Ma trận kỹ thuật số của sân chơi (chỉ số màu không khớp với chỉ số trong trò chơi)

Tôi cũng sẽ trình bày một đoạn mã thực của trò chơi. Biến colorIndex tại mỗi lần lặp của vòng lặp được gán một giá trị (chỉ số màu) từ ma trận số của sân chơi (mainDigitalMatrix). Biến màu sau đó được đặt thành màu dựa trên chỉ mục. Màu thu được sau đó được chia thành tỷ lệ đỏ, lục và lam (RGB). Và cùng với pixelPadding, thông tin này được ghi đi ghi lại vào pixel, tạo thành hình ảnh màu trong bitmap.

Mã sử ​​dụng con trỏ và các phép toán theo bit, có thể khó hiểu. Vì vậy, tôi khuyên bạn nên đọc riêng ở đâu đó về cách thức hoạt động của các cấu trúc như vậy.

Điền vào bitmap thông tin dựa trên ma trận số của sân chơi:

// 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;
   }

Theo phương pháp được mô tả ở trên, trong trò chơi Crazy Tanks, một hình ảnh (khung) được hình thành và hiển thị trên màn hình theo chức năng Draw(). Sau khi đăng ký các lần nhấn phím trong hàm input() và quá trình xử lý tiếp theo của chúng trong hàm Logic(), một hình ảnh (khung) mới sẽ được hình thành. Đúng, các đối tượng trong trò chơi có thể đã có một vị trí khác trên sân chơi và do đó, được vẽ ở một vị trí khác. Đây là cách hoạt ảnh (chuyển động) diễn ra.

Về lý thuyết (nếu tôi không quên điều gì), việc hiểu vòng lặp trò chơi từ trò chơi đầu tiên (“Snake”) và hệ thống hiển thị pixel trên màn hình từ trò chơi thứ hai (“Tanks”) là tất cả những gì bạn cần để viết bất kỳ của các trò chơi 2D của bạn trong Windows. Không kêu! 😉 Những phần còn lại chỉ là tưởng tượng thôi.

Tất nhiên, trò chơi “Tanks” phức tạp hơn nhiều so với “Rắn”. Tôi đã sử dụng ngôn ngữ C++, nghĩa là tôi đã mô tả các đối tượng trò chơi khác nhau bằng các lớp. Tôi đã tạo bộ sưu tập của riêng mình - mã có thể được xem trong headers/Box.h. Nhân tiện, bộ sưu tập rất có thể đã bị rò rỉ bộ nhớ. Con trỏ được sử dụng Làm việc với bộ nhớ. Phải nói rằng cuốn sách đã giúp tôi rất nhiều Bắt đầu C++ thông qua lập trình trò chơi. Đây là một khởi đầu tuyệt vời cho người mới bắt đầu học C++. Nó nhỏ, thú vị và được tổ chức tốt.

Phải mất khoảng sáu tháng để phát triển trò chơi này. Tôi viết chủ yếu vào bữa trưa và bữa ăn nhẹ tại nơi làm việc. Anh ngồi trong bếp văn phòng, giẫm đạp đồ ăn và viết code. Hoặc vào bữa tối ở nhà. Vì vậy, tôi đã kết thúc với những “cuộc chiến nhà bếp” này. Như mọi khi, tôi chủ động sử dụng một cuốn sổ và tất cả những thứ mang tính khái niệm đều được sinh ra trong đó.

Để hoàn thành phần thực hành, tôi sẽ quét một vài cuốn sổ tay của mình. Để thể hiện chính xác những gì tôi đã viết ra, vẽ, đếm, thiết kế...

DevOps C++ và "cuộc chiến nhà bếp" hay Tôi đã bắt đầu viết game trong khi ăn như thế nào
Thiết kế hình ảnh xe tăng. Và xác định mỗi bể sẽ chiếm bao nhiêu pixel trên màn hình

DevOps C++ và "cuộc chiến nhà bếp" hay Tôi đã bắt đầu viết game trong khi ăn như thế nào
Tính toán thuật toán và công thức cho bể quay quanh trục của nó

DevOps C++ và "cuộc chiến nhà bếp" hay Tôi đã bắt đầu viết game trong khi ăn như thế nào
Sơ đồ bộ sưu tập của tôi (rất có thể là bộ sưu tập bị rò rỉ bộ nhớ). Bộ sưu tập được tạo theo kiểu Danh sách liên kết

DevOps C++ và "cuộc chiến nhà bếp" hay Tôi đã bắt đầu viết game trong khi ăn như thế nào
Và đây là những nỗ lực vô ích nhằm gắn trí tuệ nhân tạo vào game

Теория

“Cuộc hành trình ngàn dặm cũng bắt đầu từ bước đầu tiên” (Trí tuệ Trung Hoa cổ đại)

Hãy chuyển từ thực hành sang lý thuyết! Làm thế nào để tìm thời gian cho sở thích của bạn?

  1. Xác định những gì bạn thực sự muốn (than ôi, đây là phần khó nhất).
  2. Đặt ưu tiên.
  3. Hy sinh mọi thứ “thừa” vì những ưu tiên cao hơn.
  4. Hướng tới mục tiêu mỗi ngày.
  5. Đừng mong đợi hai hoặc ba giờ rảnh rỗi để dành cho một sở thích.

Một mặt, bạn cần xác định những gì bạn muốn và ưu tiên. Mặt khác, có thể từ bỏ một số hoạt động/dự án để tập trung vào những ưu tiên này. Nói cách khác, bạn sẽ phải hy sinh mọi thứ “thừa”. Tôi nghe ở đâu đó rằng cuộc sống chỉ nên có tối đa ba hoạt động chính. Sau đó, bạn sẽ có thể làm chúng với chất lượng cao nhất. Và các dự án/hướng đi bổ sung sẽ bắt đầu quá tải. Nhưng tất cả điều này có lẽ là chủ quan và cá nhân.

Có một nguyên tắc vàng nhất định: không bao giờ có ngày 0%! Tôi đã biết về nó trong một bài viết của một nhà phát triển độc lập. Nếu bạn đang thực hiện một dự án, hãy làm điều gì đó cho nó mỗi ngày. Và không quan trọng bạn làm được bao nhiêu. Viết một từ hoặc một dòng mã, xem một video hướng dẫn hoặc đóng một chiếc đinh vào bảng - chỉ cần làm điều gì đó. Điều khó nhất là bắt đầu. Một khi bạn bắt đầu, có thể bạn sẽ làm được nhiều hơn mức bạn mong muốn một chút. Bằng cách này, bạn sẽ liên tục tiến tới mục tiêu của mình và tin tôi đi, rất nhanh chóng. Suy cho cùng, trở ngại chính của mọi việc là sự trì hoãn.

Và điều quan trọng cần nhớ là bạn không nên đánh giá thấp và bỏ qua những “mùn cưa” miễn phí trong thời gian 5, 10, 15 phút, chờ đợi một số “khúc gỗ” lớn kéo dài một hoặc hai giờ. Bạn đang đứng xếp hàng à? Hãy suy nghĩ về một cái gì đó cho dự án của bạn. Đi thang cuốn? Viết điều gì đó vào sổ ghi chú. Bạn đang đi du lịch trên xe buýt? Tuyệt vời, đọc một số bài viết. Tận dụng mọi cơ hội. Hãy ngừng xem chó và mèo trên YouTube! Đừng làm ô nhiễm bộ não của bạn!

Và một điều cuối cùng. Nếu sau khi đọc bài viết này mà bạn thích ý tưởng tạo trò chơi mà không cần sử dụng game engine thì hãy nhớ đến cái tên Casey Muratori. Anh chàng này có website. Trong phần “xem -> CÁC TẬP TRƯỚC”, bạn sẽ tìm thấy các video hướng dẫn miễn phí tuyệt vời về cách tạo một trò chơi chuyên nghiệp từ đầu. Trong năm bài học Giới thiệu về C dành cho Windows, bạn có thể sẽ học được nhiều điều hơn cả năm năm học đại học (ai đó đã viết về điều này trong phần bình luận bên dưới video).

Casey cũng giải thích rằng bằng cách phát triển công cụ trò chơi của riêng mình, bạn sẽ hiểu rõ hơn về mọi công cụ hiện có. Trong thế giới của các khuôn khổ nơi mọi người đều cố gắng tự động hóa, bạn học cách sáng tạo thay vì sử dụng. Bạn hiểu bản chất của máy tính. Và bạn cũng sẽ trở thành một lập trình viên thông minh và trưởng thành hơn rất nhiều - một chuyên gia.

Chúc bạn thành công trên con đường đã chọn! Và hãy làm cho thế giới trở nên chuyên nghiệp hơn.

tác giả: Grankin Andrey, DevOps



Nguồn: www.habr.com