之前已经实现了在场景上添加英雄,并使英雄播放待机动作,接下来让英雄在场景动起来
本游戏的代码已开源,包含游戏资源
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 ,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 ,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 |
下一节将添加上怪物们,以及让它们可以被攻击