原文链接(http://blog.csdn.net/kibaamor/article/details/12838897)
环境:
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 cls
- end
函数class的第一个参数就是我们要实现的类的名称,可以不传第二个参数或者给第二参数传一个function或者table。
我们从cocos2dx中的CCSprite继承,根据不同的状态播放不同的动画
实现:
玩家和怪物的基类可如下实现:
- require "extern"
- Actor = class("Actor", function()
- return CCSprite:create()
- end)
- Actor.__index = Actor
- -- 常量
- kActorStateUnkown = 0
- kActorStateIdle = 1
- kActorStateAttack = 2
- kActorStateDefense = 3
- kActorStateWalk = 4
- -- 属性
- Actor._state = kActorStateUnkown
- Actor._idle_action = nil
- Actor._attack_action = nil
- Actor._defense_action = nil
- Actor._walk_action = nil
- -- 方法
- function Actor:idle()
- if self._state ~= kActorStateIdle then
- self:stopAllActions()
- pcall(self:runAction(self._idle_action))
- self._state = kActorStateIdle
- end
- end
- function Actor:attack()
- if self._state ~= kActorStateAttack then
- self:stopAllActions()
- pcall(self:runAction(self._attack_action))
- self._state = kActorStateAttack
- end
- end
- function Actor:defense()
- if self._state ~= kActorStateDefense then
- self:stopAllActions()
- pcall(self:runAction(self._defense_action))
- self._state = kActorStateDefense
- end
- end
- function Actor:walk()
- if self._state ~= kActorStateWalk then
- self:stopAllActions()
- pcall(self:runAction(self._walk_action))
- self._state = kActorStateWalk
- end
- end
- function Actor:create()
- local actor = Actor.new()
- return actor
- end
有了基类后,玩家的的实现可以如下:
1、玩家的数据单例
- require "extern"
- PlayerData = class("PlayerData")
- PlayerData.__index = PlayerData
- PlayerData._inited = 0
- PlayerData._idle_action = nil
- PlayerData._attack_action = nil
- PlayerData._defense_action = nil
- PlayerData._walk_action = nil
- function 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 = 1
- end
- function PlayerData:getAllAction()
- self:lazyInit()
- return self._idle_action, self._attack_action, self._defense_action,
- self._walk_action
- end
2、玩家类
- require "actor"
- require "playerdata"
- Player = class("Player", function()
- return Actor:create()
- end)
- Player.__index = Player
- function Player:init()
- self._idle_action, self._attack_action, self._defense_action,
- self._walk_action = PlayerData:getAllAction()
- end
- function Player:create()
- local player = Player.new()
- player:init()
- return player
- end