**一、需求拆解:你要实现什么?**
1. NPC位置:固定在土城安全区,玩家无需传送。
2. 核心功能:
• 玩家对话NPC后,每10分钟扣10000金币,给10000经验。
• 玩家离开NPC一定范围(如10格)后,自动停止挂机。
3. 防作弊:玩家必须保持在线且在范围内才能持续触发。
---
**二、准备工作:找到NPC脚本文件**
1. 文件路径:游戏目录 → `NPC` 文件夹 → 找到或新建 `BaseNPC.txt`(或其他NPC配置文件)。
2. 工具准备:用记事本或Notepad++编辑脚本文件。
---
**三、第一步:创建泡经验NPC**
步骤:在 `BaseNPC.txt` 中添加NPC配置代码。
```lua
[泡经验NPC] -- NPC名称(需唯一)
StartFrame=1 -- 脚本起始触发帧
EndFrame=1 -- 结束帧(保持1即可)
NPCName=泡经验NPC -- 显示名称
X=150 -- 土城安全区X坐标(需根据实际地图调整)
Y=200 -- 土城安全区Y坐标
DialogID=1001 -- 对话框ID(自定义,需与脚本匹配)
```
---
**四、第二步:编写挂机扣金币送经验脚本**
目标:玩家对话NPC后,启动定时器,每10分钟触发一次。
代码示例(保存到 `BaseNPC.txt` 同目录下的 `.lua` 文件,如 `BubbleExp.lua`):
```lua
-- 泡经验NPC脚本
function OnDialogSelect(player, dialogid, select)
if dialogid == 1001 and select == 1 then -- 对话框ID和选项匹配
StartBubbleExp(player) -- 启动挂机
end
end
-- 启动挂机(记录时间+位置)
function StartBubbleExp(player)
player:SetVar("BubbleExpTime", GetTickCount()) -- 记录开始时间
player:SetVar("BubbleExpRange", 10) -- 有效范围10格
player:SendStatusMessage("挂机已启动!") -- 提示玩家
end
-- 每秒检测一次(游戏内时间)
function OnSecondInterval(player)
if player:GetVar("BubbleExpTime") > 0 then -- 检查是否在挂机中
local elapsed = GetTickCount() - player:GetVar("BubbleExpTime")
if elapsed >= 600000 then -- 10分钟=600,000毫秒
-- 扣金币
if player:GetGold() >= 10000 then
player:ReduceGold(10000)
-- 给经验
player:AddExp(10000)
player:SendStatusMessage("获得10000经验!消耗10000金币")
else
player:SendStatusMessage("金币不足!")
StopBubbleExp(player) -- 金币不足则停止
end
player:SetVar("BubbleExpTime", GetTickCount()) -- 重置计时器
end
-- 检测玩家是否离开范围
if GetDistance(player, player:GetX(), player:GetY()) > player:GetVar("BubbleExpRange") then
StopBubbleExp(player)
end
end
end
-- 停止挂机
function StopBubbleExp(player)
player:SetVar("BubbleExpTime", 0)
player:SendStatusMessage("挂机已停止!")
end
```
---
**五、第三步:绑定脚本到NPC**
1. 在 `BaseNPC.txt` 中添加以下代码,关联脚本文件:
```lua
[泡经验NPC]
...
Script=BubbleExp.lua -- 关联的脚本文件名
```
2. 将 `BubbleExp.lua` 文件放入游戏脚本目录(如 `Script` 文件夹)。
---
**六、第四步:测试与调试**
1. 启动游戏,找到土城安全区的NPC,对话触发挂机。
2. 验证功能:
• 等待10分钟后,检查金币和经验是否变化。
• 走出10格范围,观察是否自动停止。
3. 常见问题:
• 不扣金币/不给经验:检查脚本中的数值(如 `10000` 是否正确)。
• 范围失效:确认 `GetDistance` 函数是否支持,或改用坐标差值计算。
---
**七、进阶优化(可选)**
1. 防外挂:增加在线检测,如果玩家掉线则自动停止。
```lua
if not player:IsOnline() then
StopBubbleExp(player)
end
```
2. 多倍经验:根据VIP等级调整经验倍数。
```lua
local exp = 10000 * player:GetVipLevel() -- VIP等级越高,经验越多
```
---
**八、一句话总结**
核心逻辑:通过定时器 + 范围检测实现挂机功能,代码只需关注“时间到了扣金币给经验”和“离开范围就停”。
注意:修改前备份文件,避免脚本冲突导致游戏崩溃!

