有了地图之后,就可以添加英雄。设定英雄基本体力为100点,每走一步扣除5点,有上下左右四个方向,有障碍物的地方不能通过,有其他英雄的地方不能通过。
英雄的json数据:
{
"data":[ { "id":1, "r":5, "c":6 }, { "id":2, "r":1, "c":1 }, { "id":3, "r":6, "c":1 } ] }
数据中id为英雄id,r表示英雄所在的地图行,c表示英雄所在的地图列。
英雄类:
local Hero = class('Hero',function () return cc.Node:create()
end)
function Hero:ctor(id)
self.id = id
self.sp = ccs.Armature:create('qishi')
self.sp:getAnimation():play('stand')
self:addChild(self.sp)
self.sp:setAnchorPoint(0.5,-0.2)
if id == 1 then
self.sp:getBone('pifeng'):changeDisplayWithName('qishi_pifeng (2).png',true)
elseif id == 2 then
self.sp:getBone('pifeng'):changeDisplayWithName('qishi_pifeng (5).png',true)
self.sp:getBone('qizhi'):changeDisplayWithName('qishi_qizhi (3).png',true)
self.sp:getBone('shengti'):changeDisplayWithName('qishi_dunpai2.png',true)
elseif id == 3 then
self.sp:getBone('pifeng'):changeDisplayWithName('qishi_pifeng (8).png',true)
self.sp:getBone('qizhi'):changeDisplayWithName('qishi_qizhi (1).png',true)
self.sp:getBone('shengti'):changeDisplayWithName('qishi_dunpai1.png',true)
end
self:setNodeSize(cc.size(96,96))
end
function Hero:playAnimation(name)
self.sp:getAnimation():play(name)
end
function Hero:setDir(dir)
if dir=='left' then
self.sp:setScaleX(-1)
else
self.sp:setScaleX(1)
end
end
function Hero:setNodeSize(_size)
self.size = _size
end
function Hero:getNodeSize()
return self.size
end
function Hero:setR(r)
self.r = r
end
function Hero:setC(c)
self.c = c
end
function Hero:getR()
return self.r
end
function Hero:getC()
return self.c
end
function Hero:setMyTl(val)
self.tl = val
end
function Hero:getMyTl()
return self.tl
end
function Hero:getMyId()
return self.id
end
return Hero
基本操作为,点击英雄身上的四个方向按钮,使英雄朝相应方向前进一步。
操作使用的箭头类:
local Arrow = class('Arrow',function () return cc.Node:create()
end)
function Arrow:ctor(width)
self.btn1 = ccui.Button:create('arrow.png')
self.btn2 = self.btn1:clone()
self.btn3 = self.btn1:clone()
self.btn4 = self.btn1:clone()
-- left
self:addChild(self.btn1)
self.btn1:setAnchorPoint(1,0.5)
self.btn1:setPosition(-width/2.5-3,0)
-- up
self.btn2:setRotation(90)
self:addChild(self.btn2)
self.btn2:setAnchorPoint(0.5,0.5)
self.btn2:setPosition(0,width+6)
-- right
self.btn3:setFlippedX(true)
self.btn3:setAnchorPoint(1,0.5)
self.btn3:setPosition(width/2.5+3,0)
self:addChild(self.btn3)
-- down
self.btn4:setRotation(-90)
self.btn4:setAnchorPoint(0.5,0.5)
self.btn4:setPosition(0,-width)
self:addChild(self.btn4)
local t1m1 = cc.MoveBy:create(0.8,cc.p(12,0))
local t1m2 = cc.MoveBy:create(0.8,cc.p(-12,0))
local se1=cc.Sequence:create(t1m1,t1m2)
local re1 = cc.RepeatForever:create(se1)
local t3m1 = t1m2:clone()
local t3m2 = t1m1:clone()
local se3 = cc.Sequence:create(t3m1,t3m2)
local re3 = cc.RepeatForever:create(se3)
local t2m1 = cc.MoveBy:create(0.8,cc.p(0,-12))
local t2m2 = cc.MoveBy:create(0.8,cc.p(0,12))
local se2 = cc.Sequence:create(t2m1,t2m2)
local re2 = cc.RepeatForever:create(se2)
local t4m1 = t2m2:clone()
local t4m2 = t2m1:clone()
local se4 = cc.Sequence:create(t4m1,t4m2)
local re4 = cc.RepeatForever:create(se4)
self.btn1:runAction(re1)
self.btn2:runAction(re2)
self.btn3:runAction(re3)
self.btn4:runAction(re4)
self.btn1:setName('left')
self.btn2:setName('up')
self.btn3:setName('right')
self.btn4:setName('down')
end
function Arrow:setBtnFunc(func) -- 回调
self.btn1:addTouchEventListener(func)
self.btn2:addTouchEventListener(func)
self.btn3:addTouchEventListener(func)
self.btn4:addTouchEventListener(func)
end
function Arrow:showSomeone(name,isShow)
if self.btn1:getName()==name then
self.btn1:setVisible(isShow)
elseif self.btn2:getName()==name then
self.btn2:setVisible(isShow)
elseif self.btn3:getName()==name then
self.btn3:setVisible(isShow)
elseif self.btn4:getName()==name then
self.btn4:setVisible(isShow)
else
self.btn1:setVisible(isShow)
self.btn2:setVisible(isShow)
self.btn3:setVisible(isShow)
self.btn4:setVisible(isShow)
end
end
return Arrow
往地图上添加英雄:
local MainScene = class("MainScene", cc.load("mvc").ViewBase)
function MainScene:ctor()
self.heros = {}
self:addMap()
self:addHero()
end
function MainScene:addMap()
local mapDataStr = cc.FileUtils:getInstance():getStringFromFile('res/MapData.json')
local mapData = json.decode(mapDataStr)
local mapStr = mapData['map']
local mapInfo = self.split(mapStr,'#')
self.mapLayer = require('app/views/MapEditor').new(mapInfo)
self:addChild(self.mapLayer)
self.range = self.mapLayer:getRange()
local winSize = cc.Director:getInstance():getWinSize()
self.mapLayer:setPosition(winSize.width/2-self.mapLayer:getMapWidth()/2,winSize.height/2-self.mapLayer:getMapHeight()/2)
end
function MainScene:addHero()
local heroDataStr = cc.FileUtils:getInstance():getStringFromFile('HeroData.json')
local heroData = json.decode(heroDataStr)
local data = heroData['data']
ccs.ArmatureDataManager:getInstance():addArmatureFileInfo('qishi.ExportJson')
for i=1,#data do
local hero = require('app/views/Hero').new(data[i]['id'])
hero:setR(data[i]['r'])
hero:setC(data[i]['c'])
-- 设定初始体力为100
hero:setMyTl(100)
self.mapLayer:addChild(hero)
local tile = self.mapLayer:getTileByPos(data[i]['r'],data[i]['c'])
hero:setPosition(tile:getPosition())
table.insert(self.heros,hero)
local isShow = false
if i == 1 then
isShow = true
end
self:addArrow(hero,isShow)
end
end
function MainScene:addArrow(hero,isShow)
local arrow = require('app/views/Arrow').new(hero:getNodeSize().width)
hero:addChild(arrow)
arrow:setPositionY(hero:getNodeSize().height/2)
arrow:setName('Arrow')
-- 检查箭头该不该显示
if isShow then
self:showArrow(hero)
else
arrow:showSomeone('all',false)
end
arrow:setBtnFunc(function(sender,_type)
if _type == ccui.TouchEventType.ended then
self:heroAction(hero,sender:getName())
end
end)
end
function MainScene:showArrow(hero)
local arr = hero:getChildByName('Arrow')
local id = hero:getMyId()
local heroR = hero:getR()
local heroC = hero:getC()
local mapC = self.mapLayer:getC()
local mapR = self.mapLayer:getR()
if heroC==1 then
arr:showSomeone('left',false)
elseif heroC==mapC then
arr:showSomeone('right',false)
end
if heroC-1>0 then
arr:showSomeone('left',self:checkArrowShow(heroR,heroC-1,id))
end
if heroC+1<=mapC then
arr:showSomeone('right',self:checkArrowShow(heroR,heroC+1,id))
end
if heroR==1 then
arr:showSomeone('up',false)
elseif heroR==mapR then
arr:showSomeone('down',false)
end
if heroR-1>0 then
arr:showSomeone('up',self:checkArrowShow(heroR-1,heroC,id))
end
if heroR+1<=mapR then
arr:showSomeone('down',self:checkArrowShow(heroR+1,heroC,id))
end
end
function MainScene:checkArrowShow(r,c,id)
local tile = self.mapLayer:getTileByPos(r,c)
local have = false
if tonumber(tile:getId()) >= 3 and tonumber(tile:getId()) <= 5 then -- 障碍不可站
return false
else
for i=1,#self.heros do
local hero = self.heros[i]
if hero:getMyId() ~= id then
local _r = hero:getR()
local _c = hero:getC()
if _r == r and _c == c then
have = true
break
end
end
end
if have then
return false
else
return true
end
end
end
function MainScene:heroAction(hero,arr_dir)
local heroR = hero:getR()
local heroC = hero:getC()
local arrow = hero:getChildByName('Arrow')
local heroTl = hero:getMyTl()
local heroX,heroY = hero:getPosition()
if heroTl <= 0 then
print("--体力不足--")
return false
end
if arr_dir == 'left' then
heroX = heroX - self.range
heroC = heroC - 1
elseif arr_dir == 'up' then
heroY = heroY + self.range
heroR = heroR - 1
elseif arr_dir == 'right' then
heroX = heroX + self.range
heroC = heroC + 1
else -- down
heroY = heroY - self.range
heroR = heroR + 1
end
if heroTl >= 5 then
if arr_dir == 'left' or arr_dir == 'right' then
hero:setDir(arr_dir)
end
local move = cc.MoveTo:create(0.7,cc.p(heroX,heroY))
local function playA()
arrow:showSomeone('all',false)
hero:playAnimation('move')
end
local spawn = cc.Spawn:create(move,cc.CallFunc:create(playA))
local function playB()
hero:playAnimation('stand')
hero:setR(heroR)
hero:setC(heroC)
self:showArrow(hero)
hero:setMyTl(heroTl - 5)
end
hero:runAction(cc.Sequence:create(spawn,cc.CallFunc:create(playB)))
return true
end
end
function MainScene.split(str,reps)
local resultStrList = {}
string.gsub(str,'[^'..reps..']+',function (w)
table.insert(resultStrList,w)
end)
return resultStrList
end
return MainScene
地图类和瓦片类增加了相应方法:
local MapEditor = class('MapEditor',function ()
return cc.Layer:create()
end)
function MapEditor:ctor(mapInfo)
-- 行数
self.R = #mapInfo
local tileDataStr = cc.FileUtils:getInstance():getStringFromFile('res/TileData.json')
local tileData = json.decode(tileDataStr)
for i=1,#mapInfo do
local c = self.split(mapInfo[i],',')
for j=1,#c do
local img = tileData[c[j]]
local tile = require('app/views/TileNode').new(c[j],img)
if i==1 and j==1 then
-- 列数
self.C = #c
self:setMapWidth(tile:getNodeSize().width * #c)
self:setMapHeight(tile:getNodeSize().height * #mapInfo)
self:setRange(tile:getNodeSize().width)
end
self:addChild(tile)
local _x = (j*2-1) * (tile:getNodeSize().width/2)
local _y = (#mapInfo-i) * (tile:getNodeSize().height)
tile:setPosition(_x,_y)
tile:setMyTag(i,j)
tile:setName('Tile')
end
end
end
function MapEditor.split(str,reps)
local resultStrList = {}
string.gsub(str,'[^'..reps..']+',function (w)
table.insert(resultStrList,w)
end)
return resultStrList
end
function MapEditor:setMapWidth(_w)
self.mapWidth = _w
end
function MapEditor:setMapHeight(_h)
self.mapHeight = _h
end
function MapEditor:getMapWidth()
return self.mapWidth
end
function MapEditor:getMapHeight()
return self.mapHeight
end
function MapEditor:getR()
return self.R
end
function MapEditor:getC()
return self.C
end
function MapEditor:setRange(_range)
self.range = _range
end
function MapEditor:getRange()
return self.range
end
function MapEditor:getTileByPos(_x,_y)
local chs = self:getChildren()
for i=1,#chs do
local t = chs[i]
if t:getName()=='Tile' then
local r,c = t:getMyTag()
if r==_x and c==_y then
return t
end
end
end
end
return MapEditor
local TileNode = class('TileNode',function ()
return cc.Node:create()
end)
function TileNode:ctor(id,img)
self.id = id
local sp = cc.Sprite:create('res/dipi.png')
if id ~= 0 then
local sp1 = cc.Sprite:create('res/'..img..'.png')
sp:addChild(sp1,2)
sp1:setPosition(sp:getContentSize().width/2,sp:getContentSize().height/2)
end
sp:setAnchorPoint(0.5,0)
self:addChild(sp)
self:setNodeSize(sp:getContentSize())
end
function TileNode:setNodeSize(_size)
self.nodeSize = _size
end
function TileNode:getNodeSize()
return self.nodeSize
end
function TileNode:getId()
return self.id
end
function TileNode:setMyTag(_x,_y)
self.x = _x
self.y = _y
end
function TileNode:getMyTag()
return self.x , self.y
end
return TileNode
效果: