# 范例集合
TIP
涵盖大部分接口的使用范例集合
return (function()
-- 地图常量数据
local Cfg = {
map_size = 30, --地图大小
map_high = 5, --城墙高度
pool_width = 5, --水池竖宽
pool_lenth = 15,--水池横长
max_score = 35, --游戏分数
}
-- ItemID数据
local Items = {
waterId = 4, --水方块ID
treatId = 8, --加血方块ID
floorId = 104, --地板方块ID
fishCnt = 4, --灯笼鱼
fishIdx = 3600, --灯笼鱼ID
starCnt = 12, --闪星数量
starIdx = 997, --闪星方块
rewardCnt = 15, --肘子数量
rewardIdx = 12526,--大肘子ID
redFlagId = 919, --红旗ID
blueFlagId = 920, --蓝旗ID
mobsCnt = 7, --怪物数量/ID组
mobsIdx = {3132, 3132, 3407},
-- 测试方块trigger事件 --
trigger_tx = 11311, --动物肥料
trigger_x1 = 256, --桃花树苗
trigger_ty = 11055, --点火器
trigger_y1 = 881, --喷花烟花
trigger_y2 = 931, --蜡烛台
}
-- 系统相关数据
local Sys = {
chatType = 1, --公告类型 1:系统公告
}
local Teams = {red=1, blue=2} --游戏队伍
local Battle = {win=1, lose=2, draw=3} --战斗结果
local LiveType = {all=-1,dead=0, alive=1} --玩家状态
-- 位置区域数据
local Pos = { --初始数据
ix = 0, iy = 0, iz = 0, --默认出生点
cx = 0, cz = 0, cr = 0, --雾圈原点/半径
}
-- 游戏数据
local Data = { --随游戏逻辑变更
tickCount = 0, -- tick计数
newTicker = 20, -- 刷新时长
glEffectId = -1, -- 雾圈ID
miniMarkId = -1, -- 小地图标记
markRadius = 100, -- 地图标记半径
isTimeout = false, -- 是否超时
isGameEnd = false, -- 是否已结束
isRuleInit = false,-- 游戏是否初始化
}
-- 游戏怪物数据
local Mobs = {
objIds = {},--怪物objId
gensCnt = 0,--攻击手数量
deadCnt = 0,--已死量数量
}
-- 其他测试数据
local posBlocks = {} --正收益+5分
local negBlocks = {} --负收益/变鸡或变羊
local rewBlocks = {816, 739, 1035, 1057, 816}
local weaponIdx = {12005}--, 15000, 15501} --武器组ID
local itemBuffs = {12499, 12542, 12559}--测试Buff接口
local itemTools = {11311, 11500, 11055}--测试方块事件
local itemLamps = {881, 881, 931} --测试方块触发事件
local cgroupId1 = nil --生物组1/狼
local cgroupId2 = nil --生物组2/鱼
--[[
游戏玩法:寻找武器杀死野怪,并获取宝物积累分数,分高者胜出.
分数累计情况:1、获取宝物+1 杀死怪物+3 杀死对手+5 开启宝箱+7
游戏结束情况:1、游戏超时 2、怪物全被干掉 3、分数达到25
游戏其他效果:进入雾圈后debuff自动清除/踩上最上层草地后每秒加血
--]]
function ListenEvents_MiniDemo()
--游戏事件---
ScriptSupportEvent:registerEvent([=[Game.Start]=], Game_StartGame)
ScriptSupportEvent:registerEvent([=[Game.Run]=], Game_Update)
ScriptSupportEvent:registerEvent([=[Game.End]=], Game_GameEnd)
ScriptSupportEvent:registerEvent([=[Game.TimeOver]=], Game_TimeOver)
ScriptSupportEvent:registerEvent([=[Actor.Die]=], Actor_Die)
--玩家事件---
ScriptSupportEvent:registerEvent([=[Player.Init]=], Player_Inited)
ScriptSupportEvent:registerEvent([=[Player.Die]=], Player_Dead)
ScriptSupportEvent:registerEvent([=[Player.Revive]=], Player_Revive)
ScriptSupportEvent:registerEvent([=[Player.AddItem]=], Player_AddItem)
ScriptSupportEvent:registerEvent([=[Player.JoinTeam]=], Player_JoinTeam)
--方块事件---
ScriptSupportEvent:registerEvent_Block([=[Block.Add]=], Block_Added, {Items.redFlagId, Items.blueFlagId})
ScriptSupportEvent:registerEvent_Block([=[Block.Remove]=], Block_Removed, {Items.redFlagId, Items.blueFlagId})
ScriptSupportEvent:registerEvent_Block([=[Block.PlaceBy]=], Block_Placed, {rewBlocks[1]})
ScriptSupportEvent:registerEvent_Block([=[Block.DestroyBy]=], Block_Destroy, rewBlocks)
ScriptSupportEvent:registerEvent_Block([=[Block.Trigger]=], Block_TriggerBy, {881, 931})
--ScriptSupportEvent:registerEvent_Block([=[Block.ActorCollide]=], Block_WalkedBy, rewBlocks)
--ScriptSupportEvent:registerEvent_Block([=[Block.ActorWalking]=], Block_CollidedBy, {Items.treatId})
ScriptSupportEvent:registerEvent_Block([=[Block.Fertilize]=], Block_FertilizedBy, {Items.trigger_x1})
end
-------------------------------自定义方法-------------------------------
function InitGameRule()
Data.isRuleInit = true
GameRule.EndTime = 9 --游戏时长
GameRule.CurTime = 17.9 --当前时间
GameRule.LifeNum = 3 --玩家生命
GameRule.TeamNum = 2
GameRule.MaxPlayers = 2
GameRule.CameraDir = 1 --1:正视角
GameRule.StartMode = 0 --0:房主开启
GameRule.StartPlayers = 1
-- GameRule.ScoreKillMob = 3 --击杀特定怪物+3分
GameRule.ScoreKillPlayer = 5 --击杀玩家+5分
GameRule.PlayerDieDrops = 1 --死亡掉落 1:true
GameRule.DisplayScore = 1 --显示比分 1:true
end
function InitCenterPoint()
-- 获取出生点,并以此设置地图中心
local ret, x,y,z = Spawnport:getSpawnPoint()
Pos.ix = x
Pos.iy = y
Pos.iz = z
--地平面的y轴坐标为7
if y==0 then Pos.iy = 6 end
end
function InitGamePlayer(isTestMode)
--获取本地玩家信息
local ret, playerId = Player:getMainPlayerUin()
if ret==ErrorCode.OK then Backpack:clearAllPack(playerId) end
local teamId = isClient and Teams.blue or Teams.red
local result = Player:setTeam(playerId, teamId) --主机默认为红队
if result==ErrorCode.OK then ResetPosition(playerId, teamId) end
GainItems(playerId) --默认给玩家的道具
if isTestMode then --枪械测试
-- local itemId, itemCnt = 12247, 1 --彩蛋枪
-- Player:gainItems(playerId, itemId, itemCnt, 1)
-- local itemId, itemCnt = 12249, 1*64--子弹
-- Player:gainItems(playerId, itemId, itemCnt, 1)
local itemId, itemCnt = 15004, 1 --狙击枪
Player:gainItems(playerId, itemId, itemCnt, 1)
local itemId, itemCnt = 15003, 1*64--子弹
Player:gainItems(playerId, itemId, itemCnt, 2)
end
--设置饱食度小于90,防止自动加血
local ret, foodLv = Player:getFoodLevel(playerId)
if ret==ErrorCode.OK and foodLv>90 then
--Player:setFoodLevel(playerId, 70)
end
end
function InitGameMap(length, isTestMode)
local blockId = 1 --设置游戏围栏
local map_high = Cfg.map_high
if isTestMode then map_high = 3 end
for yPos = Pos.iy+1, Pos.iy+map_high do
for xPos = Pos.ix-length, Pos.ix+length do
Block:setBlockAll(xPos, yPos, Pos.iz-length, blockId);
Block:setBlockAll(xPos, yPos, Pos.iz+length, blockId);
end
for zPos = Pos.iz-length, Pos.iz+length do
Block:setBlockAll(Pos.ix-length, yPos, zPos, blockId);
Block:setBlockAll(Pos.ix+length, yPos, zPos, blockId);
end
end
local yPos = Pos.iy+map_high --给最上层围栏设置缺口
for xPos = Pos.ix-length, Pos.ix+length, 2 do
Block:destroyBlock(xPos, yPos, Pos.iz-length, false)
Block:destroyBlock(xPos, yPos, Pos.iz+length, false)
end
for zPos = Pos.iz-length, Pos.iz+length, 2 do
Block:destroyBlock(Pos.ix-length, yPos, zPos, false)
Block:destroyBlock(Pos.ix+length, yPos, zPos, false)
end
if not isTestMode then --测试模式不创建地板
if Items.floorId ~= 0 then --设置地板方块
for xPos = Pos.ix-length, Pos.ix+length do
for zPos = Pos.iz-length, Pos.iz+length do
Block:setBlockAll(xPos, Pos.iy, zPos, Items.floorId)--bId为1时无法生成怪物
end
end
end
end
InitSmallPool(); --设置中央水池
if not isTestMode then --测试时选择创建
InitHpTreeAndTotem(0, -5);--治疗树
InitTeamCity(Teams.red); --红队复活点
InitTeamCity(Teams.blue);--蓝队复活点
end
end
--获取某区域内可放置道具的点
function getPosition(x1,x2,z1,z2,yp,isUp)
x1 = x1 or Pos.ix-Cfg.map_size+1
x2 = x2 or Pos.ix+Cfg.map_size-1
z1 = z1 or Pos.iz-Cfg.map_size+1
z2 = z2 or Pos.iz+Cfg.map_size-1
yp = yp or Pos.iy+1 --地面/水里
isUp = isUp==nil and true or isUp--默认true
local count = 1
local xPos, zPos = 0, 0
local ret, blkId = 0, 0
while true do
count = count + 1
xPos = math.random(x1, x2)
zPos = math.random(z1, z2)
ret, blkId = Block:getBlockID(xPos, yp, zPos)
if ret==ErrorCode.OK and blkId==0 then
if isUp then --地表方块需同时判断下是否有支撑
local ret2, blkId2 = Block:getBlockID(xPos, yp-1, zPos)
if ret2==ErrorCode.OK and blkId2~=Items.waterId then break end
else --只判断当前是否有方块占着
if xPos~=0 and zPos~=0 then break end
end
end
if not isUp and blkId==Items.waterId then break end --是否在水里
--防止参数有误导致死循环
if count>99 then
print("Position Error x===>>>")
return nil
end
end
return xPos, zPos
end
function InitTeamCity(teamId)
--获取起始出生点
local xPos, yPos, zPos = Pos.ix, Pos.iy+1, Pos.iz
if teamId==Teams.red then xPos = Pos.ix-(Cfg.map_size-2) end
if teamId==Teams.blue then xPos = Pos.ix+(Cfg.map_size-2) end
local fixDist = 0 --小门朝向
local flagFix = 0
local homeIdx, reveIdx = 0, 0
if teamId==Teams.red then
fixDist = 2
flagFix = 1
homeIdx, reveIdx = 919, 991
elseif teamId==Teams.blue then
fixDist = -2
flagFix = -1
homeIdx, reveIdx = 920, 992
end
if homeIdx==0 or reveIdx==0 then return end
Block:setBlockAll(xPos, yPos, zPos, reveIdx, 0) -- 复活点
Block:placeBlock(homeIdx, xPos+fixDist, yPos+2, zPos+flagFix, 1) --队旗点
--设置战队保护区
local blockId = 101
for yIdx = yPos, yPos+1 do
for xIdx = xPos-2, xPos+2, 4 do --外边缘1
for zIdx = zPos-2, zPos+2 do
Block:placeBlock(blockId, xIdx, yIdx, zIdx, 3)
end
end
for zIdx = zPos-2, zPos+2, 4 do --外边缘2
for xIdx = xPos-2, xPos+2 do
Block:placeBlock(blockId, xIdx, yIdx, zIdx, 3)
end
end
end
local doorId = 857 --开个小门
Block:destroyBlock(xPos+fixDist, yPos, zPos, false)
Block:destroyBlock(xPos+fixDist, yPos+1, zPos, false)
Block:destroyBlock(xPos+fixDist, yPos, zPos-flagFix, false)
Block:destroyBlock(xPos+fixDist, yPos+1, zPos-flagFix, false)
Block:placeBlock(doorId, xPos+fixDist, yPos, zPos-flagFix, 3)
--]]
-- if teamId==Teams.red then --工具箱/红队
-- Block:placeBlock(881, xPos+3, yPos, zPos+1)
-- else --工具箱/蓝队
-- Block:placeBlock(881, xPos-3, yPos, zPos-1)
-- end
end
--设置治疗树/图腾
function InitHpTreeAndTotem(cx, cz)
cx = cx or 0
cz = cz or 0
--四种怪物对应四种坦克类型
local totemIds = {745, 901, 903, 908}
local x1, y1, z1 = Pos.ix-5, Pos.iy+1, Pos.iz-Cfg.map_size+5
for idx, valId in ipairs(totemIds) do
if math.mod(idx, 3)==0 then
x1 = Pos.ix-3
z1 = Pos.iz+Cfg.map_size-5
end
Block:placeBlock(valId, x1, y1, z1)
x1 = x1 + 6
end
--设置治疗树/草地
local floorId = 100--草地
local xPos1, xPos2, yPos = 0, 0, 0
for idx = 1, 3 do
yPos = Pos.iy + idx
xPos1 = Pos.ix+cx-Cfg.pool_width-2 + idx
xPos2 = Pos.ix+cx+Cfg.pool_width+2 - idx
for zPos = Pos.iz+cz-2, Pos.iz+cz+2 do
Block:placeBlock(floorId, xPos1, yPos, zPos)
Block:placeBlock(floorId, xPos2, yPos, zPos)
end
end
for zPos = Pos.iz+cz-2, Pos.iz+cz+2 do
for xPos = xPos1+1, xPos2-1 do--上层草地
Block:placeBlock(floorId, xPos, yPos, zPos)
end
for xPos = xPos1, xPos2 do--下层草地
Block:placeBlock(101, xPos, yPos-1, zPos)
end
end
local ret1 = Block:setBlockAll(xPos1-1, yPos-1, Pos.iz+cz+2, 103)
local ret2 = Block:setBlockAll(xPos2+1, yPos-1, Pos.iz+cz-2, 103)
--生成树苗/测试施肥事件/此处placeBlock会失败,因树苗无法放置在草块上
local ret1 = Block:placeBlock(Items.trigger_x1, xPos1-1, yPos, Pos.iz+cz+2)
local ret2 = Block:placeBlock(Items.trigger_x1, xPos2+1, yPos, Pos.iz+cz-2)
--print("HpTree====================>>>", ret1, ret2)
for zPos = Pos.iz+cz-2, Pos.iz+cz+2 do
for xPos = Pos.ix+cx-2, Pos.ix+cx+2 do--加血区域
--treatPos[#treatPos+1] = {xPos, yPos, zPos}
Block:setBlockAll(xPos, yPos, zPos, Items.treatId)
end
end
local direct = 4
local tyPos = 0 --设置树干
for idx = 1, 5 do --树高为5
tyPos = yPos + idx
Block:placeBlock(200, Pos.ix+cx, tyPos, Pos.iz+cz, direct)
end
--设置树叶/四层树叶
local leafId = 218
direct = 0 --第4层树叶
for xPos = Pos.ix+cx-1, Pos.ix+cx+1 do
for zPos = Pos.iz+cz-1, Pos.iz+cz+1 do
Block:placeBlock(leafId, xPos, tyPos-1, zPos, direct)
end
direct = direct + 2
end
direct = 0 --第5层树叶
for xPos = Pos.ix+cx-2, Pos.ix+cx+2 do
for zPos = Pos.iz+cz-2, Pos.iz+cz+2 do
Block:placeBlock(leafId, xPos, tyPos, zPos, direct)
end
direct = direct + 2
end
direct = 0
for xPos = Pos.ix+cx-1, Pos.ix+cx+1 do
for zPos = Pos.iz+cz-1, Pos.iz+cz+1 do
Block:placeBlock(leafId, xPos, tyPos, zPos, direct)
end
direct = direct + 2
end
direct = 0 --第6层树叶
for xPos = Pos.ix+cx-1, Pos.ix+cx+1 do
for zPos = Pos.iz+cz-1, Pos.iz+cz+1 do
Block:placeBlock(leafId, xPos, tyPos+1, zPos, direct)
end
direct = direct + 2
end
direct = 4 --最上层树叶
Block:placeBlock(leafId, Pos.ix+cx, tyPos+2, Pos.iz+cz, direct)
--]]
--治疗圈位置/半径
Pos.cx, Pos.cz, Pos.cr = Pos.ix + cx, Pos.iz + cz, 4*1.2
end
--绘制小地图标记
function drawMiniMark(isNew, x1, x2, z1, z2, rx, mType)
if Data.miniMarkId >= 0 and not mType then --清理旧标记
MapMark:deleteShape(Data.miniMarkId)
elseif Data.miniMarkId==-1 or isNew then --重新绘制标记
local ret = ErrorCode.FAILED
local markType = MAPMARK_TYPE.MMARK_CIRCLE
if mType==1 then markType = MAPMARK_TYPE.MMARK_LINE end
if mType==2 then markType = MAPMARK_TYPE.MMARK_RECTANGLE end
ret, Data.miniMarkId = MapMark:newShape(markType,false,255,255,255)
if ret~=ErrorCode.OK then Data.miniMarkId = -1 end
end
if Data.miniMarkId >= 0 and not isNew then
if mType == 1 then--线形标记
MapMark:setShapeColor(Data.miniMarkId, 255, 0, 0)
MapMark:updateLine(Data.miniMarkId, x1, z1, x2, z2)
elseif mType == 2 then--矩形标记
MapMark:setShapeColor(Data.miniMarkId, 255, 0, 0)
MapMark:updateRectangle(Data.miniMarkId, x1, z1, x2-x1, z2-z1)
else --圆形标记
MapMark:setShapeColor(Data.miniMarkId, 255, 0, 0)
MapMark:updateCircle(Data.miniMarkId, x1, z1, rx)
end
MapMark:showShape(Data.miniMarkId, true)
end
end
--地图中生成水池
function InitSmallPool(pWid, pLen)
pWid = pWid and pWid or Cfg.pool_width
pLen = pLen and pLen or Cfg.pool_lenth
local xwid, zwid = pWid, pLen
for yPos = Pos.iy-1, Pos.iy do--挖坑
for xPos = Pos.ix-(xwid-1), Pos.ix+(xwid-1) do
for zPos = Pos.iz-(zwid-1), Pos.iz+(zwid-1) do
Block:destroyBlock(xPos, yPos, zPos, false)
end
end
end
for xPos = Pos.ix-xwid, Pos.ix+xwid do--内边缘
for zPos = Pos.iz-zwid, Pos.iz+zwid do
Block:destroyBlock(xPos, Pos.iy, zPos, false)
end
end
for yPos = Pos.iy-1, Pos.iy do--生成水池
for xPos = Pos.ix-xwid, Pos.ix+xwid do
for zPos = Pos.iz-zwid, Pos.iz+zwid do
Block:placeBlock(4, xPos, yPos, zPos, 3)
end
end
end
-- 外边缘1
local blockId = 104--方块Id
for zPos = Pos.iz-zwid-2, Pos.iz+zwid+2, 2*zwid+4 do
for xPos = Pos.ix-xwid-2, Pos.ix+xwid+2 do
Block:placeBlock(blockId, xPos, Pos.iy+1, zPos, 3)
end
end
-- 外边缘2
for xPos = Pos.ix-xwid-2, Pos.ix+xwid+2, 2*xwid+4 do
for zPos = Pos.iz-zwid-2, Pos.iz+zwid+2 do
Block:placeBlock(blockId, xPos, Pos.iy+1, zPos, 3)
end
end
end
--在一定区域内初始化道具
function InitGameItems(bxsize)
-- 获取起起始出生点
local x, y, z = Pos.ix, Pos.iy+1, Pos.iz
-- 位置区域
local x1, x2 = Pos.ix-bxsize+1, Pos.ix+bxsize-1
local z1, z2 = Pos.iz-bxsize+1, Pos.iz+bxsize-1
for idx = 1, Items.rewardCnt do --Item大肘子
local xPos, zPos = getPosition(x1,x2,z1,z2)
World:spawnItem(xPos, y, zPos, Items.rewardIdx)
end
for idx = 1, Items.rewardCnt do --Item动物肥料
local xPos, zPos = getPosition(x1,x2,z1,z2)
World:spawnItem(xPos, y, zPos, Items.rewardIdx)
end
-- 设置大宝剑掉落位置
for idx=1, #weaponIdx do
-- local xPos1 = math.random(x1, x2)
-- local zPos1 = math.random(z1, z2)
local xPos1, zPos1 = getPosition(x1,x2,z1,z2)
World:spawnItem(xPos1, y, zPos1, weaponIdx[idx])
end
-- 设置BuffItem位置
for idx=1, #itemBuffs do
-- local xPos1 = math.random(x1, x2)
-- local zPos1 = math.random(z1, z2)
local xPos1, zPos1 = getPosition(x1,x2,z1,z2)
World:spawnItem(xPos1, y, zPos1, itemBuffs[idx])
end
-- 设置ToolItem位置
for idx=1, #itemTools do
local itemId = itemTools[idx]
for jdx = 1, 5 do --数量
local xPos1, zPos1 = getPosition(x1,x2,z1,z2)
World:spawnItem(xPos1, y, zPos1, itemId)
end
end
for idx = 1, #rewBlocks do --方块碰撞区
local blockId = rewBlocks[idx]
local direct = idx~=1 and 3 or 4
local xPos0, zPos0 = getPosition(x1,x2,z1,z2)
Block:placeBlock(blockId, xPos0, y, zPos0, direct)
--设置正负收益方块
local randx = math.random(1, 10)
if randx<=5 and #posBlocks<2 or idx==1 then
posBlocks[#posBlocks+1] = blockId
else
negBlocks[#negBlocks+1] = blockId
end
end
for idx = 1, #itemLamps do --方块触发区
local xPos0, zPos0 = getPosition(x1,x2,z1,z2)
Block:placeBlock(itemLamps[idx], xPos0, y, zPos0, 3)
end
for idx = 1, Items.starCnt do --方块触发区
local xPos0, zPos0 = getPosition(x1,x2,z1,z2)
Block:placeBlock(Items.starIdx, xPos0, y, zPos0, 3)
end
end
--在一定区域内初始化怪物
function InitGameMobs(bxsize)
-- 获取起起始出生点
local x, y, z = Pos.ix, Pos.iy+1, Pos.iz
-- 位置区域
local x1, x2 = Pos.ix-bxsize+1, Pos.ix+bxsize-1
local z1, z2 = Pos.iz-bxsize+1, Pos.iz+bxsize-1
-- 生成怪物并设置位置
for idx=1, Items.mobsCnt do
local xPos, zPos = getPosition(x1,x2,z1,z2)
local cIdx = math.mod(idx, #Items.mobsIdx)
cIdx = cIdx~=0 and cIdx or #Items.mobsIdx
local curMobId = Items.mobsIdx[cIdx]
local ret, objIds = World:spawnCreature(xPos, y, zPos, curMobId)
if objIds and type(objIds)=="table" then
for idx = 1, #objIds do --遍历设置攻击手属性
local attrType = MODATTRIB_TYPE.MODATTR_MOVE_SPEED
local ret, value = Creature:getModAttrib(objIds[idx], attrType)
print('MODATTR_MOVE_SPEED-------------------->>>', value)
local result = Creature:addModAttrib(objIds[idx], attrType, 1)
if result == ErrorCode.OK then print('增加怪物移动速度') end
Mobs.objIds[#Mobs.objIds+1] = objIds[idx]
if curMobId == Items.mobsIdx[1] then
Mobs.gensCnt = Mobs.gensCnt + 1 --攻击手
else -- 生物组1->狼群
Trigger.CreatureGroup:addCreatureToGroup(objIds[idx], cgroupId1)
end
end
end
end
--设置怪物属性
for idx = 1, #Mobs.objIds do
local mobObjId = Mobs.objIds[idx]
local isMob = Actor:isMob(mobObjId)
if isMob==ErrorCode.OK then --确实是怪物
local ret, actorId = Creature:getActorID(mobObjId)
if actorId == Items.mobsIdx[3] then--狼
Creature:setPanic(mobObjId, true)
Creature:setAIActive(mobObjId, true)
local result = Creature:setOxygenNeed(mobObjId, false)
end
end
end
local xwid, zwid, count = 7-1, 12-1, 3
for idx = 1, count do --水池范围生成鱼类
-- local xPos = math.random(Pos.ix-xwid, Pos.ix+xwid)
-- local zPos = math.random(Pos.iz-zwid, Pos.iz+zwid)
x1,x2,z1,z2 = Pos.ix-xwid, Pos.ix+xwid,Pos.iz-zwid, Pos.iz+zwid
local xPos,zPos = getPosition(x1,x2,z1,z2, Pos.iy, false)
local ret, objIds = World:spawnCreature(xPos, y-1, zPos, Items.fishIdx)
if objIds and type(objIds)=="table" then
for idx = 1, #objIds do --生物组2->鱼群
Trigger.CreatureGroup:addCreatureToGroup(objIds[idx], cgroupId2)
end
end
end
print("GensX===================>>>", Mobs.gensCnt)
end
--计算游戏结果
function Battle_Ended(teamId, retType)
--local isPlayerValid = Player:isMainPlayerValid()#已取消
--if isPlayerValid ~= ErrorCode.OK then return end
if teamId == Teams.red then
-- 设置红队游戏结果
Team:setTeamResults(Teams.red, retType)
Team:setTeamPlayersResults(Teams.red, retType)
-- 设置蓝队游戏结果
local blueRet = (retType==Battle.win and Battle.lose) or Battle.win
Team:setTeamResults(Teams.blue, blueRet)
Team:setTeamPlayersResults(Teams.blue, blueRet)
print("Battle1 ================>>>", teamId, retType, blueRet)
elseif teamId == Teams.blue then
-- 设置蓝队游戏结果
Team:setTeamResults(Teams.blue, retType)
Team:setTeamPlayersResults(Teams.blue, retType)
-- 设置红队游戏结果
local redRet = (retType==Battle.win and Battle.lose) or Battle.win
Team:setTeamResults(Teams.red, redRet)
Team:setTeamPlayersResults(Teams.red, redRet)
print("Battle2 ================>>>", teamId, retType, redRet)
end
ShowGBattleUI() --设置战斗总结界面
end
--游戏结算界面
function ShowGBattleUI()
-- 设置排行/分数
local ret, rank = Player:getGameRanking()
if not rank or rank==0 then rank = 1 end
local ret, score = Player:getGameScore()
-- 队伍数量及成员量
local ret1, teamNum = Team:getNumTeam()
local ret2, redNum = Team:getTeamPlayers(Teams.red)
local ret3, blueNum = Team:getTeamPlayers(Teams.blue)
local totalPlayers = 1
if ret2==ErrorCode.OK and ret3==ErrorCode.OK then
totalPlayers = redNum+blueNum
end
local ret, txtTitle = Game:getDefString(rank==1 and 8028 or 8029)
local ret, txtTRank = Game:getDefString(8032)
local ret, txtRanker = Game:getDefString(8030)
local ret, txtDefeat = Game:getDefString(3176)
UI:setGBattleUI('left_title', txtTRank..tostring(rank))--第1/1
UI:setGBattleUI('right_title', "/"..totalPlayers)
UI:setGBattleUI('left_desc', txtTitle)--大吉大利/继续努力
UI:setGBattleUI('left_little_desc', txtRanker..tostring(rank))--排名
UI:setGBattleUI('right_little_desc', txtDefeat..tostring(score))--得分
UI:setGBattleUI('battle_btn', false)
UI:setGBattleUI('result', false)
UI:setGBattleUI('result_bkg', false)
UI:setGBattleUI('reopen', true)
end
--重置玩家位置
function ResetPosition(playerId, teamId)
if playerId<0 or teamId<0 then return end
if teamId == Teams.red then --红队出生/复活点
local ret = Player:setPosition(playerId, Pos.ix-(Cfg.map_size-2)+0.5, 7, Pos.iz+0.5)
elseif teamId == Teams.blue then --蓝队出生/复活点
local ret = Player:setPosition(playerId, Pos.ix+(Cfg.map_size-2)+0.5, 7, Pos.iz+0.5)
end
end
--初始玩家道具
function GainItems(playerId)
--给玩家一把短刀做防御,优先快捷栏
local itemId, itemCnt = 12003, 1 --短刀
local ret = Backpack:enoughSpaceForItem(playerId, itemId, itemCnt)
if ret==ErrorCode.OK then Player:gainItems(playerId, itemId, itemCnt, 1) end
local itemId, itemCnt = 11001, 1 --木斧
local ret = Backpack:enoughSpaceForItem(playerId, itemId, itemCnt)
if ret==ErrorCode.OK then Player:gainItems(playerId, itemId, itemCnt, 1) end
local itemId, itemCnt = 200, 1 --果木
local ret = Backpack:enoughSpaceForItem(playerId, itemId, itemCnt)
if ret==ErrorCode.OK then Player:gainItems(playerId, itemId, itemCnt, 1) end
local itemId, itemCnt = 230, 1 --南瓜
local ret = Backpack:enoughSpaceForItem(playerId, itemId, itemCnt)
if ret==ErrorCode.OK then Player:gainItems(playerId, itemId, itemCnt, 1) end
local itemId, itemCnt = 817, 2
local isDayTx = World:isDaytime() --白天:true 黑夜:false
local result = Backpack:enoughSpaceForItem(playerId, itemId, itemCnt)
if result==ErrorCode.OK and not isDayTx then --如果是夜晚给俩火炬
Player:gainItems(playerId, itemId, itemCnt, 1)
end
end
--设置玩家分数
function PlayerAddScore(playerId, addScore)
if playerId <= 0 then return end
local ret, currScore = Player:getGameScore(playerId)
if ret==ErrorCode.OK then
local playScore = currScore+addScore
if addScore < 0 then --设置玩家分数
playScore = math.max(0, playScore)
end
Player:setGameScore(playerId, playScore)
end
local ret, teamId = Player:getTeam(playerId)
if ret==ErrorCode.OK and teamId>0 then
local ret, teamScore = Team:getTeamScore(teamId)
if addScore < 0 then --设置队伍分数
teamScore = math.max(0, addScore+teamScore)
Team:setTeamScore(teamId, teamScore)
else
Team:addTeamScore(teamId, addScore)
end
end
end
--重置tick次数
function IsCanTick(isTick)
isTick = isTick or true
if isTick then Data.tickCount = Data.tickCount+1 end
if Data.tickCount>=Data.newTicker then
Data.tickCount = 0
return true
end
return false
end
-------------------------------游戏事件-------------------------------
Game_EnterRoom = function()
-- 玩法地图不会调该方法,测试需开房间
InitGameRule() --初始化相关游戏规则
--重置游戏数据
Data.tickCount = 0
Data.isGameEnd = false
Mobs.gensCnt = 0
Mobs.deadCnt = 0
local renderType = 1--小地图显示模式 1:旋转视角 2:全图俯视
local result = UI:setMinimapRenderMode(renderType)
-- 设置一个标志位
local result = Game:setScriptVar(1, 99)
if result==ErrorCode.OK then
result = Game:sendScriptVars2Client()
end
end
Game_StartGame = function()
if not Data.isRuleInit then InitGameRule() end
InitCenterPoint() --初始化地图中心点
local isTestMode = false --测试模式
InitGameMap(Cfg.map_size, isTestMode)
InitGameMobs(Cfg.map_size) --初始化游戏怪物
InitGameItems(Cfg.map_size) --初始化游戏道具
InitGamePlayer(isTestMode) --初始化玩家信息
local x1, x2 = Pos.ix-Data.markRadius, Pos.ix+Data.markRadius
local z1, z2 = Pos.iz-Data.markRadius, Pos.iz+Data.markRadius
drawMiniMark(true, x1,x2,z1,z2, 0,2) --绘制小地图
--drawMiniMark(true, Pos.ix,Pos.iz,0,0, Data.markRadius,3)
local ret, text = Game:getDefString(3068)
Chat:sendChat(text, Sys.chatType)
end
Game_Update = function()
if Data.isGameEnd or Data.isTimeout then return end
if IsCanTick()==false then return end
Data.markRadius = Data.markRadius-1
if Data.miniMarkId > 0 then --标记还存在
if Data.markRadius > 0 then --刷新小地图标记
local x1, x2 = Pos.ix-Data.markRadius, Pos.ix+Data.markRadius
local z1, z2 = Pos.iz-Data.markRadius, Pos.iz+Data.markRadius
drawMiniMark(false, x1, x2, z1, z2, 0, 2)
--drawMiniMark(false, Pos.ix,Pos.iz,0,0, Data.markRadius,3)
elseif Data.markRadius <= 0 then
MapMark:showShape(Data.miniMarkId, false)
MapMark:deleteShape(Data.miniMarkId)
Data.miniMarkId = -1
end
end
--[==[
if Data.glEffectId >= 0 then --进入小圈后去掉全部debuff
local ret, playerId = Player:getMainPlayerUin()
if ret==ErrorCode.OK and playerId>0 then
local ret, x,y,z = Player:getPosition(playerId)
if ret == ErrorCode.OK then
if (x-Pos.cx)*(x-Pos.cx)+(z-Pos.cz)*(z-Pos.cz) < Pos.cr*Pos.cr then
Player:clearAllBadBuff(playerId)--去掉debuff
local ret, buffN, buffLt = Player:getBuffList(playerId)
if ret==ErrorCode.OK and buffNum>=3 then
end
end
end
--[[
local ret, actorHp = Actor:getHP(playerId)
if ret==ErrorCode.OK and actorHp<=15 then
local ret = Actor:tryMoveToPos(playerId, Pos.cx, Pos.iy+1, Pos.cz, 5.0)
print("Move=============>>>", ret)
end
--]]
end
end
--]==]
--/1、怪物已经全被干掉
if Mobs.gensCnt>0 and Mobs.deadCnt>=Mobs.gensCnt then
Data.isGameEnd = true
Game:doGameEnd()
return
end
--/2、分数达到某值则结束游戏/GameRule设置有问题
if Cfg.max_score > 0 then
for teamId in pairs({Teams.red, Teams.blue}) do
local ret, score = Team:getTeamScore(teamId)
if ret==ErrorCode.OK and score>=Cfg.max_score then
Data.isGameEnd = true
Game:doGameEnd()
return
end
end
end
-- 单人模式下不计算存活规则
local ret1, btNum = Team:getTeamPlayers(Teams.blue)
if ret1==ErrorCode.OK or btNum==0 then return end
local ret2, rtNum = Team:getTeamPlayers(Teams.red)
if ret2==ErrorCode.OK or rtNum==0 then return end
--/3、玩家无存活则游戏结束
local ret1, raNum = Team:getTeamPlayers(Teams.red, LiveType.alive)
local ret2, baNum = Team:getTeamPlayers(Teams.blue, LiveType.alive)
if ret1 ~= ErrorCode.OK or ret2 ~= ErrorCode.OK then return end
if raNum==0 and baNum==0 then
Data.isGameEnd = true
Game:doGameEnd()
return
end
end
Game_GameEnd = function()
print("GameEnd1 ================>>>Func")
local ret1, rxScore = Team:getTeamScore(Teams.red)
local ret2, bxScore = Team:getTeamScore(Teams.blue)
print("GameEnd2 ================>>>", ret1, ret2, rxScore, bxScore)
if ret1==ErrorCode.FAILED or ret2==ErrorCode.FAILED then return end
local result = rxScore >= bxScore
local isClient = true --主客机标志
if result then --红队/主队胜利
Battle_Ended(Teams.red, Battle.win)
if not isClient then --主队胜利提示
local ret, txtInfox = Game:getDefString(270)
Chat:sendChat(txtInfox, Sys.chatType)
else --客队失败提示
local ret, txtInfox = Game:getDefString(271)
Chat:sendChat(txtInfox, Sys.chatType)
end
else
Battle_Ended(Teams.blue, Battle.win)
if not isClient then --主队失败提示
local ret, txtInfox = Game:getDefString(271)
Chat:sendChat(txtInfox, Sys.chatType)
else --客队胜利提示
local ret, txtInfox = Game:getDefString(270)
Chat:sendChat(txtInfox, Sys.chatType)
end
end
end
Game_TimeOver = function()
--超时比得分,高分获胜
Data.isTimeout = true
end
-------------------------------玩家事件-------------------------------
Player_Inited = function(trigger_obj)
local playerId = trigger_obj['eventobjid']
if not Data.isRuleInit then InitGameRule() end
-- 进入房间开始游戏前时调用
local ret, val = Game:getScriptVar(1)
if ret==ErrorCode.OK then end
end
-- 干掉对方玩家可+5分/已在GameRule里设置
Player_Dead = function(trigger_obj)
local playerId = trigger_obj['eventobjid']
local killedBy = trigger_obj['toobjid']
if playerId <= 0 then return end
PlayerAddScore(playerId, -5) --死亡-5分
end
Player_Revive = function(trigger_obj)
local playerId = trigger_obj['eventobjid']
--复活保护BUFF<BuffId要除1000>/GameRule可设置
local buffId = math.floor(999002/1000)
Player:addBuff(playerId, buffId, 2, 10000)
local buffId1 = math.floor(27003/1000)
Player:addBuff(playerId, buffId1, 2, 500000)
local ret, teamId = Player:getTeam(playerId)
if ret~=ErrorCode.OK or teamId<=0 then return end
ResetPosition(playerId, teamId) --回到复活点复活
--设置饱食度/防止血量自增
Player:setFoodLevel(playerId, 70)
-- 默认给玩家一把短刀(ItemId:12003)防御
local itemId, itemCnt = 12003, 1
local ret = Backpack:enoughSpaceForItem(playerId, itemId, itemCnt)
if ret==ErrorCode.OK then Player:gainItems(playerId, itemId, itemCnt, 1) end
end
Player_JoinTeam = function(trigger_obj)
local playerId = trigger_obj['eventobjid']
-- 流程有问题,暂时无法设置多人组,默认1人组
local ret, teamId = Player:getTeam(playerId)
if ret==ErrorCode.OK and teamId>0 then
ResetPosition(playerId, teamId) --设置队伍位置
end
end
local itemCount = 0
Player_AddItem = function(trigger_obj)
local itemId = trigger_obj['itemid']
local itemNum = trigger_obj['itemnum']
local playerId = trigger_obj['eventobjid']
if itemId==Items.rewardIdx and playerId>0 then
PlayerAddScore(playerId, itemNum*1)
end
if itemId == Items.rewardIdx then
local result, state = World:getCameraEditState()
if result==ErrorCode.OK then print('当前视角编辑状态:', state) end
--[[
state = CameraEditState.CAMERA_EDIT_STATE_EDIT
local result = World:setCameraEditState(state)
print('已成功设置视角编辑状态?', result==ErrorCode.OK and '成功' or '失败')
--]]
local result, config = World:getCustomCameraConfig()
if result==ErrorCode.OK and config~=nil then --自定义视角
config:setOption(CAMERA_OPTION_INDEX_CONFIG_SET, CCG_FLATVIEW)
end
local actorType = 0 --OBJ_TYPE_MONSTER
local x1, y1, z1 = -5, 1, -5
local x2, y2, z2 = 15, 9, 15
local ret, num, array = World:getActorsByBox(actorType, x1,y1,z1, x2,y2,z2)
if ret == ErrorCode.OK then print('Creature ===>> ', num, array) end
local aliveType = LiveType.all
local ret, num, array = World:getAllPlayers(aliveType)
if ret == ErrorCode.OK then print('Actors ===>> ', num, array) end
local aliveType = LiveType.alive
local ret, playerId = World:randomOnePlayer(aliveType)
if ret == ErrorCode.OK then print('Player ===>> ', playerId) end
local result = World:despawnActor(Mobs.objIds[1])
if result == ErrorCode.OK then print('Despawn Actorx ===>> ', result) end
end
-- local modx = math.mod(itemCount, 3)
-- if modx==0 then CheckBackpackAPI('SC', itemId) end
-- if modx==1 then CheckBackpackAPI('BC', itemId) end
-- if modx==2 then CheckBackpackAPI('EC', itemId) end
itemCount = itemCount + 1
end
-------------------------------怪物事件-------------------------------
-- 伤害源为玩家或怪物
Actor_Die = function(trigger_obj)
print("Monster_Dead==========>>>", trigger_obj)
local mobId, actorId = trigger_obj['eventobjid'], trigger_obj['toobjid']
local addScore = 0 --额外加分情况
local ret, defId = Creature:getActorID(mobId)
if defId==Items.mobsIdx[1] then --弓手
addScore = 2
Mobs.deadCnt = Mobs.deadCnt+1
print('FFc=======>>>', Mobs.deadCnt)
elseif defId==Items.fishIdx then --灯笼鱼
addScore = 5
end
if addScore==0 then return end
local result = Actor:isPlayer(actorId)
if result==ErrorCode.OK then--怪物被玩家干掉
PlayerAddScore(actorId, addScore)
return
end
--被玩家驯服的动物干掉
local result = Actor:isMob(actorId)
if result==ErrorCode.OK then
local ret, playerId = Creature:getTamedOwnerID(actorId)
if ret==ErrorCode.OK and playerId>0 then
PlayerAddScore(playerId, addScore)
end
end
end
-------------------------------方块事件-------------------------------
--生成战旗后添加雾圈效果
Block_Added = function(trigger_obj)
print("Block_Added==========>>>", trigger_obj)
local blockId = trigger_obj['blockid']
local x, y, z = trigger_obj['x'], trigger_obj['y'], trigger_obj['z']
if blockId==919 or blockId==920 then
if Data.glEffectId >= 0 then return end
local ret, glEffectId = Game:addRenderGlobalEffect("particles/Fog.ent")
if ret==ErrorCode.OK and glEffectId >= 0 then
Data.glEffectId = glEffectId
Game:setRenderGlobalEffectPos(Data.glEffectId, Pos.cx, 0, Pos.cz)
Game:setRenderGlobalEffectScale(Data.glEffectId, Pos.cr/4.0, 0.045, Pos.cr/4.0)
end
end
end
--战旗被摧毁后雾圈消失/治疗效果消失
Block_Removed = function(trigger_obj)
print('Block_removed===========>>>', trigger_obj)
local blockId = trigger_obj['blockid']
local x, y, z = trigger_obj['x'], trigger_obj['y'], trigger_obj['z']
if Data.glEffectId >= 0 then --删除雾圈效果
local ret = Game:removeRenderGlobalEffect(Data.glEffectId)
if ret == ErrorCode.OK then Data.glEffectId = -1 end
end
end
--将南瓜灯放置到对应的队旗旁+12fen
Block_PlacedBy = function(trigger_obj)
print('Block_placed===========>>>', trigger_obj)
local blockId = trigger_obj['blockid']
local x, y, z = trigger_obj['x'], trigger_obj['y'], trigger_obj['z']
end
--获取宝箱并将其打掉的队伍可+7分
Block_DestroyBy = function(trigger_obj)
print("Block_DestroyBy===========>>>", trigger_obj)
local blockId = trigger_obj['blockid']
local actorId = trigger_obj['eventobjid']
local x, y, z = trigger_obj['x'], trigger_obj['y'], trigger_obj['z']
if actorId > 0 then
if blockId == posBlocks[1] then--罐子
PlayerAddScore(actorId, 7)
elseif blockId == posBlocks[2] then--南瓜灯
PlayerAddScore(actorId, 12)
end
end
end
--点燃台灯+10分/点燃烟花+20分
Block_TriggerBy = function(trigger_obj)
print("Block_trigger===========>>>", trigger_obj)
local blockId = trigger_obj['blockid']
local actorId = trigger_obj['eventobjid']
local x, y, z = trigger_obj['x'], trigger_obj['y'], trigger_obj['z']
if blockId==itemLamps[1] then--烟花
PlayerAddScore(actorId, 20)
elseif blockId==itemLamps[2] or blockId==itemLamps[3] then
PlayerAddScore(actorId, 10)
end
end
--[==[
--碰撞区撞到方块会触发变身效果
Block_CollidedBy = function(trigger_obj)
print("Block_Collided===========>>>", trigger_obj)
local blockId = trigger_obj['blockid']
local actorId = trigger_obj['eventobjid']
local x, y, z = trigger_obj['x'], trigger_obj['y'], trigger_obj['z']
local result = Actor:isPlayer(actorId)
if result ~= ErrorCode.OK then return end --非玩家触发
local buffId, buffLv = 0, 1
if blockId == negBlocks[1] then--变鸡Buff
buffId = math.floor(1003001/1000)
elseif blockId == negBlocks[2] then--变羊Buff
buffId = math.floor(1005001/1000)
end
if buffId == 0 then return end
local ret = Player:hasBuff(actorId, buffId)
if ret == ErrorCode.OK then --设置buff时长/60秒
local ret, ticks = Player:getBuffLeftTick(actorId, buffId)
print('TT===========>>>', ret, ticks)
if ret==ErrorCode.OK and ticks<=60*20 then
Player:addBuff(actorId, buffId, buffLv, 60*20)
end
else
Player:addBuff(actorId, buffId, buffLv, 60*20)
end
end
--加血区每秒加1生命值
Block_WalkedBy = function(trigger_obj)
print("Block_walking===========>>>", trigger_obj)
local blockId = trigger_obj['blockid']
local actorId = trigger_obj['eventobjid']
local x, y, z = trigger_obj['x'], trigger_obj['y'], trigger_obj['z']
if Data.glEffectId == -1 then return end
local result = Actor:isPlayer(actorId)
if result ~= ErrorCode.OK then return end --非玩家触发
if blockId == Items.treatId then
local ret1, maxHp = Player:getMaxHP(actorId)
if ret1 ~= ErrorCode.OK then return end
local ret2, curHp = Player:getHP(actorId)
if ret2 ~= ErrorCode.OK then return end
if curHp < maxHp then --加血
local ret = Player:addHP(actorId, 1)
end
end
end
--]==]
Block_FertilizedBy = function(trigger_obj)
print("Block_fertilized===========>>>", trigger_obj)
local blockId = trigger_obj['blockid']
local actorId = trigger_obj['eventobjid']
local x, y, z = trigger_obj['x'], trigger_obj['y'], trigger_obj['z']
end
ListenEvents_MiniDemo();
end)()