|
|
4 months ago | |
|---|---|---|
| .. | ||
| README.md | 4 months ago | |
| assignment.md | 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
- ធ្វើបច្ចុប្បន្នភាពទីតាំង – ប្ដូរទីតាំងដែលវត្ថុរបស់អ្នកគួរតែស្ថិតនៅ (ប្រហែលបញ្ចូនវាចូលទៅខាងស្តាំ 5 ភិកសែល)
- លុបទំព័រចាស់ – សម្អាតអេក្រង់ឲ្យមិនឲ្យឃើញក្ដោបដូចសត្វភ្លើង និងស្នាមដែលនៅជុំវិញ
- គូរទំព័រថ្មី – ដាក់វត្ថុនៅក្នុងទីតាំងថ្មីរបស់វា
ធ្វើរហ័សត្រឹមគ្រប់គ្រាន់ ហើយហ្នឹង! អ្នកបានចលនាដែលរលូនហើយមានអារម្មណ៍ធម្មជាតិសម្រាប់អ្នកលេង។
នេះគឺជារូបមន្តដែលវាអាចមើលឃើញបានក្នុងកូដ៖
// កំណត់ទីតាំងរបស់វីរៈតួ
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។ បើកកម្មវិធីរុករក ហើយបញ្ចូលអាសយដ្ឋាននោះ ឥឡូវវាគួរតែបង្ហាញវិរុទ្ធ និងសត្រូវទាំងអស់; មិនមានអ្វីផ្លាស់ទីទេ - រហូតដល់ឥឡូវ!
បន្ថែមកូដ
-
បន្ថែមវត្ថុផ្តល់ការ សម្រាប់
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()`
-
បន្ថែមអ្នកចាប់ព្រឹត្តិការណ៍គ្រប់គ្រង 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
- អនុញ្ញាត ប៊ូតុងផ្សេងៗដើរតួធម្មតា
ពិនិត្យកុងសូលកម្មវិធីរុករករបស់អ្នកនៅពេលនេះ ហើយមើលកំណត់ត្រាការចុចចុច។
-
អនុវត្តន៍ លំនាំ Pub sub pattern ដែលនឹងគ្រប់គ្រងកូដរបស់អ្នកឱ្យស្អាតពេលអ្នកធ្វើតាមផ្នែកដែលនៅសល់។
លំនាំ Publish-Subscribe ជួយរៀបចំកូដរបស់អ្នកដោយបំបែកការចាប់សញ្ញាព្រឹត្តិការណ៍ពីការគ្រប់គ្រង ព្រមទាំងធ្វើឲ្យកូដរបស់អ្នកគឺមានម៉ូឌុល និងងាយស្រួលថែរក្សា។
ដើម្បីធ្វើផ្នែកចុងក្រោយនេះ អ្នកអាច៖
-
បន្ថែមអ្នកស្តាប់ព្រឹត្តិការណ៍ នៅលើវីនដោ៖
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
-
បង្កើតថ្នាក់ EventEmitter ដើម្បីបោះពុម្ពផ្សាយ និងចុះជាវ ការប្រាស្រ័យទាក់ទង៖
class EventEmitter { constructor() { this.listeners = {}; } on(message, listener) { if (!this.listeners[message]) { this.listeners[message] = []; } this.listeners[message].push(listener); } -
បន្ថែមអថេរ និងរៀបចំ 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
- ចាប់ផ្តើម អារេ ដែលផ្ទុកវត្ថុហ្គេមទាំងអស់
-
ចាប់ផ្តើមហ្គេម
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; }); -
រៀបចំ លំហូរហ្គេម
បម្លែងមុខងារ
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)
- សំអាត និងគូរសារឡើងវិញអេក្រង់ទាំងមូលក្នុងរាល់ខ្ទង់ពេល
-
បន្ថែមកូដ ដើម្បីផ្លាស់ទីសត្រូវនៅចន្លោះពេលជាក់លាក់
បម្លែងមុខងារ
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។ ខណៈពេលដែលយើងខិតខំឲ្យបានភាពត្រឹមត្រូវ សូមដឹងថាការបកប្រែម៉ាស៊ីនអាចមានកំហុសឬភាពមិនត្រឹមត្រូវ។ ឯកសារដើមនៅក្នុងភាសាទ្រព្យសម្បត្តិគួរត្រូវបានគេទុកចិត្តជាគោលដៅសំខាន់។ សម្រាប់ព័ត៌មានសំខាន់ៗ សូមផ្តល់អាទិភាពការបកប្រែដោយអ្នកជំនាញមនុស្ស។ យើងមិនទទួលខុសត្រូវចំពោះការយល់ច្រឡំ ឬការប្រែក្លាយច្រឡំណាមួយមានមូលដ្ឋានចេញពីការប្រើប្រាស់ការបកប្រែនេះឡើយ។