根据浮生梦老师前端课程内容,我分析了你的飞剑代码,发现几个关键问题:
## 主要问题分析:
### 1. **怪物检测函数问题**
```lua
function FeiJianSKill.getCanAttackMonster()
if nowMonsters ~= nil then
return nowMonsters
else
nowMonsters = {}
local maxDis = 8
local mainActor = maptools.getActor(SL:GetMetaValue("MAIN_ACTOR_ID"))
local nowX = mainActor:GetMapX()
local nowY = mainActor:GetMapY()
for i, v in ipairs(SL:GetMetaValue("FIND_IN_VIEW_MONSTER_LIST")) do
-- 这里缺少对maptools.getActor(v)的nil判断
local monster = maptools.getActor(v)
if monster:GetHP() > 0 and SL:GetMetaValue("TARGET_ATTACK_ENABLE", monster:GetID()) then
-- 计算位置
if math.abs(monster:GetMapX() - nowX) <= maxDis and math.abs(monster:GetMapY() - nowY) <= maxDis then
table.insert(nowMonsters, monster)
end
end
end
end
return nowMonsters
end
```
**问题点**:
- `monster:GetHP()` 可能访问nil值
- 缺少对 `maptools.getActor(v)` 返回值的判断
### 2. **定时器更新问题**
在代码末尾的定时器更新中:
```lua
taskNode:scheduleUpdate(function(dt)
FeiJianSKill.tick(dt)
end)
```
但是 `FeiJianSKill.tick` 函数中:
```lua
function FeiJianSKill.tick(dt)
nowMonsters = nil -- 每次都清空怪物缓存
for k, v in pairs(allSwordInfo) do
-- 更新逻辑
end
nowMonsters = nil -- 再次清空
end
```
**问题**:`nowMonsters = nil` 导致每次tick都会重新计算怪物列表,但 `getCanAttackMonster()` 中又有缓存判断,逻辑冲突。
### 3. **地图判断逻辑**
```lua
if feijian_bushengxiaomap[SL:GetMetaValue("MAP_NAME")] ~= nil or SL:GetMetaValue("USER_IS_DIE") then
--指定地图飞剑不动,人物死亡飞剑回来
self:startIdle()
return
end
```
**建议**:添加调试信息确认是否进入此分支。
## 修复建议:
### 1. 修复怪物检测函数
```lua
function FeiJianSKill.getCanAttackMonster()
nowMonsters = {} -- 每次都重新计算,不要缓存
local maxDis = 8
local mainActor = maptools.getActor(SL:GetMetaValue("MAIN_ACTOR_ID"))
if not mainActor then return nowMonsters end
local nowX = mainActor:GetMapX()
local nowY = mainActor:GetMapY()
local monsterList = SL:GetMetaValue("FIND_IN_VIEW_MONSTER_LIST")
if not monsterList then return nowMonsters end
for i, v in ipairs(monsterList) do
local monster = maptools.getActor(v)
if monster and not tolua.isnull(monster) then
if monster:GetHP() > 0 and SL:GetMetaValue("TARGET_ATTACK_ENABLE", monster:GetID()) then
if math.abs(monster:GetMapX() - nowX) <= maxDis and
math.abs(monster:GetMapY() - nowY) <= maxDis then
table.insert(nowMonsters, monster)
end
end
end
end
return nowMonsters
end
```
### 2. 修改tick函数
```lua
function FeiJianSKill.tick(dt)
-- 移除 nowMonsters = nil 的调用
for k, v in pairs(allSwordInfo) do
if v.id == 99 then
if v.node then
for i, n in ipairs(v.node) do
if n and not tolua.isnull(n) then
n:update(dt)
end
end
end
elseif v and v.node and not tolua.isnull(v.node) then
v.node:update(dt)
end
end
end
```
### 3. 添加调试信息
在关键位置添加调试:
```lua
function FlyingSword:seekEnemy()
SL:Print("开始索敌...")
local monsters = FeiJianSKill.getCanAttackMonster()
SL:Print("找到怪物数量:" .. #monsters)
-- ... 其他代码
end
```
## 检查步骤:
1. 确认 `SL:GetMetaValue("FIND_IN_VIEW_MONSTER_LIST")` 返回有效数据
2. 确认 `SL:GetMetaValue("TARGET_ATTACK_ENABLE", monsterID)` 返回true
3. 检查是否在禁用飞剑的地图中
4. 确认玩家没有死亡状态
下次写代码时要注意对nil值的判断,特别是从服务端获取的数据。不懂的地方可以问浮生梦尊师!