µ±Ç°Î»Öà : 145zÓÎÏ·Õ¾¡¡|¡¡ÈÈѪ´«Ææ¡¡|¡¡¼¼Êõ½Ì³Ì¡¡|¡¡

GOM´«ÆæÒýÇæÖÐÔö¼ÓÒþÉíÊõºÍ·ÖÉíÊõµÄʵÏÖ¼°³£¼ûÎÊÌâ½â¾ö

Èȶȣº
ÔÚGOMÒýÇæÖÐʵÏÖ**ÒþÉíÊõ**Óë**·ÖÉíÊõ**ʱ£¬¿ª·¢Õß³£Óöµ½¼¼ÄÜЧ¹ûÒì³£¡¢·ÖÉí°ë͸Ã÷¡¢Êý¾Ý¿âÅäÖÃʧЧµÈÎÊÌâ¡£±¾ÎĽ«´Ó¼¼ÄܵײãÂß¼­ÇÐÈ룬½áºÏ½Å±¾ÓëÒýÇæÏÞÖÆ£¬ÌṩÁ½ÖÖ¼¼ÄܵÄ**Ë«·½°¸ÊµÏÖ·¾¶**£¨Êý¾Ý¿âÔ­ÉúÅäÖÃÓë½Å±¾Ä£Ä⣩£¬²¢Õë¶Ô·ÖÉí²ÐÓ°¡¢Í¸Ã÷¶ÈÒì³£µÈÎÊÌâ¸ø³öÖÕ¼«½â¾ö·½°¸¡£

---

### Ò»¡¢ÒþÉíÊõµÄÁ½ÖÖʵÏÖ·½°¸
#### 1. Êý¾Ý¿âÔ­ÉúÅäÖã¨ÍƼö£©
**²½Öè**£º
1. ´ò¿ª**Magic.DB**£¬ÕÒµ½ÒþÉíÊõ¶ÔÓ¦ÐУ¨Í¨³£Îª¼¼ÄÜID=60£©£¬ÐÞ¸ÄÒÔÏÂ×ֶΣº
```
EffectType=6 -- ÒþÉíÊõЧ¹û±êʶ
EffectHit=0 -- ÎÞ¹¥»÷¶¯×÷
Duration=30 -- ÒþÉí³ÖÐøÊ±¼ä£¨Ã룩
```

2. ÔÚ**QFunction-0.txt**ÖÐÌí¼Ó´¥·¢¼ì²â£º
```lua
[@MagSelfFunc60] -- 60ΪÒþÉíÊõ¼¼ÄÜID
#IF
#ACT
SetInvisible 1 -- ¿ªÆôÒþÉí
SetTimer 3600 30 -- 30Ãëºó¹Ø±ÕÒþÉí
SendMsg 5 ÒþÉíÊõÉúЧ£¬Ê£Óàʱ¼ä£º<$STR(T3600)>Ãë

[@Timer3600]
#ACT
SetInvisible 0
SendMsg 5 ÒþÉíÊõÒÑʧЧ£¡
```


#### 2. ´¿½Å±¾Ä£ÄâÒþÉíÊõ£¨¼æÈÝÀϰ汾£©
```lua
[@ÊÍ·ÅÒþÉíÊõ]
#IF
CheckLevel > 40
#ACT
SetInvisible 1
MESSAGEBOX ÒþÉíÖУ¬Òƶ¯»ò¹¥»÷½«½â³ý
SetOnTimer 7 1 -- ÿÃë¼ì²â״̬

[@Timer7]
#IF
CheckHitMode -- ¼ì²âÊÇ·ñ¹¥»÷
CheckMove -- ¼ì²âÊÇ·ñÒÆ¶¯
#ACT
SetInvisible 0
SetOffTimer 7
```


---

### ¶þ¡¢·ÖÉíÊõÎÞ·¨Ìí¼ÓµÄºËÐÄÔ­Òò
#### 1. ÒýÇæ¹¦ÄÜÏÞÖÆ·ÖÎö
GOMÒýÇæÔ­Éú**²»Ö§³Ö±ê×¼·ÖÉíÊõ**£¨Èç´«Ææ¹ÖÎï·ÖÉí¡¢¾µÏñ·ÖÉí£©£¬Ô­ÒòÔÚÓÚ£º
- **Êý¾Ý¿âȱÏÝ**£ºMagic.DBÖÐÎÞ¶ÔÓ¦EffectType±êʶ
- **¹ÖÎïAIÏÞÖÆ**£º·ÖÉíµÄ¹¥»÷Âß¼­Ðè¶ÀÁ¢±àд£¬ÎÞ·¨¼Ì³ÐÖ÷ÌåÖÇÄÜ

#### 2. Ìæ´ú·½°¸£º½Å±¾Ä£Äâ·ÖÉíÊõ£¨ÍêÕûÁ÷³Ì£©
**²½Öè1£ºÅäÖ÷ÖÉí¹ÖÎï**
ÔÚ**Monster.DB**Öд´½¨·ÖÉíÄ£°å£º
```
Name=Íæ¼Ò·ÖÉí
Race=151 -- ÈËÐιÖ
Appr=Íæ¼ÒÍâ¹Û´úÂë
Level=<$LEVEL> -- ¼Ì³ÐÖ÷ÌåµÈ¼¶
HP=<$MAXHP/2>
```


**²½Öè2£º¼¼ÄÜÊͷŽű¾**
```lua
[@ÊÍ·Å·ÖÉíÊõ]
#IF
CheckItem ·ÖÉí¾íÖá 1
#ACT
Take ·ÖÉí¾íÖá 1
MobPlace <$MAP> <$X> <$Y> Íæ¼Ò·ÖÉí 1 60 -- ÕÙ»½1¸ö³ÖÐø60ÃëµÄ·ÖÉí
SetMirrorImage 1 -- ¿ªÆô·ÖÉí¾µÏñ±êʶ

; ·ÖÉí´©´Ì¹¥»÷Ä£Äâ
[@OnTimer]
#IF
CheckMirrorImage=1
Random 30 -- 30%¸ÅÂÊ´¥·¢¹¥»÷
#ACT
HITMON <$CURRTARGET> 100 -- Ç¿ÖÆ¹¥»÷µ±Ç°Ä¿±ê
```


**²½Öè3£º·ÖÉíÍâ¹Ûͬ²½£¨½â¾ö°ë͸Ã÷ÎÊÌ⣩**
ÔÚ¿Í»§¶Ë**Data\Monster\**Ŀ¼Ï£º
1. ¸´ÖÆÍæ¼ÒÍâ¹ÛËØ²Ä£¨È磺HumEffect.wil£©²¢ÖØÃüÃûΪ·ÖÉíרÓÃÎļþ£¨È磺MirrorImage.wil£©
2. ÐÞ¸ÄËØ²Ä͸Ã÷¶È£º
- ÓÃPhotoshop½«AlphaͨµÀµÄ**²»Í¸Ã÷¶È´Ó50%¸ÄΪ100%**
- ±£´æÎª32λBMP¸ñʽ£¨´øAlphaͨµÀ£©

---

### Èý¡¢·ÖÉí°ë͸Ã÷/²ÐÓ°ÎÊÌâÖÕ¼«½â¾ö·½°¸
#### 1. °ë͸Ã÷¸ùÔ´·ÖÎö
- **ËØ²ÄÎÊÌâ**£º·ÖÉíµÄWILÎļþδÕýÈ·ÅäÖÃAlphaͨµÀ
- **ÒýÇæäÖȾBUG**£º²¿·ÖGOM°æ±¾¶ÔRace=151µÄ¹ÖÎïÇ¿ÖÆÆôÓðë͸Ã÷

#### 2. Èý²½ÐÞ¸´·¨
**²½Öè1£ºÐ޸ĹÖÎïRaceÀàÐÍ**
```
Race=81 -- ¸ÄΪ²»ËÀϵ¹ÖÎÒýÇæäÖȾ¸üÎȶ¨£©
```


**²½Öè2£ºÇ¿ÖÆËø¶¨ËزÄ͸Ã÷¶È**
ÔÚ**M2Server**ÖУº
1. ´ò¿ª“Ñ¡Ïî-¿Í»§¶Ë¿ØÖÆ”
2. ¹´Ñ¡“½ûÖ¹¹ÖÎï°ë͸Ã÷äÖȾ”

**²½Öè3£º¶¯Ì¬µ÷Õû·ÖÉíÊôÐÔ**
```lua
[@·ÖÉíÉú³Éºó]
#ACT
CALCVAR HUMAN ·ÖÉí·ÀÓù = <$HUMAN(·ÀÓù)> * 0.8
SAVEVAR HUMAN ·ÖÉí·ÀÓù ..\QuestDiary\·ÖÉíÊôÐÔ\·ÀÓù.txt
```


---

### ËÄ¡¢Á½ÖÖ·½°¸ÐÔÄܶԱÈ

| **¶Ô±ÈÏî** | Êý¾Ý¿âÔ­ÉúÅäÖà | ½Å±¾Ä£Äâ·½°¸ |
|------------------|--------------------------|--------------------------|
| ×ÊÔ´Õ¼Óà | µÍ£¨ÒýÇæµ×²ãÖ§³Ö£© | ÖУ¨ÐèÆµ·±¼ì²â¼ÆÊ±Æ÷£© |
| ¼æÈÝÐÔ | ½öаæGOMÖ§³Ö | È«°æ±¾Í¨Óà |
| ¹¦ÄÜÍêÕûÐÔ | ÎÞ×ÔÖ÷AI | ¿É×Ô¶¨Òå¹¥»÷Âß¼­ |
| ¿ª·¢ÄÑ¶È | ¼òµ¥£¨×Ö¶ÎÐ޸ģ© | ¸´ÔÓ£¨ÐèÁª¶¯½Å±¾ÓëDB£© |


---

### Îå¡¢³£¼ûÎÊÌâÅŲéÇåµ¥
1. **·ÖÉí²»¹¥»÷**£º
- ¼ì²é¹ÖÎïRaceÀàÐÍÊÇ·ñÖ§³Ö¹¥»÷¶¯×÷£¨Race=81ÐèÅäÖÃAttackMode=1£©
- ÔÚQFunction-0.txtÖÐÌí¼Ó[@OnDie]´¥·¢¼ì²â

2. **ÒþÉíÊõ±»ÈºÌå¼¼ÄÜ´òÆÆ**£º
```lua
[@OnDamage]
#IF
CheckSkillName »ðǽ
#ACT
SetInvisible 0 -- Êܵ½·¶Î§É˺¦½â³ýÒþÉí
```


3. **·ÖÉíËØ²Ä´íÂÒ**£º
- ʹÓÃ**WIL±à¼­Æ÷**È·ÈÏAppr±àºÅÓëHumEffect.wilÒ»ÖÂ
- ɾ³ý¿Í»§¶ËCacheÎļþ¼ÐÇ¿ÖÆÖØÐ¼ÓÔØËØ²Ä

---

### ½áÓï
ͨ¹ýÊý¾Ý¿âÓë½Å±¾µÄЭͬÉè¼Æ£¬¿ª·¢Õß¿ÉÍ»ÆÆGOMÒýÇæµÄ¹¦ÄÜÏÞÖÆ£¬ÊµÏָ߶ȶ¨ÖƵÄÒþÉíÓë·ÖÉíЧ¹û¡£¹Ø¼üµãÔÚÓÚ£º
1. **·ÖÉí°ë͸Ã÷**£ºÓÅÏȵ÷ÕûRaceÀàÐÍÓëËØ²ÄAlphaͨµÀ
2. **¼¼ÄÜʵʱÐÔ**£ºÓüÆÊ±Æ÷£¨SetOnTimer£©Ìæ´ú¹Ì¶¨ÑÓʱ
3. **ÐÔÄÜÓÅ»¯**£º±ÜÃâÔÚ·ÖÉí½Å±¾ÖÐʹÓôóÁ¿È«¾Ö±äÁ¿

¸½Ôù×ÊÔ´°ü£º
- ÐÞ¸´°æ·ÖÉíËØ²Ä£¨100%²»Í¸Ã÷£©
- ÒþÉíÊõ+·ÖÉíÊõÕûºÏ½Å±¾
- GOMÒýÇæRace´úÂë±í

ÕÆÎÕÉÏÊö·½°¸ºó£¬¿É½øÒ»²½¿ª·¢³ö“»ÃÓ°·ÖÉí¼Ì³ÐÖ÷Ìå¼¼ÄÜ”µÈ¸ß¼¶¹¦ÄÜ£¬´ó·ùÌáÉýÓÎÏ·¿ÉÍæÐÔ¡£

#### 1. ×¼±¸¹¤×÷
ÔÚ¿ªÊ¼Ö®Ç°£¬ÇëÈ·±£ÄãÒѾ­ÊìϤÁËGOMÒýÇæµÄ»ù±¾½á¹¹ºÍ¹¤×÷Ô­Àí£¬²¢ÇÒÒѾ­±¸·ÝÁËËùÓеÄÖØÒªÎļþ¡£ÓÉÓÚÉæ¼°µ½´úÂëºÍÅäÖÃÎļþµÄÐ޸ģ¬Ò»µ©²Ù×÷²»µ±£¬¿ÉÄܻᵼÖÂÊý¾Ý¶ªÊ§»òÆäËû²»¿ÉÄæµÄÎÊÌâ¡£

#### 2. Ôö¼ÓÒþÉíÊõ

##### ²½ÖèÒ»£º¶¨Òå¼¼ÄÜÐÅÏ¢
Ê×ÏÈ£¬ÔÚ`data\skill_proto.txt`ÎļþÖÐÌí¼Óеļ¼ÄÜÐÅÏ¢¡£¼ÙÉèÎÒÃÇÒªÌí¼ÓÒ»¸öÃûΪ“ÒþÉíÊõ”µÄ¼¼ÄÜ¡£

```plaintext
vnum name type level skill_point target_type weapon_sub_type damage_factor range delay cast_time effect_duration effect_value script
10001 ÒþÉíÊõ SKILL_TYPE_MAGIC 1 5 TARGET_SELF WEAPON_SUBTYPE_NONE 0.0 10 1000 3000 EF_INVISIBILITY 0
```

- `vnum`: ¼¼ÄÜΨһ±àºÅ¡£
- `name`: ¼¼ÄÜÃû³Æ¡£
- `type`: ¼¼ÄÜÀàÐÍ£¨Ä§·¨¡¢ÎïÀíµÈ£©¡£
- `level`: ¼¼ÄÜËùÐèµÈ¼¶¡£
- `skill_point`: ¼¼ÄܵãÊýÏûºÄ¡£
- `target_type`: Ä¿±êÀàÐÍ£¨×ÔÉí¡¢µÐÈ˵ȣ©¡£
- `weapon_sub_type`: ÎäÆ÷×ÓÀàÐÍ£¨Í¨³£ÎªNONE£©¡£
- `damage_factor`: ËðÉËÒò×Ó£¨¶ÔÓÚÒþÉíÊõΪ0£©¡£
- `range`: Ê©·¨·¶Î§¡£
- `delay`: Àäȴʱ¼ä¡£
- `cast_time`: Ê©·¨Ê±¼ä¡£
- `effect_duration`: Ч¹û³ÖÐøÊ±¼ä¡£
- `effect_value`: Ч¹ûÖµ£¨¶ÔÓÚÒþÉíÊõΪ0£©¡£
- `script`: ½Å±¾£¨Èç¹ûÐèÒª¶îÍâÂß¼­£©¡£

##### ²½Öè¶þ£º´¦Àí¼¼ÄÜЧ¹û
´ò¿ª`src\skill_manager.cpp`Îļþ£¬ÕÒµ½´¦Àí¼¼ÄÜЧ¹ûµÄ²¿·Ö£¬Ìí¼ÓÒþÉíÊõµÄЧ¹û¡£

```cpp
void CSkillManager::ApplySkillEffect(CCharacter* caster, CCharacter* target, SKILL_INFO* skillInfo)
{
switch (skillInfo->vnum)
{
case 10001: // ÒþÉíÊõ
ApplyInvisibility(caster, skillInfo);
break;
// ÆäËû¼¼ÄÜ...
}
}

void CSkillManager::ApplyInvisibility(CCharacter* character, SKILL_INFO* skillInfo)
{
character->SetFlag(FLAG_INVISIBLE);
SetTimer(skillInfo->effect_duration, [character]() {
character->ClearFlag(FLAG_INVISIBLE);
});
}
```

##### ²½ÖèÈý£ºÌí¼Ó¼¼Äܵ½½ÇÉ«
ÔÚ`data\char_proto.txt`ÎļþÖУ¬¸ø½ÇÉ«Ìí¼ÓÒþÉíÊõ¡£

```plaintext
vnum class race gender str dex int con hit point attack_defense damage resist_magic magic_defense poison_resist hp_recovery sp_recovery special_effect skills
1 WARRIOR HUMAN MALE 20 20 10 15 100 100 10 10 0 0 0 0 0 10001
```

- `skills`: ½ÇɫӵÓеļ¼ÄÜÁÐ±í£¬ÓöººÅ·Ö¸ô¡£

#### 3. Ôö¼Ó·ÖÉíÊõ

##### ²½ÖèÒ»£º¶¨Òå¼¼ÄÜÐÅÏ¢
ÔÚ`data\skill_proto.txt`ÎļþÖÐÌí¼Óеļ¼ÄÜÐÅÏ¢¡£¼ÙÉèÎÒÃÇÒªÌí¼ÓÒ»¸öÃûΪ“·ÖÉíÊõ”µÄ¼¼ÄÜ¡£

```plaintext
vnum name type level skill_point target_type weapon_sub_type damage_factor range delay cast_time effect_duration effect_value script
10002 ·ÖÉíÊõ SKILL_TYPE_MAGIC 10 10 TARGET_SELF WEAPON_SUBTYPE_NONE 0.0 10 2000 5000 EF_CLONE 0
```

##### ²½Öè¶þ£º´¦Àí¼¼ÄÜЧ¹û
´ò¿ª`src\skill_manager.cpp`Îļþ£¬ÕÒµ½´¦Àí¼¼ÄÜЧ¹ûµÄ²¿·Ö£¬Ìí¼Ó·ÖÉíÊõµÄЧ¹û¡£

```cpp
void CSkillManager::ApplySkillEffect(CCharacter* caster, CCharacter* target, SKILL_INFO* skillInfo)
{
switch (skillInfo->vnum)
{
case 10001: // ÒþÉíÊõ
ApplyInvisibility(caster, skillInfo);
break;
case 10002: // ·ÖÉíÊõ
CreateClone(caster, skillInfo);
break;
// ÆäËû¼¼ÄÜ...
}
}

void CSkillManager::CreateClone(CCharacter* caster, SKILL_INFO* skillInfo)
{
CCharacter* clone = new CCharacter();
clone->CopyFrom(caster);
clone->SetPosition(caster->GetX(), caster->GetY());
clone->SetFlag(FLAG_CLONE);
GetWorld()->AddObject(clone);

SetTimer(skillInfo->effect_duration, [clone]() {
delete clone;
});
}
```

##### ²½ÖèÈý£ºÌí¼Ó¼¼Äܵ½½ÇÉ«
ÔÚ`data\char_proto.txt`ÎļþÖУ¬¸ø½ÇÉ«Ìí¼Ó·ÖÉíÊõ¡£

```plaintext
vnum class race gender str dex int con hit point attack_defense damage resist_magic magic_defense poison_resist hp_recovery sp_recovery special_effect skills
1 WARRIOR HUMAN MALE 20 20 10 15 100 100 10 10 0 0 0 0 0 10001,10002
```

#### 4. ½â¾ö·ÖÉíÊõÎÞ·¨Ìí¼Ó»òÕÙ»½³ö°ëÉíµÄÎÊÌâ

##### ÎÊÌâ·ÖÎö
1. **¼¼ÄÜδÕýÈ·¼ÓÔØ**£ºÈ·±£`skill_proto.txt`Öеļ¼ÄÜÐÅÏ¢¸ñʽÕýÈ·£¬²¢ÇÒ¼¼ÄÜIDÔÚ´úÂëÖб»Õýȷʶ±ð¡£
2. **½Çɫδ»ñµÃ¼¼ÄÜ**£ºÈ·ÈϽÇÉ«ÊÇ·ñÕýÈ·»ñµÃÁË·ÖÉíÊõ¼¼ÄÜ¡£
3. **¿Ë¡¶ÔÏó´´½¨Ê§°Ü**£º¼ì²é¿Ë¡¶ÔÏóµÄ´´½¨ºÍ³õʼ»¯¹ý³ÌÊÇ·ñÓдíÎó¡£
4. **äÖȾÎÊÌâ**£ºÈ·±£¿Ë¡¶ÔÏóÔÚ¿Í»§¶ËÕýÈ·äÖȾ¡£

##### ½â¾ö²½Öè

###### ²½ÖèÒ»£º¼ì²é¼¼ÄܼÓÔØ
È·±£`skill_proto.txt`Öеļ¼ÄÜÐÅÏ¢¸ñʽÕýÈ·£¬²¢ÇÒ¼¼ÄÜIDÔÚ´úÂëÖб»Õýȷʶ±ð¡£

```cpp
bool CSkillManager::LoadSkills()
{
ifstream file("data/skill_proto.txt");
if (!file.is_open())
{
Log("Failed to open skill_proto.txt.");
return false;
}

string line;
while (getline(file, line))
{
vector<string> tokens = SplitString(line, '\t');
if (tokens.size() < 16)
{
Log("Invalid skill entry in skill_proto.txt.");
continue;
}

SKILL_INFO* skillInfo = new SKILL_INFO();
skillInfo->vnum = stoi(tokens[0]);
skillInfo->name = tokens[1];
skillInfo->type = static_cast<SKILL_TYPE>(stoi(tokens[2]));
skillInfo->level = stoi(tokens[3]);
skillInfo->skill_point = stoi(tokens[4]);
skillInfo->target_type = static_cast<TARGET_TYPE>(stoi(tokens[5]));
skillInfo->weapon_sub_type = static_cast<WEAPON_SUBTYPE>(stoi(tokens[6]));
skillInfo->damage_factor = stof(tokens[7]);
skillInfo->range = stoi(tokens[8]);
skillInfo->delay = stoi(tokens[9]);
skillInfo->cast_time = stoi(tokens[10]);
skillInfo->effect_duration = stoi(tokens[11]);
skillInfo->effect_value = stoi(tokens[12]);
skillInfo->script = tokens[13];

m_skillMap[skillInfo->vnum] = skillInfo;
}

file.close();
return true;
}
```

###### ²½Öè¶þ£º¼ì²é½ÇÉ«¼¼ÄÜ
È·±£½ÇÉ«ÕýÈ·»ñµÃÁË·ÖÉíÊõ¼¼ÄÜ¡£

```cpp
bool CCharacter::LoadSkills()
{
ifstream file("data/char_proto.txt");
if (!file.is_open())
{
Log("Failed to open char_proto.txt.");
return false;
}

string line;
while (getline(file, line))
{
vector<string> tokens = SplitString(line, '\t');
if (tokens.size() < 16 || stoi(tokens[0]) != m_vnum)
{
continue;
}

vector<string> skills = SplitString(tokens[15], ',');
for (const auto& skill : skills)
{
int skillId = stoi(skill);
AddSkill(skillId);
}

break;
}

file.close();
return true;
}
```

###### ²½ÖèÈý£º¼ì²é¿Ë¡¶ÔÏó´´½¨
È·±£¿Ë¡¶ÔÏóÔÚ·þÎñÆ÷¶ËÕýÈ·´´½¨ºÍ³õʼ»¯¡£

```cpp
void CSkillManager::CreateClone(CCharacter* caster, SKILL_INFO* skillInfo)
{
CCharacter* clone = new CCharacter();
if (!clone)
{
Log("Failed to create clone object.");
return;
}

clone->CopyFrom(caster);
clone->SetPosition(caster->GetX(), caster->GetY());
clone->SetFlag(FLAG_CLONE);
GetWorld()->AddObject(clone);

SetTimer(skillInfo->effect_duration, [clone]() {
delete clone;
});
}
```

###### ²½ÖèËÄ£º¼ì²é¿Í»§¶ËäÖȾ
È·±£¿Ë¡¶ÔÏóÔÚ¿Í»§¶ËÕýÈ·äÖȾ¡£

```cpp
void CGameUI::RenderFrame()
{
// äÖȾÆäËûUIÔªËØ...

// äÖȾËùÓнÇÉ«
for (auto& obj : GetWorld()->GetObjects())
{
if (obj->GetType() == OBJECT_TYPE_CHARACTER)
{
CCharacter* character = dynamic_cast<CCharacter*>(obj);
RenderCharacter(character);
}
}
}

void CGameUI::RenderCharacter(CCharacter* character)
{
if (character->HasFlag(FLAG_CLONE))
{
// äÖȾ¿Ë¡¶ÔÏó
DrawImage(cloneSprite, character->GetX(), character->GetY());
}
else
{
// äÖȾÆÕͨ½ÇÉ«
DrawImage(characterSprite, character->GetX(), character->GetY());
}
}
```

#### 5. ±àÒë²¢²âÊÔ
Íê³ÉÉÏÊö²½Öèºó£¬±àÒëÕû¸öÏîÄ¿¡£Èç¹ûÒ»ÇÐ˳Àû£¬ÄãÓ¦¸ÃÄܹ»ÔÚÓÎÏ·Öп´µ½ÒþÉíÊõºÍ·ÖÉíÊõµÄЧ¹û¡£

##### µ÷ÊÔ¼¼ÇÉ
- **¼ì²é´íÎóÈÕÖ¾**£ºÈç¹û±àÒëʧ°Ü£¬×Ðϸ²é¿´´íÎóÈÕÖ¾£¬ÐÞ¸´ÏàÓ¦µÄÓï·¨´íÎó¡£
- **Öð²½µ÷ÊÔ**£ºÊ¹Óõ÷ÊÔ¹¤¾ßÖð²½Ö´ÐдúÂ룬ȷ±£Ã¿Ò»²½¶¼Äܰ´Ô¤ÆÚ¹¤×÷¡£
- **ÑéÖ¤Êý¾Ý´¦Àí**£ºÈ·ÈÏ´Ó·þÎñÆ÷·¢Ë͵ÄÊý¾ÝÊÇ·ñÕýÈ·½âÎö²¢ÏÔʾÔÚ½çÃæÉÏ¡£

#### 6. ÍêÉÆºÍÀ©Õ¹
Äã¿ÉÒÔ¸ù¾ÝÐèÒª½øÒ»²½ÍêÉÆºÍÀ©Õ¹ÕâЩ¼¼ÄܵŦÄÜ¡£ÀýÈ磬¿ÉÒÔÌí¼Ó¸ü¶àµÄÌØÐ§¡¢Àäȴʱ¼äµ÷Õû¡¢¼¼ÄÜ×éºÏµÈ¡£

#### ×ܽá
ͨ¹ýÒÔÉϲ½Ö裬Äã¿ÉÒÔÔÚGOMÒýÇæÖгɹ¦µØÔö¼ÓÒþÉíÊõºÍ·ÖÉíÊõ£¬²¢½â¾ö³£¼ûµÄÎÊÌâ¡£Õâ²»½öÌáÉýÁËÓÎÏ·µÄ»¥¶¯ÐÔºÍÌôÕ½ÐÔ£¬Ò²ÎªºóÐøµÄ¹¦ÄÜÀ©Õ¹µì¶¨ÁË»ù´¡¡£Ï£ÍûÕâÆª½Ì³Ì¶ÔÄãÓÐËù°ïÖú£¡

---

ÒÔÉϾÍÊǹØÓÚÈçºÎÔÚGOMÒýÇæÖÐÔö¼ÓÒþÉíÊõºÍ·ÖÉíÊõµÄÈ«²¿ÄÚÈÝ¡£Èç¹ûÄãÓÐÈκÎÒÉÎÊ»ò½¨Ò飬»¶Ó­ËæÊ±ÁôÑÔÌÖÂÛ¡£