环境:
cocos2dx版本为2.1.4
目标:
游戏中一般有玩家和怪物,他们都有相同的动作状态,如:idle、walk、attack、defense等,我们需要抽象出玩家和怪物的代码实现中中相同的部分
方法:
cocos2dx中其实已经提供了类继承的一下工具函数,在sdk中的samples/lua/testlua/resources/luascript目录下有一个名为“extern.lua”,其中有段代码如下:
--create an class.function class(classname, super) local supertype = type(super) local cls if supertype ~= function and supertype ~= table then supertype = nil super = nil end if supertype == function or (super and super.__ctype == 1) then -- inherited from native c++ object cls = {} if supertype == table then -- copy fields from super for k,v in pairs(super) do cls[k] = v end cls.__create = super.__create cls.super = super else cls.__create = super end cls.ctor = function() end cls.__cname = classname cls.__ctype = 1 function cls.new(...) local instance = cls.__create(...) -- copy fields from class to native object for k,v in pairs(cls) do instance[k] = v end instance.class = cls instance:ctor(...) return instance end else -- inherited from lua object if super then cls = clone(super) cls.super = super else cls = {ctor = function() end} end cls.__cname = classname cls.__ctype = 2 -- lua cls.__index = cls function cls.new(...) local instance = setmetatable({}, cls) instance.class = cls instance:ctor(...) return instance end end return clsend
函数class的第一个参数就是我们要实现的类的名称,可以不传第二个参数或者给第二参数传一个function或者table。
我们从cocos2dx中的ccsprite继承,根据不同的状态播放不同的动画
实现:
玩家和怪物的基类可如下实现:
require externactor = class(actor, function() return ccsprite:create()end)actor.__index = actor-- 常量kactorstateunkown = 0kactorstateidle = 1kactorstateattack = 2kactorstatedefense = 3kactorstatewalk = 4-- 属性actor._state = kactorstateunkownactor._idle_action = nilactor._attack_action = nilactor._defense_action = nilactor._walk_action = nil-- 方法function actor:idle() if self._state ~= kactorstateidle then self:stopallactions() pcall(self:runaction(self._idle_action)) self._state = kactorstateidle endendfunction actor:attack() if self._state ~= kactorstateattack then self:stopallactions() pcall(self:runaction(self._attack_action)) self._state = kactorstateattack endendfunction actor:defense() if self._state ~= kactorstatedefense then self:stopallactions() pcall(self:runaction(self._defense_action)) self._state = kactorstatedefense endendfunction actor:walk() if self._state ~= kactorstatewalk then self:stopallactions() pcall(self:runaction(self._walk_action)) self._state = kactorstatewalk endendfunction actor:create() local actor = actor.new() return actorend
有了基类后,玩家的的实现可以如下:
1、玩家的数据单例
require externplayerdata = class(playerdata)playerdata.__index = playerdataplayerdata._inited = 0playerdata._idle_action = nilplayerdata._attack_action = nilplayerdata._defense_action = nilplayerdata._walk_action = nilfunction playerdata:lazyinit() if (self._inited ~= 0) then return end local cache = ccspriteframecache:sharedspriteframecache() cache:addspriteframeswithfile(pd_sprites.plist) local frames = nil local frame = nil local anim = nil -- idle frames = ccarray:createwithcapacity(6) for i = 0, 5 do frame = cache:spriteframebyname( string.format(hero_idle_%02d.png, i)) frames:addobject(frame) end anim = ccanimation:createwithspriteframes(frames, 1.0 / 12.0) self._idle_action = ccrepeatforever:create(ccanimate:create(anim)) -- attack frames = ccarray:createwithcapacity(3) for i = 0, 2 do frame = cache:spriteframebyname( string.format(hero_attack_00_%02d.png, i)) frames:addobject(frame) end anim = ccanimation:createwithspriteframes(frames, 1.0 / 12.0) self._attack_action = ccrepeatforever:create(ccanimate:create(anim)) -- defense self._defense_action = self._idle_action -- walk frames = ccarray:createwithcapacity(8) for i = 0, 7 do frame = cache:spriteframebyname( string.format(hero_walk_%02d.png, i)) frames:addobject(frame) end anim = ccanimation:createwithspriteframes(frames, 1.0 / 12.0) self._walk_action = ccrepeatforever:create(ccanimate:create(anim)) self._inited = 1endfunction playerdata:getallaction() self:lazyinit() return self._idle_action, self._attack_action, self._defense_action, self._walk_actionend
2、玩家类
require actorrequire playerdataplayer = class(player, function() return actor:create()end)player.__index = playerfunction player:init() self._idle_action, self._attack_action, self._defense_action, self._walk_action = playerdata:getallaction()endfunction player:create() local player = player.new() player:init() return playerend
