You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/km/6-space-game/3-moving-elements-around
localizeflow[bot] 388926566b
chore(i18n): sync translations with latest source changes (chunk 1/1, 243 changes)
4 months ago
..
README.md chore(i18n): sync translations with latest source changes (chunk 1/1, 243 changes) 4 months ago
assignment.md chore(i18n): sync translations with latest source changes (chunk 1/1, 243 changes) 4 months ago

README.md

សាងសង់ហ្គេមអាកាសយាន Part 3: បន្ថែមចលនា

journey
    title ផ្លូវការជំនាញរបស់អ្នកក្នុងការចលនាเกมส์
    section គន្លឹះចលនា
      យល់ដឹងគោលការណ៍ចលនា: 3: Student
      រៀនការអាប់ដេតសំកាត់: 4: Student
      អនុវត្តចលនាមូលដ្ឋាន: 4: Student
    section ការគ្រប់គ្រងគ្រប់លក្ខណៈ
      រៀបចំព្រឹត្តិការណ៍ក្តារចុច: 4: Student
      បញ្ឈប់អាកប្បកិរិយាដើម: 5: Student
      បង្កើតការគ្រប់គ្រងចម្លើយរហ័ស: 5: Student
    section ប្រព័ន្ធហ្គេម
      សង់រង្វិលហ្គេម: 5: Student
      គ្រប់គ្រងអាយុកាលវត្ថុ: 5: Student
      អនុវត្តការនិយោគ pub/sub: 5: Student

គិតអំពីហ្គេមដែលអ្នកចូលចិត្តបំផុត អ្វីដែលធ្វើអោយវាគួរឲ្យទាក់ទាញមិនមែនមានតែក្រាហ្វិកស្រស់ស្អាតណាមួយទេ វាជារបៀបដែលគ្រប់យ៉ាងផ្លាស់ទី និងឆ្លើយតបនឹងសកម្មភាពរបស់អ្នក។ ពេលនេះហ្គេមអាកាសយានរបស់អ្នកដូចជារូបភាពស្អាតមួយ ប៉ុន្តាយើងត្រៀមបន្ថែមចលនាដែលនាំឲ្យវាមានជីវិត។

ពេលវិស្វកររបស់ NASA បង្កើតកម្មវិធីកុំព្យូទ័រណែនាំសម្រាប់បេសកកម្ម Apollo ពួកគេបានប្រឈមមុខនឹងបញ្ហាដូចគ្នាមួយ៖ តើធ្វើដូចម្តេចឲ្យយន្តហោះចរណ៍ឆ្លើយតបនឹងបញ្ចូលពីអ្នកបើកបរ ខណៈដែលរក្សាការកែតម្រូវទិសដៅដោយស្វ័យប្រវត្តិ? គន្លឹះដែលយើងនឹងរៀនថ្ងៃនេះមានសំឡេងដូចគ្នានឹងគំនិតទាំងនោះ គ្រប់គ្រងចលនាដែលត្រូវបានគ្រប់គ្រងដោយអ្នកលេងរួមជាមួយអាកម្មវិធីប្រព័ន្ធដោយស្វ័យប្រវត្តិ។

ក្នុងមេរៀននេះ អ្នកនឹងរៀនពីរបៀបធ្វើឲ្យយន្តហោះអាកាសរត់ផ្លាស់ទីនៅលើអេក្រង់ ឆ្លើយតបនឹងពាក្យបញ្ជារបស់អ្នកលេង និងបង្កើតរបៀបចលនាត្រង់សុភាព។ យើងនឹងបំបែកគ្រប់យ៉ាងទៅជាគំនិតដែលអាចគ្រប់គ្រងបាន ដែលចុះសារពើភ័ណ្ឌគ្នាដោយធម្មតា។

នៅចុងមេរៀន អ្នកនឹងមានអ្នកលេងបង្វៀនយន្តហោះចម្ងាយរបស់ពួកគេនៅលើអេក្រង់ ខណៈដែលនាវាសត្រូវកំពុងបញ្ចុះមេឃមើលថែទាំ។​ សំខាន់ជាងនេះ អ្នកនឹងយល់ស្រាប់ពីគន្លឹះសំខាន់នៃប្រព័ន្ធចលនាហ្គេម។

mindmap
  root((ការប្រតិបត្តិអានីម៉ង់ហ្គេម))
    Movement Types
      Player Controlled [បានគ្រប់គ្រងដោយអ្នកលេង]
      Automatic Motion [ចលនាដោយស្វ័យប្រវត្តិ]
      Physics Based [ផ្អែកលើរូបវិទ្យា]
      Scripted Paths [ផ្លូវដែលបានសរសេរ]
    Event Handling
      Keyboard Input [ការបញ្ចូលពីក្តារចុច]
      Mouse Events [ព្រឹត្តិការណ៍កណ្តុរ]
      Touch Controls [ការគ្រប់គ្រងដោយប៉ះ]
      Default Prevention [ការបង្ការ​ព្យាបាលលំនាំដើម]
    Game Loop
      Update Logic [ធ្វើបច្ចុប្បន្នភាពហេតុផល]
      Render Frame [បង្ហាញក្រឡាចត្រង្គ]
      Clear Canvas [លាងសម្អាតកំណត់ត្រា]
      Frame Rate Control [ការគ្រប់គ្រងអត្រាខេមរ៉ា]
    Object Management
      Position Updates [បច្ចុប្បន្នភាពទីតាំង]
      Collision Detection [ការរកឃើញការកើតជម្លោះ]
      Lifecycle Management [ការគ្រប់គ្រងជីវិតវត្ថុ]
      State Tracking [ការតាមដានស្ថានភាព]
    Communication
      Pub/Sub Pattern [លំនាំផ្សាយ/ជាវ]
      Event Emitters [អ្នកបញ្ចេញព្រឹត្តិការណ៍]
      Message Passing [ការបញ្ជូនសារ]
      Loose Coupling [ការចងភ្ជាប់ទន្ត្រឹម]

សំណួរពីមុនមេរៀន

សំណួរពីមុនមេរៀន

ការយល់ដឹងពីចលនាហ្គេម

ហ្គេមមានជីវិតនៅពេលវាផ្លាស់ទីជុំវិញ ហើយមានពីរប្រភេទទាំងមូលដែលវាផ្លាស់ទី៖

  • ចលនាដោយអ្នកលេងគ្រប់គ្រង៖ ពេលអ្នកចុចក្តារចុច ឬចុចម៉ៅស៍ អ្វីមួយចលនា។ នេះគឺជាការភ្ជាប់ដោយផ្ទាល់រវាងអ្នក និងពិភពហ្គេមរបស់អ្នក។
  • ចលនាដោយស្វ័យប្រវត្តិ៖ ពេលហ្គេមនៅជាគម្រោងចលនាអ្វីមួយ ដូចជានាវាសត្រូវដែលត្រូវបន្តបើកដំណើរកម្សាន្តលើអេក្រង់ ព្រោះអ្នកមិនបានធ្វើអ្វីទេក៏ដោយ។

ការធ្វើអោយវត្ថុផ្លាស់ទីលើអេក្រង់កុំព្យូទ័រងាយស្រួលជាងមើលមួយ។ ចងចាំកូអរដោនេ x និង y ពីថ្នាក់គណិតវិទ្យាដែរឬ? នេះគឺជាម៉ាស៊ីនដែលយើងកំពុងប្រើប្រាស់នៅទីនេះ។ ពេល Galileo តាមដានព្រះច័ន្ទរបស់ Jupiter នៅឆ្នាំ 1610 គាត់គឺកំពុងធ្វើដូចគ្នា គំនិតតម្លែងទីតាំងអំឡុងពេលដើម្បីយល់ពីរបៀបចលនា។

ការផ្លាស់ទីវត្ថុលើអេក្រង់ដូចជាធ្វើអាណីម៉េសិនសៀវភៅបង្វិល អ្នកត្រូវតែអនុវត្តតាមជំហ៊ានសាមញ្ញទាំងបីដូចខាងក្រោម៖

flowchart LR
    A["ស៊ុម N"] --> B["ធ្វើបច្ចុប្បន្នភាពទីតាំង"]
    B --> C["សម្អាតក្រណាត់"]
    C --> D["គូរផលិតផល"]
    D --> E["ស៊ុម N+1"]
    E --> F{បន្តទេ?}
    F -->|បាទ| B
    F -->|ទេ| G["ល្បែងបញ្ចប់"]
    
    subgraph "វដ្តនៃបានិច"
        H["1. គណនាទីតាំងថ្មី"]
        I["2. លុបស៊ុមមុន"]
        J["3. បង្ហាញស៊ុមថ្មី"]
    end
    
    style B fill:#e1f5fe
    style C fill:#ffebee
    style D fill:#e8f5e8
  1. ធ្វើបច្ចុប្បន្នភាពទីតាំង ប្ដូរទីតាំងដែលវត្ថុរបស់អ្នកគួរតែស្ថិតនៅ (ប្រហែលបញ្ចូនវាចូលទៅខាងស្តាំ 5 ភិកសែល)
  2. លុបទំព័រចាស់ សម្អាតអេក្រង់ឲ្យមិនឲ្យឃើញក្ដោបដូចសត្វភ្លើង និងស្នាមដែលនៅជុំវិញ
  3. គូរទំព័រថ្មី ដាក់វត្ថុនៅក្នុងទីតាំងថ្មីរបស់វា

ធ្វើរហ័សត្រឹមគ្រប់គ្រាន់ ហើយហ្នឹង! អ្នកបានចលនាដែលរលូនហើយមានអារម្មណ៍ធម្មជាតិសម្រាប់អ្នកលេង។

នេះគឺជារូបមន្តដែលវាអាចមើលឃើញបានក្នុងកូដ៖

// កំណត់ទីតាំងរបស់វីរៈតួ
hero.x += 5;
// សម្អាតចតុកោណដែលផ្ទុកវីរៈតួ
ctx.clearRect(0, 0, canvas.width, canvas.height);
// ផ្ដល់គំនូរជាមួយផ្ទៃខាងក្រោយនៃហ្គេម និងវីរៈតួឡើងវិញ
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "black";
ctx.drawImage(heroImg, hero.x, hero.y);

នេះជារឿងដែលកូដនេះធ្វើ:

  • ធ្វើបច្ចុប្បន្នភាព លេខកូអរដោនេ x របស់វិរុទ្ធដោយ 5 ភិកសែល ក្នុងការផ្លាស់ទីឱ្យចំហៀង
  • សម្អាត សៀវភៅសនៅមូលដ្ឋានរុំជាមួយប្រអប់ទាំងមូលដើម្បីលុបបំបាត់ទំព័រមុន
  • បំពេញ សៀវភៅសដោយពណ៌ខ្មៅផ្ទៃខាងក្រោយ
  • គូរ​ រូបភាពរបស់វិរុទ្ធនៅទីតាំងថ្មីរបស់វា

តើអ្នកអាចគិតបានហេតុអ្វីមួយដែលការគូរវិរុទ្ធជាប្រព័ន្ធរាប់សំណុំគ្រប់ៗគ្នារក្សាទុកអាចបង្កឲ្យមានការចំណាយប្រសិទ្ធភាពខ្ពស់? អានអំពី ជម្រើសជំនួសនៃលំនាំនេះ

គ្រប់គ្រងព្រឹត្តិការណ៍ផ្ទាំងក្តារចុច

នេះគឺជាកន្លែងដែលយើងភ្ជាប់ការបញ្ចូលពីអ្នកលេងទៅសកម្មភាពហ្គេម។ ពេលនរណាម្នាក់ចុច spacebar ដើម្បីបាញ់កាំភ្លើង ឬប៉ះក្តារចុចមុំដើម្បីជៀសវាងត្មួយផ្កាយ យើងត្រូវការឲ្យហ្គេមចាប់សញ្ញានិងឆ្លើយតបនឹងការបញ្ចូលនោះ។

ព្រឹត្តិការណ៍ក្តារចុចកើតឡើងនៅលើបិទបើកវីនដោ (window) មានន័យថាវីនដោកំណត់តម្រូវគ្រប់គ្រងនូវព្រឹត្តិការណ៍ទាំងនោះទាំងមូល។ ចុចម៉ៅស៍ផ្ទាល់ត្រូវបានភ្ជាប់ទៅធាតុជាក់លាក់ទេ (ដូចការចុចប៊ូតុងមួួយ)។ សម្រាប់ហ្គេមអាកាសយានរបស់យើង យើងនឹងផ្តោតទៅលើការគ្រប់គ្រងតាមរយៈក្តារចុចពីព្រោះវ៉ាអាចផ្តល់អារម្មណ៍ហ្គេម arcade ដោយសារៈសំខាន់ដល់អ្នកលេង។

វាបម្រាមជួយជំរាបថាការចុចក្តារចុចមានអត្ថន័យដូចការប្រែសំឡេង ម៉ូស៍កូដ (Morse code) ដែលអ្នកប្រើtelegramនៅសតវត្សទី១៩ត្រូវបម្លែងវាទៅជាសារសំខាន់ៗ យើងកំពុងធ្វើអ្វីដូចគ្នា សន្ទស្សន៏ក្តារចុចទៅជាពាក្យបញ្ជាហ្គេម។

ដើម្បីគ្រប់គ្រងព្រឹត្តិការណ៍ អ្នកត្រូវប្រើវិធីសាស្រ្ត addEventListener() របស់វីនដោ ហើយផ្តល់ឲ្យវាជាមួយប៉ារ៉ាម៉ែត្រពីរពីការបញ្ចូល។ ប៉ារ៉ាម៉ែត្រដំបូងគឺឈ្មោះព្រឹត្តិការណ៍ ចំ. keyup។ ប៉ារ៉ាម៉ែត្រទីពីរគឺមុខងារដែលត្រូវចាប់អ្វីមួយខណៈពេលព្រឹត្តិការណ៍កើតមាន។

ឧទាហរណ៍ខាងក្រោម៖

window.addEventListener('keyup', (evt) => {
  // evt.key = ការប្រតិបត្តិជាស្រមោលសរសេររបស់ក្តារចុច
  if (evt.key === 'ArrowUp') {
    // ធ្វើអ្វីមួយ
  }
});

បំបែកអ្វីកើតឡើងនៅទីនេះ៖

  • ស្តាប់ ព្រឹត្តិការណ៍ក្តារចុចនៅលើវីនដោទាំងមូល
  • ចាប់យក វត្ថុព្រឹត្តិការណ៍ ដែលមានព័ត៌មានអំពីលេខកូដដែលត្រូវបានចុច
  • ពិនិត្យ ថាតើប៊ូតុងមួយៗដែលត្រូវបានចុចផ្គូផ្គងគ្នាជាមួយប៊ូតុងជាក់លាក់ឬនៅ (នៅក្នុងករណីនេះ គឺស៊ុមលើ)
  • អនុវត្ត កូដនៅពេលលក្ខខណ្ឌត្រូវគ្នា

សម្រាប់ព្រឹត្តិការណ៍ក្តារចុច មានលក្ខណៈពិសេសពីរដែលអ្នកអាចប្រើដើម្បីមើលថាតើប៊ូតុងណាត្រូវបានចុច៖

  • key -នេះជាជួរខ្សែតំណាងឱ្យប៊ូតុងដែលត្រូវបានចុច ឧ. 'ArrowUp'
  • keyCode -នេះជាការតំណាងជាលេខ, ឧ. 37, តំណាងនៅ ArrowLeft

ការគ្រប់គ្រងព្រឹត្តិការណ៍ក្តារចុចមានប្រយោជន៍នៅខាងក្រៅការអភិវឌ្ឍហ្គេម។ តើអ្នកអាចគិតបានប្រើប្រាស់ផ្សេងៗជាអ្វីសម្រាប់បច្ចេកទេសនេះ?

sequenceDiagram
    participant User
    participant Browser
    participant EventSystem
    participant GameLogic
    participant Hero
    
    User->>Browser: ចុចក្តារចុច ArrowUp
    Browser->>EventSystem: ព្រឹត្តិការណ៍ keydown
    EventSystem->>EventSystem: preventDefault()
    EventSystem->>GameLogic: emit('KEY_EVENT_UP')
    GameLogic->>Hero: hero.y -= 5
    Hero->>Hero: បន្តភាពតំណាង
    
    Note over Browser,GameLogic: ជំហានព្រឹត្តិការណ៍ទប់ស្កាត់លំនាំដើមរបស់កម្មវិធីរុករក
    Note over GameLogic,Hero: លំនាំ pub/sub អនុញ្ញាតឱ្យមានការផ្ទេរព័ត៌មានល្អ

ប៊ូតុងពិសេស៖ ការពារជាប្រយ័ត្ន!

ខ្លះៗមានរបៀបធ្វើបែបខ្លួនឯងក្នុងកម្មវិធីរុករកដែលអាចបញ្ហាជាមួយហ្គេមរបស់អ្នក។ ប៊ូតុងព្រួញស្លាបផ្ដួលទំព័រ និងប៊ូតុង spacebar លោតចុះ របៀបដែលអ្នកមិនចង់ឲ្យកើតឡើងពេលនរណាម្នាក់កំពុងបើកបរ យន្តហោះរបស់ពួកគេ។

យើងអាចរារាំងរបៀបតាមលំនាំដើមទាំងនេះ ហើយឲ្យហ្គេមរបស់យើងគ្រប់គ្រងចូលខ្ទង់វិញ។ នេះដូចជាពេលអ្នកសរសេរកម្មវិធីកុំព្យូទ័រដ៏ដំបូងត្រូវរារាំងការជ្រៀតចូលមិនគួរឱ្យមាន ពីប្រព័ន្ធ ដើម្បីបង្កើតអាកប្បកិច្ចផ្ទាល់ខ្លួន យើងក៏កំពុងធ្វើបែបនោះនៅកម្រិតកម្មវិធីរុករក។ វាជារបៀបដូចខាងក្រោម៖

const onKeyDown = function (e) {
  console.log(e.keyCode);
  switch (e.keyCode) {
    case 37:
    case 39:
    case 38:
    case 40: // សោរចំណុចបូមុន
    case 32:
      e.preventDefault();
      break; // ចន្លោះ
    default:
      break; // កុំរារាំងកូនសោផ្សេងទៀត
  }
};

window.addEventListener('keydown', onKeyDown);

យល់ដឹងពីកូដរារាំងនេះ៖

  • ពិនិត្យ រកលេខកូដប៊ូតុងជាក់លាក់ដែលអាចបង្កការប្រើប្រាស់មិនចង់បានក្នុងកម្មវិធីរុករក
  • រារាំង សកម្មភាពលំនាំដើមសម្រាប់ប៊ូតុងព្រួញ និង spacebar
  • អនុញ្ញាត ប៊ូតុងផ្សេងទៀតដើរតួធម្មតា
  • ប្រើ e.preventDefault() ដើម្បីបញ្ឈប់អាកប្បកិច្ចរបស់កម្មវិធីរុករក

🔄 ការត្រួតពិនិត្យផ្នែកសិក្សា

ការយល់ដឹងពីការគ្រប់គ្រងព្រឹត្តិការណ៍៖ មុនរំពឹងចូលចលនាស្វ័យប្រវត្តិ សូមប្រាកដថាអ្នកអាច៖

  • ពន្យល់ភាពខុសគ្នារវាងព្រឹត្តិការណ៍ keydown និង keyup
  • យល់ថាប៉ុណ្ណាដូចម្តេចយើងរារាំងអាកប្បកម្មរុករកលំនាំដើម
  • ពិពណ៌នាថាលដ្ឋានព្រឹត្តិការណ៍ភ្ជាប់ការបញ្ចូលអ្នកប្រើទៅលើផ្លូវហ្គេម
  • កំណត់ថាប៊ូតុងណាដែលអាចបញ្ហាជាមួយការគ្រប់គ្រងហ្គេម

តេស្តខ្លីមួយ៖ តង្វើអ្វីប្រសិនបើអ្នកមិនរារាំងអាកប្បកម្មលំនាំដើមសម្រាប់ប៊ូតុងព្រួញ?
ចម្លើយ៖ កម្មវិធីរុករកនឹងរំកិលទំព័រ ប៉ះបញ្ហាចលនាហ្គេម

រចនាសម្ព័ន្ធប្រព័ន្ធព្រឹត្តិការណ៍៖ ឥឡូវនេះ អ្នកយល់ថា៖

  • ស្ដាប់ព្រឹត្តិការណ៍នៅកម្រិតវីនដោ៖ ចាប់ព្រឹត្តិការណ៍នៅកម្រិតកម្មវិធីរុករក
  • លក្ខណៈវត្ថុព្រឹត្តិការណ៍៖ ខ្សែអក្សរសម្រាប់ key ទល់នឹងលេខសម្រាប់ keyCode
  • ការរារាំងលំនាំដើម៖ បោះបង់អាកប្បកម្មរុករកមិនចង់បាន
  • យុទ្ធសាស្ត្រកំណត់លក្ខខណ្ឌ៖ ឆ្លើយតបនៅលើប៊ូតុងជាក់លាក់

ចលនាដែលហ្គេមបង្កើតហើយ

ឥឡូវនេះ យើងនិយាយអំពីវត្ថុដែលផ្លាស់ទីដោយគ្មានការបញ្ចូលពីអ្នកលេង។ គិតអំពីនាវាសត្រូវហោះបេីកលើអេក្រង់, កាំភ្លើងប៊ុល្លេតហោះជាន់ត្រង់ ឬពពកហោះផ្លាស់ទីនៅក្រោយ។ ចលនាស្វ័យប្រវត្តិនេះធ្វើឲ្យពិភពហ្គេមរបស់អ្នកមានជីវិតទើបមិនថានរណាម្នាក់អាចប៉ះពាល់ការគ្រប់គ្រងក៏ដោយ។

យើងប្រើម៉ោងរាប់វិនាទីដែលបានបង្កើតរួចក្នុង JavaScript ដើម្បីធ្វើបច្ចុប្បន្នភាពទីតាំងជាប្រចាំ។ គំនិតនេះស្រដៀងនឹងម៉ោងជណ្តើរទឹក ប្រព័ន្ធធម្មតាមួយដែលបញ្ចេញសកម្មភាពគ្រប់គ្រងរយៈពេលជាប្រចាំ។ ខាងក្រោមជារបៀបដែលវាសាមញ្ញ៖

const id = setInterval(() => {
  // បញ្ជូនសត្រូវទៅលើអ័ក្ស y
  enemy.y += 10;
}, 100);

នេះជារឿងដែលកូដចលនានេះធ្វើ:

  • បង្កើត ម៉ោងរាប់វិនាទីដែលដំណើរការជារៀងរាល់ 100 មីលីវិនាទី
  • ធ្វើបច្ចុប្បន្នភាព លេខកូអរដោនេ y របស់សត្រូវដោយ 10 ភិកសែលគ្រប់ពេល
  • រក្សា លេខសម្គាល់រង្វាស់ម៉ោងនោះ ដើម្បីបញ្ឈប់វាបានបន្ទាប់ប្រសិនបើចាំបាច់
  • ផ្លាស់ទី សត្រូវចុះក្រោមអេក្រង់ដោយស្វ័យប្រវត្តិ

រង្វង់ហ្គេម

នេះជាគំនិតដែលភ្ជាប់គ្រប់យ៉ាងទាំងអស់ រង្វង់ហ្គេម។ ប្រសិនបើហ្គេមរបស់អ្នកជាផលិតកម្មភាពយន្ត រង្វង់ហ្គេមនឹងជាឧបករណ៍បញ្ចាំងទាំងអស់ បង្ហាញទំព័រតាមទំព័រយ៉ាងរហ័សទាំងដែលឲ្យមើលឃើញចលនាត្រង់សុភាព។

គ្រប់ហ្គេមមានរង្វង់បែបនេះដែលដំណើរការក្រោយឆatem។ វាជាមុខងារដែលធ្វើបច្ចុប្បន្នភាពវត្ថុរបស់ហ្គេមទាំងអស់ គូរឡើងវិញអេក្រង់ និងធ្វើឡើងម្ដងម្កាលជាបន្តបន្ទាប់។ វាអាចតាមដានវិរុទ្ធរបស់អ្នក រួមទាំងសត្រូវ ទាំងកាំភ្លើង និងសភាពហ្គេមទាំងមូល។

គំនិតនេះធ្វើឲ្យចង្អុលបង្ហាញពីរបៀបដែលអ្នកគូរអាណីម៉េត័រប្រទេសដើមជាមួយ Walt Disney ជាលំដាប់ផ្ទាល់ដោយគូរតួអង្គមួយៗជាទំព័រដើម្បីបង្កើតអារម្មណ៍ចលនា។ យើងកំពុងធ្វើដូចគ្នា តែប្រើកូដជំនួសថែមពីនខ្មៅ។

នេះជារូបមន្តមួយសម្រាប់រង្វង់ហ្គេម ដាក់ជាកូដ៖

flowchart TD
    A["ចាប់ផ្តើមរង្វិលហ្គេម"] --> B["សម្អាតផ្ទៃគំនូរ"]
    B --> C["បំពេញផ្ទៃខាងក្រោយ"]
    C --> D["បន្ទាន់សម័យវត្ថុហ្គេម"]
    D --> E["គូរវីរុស"]
    E --> F["គូរទាហានចូលលេប"]
    F --> G["គូរគ្រឿងចក្រ UI"]
    G --> H["រង់ចាំស្ដង់ដារថ្មី"]
    H --> I{ហ្គេមកំពុងដំណើរការ?}
    I -->|បាទ| B
    I -->|ទេ| J["បញ្ចប់ហ្គេម"]
    
    subgraph "ការត្រួតពិនិត្យអត្រាថតរូប"
        K["60 FPS = 16.67ms"]
        L["30 FPS = 33.33ms"]
        M["10 FPS = 100ms"]
    end
    
    style B fill:#ffebee
    style D fill:#e1f5fe
    style E fill:#e8f5e8
    style F fill:#e8f5e8
const gameLoopId = setInterval(() => {
  function gameLoop() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = "black";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    drawHero();
    drawEnemies();
    drawStaticObjects();
  }
  gameLoop();
}, 200);

យល់ដឹងពីរចនាសម្ព័ន្ធរង្វង់ហ្គេម៖

  • សម្អាត សៀវភៅសទាំងមូលដើម្បីលុបតំបន់យោងមុន
  • បំពេញ ផ្ទៃខាងក្រោយជាពណ៌រឹងមាំ
  • គូរ វត្ថុហ្គេមទាំងអស់នៅទីតាំងបច្ចុប្បន្នរបស់ពួកវា
  • ធ្វើឡើងម្ដងម្កាល ជារៀងរាល់ 200 មីលីវិនាទី ដើម្បីបង្កើតអាណីម៉េសិនរលូន
  • គ្រប់គ្រង ល្បឿនបង្ហាញពីរបៀបគ្រប់គ្រងរយៈពេលរង្វង់

បន្តហ្គេមអាកាសយាន

ឥឡូវយើងនឹងបន្ថែមចលនាចូលទៅក្នុងទេសភាពស្ងាត់ដែលអ្នកបានបង្កើតមុននេះ។ យើងនឹងបម្លែងវាពីរូបភាពថតទៅជាបទពិសោធន៍អន្តរកម្ម។ យើងនឹងធ្វើការដោយជំហាន តាមដានត្រឹមត្រូវទៅជាគ្នា។

ទាញយកកូដពីកន្លែងដែលយើងបានរួចនៅមេរៀនមុន (ឬចាប់ផ្តើមជាមួយកូដក្នុងថត Part II- starter ប្រសិនបើអ្នកត្រូវការចាប់ផ្តើមថ្មី)។

នេះគឺអ្វីដែលយើងកំពុងសាងសង់ថ្ងៃនេះ៖

  • ការគ្រប់គ្រងវិរុទ្ធ៖ ប៊ូតុងព្រួញនឹងបើកបរ យន្តហោះរបស់អ្នកនៅរង្វង់អេក្រង់
  • ចលនាសត្រូវ៖ នាវាអ alien នឹងចាប់ផ្តើមចាក់ដំណើរការ

ចាប់ផ្តើមអនុវត្តលក្ខណះទាំងនេះ។

ជំហានដែលសូមណែនាំ

ស្វែងរកឯកសារដែលបានបង្កើតសម្រាប់អ្នកក្នុងថត your-work។ វាគួរតែមានអ្វីខាងក្រោម៖

-| assets
  -| enemyShip.png
  -| player.png
-| index.html
-| app.js
-| package.json

អ្នកចាប់ផ្តើមគម្រោងរបស់អ្នកនៅក្នុងថត your-work ដោយវាយបញ្ជា៖

cd your-work
npm start

អ្វីដែលពាក្យបញ្ជានេះធ្វើ:

  • ចូលទៅថតគម្រោងរបស់អ្នក
  • ចាប់ផ្តើម ម៉ាស៊ីនមេ HTTP នៅអាសយដ្ឋាន http://localhost:5000
  • បម្រើ ឯកសារហ្គេមរបស់អ្នក ដើម្បីអ្នកអាចសាកល្បងក្នុងកម្មវិធីរុករក

ខាងលើនឹងចាប់ផ្តើមម៉ាស៊ីនមេ HTTP នៅអាសយដ្ឋាន http://localhost:5000។ បើកកម្មវិធីរុករក ហើយបញ្ចូលអាសយដ្ឋាននោះ ឥឡូវវាគួរតែបង្ហាញវិរុទ្ធ និងសត្រូវទាំងអស់; មិនមានអ្វីផ្លាស់ទីទេ - រហូតដល់ឥឡូវ!

បន្ថែមកូដ

  1. បន្ថែមវត្ថុផ្តល់ការ សម្រាប់ hero និង enemy និង game object ពួកវាគួរតែមានគុណលក្ខណៈ x និង y។ (ចងចាំផ្នែក Inheritance ឬ composition)។

    សំគាល់ game object គួរតែជាវត្តុដែលមាន x និង y និងមានសមត្ថភាពគូរទៅ canvas។

    ជំនួយ៖ ចាប់ផ្តើមដោយបន្ថែមថ្នាក់ GameObject ថ្មីដែលមាន constructor ដូចខាងក្រោម ហើយបន្ទាប់មកគូរវាទៅ canvas៖

    class GameObject {
      constructor(x, y) {
        this.x = x;
        this.y = y;
        this.dead = false;
        this.type = "";
        this.width = 0;
        this.height = 0;
        this.img = undefined;
      }
    
      draw(ctx) {
        ctx.drawImage(this.img, this.x, this.y, this.width, this.height);
      }
    }
    

    យល់ដឹងពីថ្នាក់មូលដ្ឋាននេះ:

    • កំណត់ គុណលក្ខណៈសមរម្យដែលវត្ថុហ្គេមទាំងអស់ប្រើរួមគ្នា (ទីតាំង, ទំហំ, រូបភាព)
    • រួមបញ្ចូល ទង់ស្លា dead ដើម្បីតាមដានថាវត្ថុនោះគួរតែបានលុបចោលឬយ៉ាងណា
    • ផ្តល់ មុខងារ draw() ដែលគូរវត្ថុទៅលើ canvas
    • កំណត់ តម្លៃលំនាំដើមសម្រាប់គុណលក្ខណៈទាំងអស់ដែលថ្នាក់កូនអាចលើកឡើងបាន
classDiagram
    class GameObject {
        +x: number
        +y: number
        +dead: boolean
        +type: string
        +width: number
        +height: number
        +img: រូបភាព
        +draw(ctx)
    }
    
    class Hero {
        +speed: ចំនួន
        +type: "វីរបុរស"
        +width: 98
        +height: 75
    }
    
    class Enemy {
        +type: "សត្រូវ"
        +width: 98
        +height: 50
        +setInterval()
    }
    
    GameObject <|-- Hero
    GameObject <|-- Enemy
    
    class EventEmitter {
        +listeners: វត្ថុ
        +on(សារ, អ្នកស្តាប់)
        +emit(សារ, ទម្រង់ទិន្នន័យ)
    }
ឥឡូវនេះ បន្ថែមពីថ្នាក់ `GameObject` ដើម្បីបង្កើត `Hero` និង `Enemy`៖

```javascript
class Hero extends GameObject {
  constructor(x, y) {
    super(x, y);
    this.width = 98;
    this.height = 75;
    this.type = "Hero";
    this.speed = 5;
  }
}
```

```javascript
class Enemy extends GameObject {
  constructor(x, y) {
    super(x, y);
    this.width = 98;
    this.height = 50;
    this.type = "Enemy";
    const id = setInterval(() => {
      if (this.y < canvas.height - this.height) {
        this.y += 5;
      } else {
        console.log('Stopped at', this.y);
        clearInterval(id);
      }
    }, 300);
  }
}
```

**គំនិតសំខាន់ក្នុងថ្នាក់ទាំងនេះ៖**
- **ទទួលបន្លាស់** ពី `GameObject` ដោយប្រើពាក្យគន្លង `extends`
- **ហៅ** កំណត់ constructor ប៉ារ៉េនត៍ជាមួយ `super(x, y)`
- **កំណត់** ទំហំនិងគុណលក្ខណៈជាក់លាក់ សម្រាប់វត្ថុបែបផ្សេងៗ
- **អនុវត្ត** ចលនាស្វ័យប្រវត្តិសម្រាប់សត្រូវដោយប្រើ `setInterval()`
  1. បន្ថែមអ្នកចាប់ព្រឹត្តិការណ៍គ្រប់គ្រង key-event សម្រាប់គ្រប់គ្រងការត្រួតពិនិត្យក្តារចុច (ចលាវិរុទ្ធឡើង/ចុះឆ្វេង/ស្តាំ)

    ចងចាំ វាជាប្រព័ន្ធកាតេស៊្យាន(top-left ជា 0,0) ហើយចងចាំបន្ថែមកូដដើម្បីបញ្ឈប់ អាកប្បកម្មលំនាំដើម

    ជំនួយ៖ បង្កើតមុខងារ onKeyDown របស់អ្នក ហើយភ្ជាប់ចូលទៅកាន់វីនដោ៖

    const onKeyDown = function (e) {
      console.log(e.keyCode);
      // បន្ថែមកូដពីមេរៀនខាងលើដើម្បីបញ្ឈប់អាកប្បកិរិយាដើម
      switch (e.keyCode) {
        case 37:
        case 39:
        case 38:
        case 40: // ចំណុចមួយៗជំរុញ
        case 32:
          e.preventDefault();
          break; // កន្លែងទទេ
        default:
          break; // កុំបិទខ្ទប់កូនសោផ្សេងទៀត
      }
    };
    
    window.addEventListener("keydown", onKeyDown);
    

    អ្វីដែលអ្នកគ្រប់គ្រងព្រឹត្តិការណ៍នេះធ្វើ:

    • ស្តាប់ ព្រឹត្តិការណ៍ keydown នៅលើវីនដោទាំងមូល
    • កត់ត្រា លេខកូដប៊ូតុង ដើម្បីជួយអ្នករកកំហុស ថាតើប៊ូតុងណាត្រូវបានចុច
    • រារាំង អាកប្បកម្មលំនាំដើមសម្រាប់ប៊ូតុងព្រួញនិង spacebar
    • អនុញ្ញាត ប៊ូតុងផ្សេងៗដើរតួធម្មតា

    ពិនិត្យកុងសូលកម្មវិធីរុករករបស់អ្នកនៅពេលនេះ ហើយមើលកំណត់ត្រាការចុចចុច។

  2. អនុវត្តន៍ លំនាំ Pub sub pattern ដែលនឹងគ្រប់គ្រងកូដរបស់អ្នកឱ្យស្អាតពេលអ្នកធ្វើតាមផ្នែកដែលនៅសល់។

    លំនាំ Publish-Subscribe ជួយរៀបចំកូដរបស់អ្នកដោយបំបែកការចាប់សញ្ញាព្រឹត្តិការណ៍ពីការគ្រប់គ្រង ព្រមទាំងធ្វើឲ្យកូដរបស់អ្នកគឺមានម៉ូឌុល និងងាយស្រួលថែរក្សា។

    ដើម្បីធ្វើផ្នែកចុងក្រោយនេះ អ្នកអាច៖

    1. បន្ថែមអ្នកស្តាប់ព្រឹត្តិការណ៍ នៅលើវីនដោ៖

      window.addEventListener("keyup", (evt) => {
        if (evt.key === "ArrowUp") {
          eventEmitter.emit(Messages.KEY_EVENT_UP);
        } else if (evt.key === "ArrowDown") {
          eventEmitter.emit(Messages.KEY_EVENT_DOWN);
        } else if (evt.key === "ArrowLeft") {
          eventEmitter.emit(Messages.KEY_EVENT_LEFT);
        } else if (evt.key === "ArrowRight") {
          eventEmitter.emit(Messages.KEY_EVENT_RIGHT);
        }
      });
      

    អ្វីដែលប្រព័ន្ធព្រឹត្តិការណ៍នេះធ្វើ:

    • ចាប់ ការបញ្ចូលពីក្តារចុច និងបម្លែងវាទៅជាព្រឹត្តិការណ៍ហ្គេមផ្ទាល់ខ្លួន
    • បំបែក ការចាប់សញ្ញាពីផ្លូវហ្គេម
    • ធ្វើឲ្យ ប្រែប្រួលការគ្រប់គ្រងបានយ៉ាងងាយស្រួលក្រោយពេលនេះដោយមិនប៉ះពាល់កូដហ្គេម
    • អនុញ្ញាត ប្រព័ន្ធច្រើនឆ្លើយតបនឹងដំណើរការ តែមួយសញ្ញា
flowchart TD
    A["ការបញ្ចូលក្បាលពុម្ព"] --> B["អ្នកស្តាប់ព្រឹត្តិការណ៍បង្អួច"]
    B --> C["អ្នកបញ្ចេញព្រឹត្តិការណ៍"]
    C --> D["KEY_EVENT_UP"]
    C --> E["KEY_EVENT_DOWN"]
    C --> F["KEY_EVENT_LEFT"]
    C --> G["KEY_EVENT_RIGHT"]
    
    D --> H["ចលនាមនុស្សវីរភាព"]
    D --> I["ប្រព័ន្ធសម្លេង"]
    D --> J["ផលប៉ះពាល់រូបភាព"]
    
    E --> H
    F --> H
    G --> H
    
    style A fill:#e1f5fe
    style C fill:#e8f5e8
    style H fill:#fff3e0
  1. បង្កើតថ្នាក់ EventEmitter ដើម្បីបោះពុម្ពផ្សាយ និងចុះជាវ ការប្រាស្រ័យទាក់ទង៖

    class EventEmitter {
      constructor() {
        this.listeners = {};
      }
    
      on(message, listener) {
        if (!this.listeners[message]) {
          this.listeners[message] = [];
        }
        this.listeners[message].push(listener);
      }
    
    
  2. បន្ថែមអថេរ និងរៀបចំ EventEmitter៖

    const Messages = {
      KEY_EVENT_UP: "KEY_EVENT_UP",
      KEY_EVENT_DOWN: "KEY_EVENT_DOWN",
      KEY_EVENT_LEFT: "KEY_EVENT_LEFT",
      KEY_EVENT_RIGHT: "KEY_EVENT_RIGHT",
    };
    
    let heroImg, 
        enemyImg, 
        laserImg,
        canvas, ctx, 
        gameObjects = [], 
        hero, 
        eventEmitter = new EventEmitter();
    

យល់ដឹងអំពីការរៀបចំ:

  • កំណត់ អថេរពាក្យសារ ដើម្បីជៀសវាងកំហុសហ្រ្វាំ និងងាយស្រួលកែលម្អ
  • ប្រកាស អថេររូបភាព, context canvas និងស្ថានភាពហ្គេម
  • បង្កើត រង្វង់ព្រឹត្តិការណ៍សកលសំរាប់ប្រព័ន្ធ pub-sub
  • ចាប់ផ្តើម អារេ ដែលផ្ទុកវត្ថុហ្គេមទាំងអស់
  1. ចាប់ផ្តើមហ្គេម

    function initGame() {
      gameObjects = [];
      createEnemies();
      createHero();
    
      eventEmitter.on(Messages.KEY_EVENT_UP, () => {
        hero.y -= 5;
      });
    
      eventEmitter.on(Messages.KEY_EVENT_DOWN, () => {
        hero.y += 5;
      });
    
      eventEmitter.on(Messages.KEY_EVENT_LEFT, () => {
        hero.x -= 5;
      });
    
    
  2. រៀបចំ លំហូរ​ហ្គេម

    បម្លែងមុខងារ window.onload ដើម្បីចាប់ផ្ដើមហ្គេម និងរៀបចំលំហូរ​ហ្គេមនៅលើចន្លោះពេលល្អមួយ។ អ្នកនឹងបន្ថែមកាំភ្លើងលេស័រមួយផងដែរ៖

    window.onload = async () => {
      canvas = document.getElementById("canvas");
      ctx = canvas.getContext("2d");
      heroImg = await loadTexture("assets/player.png");
      enemyImg = await loadTexture("assets/enemyShip.png");
      laserImg = await loadTexture("assets/laserRed.png");
    
      initGame();
      const gameLoopId = setInterval(() => {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.fillStyle = "black";
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        drawGameObjects(ctx);
      }, 100);
    };
    

    យល់ដឹងអំពីការរៀបចំហ្គេម៖

    • រង់ចាំ ទំព័រត្រូវបានផ្ទុកពេញលេញមុនចាប់ផ្ដើម
    • យក ធាតុ canvas និង context សំរាប់គំនូរ 2D របស់វា
    • ផ្ទុក រូបភាពទាំងអស់យ៉ាងអាស៊ីនខណៈដោយប្រើ await
    • ចាប់ផ្ដើម លំហូរហ្គេមដែលរត់ជាប្រក្រឹត់លើចន្លោះ 100ms (10 FPS)
    • សំអាត និងគូរសារឡើងវិញអេក្រង់ទាំងមូលក្នុងរាល់ខ្ទង់ពេល
  3. បន្ថែមកូដ ដើម្បីផ្លាស់ទីសត្រូវនៅចន្លោះពេលជាក់លាក់

    បម្លែងមុខងារ createEnemies() ដើម្បីបង្កើតសត្រូវ និងដាក់ពួកវាទៅក្នុងថ្នាក់ gameObjects ថ្មី៖

    function createEnemies() {
      const MONSTER_TOTAL = 5;
      const MONSTER_WIDTH = MONSTER_TOTAL * 98;
      const START_X = (canvas.width - MONSTER_WIDTH) / 2;
      const STOP_X = START_X + MONSTER_WIDTH;
    
      for (let x = START_X; x < STOP_X; x += 98) {
        for (let y = 0; y < 50 * 5; y += 50) {
          const enemy = new Enemy(x, y);
          enemy.img = enemyImg;
          gameObjects.push(enemy);
        }
      }
    }
    

    អ្វីដែលការបង្កើតសត្រូវធ្វើ៖

    • គណនាបរិយាកាស ដើម្បីមធ្យមសត្រូវនៅលើអេក្រង់
    • បង្កើត បណ្តាញសត្រូវដោយប្រើរបៀបរំលងស្រួចៗ
    • ផ្ដល់ រូបភាពសត្រូវទៅគ្រប់វត្ថុសត្រូវ
    • បន្ថែម គ្រប់សត្រូវចូលទៅក្នុងអារ​យ៉ាងលំដាប់លំដោយតាមកូដប្រព័ន្ធសកល

    ហើយបន្ថែមមុខងារ createHero() ដើម្បីធ្វើដូចគ្នាសម្រាប់វីរបុរស។

    function createHero() {
      hero = new Hero(
        canvas.width / 2 - 45,
        canvas.height - canvas.height / 4
      );
      hero.img = heroImg;
      gameObjects.push(hero);
    }
    

    អ្វីដែលការបង្កើតវីរបុរសធ្វើ៖

    • ចាក់ទីតាំង វីរបុរសនៅចំណុចខាងក្រោមកណ្ដាលអេក្រង់
    • ផ្ដល់ រូបភាពវីរបុរសទៅវត្ថុវីរបុរស
    • បន្ថែម វីរបុរសទៅក្នុងអារ game objects សម្រាប់គំនូរ

    ហើយចុងបញ្ចប់ បន្ថែមមុខងារ drawGameObjects() ដើម្បីចាប់ផ្ដើមគូរវត្ថុ:

    function drawGameObjects(ctx) {
      gameObjects.forEach(go => go.draw(ctx));
    }
    

    យល់ដឹងអំពីមុខងារគូរ៖

    • ធ្វើបន្ទាត់ តាមរយៈវត្ថុំហ្គេមទាំងអស់ក្នុងអារ
    • ហៅ មុខងារ draw() លើគ្រប់វត្ថុ
    • ផ្ដល់ context canvas ដូច្នេះវត្ថុអាចគូរផ្ទាល់ខ្លួន

    🔄 ពិនិត្យការយល់ដឹង​ចំណេះដឹង

    យល់ដឹងឆ្លាតវៃអំពីប្រព័ន្ធហ្គេមសរុប៖ ពិនិត្យការយល់ដឹងរបស់អ្នកអំពីសំណង់ទាំងមូល៖

    • តើការចិញ្ចើមធ្វើឲ្យ Hero និង Enemy ចែករំលែកលក្ខណៈ GameObject យ៉ាងដូចម្តេច?
    • ហេតុអ្វីបានជា​របៀប pub/sub ធ្វើឲ្យកូដរបស់អ្នកអាចថែរក្សาง่ายជាងមុន?
    • តើលំហូរហ្គេមមានតួនាទីអ្វីក្នុងការបង្កើតអង់ម៉ាស៊ីនរលូន?
    • តើអ្នកស្ដាប់ព្រឹតិ្តការណ៍ភ្ជាប់ការបញ្ចូលរបស់អ្នកប្រើទៅនឹងអាកប្បកិរិយាវត្ថុហ្គេមដូចម្តេច?

    ការរួមបញ្ចូលប្រព័ន្ធ៖ ហ្គេមរបស់អ្នកឥឡូវនេះបង្ហាញថា៖

    • រចនាបថអចិន្រ្តៃយ៍៖ ថ្នាក់មូលដ្ឋានដែលមានការចិញ្ចើមជាពិសេស
    • សំណង់លើព្រឹតិ្តការណ៍៖ របៀប pub/sub សម្រាប់ការតភ្ជាប់បន្តួយៗ
    • ស៊ុមខ្សែអនុភាព៖ លំហូរហ្គេមដែលមានការអាប់ដេតថេរៗ
    • សម្ភារៈបញ្ចូល៖ ព្រឹតិ្តការណ៍ក្តារចុចជាមួយការព្រមានលំនាំដើម
    • គ្រប់គ្រងទ្រព្យសម្បត្តិ៖ ការផ្ទុករូបភាព និងគូរបង្ហាញ sprites

    គំរូវិជ្ជាជីវៈ៖ អ្នកបានអនុវត្ត៖

    • បំបែកការទំនួលខុសត្រូវ៖ បញ្ចូល, តុល្យភាព និងគំនូរត្រូវបានបំបែក
    • ពហុរាង៖ គ្រប់វត្ថុហ្គេមចែករំលែកផ្ទាំងតំណាងគូរ
    • ផ្លូវសារ៖ ការប្រាស្រ័យទាក់ទងស្អាតរវាងក្រុមផ្សេងៗ
    • គ្រប់គ្រងធនធាន៖ ការគ្រប់គ្រងស្ព្រាយ និងអនុភាពមានប្រសិទ្ធិភាព

    សត្រូវរបស់អ្នកគួរតែចាប់ផ្ដើមរំកិលទៅលើកប៉ាល់មហានៅរបស់អ្នកហើយ! } }

    
    and add a `createHero()` function to do a similar process for the hero.
    
    ```javascript
    function createHero() {
      hero = new Hero(
        canvas.width / 2 - 45,
        canvas.height - canvas.height / 4
      );
      hero.img = heroImg;
      gameObjects.push(hero);
    }
    

    ហើយចុងបញ្ចប់ បន្ថែមមុខងារ drawGameObjects() ដើម្បីចាប់ផ្ដើមគូរវត្ថុ:

    function drawGameObjects(ctx) {
      gameObjects.forEach(go => go.draw(ctx));
    }
    

    សត្រូវរបស់អ្នកគួរតែចាប់ផ្ដើមរំកិលទៅលើកប៉ាល់មហានៅរបស់អ្នកហើយ!


ការប្រកួត GitHub Copilot Agent 🚀

នេះជាការប្រកួតមួយដែលនឹងធ្វើឲ្យហ្គេមរបស់អ្នកមានភាពរលោងជាងមុន៖ បន្ថែមដែនកំណត់ និងការគ្រប់គ្រងរលូន។ នៅពេលនេះ វីរបុរសរបស់អ្នកអាចហោះទៅខាងក្រៅអេក្រង់ ហើយក៏ចលនាក៏អាចមានអារម្មណ៍ថា មិនរលោងទេ។

បេសកកម្មរបស់អ្នក៖ ធ្វើឲ្យកប៉ាល់មហានៅរបស់អ្នកមានអារម្មណ៍ស្របតាមការពិតជាងមុន ដោយអនុវត្តដែនកំណត់អេក្រង់ និងចលនារលូន។ វានៅស្រដៀងនឹងប្រព័ន្ធគ្រប់គ្រងបញ្ជាការហោះហើររបស់ NASA ដែលការពារកាឡាក់ភ័ឡង់ពីការលំលងចំណុចប្រតិបត្តិការដែលមានសុវត្ថិភាព។

អ្វីដែលត្រូវបង្កើត៖ បង្កើតប្រព័ន្ធដែលរក្សាវីរបុរសរបស់អ្នកនៅលើអេក្រង់ ហើយធ្វើឲ្យការគ្រប់គ្រងមានភាពរលោង។ នៅពេលអ្នកលេងចុចរាល់លើប៊ូតុងអក្សរបស់ភ្លើងដែលចុច។ កប៉ាល់គួរជ្រេបទៅមុខបន្តបន្ទាប់ មិនមែនផ្លាស់ទីតាមជំហានតែមួយៗទេ។ ពិចារណាបន្ថែមមាតិកាដែលបង្ហាញរូបភាពពេលកប៉ាល់ដល់ដែនកំណត់អេក្រង់ — ប្រហែលជា​អេហ្វធីតតូចៗមួយដើម្បីបង្ហាញដែនលេង។

​សូមស្វែងយល់បន្ថែមអំពី ម៉ូដ​ក្នុង​តំណាង នៅទីនេះ។

🚀 ការប្រកួត

ការរៀបចំកូដកាន់តែមានសារៈសំខាន់បន្ថែមឡើងពេលគម្រោងធំឡើង។ អ្នកអាចមានមើលឃើញថា​ឯកសាររបស់អ្នកពោរពេញដោយមុខងារ អថេរ និងថ្នាក់។ វាជារៀនសូត្រដូចជាអ្នកវិស្វករសម្រាប់ការរៀបចំកូដភាគច្រើនដែលក្រុមនានាត្រូវបានធ្វើការជាមួយគ្នា។

បេសកកម្មរបស់អ្នក៖ គិតដូចជាវិស្វករពហុកម្មវិធី។ តើអ្នកនឹងរៀបចំកូដរបស់អ្នកដូចម្តេច ដើម្បីឲ្យប្រាំមួយខែទៀត អ្នកឬសមាជិកក្រុមអាចយល់ពីអ្វីកំពុងកើតឡើង? ទោះបីឯកសារទាំងអស់នៅក្នុងឯកសារមួយ ក៏អ្នកអាចបង្កើតការរៀបចំដែលល្អជាងនេះ៖

  • ក្រុមមុខងារពាក់ព័ន្ធគ្នា ជាមួយក្បួនមតិការអធិប្បាយច្បាស់លាស់
  • បំបែកការទំនួលខុសត្រូវ - រក្សាគ្រប់គ្រងហ្គេមពីការជួរមុខគំនូរ
  • ប្រើកំណត់ឈ្មោះយ៉ាងត្រឹមត្រូវ សម្រាប់អថេរ និងមុខងារ
  • បង្កើតម៉ូឌុល ឬ namespace ដើម្បីរៀបចំផ្នែកផ្សេងៗក្នុងហ្គេម
  • បន្ថែមឯកសារសង្ខេប ដែលពន្យល់ពីគោលបំណងនៃផ្នែកធម្មតាៗ

សំណួរពិចារណា៖

  • តើផ្នែកណានៃកូដរបស់អ្នកពិបាកយល់បំផុត នៅពេលអ្នកត្រឡប់មកវិញ?
  • តើអ្នកអាចរៀបចំកូដរបស់អ្នកដូចម្តេច ដើម្បីធ្វើឲ្យមនុស្សផ្សេងទៀតអាចរួមចំណែកបានកាន់តែងាយស្រួល?
  • តើអ្វីនឹងកើតឡើង ប្រសិនបើអ្នកចង់បន្ថែមមុខងារថ្មីៗ ដូចជាពូម៉ឺ up ឬ ប្រភេទសត្រូវផ្សេងទៀត?

សំនួរប្រឡងបន្ទាប់ពីមេរៀន

សំនួរប្រឡងបន្ទាប់ពីមេរៀន

ពិនិត្យឡើងវិញ & ការសិក្សាឯករាជ្យ

យើងបានបង្កើតគ្រប់អ្វីពីដើម ដែលវាអស្ចារ្យសម្រាប់ការរៀន ប៉ុន្តែល្អប្រសើរជាងនេះ មាន框架 JavaScript ខ្លះៗដែលអាចធ្វើការទាញទំនិញធ្ងន់ធ្ងរច្រើនសម្រាប់អ្នក។ បន្ទាប់ពីអ្នកមានអារម្មណ៍ស្រួលល្អជាមួយមូលដ្ឋានយើងបានគ្រប់ដ្ឋាន អ្នកគួរតែ ស្វែងយល់វត្ថុដែលអាចប្រើបាន

គិតថា 框架ដូចជា ប្រដាប់ឧបករណ៍ដែលមានឧបករណ៍ពេញលេញជំនួសអំពីការធ្វើឧបករណ៍ដោយដៃ។ វាអាចដោះស្រាយបញ្ហានៃការរៀបចំកូដយើងបាននិយាយ និងផ្តល់លក្ខណៈពិសេសដែលត្រូវការពេលប៉ុន្មានសប្តាហ៍ដើម្បីបង្កើតដោយខ្លួនឯង។

រឿងដែលគួរនៅស្វែងយល់៖

  • របៀបដែលហ្គេមម៉ាស៊ីនរៀបចំកូដ - អ្នកនឹងភ្ញាក់ផ្អើលពីគំរូវៃឆ្លាតដែលពួកគេប្រើ
  • ល្បិចប្រសិទ្ធភាពសម្រាប់ធ្វើឲ្យហ្គេម canvas រត់រលូន
  • លក្ខណៈពិសេស JavaScript សម័យថ្មីដែលអាចធ្វើឲ្យកូដអ្នកស្អាតនិងថែទាំបានងាយ
  • មធ្យោបាយផ្សេងៗក្នុងការគ្រប់គ្រងវត្ថុហ្គេម និងទំនាក់ទំនងរបស់ពួកវា

🎯 របៀបម៉ាស៊ីនរូបភាពហ្គេមរបស់អ្នក

timeline
    title ការរៀនអំពីផ្នែកចលនា និងអន្តរការ ឯកទេសហ្គេម
    
    section មូលដ្ឋានចលនា (២០ នាទី)
        គោលការណ៍ អ្នកចលនា: ស៊េរីឯកសារជារូបភាព
                            : ការអាប់ដេតទីតាំង
                            : ប្រព័ន្ធកូអរដោនេ이트
                            : ចលនារលូន
        
    section ប្រព័ន្ធព្រឹត្តិការណ៍ (២៥ នាទី)
        បញ្ចូលអ្នកប្រើ: ការគ្រប់គ្រងព្រឹត្តិការណ៍ក្តាស់ក្លាវ
                      : ការកាត់បន្ថយការជីកអោយមានការសកម្មឯកសារ
                      : លក្ខណៈព្រឹត្តិការណ៍វត្ថុ
                      : ការស្តាប់នៅលើបន្ទាត់បង្អួច
        
    section រចនាសម្ព័ន្ធហ្គេម (៣០ នាទី)
        ការរចនាវត្ថុ: រចនាបថបInheritance
                     : បង្កើតថ្នាក់មេ
                     : អាកប្បកិរិយាពិសេស
                     : ចំណុចប្រទាក់ងាយបម្លែង
        
    section រចនាបទការទំនាក់ទំនង (៣៥ នាទី)
        ការអនុវត្ត Pub/Sub: អ្នកបញ្ចេញព្រឹត្តិការណ៍
                            : អចលនាប័ណ្ណសារ
                            : ការតភ្ជាប់រាបសារ
                            : ការរួមបញ្ចូលប្រព័ន្ធ
        
    section ជំនាញវដ្តហ្គេម (៤០ នាទី)
        ប្រព័ន្ធពេលពិត: ការគ្រប់គ្រងអត្រារ៉េម
                         : វដ្តកែប្រែ/បង្ហាញ
                         : ការគ្រប់គ្រងស្ថានភាព
                         : បង្កើនប្រសិទ្ធភាព
        
    section បច្ចេកទេសខ្ពស់ (៤៥ នាទី)
        លក្ខណៈជំនាញ: ការរកឃើញការប៉ះទង្គិច
                         : ការសំឡេងហ័រ
                         : ម៉ាស៊ីនស្ថានភាព
                         : ប្រព័ន្ធបន្ទុក
        
    section គំនិតម៉ាស៊ីនហ្គេម (១ សប្តាហ៍)
        ការយល់ដឹងស៊េរី: ប្រព័ន្ធអង្គភាព-ផ្សេងៗ
                           : ក្រាហ្វភីបន្ទះ
                           : បណ្តោយទ្រព្យសម្បត្តិ
                           : ការវាយតម្លៃប្រសិទ្ធភាព
        
    section ជំនាញផលិតកម្ម (១ ខែ)
        ការអភិវឌ្ឍជំនាញ: ការរៀបចំកូដ
                            : ការសហការជាក្រុម
                            :យុទ្ធសាស្រ្តការប្រមូលផ្តុំនូវតេស្ត
                            : ការបង្កើនប្រសិទ្ធភាពដាក់បញ្ចេញ

🛠️ សង្ខេបប្រដាប់សម្រាប់អភិវឌ្ឍហ្គេមរបស់អ្នក

បន្ទាប់ពីបញ្ចប់មេរៀននេះ អ្នកបានទទួលជំនាញ៖

  • គោលការណ៍អនុភាព៖ ចលនាដោយខ្ទង់ និងការប្រែប្រួលរលូន
  • កម្មវិធីផ្អែកលើព្រឹតិ្តការណ៍៖ ការគ្រប់គ្រងបញ្ចូលពីក្តារចុច ជាមួយការគ្រប់គ្រងព្រឹតិ្តការណ៍ត្រឹមត្រូវ
  • រចនាបថអចិន្រ្តៃយ៍៖ ការចិញ្ចើមរៀងៗខ្លួន និងផ្ទាំងតំណាងភាគីជាច្រើនរាង
  • គំរូការប្រាស្រ័យ៖ សំណង់ pub/sub សម្រាប់កូដងាយថែរក្សា
  • សំណង់លំហូរហ្គេម៖ ការអាប់ដេត និងគំនូរផ្សេងៗទាន់ពេលវេលា
  • ប្រព័ន្ធបញ្ចូល៖ ការច្រកការគ្រប់គ្រងអ្នកប្រើជាមួយការព្រមានលំនាំដើម
  • គ្រប់គ្រងទ្រព្យសម្បត្តិ៖ ការផ្ទុកស្ព្រាយ និងការគូរបង្ហាញប្រសិទ្ធិភាព

អ្វីដែលអ្នកអាចធ្វើបានក្នុង 5 នាទីបន្ទាប់

  • បើក consoleក្នុងbrowser ហើយសាកល្បង addEventListener('keydown', console.log) ដើម្បីមើលព្រឹតិ្តការណ៍ក្តារចុច
  • បង្កើតធាតុ div សាមញ្ញ និងផ្លាស់ទីវាដោយប្រើក្តារចុចបង្ខូច
  • សាកល្បង setInterval ដើម្បីបង្កើតចលនាបន្ត
  • ព្យាយាមការពារលំនាំដើម​ដោយ event.preventDefault()

🎯 អ្វីដែលអ្នកអាចសម្រេចបានក្នុងម៉ោងនេះ

  • បញ្ចប់សំណួរប្រឡងបន្ទាប់ពីមេរៀន និងយល់ដឹងកម្មវិធីផ្អែកលើព្រឹតិ្តការណ៍
  • បង្កើតកប៉ាល់វីរបុរសចលនាជាមួយការគ្រប់គ្រងក្តារចុចពេញលេញ
  • អនុវត្តលំនាំចលនាសត្រូវទន់Smooth
  • បន្ថែមដែនកំណត់ដើម្បីរារាំងវត្ថុហ្គេមចេញពីអេក្រង់
  • បង្កើតការស្កេនករណីជួបប្រទៈមូលដ្ឋានរវាងវត្ថុហ្គេម

📅 ការធ្វើដំណើរអនុភាពរបស់អ្នកក្នុងមួយសប្តាហ៍

  • បញ្ចប់ហ្គេមអាកាសពេញលេញជាមួយចលនាបន្លឺ និងអថេរភាព
  • បន្ថែមលំនាំចលនាជ្រៅដូចជា​ខ្សែ, បន្ទុះ, និងរូបវិទ្យា
  • អនុវត្តពន្លឺរលោង និងមុខងារជ្រេបរលាក
  • បង្កើតប៉ាត្រិច និងប្រព័ន្ធត្រួតពិនិត្យរូបភាព
  • បង្កើតប្រសិទ្ធភាពហ្គេមសម្រាប់ការរត់រលូន 60fps
  • បន្ថែមការគ្រប់គ្រងប៉ះជាមួយទូរស័ព្ទ និងរចនាប័ទ្មឆ្លាត

🌟 ការអភិវឌ្ឍរបស់អ្នកក្នុងមួយខែ

  • បង្កើតកម្មវិធីអន្តរជាតិកាន់តែស្មុគស្មាញជាមួយប្រព័ន្ធអនុភាពជ្រៅ
  • រៀនបណ្ណាល័យអនុភាពដូចជា GSAP ឬបង្កើតម៉ាស៊ីនអនុភាពដោយខ្លួនឯង
  • ធ្វើឲ្យមានការរួមចំណែកទៅព្រឹត្តិការណ៍កូដហ្គេម និងអនុភាពអន្តរជាតិ
  • ជំនាញបង្កើតអតិថិជនប្រសិទ្ធិភាពសម្រាប់កម្មវិធីក្រាហ្វិកខ្ពស់
  • បង្កើតមាតិកាសិក្សា​ជំនាញ​អំពីអភិវឌ្ឍហ្គេម និងអនុភាព
  • បង្កើតផត្រិយូដែលបង្ហាញជំនាញកម្មវិធីអន្តរជាតិ

កម្មវិធីពិតប្រាកដក្នុងជីវិត៖ ជំនាញអនុភាពហ្គេមរបស់អ្នកអាចប្រើបានដោយផ្ទាល់សម្រាប់៖

  • កម្មវិធីវិបអន្តរជាតិ៖ ផ្ទាំងគ្រប់គ្រងប្រតិបត្តិការ និងអ៊ីនធឺហ្វេសថេលើពេលពិត
  • ការបង្ហាញទិន្នន័យ៖ តារាងអនុភាព និងក្រាហ្វិកអន្តរជាតិ
  • កម្មវិធីអប់រំ៖ សមិទ្ធផលអន្តរជាតិ និងឧបករណ៍រៀនសូត្រ
  • ការអភិវឌ្ឍទូរស័ព្ទ៖ ហ្គេមរើសទំងន់ និងការគ្រប់គ្រងចលនា
  • កម្មវិធីមានតំឡើងក្នុងកុំព្យូទ័រ៖ កម្មវិធី Electron ជាមួយអនុភាពរលោង
  • អនុភាពវិប៖ បណ្ណាល័យ CSS និង JavaScript សម្រាប់អនុភាព

ជំនាញវិជ្ជាជីវៈដែលទទួលបាន៖ អ្នកឥឡូវនេះអាចៈ

  • សំណង់ ប្រព័ន្ធផ្អែកលើព្រឹតិ្តការណ៍ដែលធំឡើងជាមួយភាពស្មុគស្មាញ
  • អនុវត្ត អនុភាពរលោងដោយគោលការណ៍គណិតវិទ្យា
  • តម្រាម ប្រព័ន្ធអន្តរកម្មស្មុគស្មាញដោយប្រើឧបករណ៍អភិវឌ្ឍប្រេាហ្សើរ
  • បង្កើនប្រសិទ្ធភាព ហ្គេមសម្រាប់ឧបករណ៍និងប្រេាហ្សើរផ្សេងៗ
  • រចនា រចនាសម្ព័ន្ធកូដងាយថែរក្សាប្រើគំរូដែលបានគាំទ្រ

មេត្តាធ្វើការបរាជ័យក្នុងការអភិវឌ្ឍហ្គេម

  • គ្រប់គ្រងល្បឿនផ្ទាំង៖ យល់ដឹងពី FPS និងការគ្រប់គ្រងពេលវេលា
  • ការគ្រប់គ្រងបញ្ចូល៖ ក្តារចុច និងប្រព័ន្ធព្រឹតិ្តការណ៍ឆ្លងកាត់វេទិកា
  • ជីវិតវត្ថុ៖ ការបង្កើត, ការអាប់ដេត, និងគំរូបំផ្លាញ
  • ការសំភាសន៍ស្ថិតិ៖ រក្សារដ្ឋហ្គេមឲ្យស្ថិតស្ថេរ​ជួរ​ខ្ទង់​ពេល
  • សំណង់ព្រឹតិ្តការណ៍៖ ការប្រាស្រ័យបញ្ចេញៗជាលក្ខណៈបំភ្លឺរវាងប្រព័ន្ធហ្គេម។

កម្រិតបន្ទាប់៖ អ្នករួចរាល់ក្នុងការបន្ថែមវាយតម្លៃជួបប្រទៈ ការគិតពិន្ទុ, សូរិយភព, ឬស្វែងយល់ខ្លឹមសារហ្គេមសម័យថ្មីដូចជា Phaser ឬ Three.js!

🌟 ការសម្រេចបាន៖ អ្នកបានបង្កើតប្រព័ន្ធហ្គេមអន្តរជាតិកម្មពេញលេញជាមួយសំណង់វិជ្ជាជីវៈ!

ការងារ

យោបល់អំពីកូដរបស់អ្នក


ការបញ្ជាក់
ឯកសារនេះត្រូវបានបកប្រែដោយប្រើសេវាកម្មបកប្រែ AI Co-op Translator។ ខណៈពេលដែលយើងខិតខំឲ្យបានភាពត្រឹមត្រូវ សូមដឹងថាការបកប្រែម៉ាស៊ីនអាចមានកំហុសឬភាពមិនត្រឹមត្រូវ។ ឯកសារដើមនៅក្នុងភាសាទ្រព្យសម្បត្តិគួរត្រូវបានគេទុកចិត្តជាគោលដៅសំខាន់។ សម្រាប់ព័ត៌មានសំខាន់ៗ សូមផ្តល់អាទិភាពការបកប្រែដោយអ្នកជំនាញមនុស្ស។ យើងមិនទទួលខុសត្រូវចំពោះការយល់ច្រឡំ ឬការប្រែក្លាយច្រឡំណាមួយមានមូលដ្ឋានចេញពីការប្រើប្រាស់ការបកប្រែនេះឡើយ។