之前已经实现了在场景上添加英雄,并使英雄播放待机动作,接下来让英雄在场景动起来
本游戏的代码已开源,包含游戏资源
git地址
https://github.com/dreamfairy/PrompaLua
首先我们创建用户控制层 HudLayer.lua 包位置为 scenes.layers.HudLayer.lua
HudLayer.lua 的内容为
[cc lang=”lua”]
local HudLayer = class(“HudLayer”, function()
return display.newLayer()
end)
local DPad
function HudLayer:ctor()
end
function HudLayer:getDPad()
return DPad
end
return HudLayer
[/cc]
可以看到我们实现了一个 getDPad()方法,但是DPad目前还是nil, 接下来开始创建 DPad 用户操控面板
创建 SimpleDPad.lua 包位置为 scenes.Controller.SimpleDPad.lua
SimpleDPad 内容:
[cc lang=”lua”]
local SimpleDPad = class(“SimpleDPad”, function()
return display.newSprite(“pd_dpad.png”)
end)
local Radius
local Direction
local IsHeld
local Delegate
function SimpleDPad:ctor()
local updateFunc = function(dt) self:onUpdate(dt) end
IsHeld = false
Direction = CCPointZero
self:scheduleUpdate(updateFunc)
self:setNodeEventEnabled(true)
self.touchLayer = display.newLayer()
self:addChild(self.touchLayer)
end
function SimpleDPad:updateDirectionForTouchLocation(location)
local radians = ccpToAngle(ccpSub(location,ccp(self:getPositionX(),self:getPositionY())))
local degrees = -1 * math.deg(radians)
if degrees <= 22.5 and degrees >= -22.5 then
–right
Direction = ccp(1.0,0.0)
elseif degrees > 22.5 and degrees < 67.5 then
--bottom right
Direction = ccp(1.0,-1.0)
elseif degrees >= 67.5 and degrees <= 112.5 then
--bottom
Direction = ccp(0.0,-1.0)
elseif degrees > 112.5 and degrees < 157.5 then
--bottom left
Direction = ccp(-1.0,-1.0)
elseif degrees >= 157.5 or degrees <= -157.5 then
--left
Direction = ccp(-1.0,0.0)
elseif degrees < -22.5 and degrees > -67.5 then
–top right
Direction = ccp(1.0,1.0)
elseif degrees <= -67.5 and degrees >= -112.5 then
–top
Direction = ccp(0.0,1.0)
elseif degrees < -112.5 and degrees > -157.5 then
–top left
Direction = ccp(-1.0,1.0)
end
Delegate:didChangeDirectionTo(self,Direction)
end
function SimpleDPad:onEnter()
self.touchLayer:addTouchEventListener(function(event,x,y)
return self:onTouch(event,x,y)
end)
self.touchLayer:setTouchEnabled(true)
end
function SimpleDPad:onExit()
self.touchLayer:removeTouchEventListener()
self:setTouchEnabled(false)
end
function SimpleDPad:onUpdate(dt)
–CCLuaLog(dt)
if IsHeld == true then
Delegate:isHoldingDirection(self,Direction)
end
end
function SimpleDPad:setRadius(value)
Radius = value;
end
function SimpleDPad:setDelegate(value)
Delegate = value
end
function SimpleDPad:onTouch(event,x,y)
local location = ccp(x,y)
if event == “began” then
local distanceSQ = ccpDistanceSQ(location, ccp(self:getPositionX(),self:getPositionY()))
if distanceSQ <= Radius * Radius then
self:updateDirectionForTouchLocation(location)
IsHeld = true
return true
end
return false
end
if event == "moved" then
self:updateDirectionForTouchLocation(location)
end
if event == "ended" then
location = CCPointZero
IsHeld = false
Delegate:simpleDPadTouchEnded(self)
end
end
return SimpleDPad
[/cc]
使用 display.newSprite("pd_dpad.png") 8方向键作为用户的操作面板
self:setNodeEventEnabled(true) 开启节点事件,只有开启该事件 onEnter 和 onExit函数才会被调用,我们需要在 onEnter 函数中添加触摸事件监听,并在 onExit中移除它
self.touchLayer = display.newLayer() 建立一个 touch 层,用来接收触摸事件
self:addChild(self.touchLayer)
在编写的时候,Delegate 是在 setDelegate 函数调用后初始化的,Delegate 实际上市一个 接口,任何实现该接口的类都可以被set进来
现在来编写 Delegate 接口,一共有3个函数和1个继承方法
创建 SimpleDPadDelegate.lua 包位置 scenes.Controller.SimpleDPadDelegate.lua
SimpleDPadDelegate 的内容如下
[cc lang="lua"]
local SimleDpadDelegate = {}
function SimleDpadDelegate:extend()
local o = {}
setmetatable(o,self)
self.__index = self
return o
end
function SimleDpadDelegate:didChangeDirectionTo(SimpleDPad,Direction)
CCLuaLog("This function muse be written")
end
function SimleDpadDelegate:isHoldingDirection(SimpleDPad,Direction)
CCLuaLog("This function muse be written")
end
function SimleDpadDelegate:simpleDPadTouchEnded(SimpleDPad, Direction)
CCLuaLog("This function muse be written")
end
return SimleDpadDelegate
[/cc]
好了,现在有Delegate 接口了,我们让 GameLayer 来实现它,并在GameLayer上实现操控英雄的逻辑
GamLayer.lua 中添加一个变量
[cc lang="lua"]
local Delegate = require("scenes.Controller.SimpleDPadDelegate"):extend()
[/cc]
Delegate 继承了 SimpleDPadDelegate中的方法,之后要在GameLayer中具体实现
继续实现3个方法
[cc lang="lua"]
function Delegate:didChangeDirectionTo(SimpleDPad,Direction)
Hero:walkWithDirection(Direction)
end
function Delegate:isHoldingDirection(SimpleDPad,Direction)
Hero:walkWithDirection(Direction)
end
function Delegate:simpleDPadTouchEnded(SimpleDPad, Direction)
if Hero:getActionState() == ACTION_STATE_WALK then
Hero:idle()
end
end
[/cc]
操作的逻辑部分基本完成,现在将它们组装起来
在HudLayer.lua 的ctor()中添加下列代码
[cc lang="lua"]
function HudLayer:ctor()
DPad = require("scenes.Controller.SimpleDPad").new()
DPad:setRadius(64)
DPad:setPosition(64,64)
DPad:setOpacity(100)
self:addChild(DPad)
end
[/cc]
在 GameScene 中添加HudLayer,并将 GameLayer 设置为Delegate
GameScene.lua 现在完整代码如下
[cc lang="lua"]
require("config")
local GameScene = class("GameScene", function()
return display.newScene("GameScene")
end)
local GameLayer = require("scenes.layers.GameLayer").new()
local HudLayer = require("scenes.layers.HudLayer").new()
function GameScene:ctor()
self:addChild(GameLayer)
self:addChild(HudLayer)
local DPad = HudLayer:getDPad()
DPad:setDelegate(GameLayer:getClass())
end
到此为止,你已经可以使用你的控制器,控制英雄行走了
return GameScene
[/cc]
下一节将添加上怪物们,以及让它们可以被攻击