DevOps C++ እና "የወጥ ቤት ጦርነቶች"፣ ወይም እንዴት እየተመገብኩ ጨዋታዎችን መፃፍ እንደጀመርኩኝ።

"ምንም እንደማላውቅ አውቃለሁ" ሶቅራጠስ

ለማን: በሁሉም ገንቢዎች ላይ ለሚተፉ እና ጨዋታቸውን መጫወት ለሚፈልጉ የአይቲ ሰዎች!

ስለምን: ከፈለጉ ጨዋታዎችን በC/C++ እንዴት መፃፍ እንደሚጀምሩ!

ለምን ይህን ማንበብ አለብዎት: የመተግበሪያ ልማት የእኔ የስራ ልዩ አይደለም፣ ግን በየሳምንቱ ኮድ ለማድረግ እሞክራለሁ። ጨዋታዎችን ስለምወድ!

ሃይ ስሜ አንድሬ ግራንኪን፣ በሉክሶፍት ውስጥ ዴቭኦፕስ ነኝ። የመተግበሪያ ልማት የእኔ ሥራ ልዩ አይደለም ፣ ግን በየሳምንቱ ኮድ ለማድረግ እሞክራለሁ። ጨዋታዎችን ስለምወድ!

የኮምፒዩተር ጌም ኢንደስትሪ በጣም ትልቅ ነው፣ ዛሬም ከፊልም ኢንደስትሪ የበለጠ እየተወራ ነው። ጨዋታዎች የተፃፉት የኮምፒዩተሮች እድገት ከተጀመረበት ጊዜ ጀምሮ ነው, በዘመናዊ ደረጃዎች, ውስብስብ እና መሰረታዊ የእድገት ዘዴዎች በመጠቀም. በጊዜ ሂደት የጨዋታ ሞተሮች ቀድሞ በተዘጋጀ ግራፊክስ፣ ፊዚክስ እና ድምጽ መታየት ጀመሩ። በጨዋታው በራሱ እድገት ላይ እንዲያተኩሩ እና ስለ መሰረቱ እንዳይጨነቁ ያስችሉዎታል. ነገር ግን ከነሱ ጋር, ከኤንጂኖች ጋር, ገንቢዎቹ "ዓይነ ስውር" እና ዝቅ ያደርጋሉ. የጨዋታዎች ምርት በማጓጓዣው ላይ ተጭኗል። እና የምርት መጠን ከጥራት በላይ ማሸነፍ ይጀምራል.

በተመሳሳይ ጊዜ፣ የሌሎች ሰዎችን ጨዋታዎች ስንጫወት፣ ሌሎች ሰዎች ባመጡት ቦታ፣ ሴራ፣ ገጸ-ባህሪያት፣ የጨዋታ መካኒኮች ያለማቋረጥ እንገደዳለን። ስለዚህ ያንን ተገነዘብኩ…

ለእኔ ብቻ ተገዥ በመሆን የራሳችሁን ዓለሞች ለመፍጠር ጊዜው አሁን ነው። እኔ አብ፣ ወልድ እና መንፈስ ቅዱስ የሆንኩባቸው ዓለማት!

እና የእራስዎን የጨዋታ ሞተር እና በላዩ ላይ ጨዋታ በመፃፍ ፣ ዓይኖችዎን ለመክፈት ፣ መስኮቶቹን መጥረግ እና ካቢኔዎን በፓምፕ በመሳብ የበለጠ ልምድ ያለው እና ጠቃሚ ፕሮግራመር ለመሆን እንደሚችሉ በቅንነት አምናለሁ።

በዚህ ጽሑፍ ውስጥ በ C / C ++ ውስጥ ትናንሽ ጨዋታዎችን እንዴት መጻፍ እንደጀመርኩ ፣ የእድገት ሂደቱ ምን እንደሆነ እና በተጨናነቀ አካባቢ ውስጥ የትርፍ ጊዜ ማሳለፊያ ጊዜ እንዳገኝ ልነግርዎ እሞክራለሁ። እሱ ግላዊ ነው እናም የግለሰብን ጅምር ሂደት ይገልጻል። ቁሳቁስ ስለ ድንቁርና እና እምነት ፣ ስለ ግላዊ የአለም እይታዬ በአሁኑ ጊዜ። በሌላ አነጋገር "አስተዳደሩ ለግል አእምሮህ ተጠያቂ አይደለም!"

ልምምድ

"ያለ ልምምድ እውቀት ከንቱ ነው፣ ያለ እውቀት መለማመድ አደገኛ ነው።" ኮንፊሽየስ

ማስታወሻ ደብተሬ ሕይወቴ ነው!


ስለዚህ, በተግባር, ለእኔ ሁሉም ነገር የሚጀምረው በማስታወሻ ደብተር ነው ማለት እችላለሁ. እዚያ የምጽፈው የእለት ተእለት ተግባሮቼን ብቻ ሳይሆን መሳል፣ ፕሮግራም ማውጣት፣ የፍሰት ገበታዎችን መንደፍ እና ችግሮችን እፈታለሁ፣ የሂሳብ ችግሮችንም ጭምር። ሁልጊዜ የማስታወሻ ደብተር ተጠቀም እና በእርሳስ ብቻ ጻፍ። ንጹህ፣ ምቹ እና አስተማማኝ ነው፣ IMHO።

DevOps C++ እና "የወጥ ቤት ጦርነቶች"፣ ወይም እንዴት እየተመገብኩ ጨዋታዎችን መፃፍ እንደጀመርኩኝ።
የእኔ (ቀድሞውኑ የተሞላ) ማስታወሻ ደብተር። ይህ ይመስላል። የዕለት ተዕለት ተግባራትን, ሀሳቦችን, ስዕሎችን, ንድፎችን, መፍትሄዎችን, ጥቁር መጽሃፍቶችን, ኮድን እና የመሳሰሉትን ይዟል.

በዚህ ደረጃ, ሶስት ፕሮጀክቶችን ማጠናቀቅ ችያለሁ (ይህ በ "መጨረሻ" ግንዛቤ ውስጥ ነው, ምክንያቱም ማንኛውም ምርት በአንጻራዊነት ማለቂያ በሌለው ሊዳብር ይችላል).

  • ፕሮጀክት 0 ይህ የአንድነት ጨዋታ ሞተርን በመጠቀም በC# የተጻፈ አርክቴክት ማሳያ 3D ትዕይንት ነው። ለ macOS እና ዊንዶውስ መድረኮች።
  • ጨዋታ 1: የኮንሶል ጨዋታ ቀላል እባብ (ለሁሉም ሰው "እባብ" በመባል ይታወቃል) ለዊንዶው። በ C ተፃፈ።
  • ጨዋታ 2: የኮንሶል ጨዋታ Crazy Tanks (ለሁሉም ሰው "ታንክስ" በመባል የሚታወቅ)፣ አስቀድሞ በC ++ (ክፍሎችን በመጠቀም) እና እንዲሁም በዊንዶው የተጻፈ።

ፕሮጀክት 0 አርክቴክት ማሳያ

DevOps C++ እና "የወጥ ቤት ጦርነቶች"፣ ወይም እንዴት እየተመገብኩ ጨዋታዎችን መፃፍ እንደጀመርኩኝ።
3D ትዕይንት አርክቴክት ማሳያ

የመጀመሪያው ፕሮጀክት የተተገበረው በC/C++ ሳይሆን በC # የዩኒቲ ጨዋታ ሞተርን በመጠቀም ነው። ይህ ሞተር በሃርድዌር ላይ የሚፈልገውን ያህል አልነበረም ትክክለኛ ፍርግም, እና ደግሞ ለመጫን እና ለመጠቀም ቀላል መሰለኝ። ሌሎች ሞተሮችን ግምት ውስጥ አላስገባኝም.

ለኔ በዩኒቲ ውስጥ የነበረው አላማ አንድ አይነት ጨዋታን ማዳበር አልነበረም። የሆነ አይነት ባህሪ ያለው 3D ትዕይንት መፍጠር ፈልጌ ነበር። እሱ ወይም ይልቁኑ እሷ (የምወዳትን ልጅ ሞዴል አድርጌዋለሁ =) መንቀሳቀስ እና ከውጭው ዓለም ጋር መገናኘት ነበረባት። አንድነት ምን እንደሆነ፣ የእድገት ሂደቱ ምን እንደሆነ እና አንድን ነገር ለመፍጠር ምን ያህል ጥረት እንደሚያስፈልግ መረዳት ብቻ አስፈላጊ ነበር። የአርክቴክት ዴሞ ፕሮጀክት የተወለደው በዚህ መንገድ ነው (ስሙ የተፈለሰፈው ከበሬ ወለደ) ነው። ፕሮግራሚንግ፣ ሞዴሊንግ፣ አኒሜሽን፣ ቴክስት ማድረግ ምናልባት የሁለት ወር የእለት ስራ ፈጅቶብኛል።

በዩቲዩብ ላይ የ3-ል ሞዴሎችን እንዴት መፍጠር እንደሚቻል በማስተማሪያ ቪዲዮዎች ጀመርኩ። መፍጫ. Blender ለ 3D ሞዴሊንግ (እና ሌሎችም) መጫንን የማይፈልግ ምርጥ መሳሪያ ነው። እና እዚህ ድንጋጤ ጠበቀኝ ... ሞዴሊንግ ፣ አኒሜሽን ፣ ጽሑፍ መፃፍ መጽሃፎችን መፃፍ የሚችሉባቸው ትልቅ የተለያዩ ርዕሰ ጉዳዮች ናቸው። ይህ በተለይ ለገጸ-ባህሪያቱ እውነት ነው. ጣቶችን፣ ጥርሶችን፣ አይኖችን እና ሌሎች የሰውነት ክፍሎችን ሞዴል ለማድረግ ስለ የሰውነት አካል እውቀት ያስፈልግዎታል። የፊት ጡንቻዎች እንዴት ይደረደራሉ? ሰዎች እንዴት ይንቀሳቀሳሉ? በእያንዳንዱ ክንድ፣ እግር፣ ጣት፣ አንጓ ላይ አጥንትን "ማስገባት" ነበረብኝ!

አኒሜሽኑ ተፈጥሯዊ እንዲመስል ክላቭልን ፣ ተጨማሪ የአጥንት ማንሻዎችን ሞዴል ያድርጉ። ከእንደዚህ አይነት ትምህርቶች በኋላ የ 30 ሰከንድ ቪዲዮ ለመፍጠር ብቻ የአኒሜሽን ፊልሞች ፈጣሪዎች ምን ያህል ትልቅ ስራ እንደሚሰሩ ይገነዘባሉ. ግን 3D ፊልሞች ለሰዓታት ይቆያሉ! እና ከዚያ ከቲያትር ቤቶች ወጥተን አንድ ነገር እንናገራለን፡- “Ta, a shitty cartoon / movie! የተሻለ መስራት ይችሉ ነበር…” ሞኞች!

እና በዚህ ፕሮጀክት ውስጥ ስለ ፕሮግራሚንግ አንድ ተጨማሪ ነገር. እንደ ተለወጠ፣ ለእኔ በጣም የሚያስደስት ክፍል የሂሳብ ክፍል ነበር። ትዕይንቱን ካከናወኑ (በፕሮጀክቱ መግለጫ ውስጥ ካለው የመረጃ ቋት ጋር ማገናኘት) ፣ ካሜራው በሴት ልጅ ገጸ-ባህሪ ላይ በክብ ዙሪያ እንደሚሽከረከር ያስተውላሉ። እንዲህ ዓይነቱን የካሜራ ማሽከርከር ፕሮግራም ለማዘጋጀት በመጀመሪያ በክበብ (2D) ላይ ያለውን የቦታ ነጥብ መጋጠሚያዎች እና ከዚያም በሉል (3D) ላይ ማስላት ነበረብኝ. የሚያስቀው ነገር በትምህርት ቤት ሒሳብን ጠላሁ እና በትንሽ መጠን ማወቄ ነው። በከፊል ፣ ምናልባት ፣ ምክንያቱም በትምህርት ቤት ይህ ሂሳብ በህይወት ውስጥ እንዴት ገሃነም እንደሚተገበር በቀላሉ አያስረዱዎትም። ነገር ግን በዓላማህ ስትታመስ፣ አልም፣ ያኔ አእምሮ ይጸዳል፣ ይገለጣል! እና ውስብስብ ስራዎችን እንደ አስደሳች ጀብዱ ማስተዋል ይጀምራሉ. እና ከዚያ እርስዎ ያስባሉ: "ደህና, ለምን * የተወደዳችሁ * የሂሳብ ሊቅ እነዚህ ቀመሮች የት ዘንበል ሊሉ እንደሚችሉ ሊነግሩ አልቻሉም?"

DevOps C++ እና "የወጥ ቤት ጦርነቶች"፣ ወይም እንዴት እየተመገብኩ ጨዋታዎችን መፃፍ እንደጀመርኩኝ።
በክበብ እና በሉል ላይ የነጥብ መጋጠሚያዎችን ለማስላት የቀመሮች ስሌት (ከእኔ ማስታወሻ ደብተር)

ጨዋታ 1

  • መድረክ ዊንዶውስ (በዊንዶውስ 7 ፣ 10 ላይ ተፈትኗል)
  • ቋንቋ: በንፁህ ሲ የተጻፈ ይመስለኛል
  • የጨዋታ ሞተር; የዊንዶው ኮንሶል
  • ተነሳሽነት፡- javidx9
  • ማከማቻ፡ የፊልሙ

DevOps C++ እና "የወጥ ቤት ጦርነቶች"፣ ወይም እንዴት እየተመገብኩ ጨዋታዎችን መፃፍ እንደጀመርኩኝ።
ቀላል የእባብ ጨዋታ

የ3-ል ትዕይንቱ ጨዋታ አይደለም። በተጨማሪም የ3-ል ዕቃዎችን (በተለይ ገጸ-ባህሪያትን) መቅረጽ እና ማንቀሳቀስ ረጅም እና ከባድ ነው። ከአንድነት ጋር ከተጫወትኩ በኋላ፣ መቀጠል እንዳለብኝ ተገነዘብኩ፣ ወይም ከመሠረቱ መጀመር እንዳለብኝ ተረዳሁ። ቀላል እና ፈጣን የሆነ ነገር, ግን በተመሳሳይ ጊዜ ዓለም አቀፋዊ, የጨዋታዎችን መዋቅር ለመረዳት.

እና ቀላል እና ፈጣን ምን አለን? ልክ ነው ኮንሶል እና 2D ይበልጥ በትክክል ፣ ኮንሶል እና ምልክቶች እንኳን። እንደገና በበይነመረቡ ላይ ተመስጦ መፈለግ ጀመርኩ (በአጠቃላይ በይነመረብ የ XNUMX ኛው ክፍለ ዘመን በጣም አብዮታዊ እና አደገኛ ፈጠራ እንደሆነ እቆጥረዋለሁ)። ኮንሶል ቴትሪስን የሰራው የአንድ ፕሮግራመር ቪዲዮ ቆፍሬያለሁ። እና በጨዋታው ተመሳሳይነት, "እባቡን" ለመቁረጥ ወሰነ. ከቪዲዮው ፣ ስለ ሁለት መሠረታዊ ነገሮች ተማርኩኝ - የጨዋታ loop (ከሶስት መሠረታዊ ተግባራት / ክፍሎች) እና ወደ ቋት ውፅዓት።

የጨዋታ ምልልሱ እንደዚህ ያለ ነገር ሊመስል ይችላል፡-

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

ኮዱ ሙሉውን ዋና () ተግባር በአንድ ጊዜ ያቀርባል. እና የጨዋታው ዑደት የሚጀምረው ከተዛማጅ አስተያየት በኋላ ነው. በ loop ውስጥ ሶስት መሰረታዊ ተግባራት አሉ፡ ግቤት()፣ ሎጂክ()፣ ስዕል()። በመጀመሪያ ፣ የግቤት ውሂብ ግቤት (በዋነኛነት የቁልፍ ጭነቶች ቁጥጥር) ፣ ከዚያ የገባውን ውሂብ ሎጂክን በማስኬድ ፣ ከዚያ በማያ ገጹ ላይ - ይሳሉ። እና ስለዚህ እያንዳንዱ ፍሬም. አኒሜሽን የሚፈጠረው በዚህ መንገድ ነው። እንደ ካርቱኖች ነው። ብዙውን ጊዜ የግቤት ውሂቡን ማካሄድ ብዙ ጊዜ ይወስዳል እና እኔ እስከማውቀው ድረስ የጨዋታውን ፍሬም ፍጥነት ይወስናል። ግን እዚህ የሎጂክ () ተግባር በጣም ፈጣን ነው. ስለዚህ የፍሬም ፍጥነቱ ይህንን መጠን የሚወስነው በእንቅልፍ () ተግባር በጨዋታ የፍጥነት መለኪያ መቆጣጠር አለበት።

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++ እና "የወጥ ቤት ጦርነቶች"፣ ወይም እንዴት እየተመገብኩ ጨዋታዎችን መፃፍ እንደጀመርኩኝ።
የእብድ ታንኮች ጨዋታ

ቁምፊዎችን ወደ ኮንሶሉ ማተም ምናልባት ወደ ጨዋታ መቀየር የሚችሉት ቀላሉ ነገር ነው። ግን ከዚያ አንድ ችግር ይታያል-ቁምፊዎቹ የተለያየ ቁመት እና ስፋት አላቸው (ቁመቱ ከስፋቱ የበለጠ ነው). ስለዚህ ፣ ሁሉም ነገር ያልተመጣጠነ ይመስላል ፣ እና ወደ ላይ ወይም ወደ ላይ መንቀሳቀስ ወደ ግራ ወይም ቀኝ ከመንቀሳቀስ የበለጠ ፈጣን ይመስላል። ይህ ተፅዕኖ በ "እባብ" (ጨዋታ 1) ውስጥ በጣም የሚታይ ነው. "ታንክስ" (ጨዋታ 2) እንደዚህ አይነት ችግር አይፈጥርም, ምክንያቱም እዚያ ያለው ውጤት የተደራጀው ማያ ገጹን በተለያየ ቀለም በመሳል ነው. አተረጓጎም ጻፍኩ ማለት ትችላለህ። እውነት ነው ፣ ይህ ቀድሞውኑ ትንሽ የተወሳሰበ ነው ፣ ምንም እንኳን የበለጠ አስደሳች ነው።

ለዚህ ጨዋታ, በስክሪኑ ላይ ፒክስሎችን ለማሳየት የእኔን ስርዓት ለመግለጽ በቂ ይሆናል. ይህ የጨዋታው ዋና አካል ይመስለኛል። እና ሁሉም ነገር ከራስዎ ጋር መምጣት ይችላሉ.

ስለዚህ፣ በስክሪኑ ላይ የሚያዩት የሚንቀሳቀሱ ባለ አራት ማዕዘናት ስብስብ ነው።

DevOps C++ እና "የወጥ ቤት ጦርነቶች"፣ ወይም እንዴት እየተመገብኩ ጨዋታዎችን መፃፍ እንደጀመርኩኝ።
አራት ማዕዘን ስብስብ

እያንዳንዱ አራት ማዕዘን በቁጥር በተሞላ ማትሪክስ ይወከላል. በነገራችን ላይ አንድ አስደሳች ነገር ማጉላት እችላለሁ - በጨዋታው ውስጥ ያሉት ሁሉም ማትሪክስ እንደ አንድ-ልኬት ድርድር ተዘጋጅተዋል። ባለ ሁለት አቅጣጫ ሳይሆን አንድ-ልኬት! አንድ-ልኬት ድርድሮች ለመሥራት በጣም ቀላል እና ፈጣን ናቸው።

DevOps C++ እና "የወጥ ቤት ጦርነቶች"፣ ወይም እንዴት እየተመገብኩ ጨዋታዎችን መፃፍ እንደጀመርኩኝ።
የጨዋታ ታንክ ማትሪክስ ምሳሌ

DevOps C++ እና "የወጥ ቤት ጦርነቶች"፣ ወይም እንዴት እየተመገብኩ ጨዋታዎችን መፃፍ እንደጀመርኩኝ።
የጨዋታ ታንክ ማትሪክስ ከአንድ-ልኬት አደራደር ጋር በመወከል

DevOps C++ እና "የወጥ ቤት ጦርነቶች"፣ ወይም እንዴት እየተመገብኩ ጨዋታዎችን መፃፍ እንደጀመርኩኝ።
በባለ አንድ-ልኬት ድርድር የማትሪክስ ውክልና የበለጠ ገላጭ ምሳሌ

ነገር ግን የዝግጅቱ አካላት መዳረሻ በሁለት ዙር ይከሰታል፣ አንድ-ልኬት ሳይሆን ባለ ሁለት-ልኬት ድርድር። ይህ የተደረገው አሁንም ከማትሪክስ ጋር እየሰራን ስለሆነ ነው።

DevOps C++ እና "የወጥ ቤት ጦርነቶች"፣ ወይም እንዴት እየተመገብኩ ጨዋታዎችን መፃፍ እንደጀመርኩኝ።
ባለ አንድ-ልኬት ድርድር በድርብ ዑደት ውስጥ ማለፍ። Y የረድፍ መታወቂያ ነው፣ X የአምድ መታወቂያ ነው።

እባክዎን ያስታውሱ ከተለመዱት ማትሪክስ ለዪዎች i፣ j፣ለዪዎችን x እና y እጠቀማለሁ። ስለዚህ፣ ለእኔ የሚመስለኝ፣ ለዓይን ይበልጥ የሚያስደስት እና ለአእምሮ ይበልጥ ግልጽ ነው። በተጨማሪም ፣ እንደዚህ ዓይነቱ ማስታወሻ ባለ ሁለት አቅጣጫዊ ምስል በተጋጠሙትም ዘንጎች ላይ የሚያገለግሉትን ማትሪክስ በጥሩ ሁኔታ ለማስኬድ ያስችላል።

አሁን ስለ ፒክስሎች፣ ቀለም እና ማሳያ። የStretchDIBits ተግባር (ራስጌ፡ 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
               );

የቨርቹዋልAlloc() ተግባርን በመጠቀም ማህደረ ትውስታ ለዚህ ቢትማፕ አስቀድሞ ተመድቧል። ያም ማለት ስለ ሁሉም ፒክስሎች መረጃን ለማከማቸት የሚፈለገው የባይት ቁጥር ተይዟል, ከዚያም በስክሪኑ ላይ ይታያል.

m_p_bitmapMemory bitmap መፍጠር፡-

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

በግምት፣ ቢትማፕ የፒክሰሎች ስብስብን ያካትታል። በድርድር ውስጥ ያለው እያንዳንዱ አራት ባይት RGB ፒክሰል ነው። አንድ ባይት በቀይ እሴት፣ አንድ ባይት በአረንጓዴ እሴት (ጂ) እና አንድ ባይት በሰማያዊ ቀለም (ቢ)። በተጨማሪም፣ በአንድ ገብ አንድ ባይት አለ። እነዚህ ሶስት ቀለሞች - ቀይ / አረንጓዴ / ሰማያዊ (RGB) - በተለያየ መጠን እርስ በርስ ይደባለቃሉ - ውጤቱም የፒክሰል ቀለም ተገኝቷል.

አሁን፣ እንደገና፣ እያንዳንዱ ሬክታንግል፣ ወይም የጨዋታ ነገር፣ በቁጥር ማትሪክስ ይወከላል። እነዚህ ሁሉ የጨዋታ እቃዎች በስብስብ ውስጥ ይቀመጣሉ. እና ከዚያም አንድ ትልቅ የቁጥር ማትሪክስ በመፍጠር በመጫወቻ ሜዳ ላይ ይቀመጣሉ. በማትሪክስ ውስጥ ያለውን እያንዳንዱን ቁጥር ወደ አንድ የተወሰነ ቀለም ካርታ አድርጌዋለሁ። ለምሳሌ, ቁጥር 8 ሰማያዊ ነው, ቁጥር 9 ቢጫ ነው, ቁጥር 10 ጥቁር ግራጫ, ወዘተ. ስለዚህ, እያንዳንዱ ቁጥር አንድ ዓይነት ቀለም ያለው የመጫወቻ ሜዳ ማትሪክስ አለን ማለት እንችላለን.

ስለዚህ በአንድ በኩል የመጫወቻ ሜዳው የቁጥር ማትሪክስ እና በሌላ በኩል ምስሉን ለማሳየት ቢትማፕ አለን። እስካሁን ድረስ, ቢትማፕ "ባዶ" ነው - ስለ ተፈላጊው ቀለም ፒክስሎች ገና መረጃ የለውም. ይህ ማለት የመጨረሻው እርምጃ በመጫወቻ ሜዳው የቁጥር ማትሪክስ ላይ በመመስረት ስለ እያንዳንዱ ፒክሰል መረጃ ቢትማፕ መሙላት ይሆናል። የዚህ ዓይነቱ ለውጥ ምሳሌያዊ ምሳሌ ከዚህ በታች ባለው ሥዕል ውስጥ ነው ።

DevOps C++ እና "የወጥ ቤት ጦርነቶች"፣ ወይም እንዴት እየተመገብኩ ጨዋታዎችን መፃፍ እንደጀመርኩኝ።
በመጫወቻ ሜዳው የቁጥር ማትሪክስ (ዲጂታል ማትሪክስ) ላይ የተመሰረተ መረጃ የቢትማፕ (ፒክሴል ማትሪክስ) የመሙላት ምሳሌ (የቀለም ኢንዴክሶች በጨዋታው ውስጥ ካሉ ኢንዴክሶች ጋር አይዛመዱም)

እንዲሁም ከጨዋታው ውስጥ የእውነተኛ ኮድ ቁራጭ አቀርባለሁ። በእያንዳንዱ የሉፕ ድግግሞሽ ላይ ያለው ተለዋዋጭ የቀለም መረጃ ጠቋሚ ከመጫወቻ ሜዳው የቁጥር ማትሪክስ (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() ተግባር ውስጥ የቁልፍ ጭነቶችን ከተመዘገቡ በኋላ እና ተከታዩ ሂደታቸው በሎጂክ() ተግባር ውስጥ፣ አዲስ ምስል (ፍሬም) ይመሰረታል። እውነት ነው, የጨዋታ እቃዎች ቀድሞውኑ በመጫወቻ ሜዳ ላይ የተለየ አቋም ሊኖራቸው ይችላል, እና በዚህ መሰረት, በተለየ ቦታ ይሳባሉ. አኒሜሽን (እንቅስቃሴ) የሚሆነው በዚህ መንገድ ነው።

በንድፈ ሀሳብ (ምንም ነገር ያልረሱ ከሆነ) ከመጀመሪያው ጨዋታ የጨዋታውን ዑደት መረዳት ("እባብ") እና ከሁለተኛው ጨዋታ ("ታንክስ") በስክሪኑ ላይ ፒክስሎችን ለማሳየት ስርዓቱን መረዳት ብቻ ነው ማንኛውንም መጻፍ ያስፈልግዎታል. ለዊንዶውስ የእርስዎ 2D ጨዋታዎች። ድምጽ አልባ! 😉 የተቀሩት ክፍሎች የጌጥ በረራ ብቻ ናቸው።

እርግጥ ነው, ጨዋታው "ታንኮች" ከ "እባብ" የበለጠ የተወሳሰበ ነው. አስቀድሜ የC++ ቋንቋን ተጠቀምኩኝ፣ ማለትም፣ የተለያዩ የጨዋታ ቁሳቁሶችን ከክፍል ጋር ገለጽኩላቸው። የራሴን ስብስብ ፈጠርኩ - ኮዱን በራስጌዎች/Box.h ውስጥ ማየት ትችላለህ። በነገራችን ላይ, ክምችቱ ብዙውን ጊዜ የማስታወስ ችሎታው መፍሰስ አለበት. ያገለገሉ ጠቋሚዎች. ከማስታወስ ጋር ሰርቷል። መጽሐፉ ብዙ ረድቶኛል ማለት አለብኝ። በጨዋታ ፕሮግራሚንግ ሲ ++ ጅምር. ይህ በC++ ውስጥ ለጀማሪዎች ጥሩ ጅምር ነው። እሱ ትንሽ ፣ አስደሳች እና በደንብ የተደራጀ ነው።

ይህንን ጨዋታ ለማዳበር ስድስት ወራት ያህል ፈጅቷል። እኔ በዋነኝነት የጻፍኩት በምሳ እና በሥራ ቦታ በሚመገቡበት ወቅት ነው። እሱ ቢሮው ኩሽና ውስጥ ተቀምጦ ምግብ ላይ ረግጦ ኮድ ጻፈ። ወይም ለእራት ቤት ውስጥ። ስለዚህ እንደዚህ አይነት "የኩሽና ጦርነቶች" አገኘሁ. እንደ ሁልጊዜ, የማስታወሻ ደብተርን በንቃት ተጠቀምኩኝ, እና ሁሉም ጽንሰ-ሐሳቦች በእሱ ውስጥ ተወለዱ.

በተግባራዊው ክፍል መጨረሻ ላይ የማስታወሻ ደብተሬን ጥቂት ስካን አወጣለሁ። በትክክል የምጽፈውን፣ እየሳልኩ፣ እየቆጠርኩ፣ እየቀረጽኩ እንደነበረ ለማሳየት…

DevOps C++ እና "የወጥ ቤት ጦርነቶች"፣ ወይም እንዴት እየተመገብኩ ጨዋታዎችን መፃፍ እንደጀመርኩኝ።
የታንክ ምስል ንድፍ. እና እያንዳንዱ ታንክ ምን ያህል ፒክሰሎች በስክሪኑ ላይ መያዝ እንዳለበት ፍቺ

DevOps C++ እና "የወጥ ቤት ጦርነቶች"፣ ወይም እንዴት እየተመገብኩ ጨዋታዎችን መፃፍ እንደጀመርኩኝ።
የ ስልተ ቀመር ስሌት እና ቀመሮች በውስጡ ዘንግ ዙሪያ ታንክ ማሽከርከር

DevOps C++ እና "የወጥ ቤት ጦርነቶች"፣ ወይም እንዴት እየተመገብኩ ጨዋታዎችን መፃፍ እንደጀመርኩኝ።
የእኔ ስብስብ ዲያግራም (የማስታወሻ መፍሰስ ያለበት ፣ ምናልባትም)። ስብስቡ እንደ የተገናኘ ዝርዝር ነው የተፈጠረው

DevOps C++ እና "የወጥ ቤት ጦርነቶች"፣ ወይም እንዴት እየተመገብኩ ጨዋታዎችን መፃፍ እንደጀመርኩኝ።
እና እነዚህ አርቴፊሻል ኢንተለጀንስ በጨዋታው ውስጥ ለመክተት ከንቱ ሙከራዎች ናቸው።

ቲዮሪ

"የሺህ ማይል ጉዞ እንኳን የሚጀምረው ከመጀመሪያው እርምጃ ነው" (የጥንቷ ቻይንኛ ጥበብ)

ከተግባር ወደ ቲዎሪ እንሸጋገር! ለትርፍ ጊዜዎ ጊዜ እንዴት ያገኛሉ?

  1. በትክክል የሚፈልጉትን ይወስኑ (ወዮ ፣ ይህ በጣም ከባድ ነው)።
  2. ቅድሚያ የሚሰጣቸውን ነገሮች አዘጋጅ።
  3. ለበላይ ቅድሚያ የሚሰጣቸውን ነገሮች ሁሉ "ከእጅግ በላይ" መስዋዕት አድርጉ።
  4. በየቀኑ ወደ ግቦችዎ ይሂዱ።
  5. ለትርፍ ጊዜ ማሳለፊያ ሁለት ወይም ሶስት ሰዓታት ነፃ ጊዜ ይኖራል ብለው አይጠብቁ።

በአንድ በኩል, የሚፈልጉትን መወሰን እና ቅድሚያ መስጠት ያስፈልግዎታል. በሌላ በኩል, እነዚህን ቅድሚያ የሚሰጣቸውን ጉዳዮች በመደገፍ አንዳንድ ጉዳዮችን / ፕሮጀክቶችን መተው ይቻላል. በሌላ አገላለጽ ሁሉንም ነገር "እጅግ የበዛ" መስዋዕት ማድረግ አለብዎት. በህይወት ውስጥ ቢበዛ ሶስት ዋና ዋና ተግባራት ሊኖሩ እንደሚገባ አንድ ቦታ ሰማሁ። ከዚያም በተቻለ መጠን እነሱን መቋቋም ይችላሉ. እና ተጨማሪ ፕሮጀክቶች/አቅጣጫዎች በቆሎ ከመጠን በላይ መጫን ይጀምራሉ. ግን ይህ ሁሉ ፣ ምናልባትም ፣ ግላዊ እና ግላዊ ነው።

አንድ የተወሰነ ወርቃማ ህግ አለ: በጭራሽ 0% ቀን አይኑር! ስለ እሱ በአንድ ኢንዲ ገንቢ በተጻፈ ጽሑፍ ውስጥ ተማርኩ። በፕሮጀክት ላይ እየሰሩ ከሆነ, ስለዚህ በየቀኑ አንድ ነገር ያድርጉ. እና ምን ያህል ብታገኙ ምንም ለውጥ አያመጣም። አንድ ቃል ወይም አንድ የኮድ መስመር ይጻፉ፣ አንድ አጋዥ ቪዲዮ ይመልከቱ፣ ወይም አንድ ሚስማር በቦርዱ ላይ መዶሻ - አንድ ነገር ብቻ ያድርጉ። በጣም አስቸጋሪው ነገር መጀመር ነው. አንዴ ከጀመርክ ምናልባት ከምትፈልገው በላይ ትንሽ ታደርጋለህ። ስለዚህ ያለማቋረጥ ወደ ግብህ ትሄዳለህ እና እመኑኝ፣ በጣም በፍጥነት። ከሁሉም በላይ, በሁሉም ነገሮች ላይ ዋናው ብሬክ መዘግየት ነው.

እና በ 5 ፣ 10 ፣ 15 ደቂቃዎች ውስጥ ነፃውን “መጋዝ” ጊዜን ማቃለል እና ችላ ማለት እንደሌለብዎት ማስታወስ አስፈላጊ ነው ፣ ለአንድ ወይም ለሁለት ሰዓታት የሚቆይ ትልቅ “ሎግ” ይጠብቁ ። በመስመር ላይ ቆመሃል? ለፕሮጀክትዎ የሆነ ነገር ያስቡ. ወደላይ መወጣጫ እየወጣህ ነው? በማስታወሻ ደብተር ውስጥ የሆነ ነገር ይፃፉ። በአውቶቡስ ውስጥ ትበላለህ? እሺ፣ አንዳንድ መጣጥፍ አንብብ። አጋጣሚውን ሁሉ ተጠቀም። በYouTube ላይ ድመቶችን እና ውሾችን መመልከት አቁም! ከአእምሮህ ጋር አትዘባርቅ!

እና የመጨረሻው. ይህንን ጽሑፍ ካነበቡ በኋላ የጨዋታ ሞተሮችን ሳይጠቀሙ ጨዋታዎችን የመፍጠር ሀሳብ ከወደዱ ፣ ከዚያ Casey Muratori የሚለውን ስም ያስታውሱ። ይህ ሰው አለው ድር ጣቢያ. በ"watch -> ቀዳሚ ትዕይንቶች" ክፍል ውስጥ የፕሮፌሽናል ጨዋታን ከባዶ እንዴት መፍጠር እንደሚችሉ የሚገርሙ የነጻ የቪዲዮ ትምህርቶችን ያገኛሉ። ከመግቢያ እስከ ሲ ለዊንዶውስ ባሉት አምስት ትምህርቶች በዩኒቨርሲቲ ውስጥ ከአምስት ዓመታት በላይ ጥናት ሊማሩ ይችላሉ (አንድ ሰው ስለዚህ ጉዳይ በቪዲዮው ስር ባሉት አስተያየቶች ውስጥ ጽፏል).

በተጨማሪም ኬሲ የእራስዎን የጨዋታ ሞተር በማዳበር ስለ ነባር ሞተሮች የተሻለ ግንዛቤ እንዲኖርዎት ያብራራል። በማዕቀፎች ዓለም ውስጥ፣ ሁሉም ሰው በራስ ሰር ለመስራት በሚሞክርበት፣ እንዴት መፍጠር እንደሚችሉ ይማራሉ እንጂ አይጠቀሙ። የኮምፒውተሮችን ምንነት ይረዱ። እና እርስዎም የበለጠ ብልህ እና ጎልማሳ ፕሮግራመር ይሆናሉ - ባለሙያ።

በተመረጠው መንገድ ላይ መልካም ዕድል! እና ዓለምን የበለጠ ባለሙያ እናድርግ።

ደራሲ: ግራንኪን አንድሬ, DevOps



ምንጭ: hab.com