之前已经实现了在场景上添加英雄,并使英雄播放待机动作,接下来让英雄在场景动起来
本游戏的代码已开源,包含游戏资源
git地址
https://github.com/dreamfairy/PrompaLua
首先我们创建用户控制层 HudLayer.lua 包位置为 scenes.layers.HudLayer.lua
HudLayer.lua 的内容为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | local HudLayer = class("HudLayer", function() return display.newLayer() end) local DPad function HudLayer:ctor() end function HudLayer:getDPad() return DPad end return HudLayer |
可以看到我们实现了一个 getDPad()方法,但是DPad目前还是nil, 接下来开始创建 DPad 用户操控面板
创建 SimpleDPad.lua 包位置为 scenes.Controller.SimpleDPad.lua
SimpleDPad 内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | 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 |
使用 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 的内容如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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 |
好了,现在有Delegate 接口了,我们让 GameLayer 来实现它,并在GameLayer上实现操控英雄的逻辑
GamLayer.lua 中添加一个变量
1 | local Delegate = require("scenes.Controller.SimpleDPadDelegate"):extend() |
Delegate 继承了 SimpleDPadDelegate中的方法,之后要在GameLayer中具体实现
继续实现3个方法
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 |
操作的逻辑部分基本完成,现在将它们组装起来
在HudLayer.lua 的ctor()中添加下列代码
1 2 3 4 5 6 7 | function HudLayer:ctor() DPad = require("scenes.Controller.SimpleDPad").new() DPad:setRadius(64) DPad:setPosition(64,64) DPad:setOpacity(100) self:addChild(DPad) end |
在 GameScene 中添加HudLayer,并将 GameLayer 设置为Delegate
GameScene.lua 现在完整代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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 到此为止,你已经可以使用你的控制器,控制英雄行走了 <img src="http://www.dreamfairy.cn/blog/wp-content/uploads/2013/10/p3.jpg" alt="p3" width="486" height="368" class="aligncenter size-full wp-image-1576" /> return GameScene |
下一节将添加上怪物们,以及让它们可以被攻击