1. 程式人生 > >RPG遊戲狀態機實現例項

RPG遊戲狀態機實現例項

local Hero = class("Hero", function (  )
	return display.newNode()
end)

function Hero:ctor(  )
	self:initHero()
	self:addStateMachine()--新增狀態機函式
end

function Hero:initHero(  )
	self.hero = sp.SkeletonAnimation:create("spine/sp-zuozhu/skeleton.json","spine/sp-zuozhu/skeleton.atlas",1)
	self.hero.debugBones = true;
	self.jineng = sp.SkeletonAnimation:create("spine/sp-zuozhu/skeleton_effect.json","spine/sp-zuozhu/skeleton_effect.atlas",1)
	self:addChild(self.hero)
	self:addChild(self.jineng)  --建立spine骨骼動畫精靈

	self.sk = sp.SkeletonAnimation:create(
		"spine/effects/huangseguanghuan/huangseguanghuan.json",
		"spine/effects/huangseguanghuan/huangseguanghuan.atlas",1)
	self.sk:setAnimation(0,"animation",true)
	self:addChild(self.sk) --新增動畫


	self.hero:setAnimation(0,"run",true)

	
end

--增加狀態機
function Hero:addStateMachine(  )
	--存放狀態的表
	self.fsm = {}
	cc.GameObject.extend(self.fsm)
		:addComponent("components.behavior.StateMachine")
		:exportMethods()    --建立一個狀態機物件
	self.fsm:setupState({
		--初始化狀態為閒置狀態
		initial = "idle",
		events = {  --狀態發生轉變時對應的事件
		{name ="normal", from={ "walk", "run", "atk1", "atk2","atk3","skill1","skill2","skill3","floorhurt","win"}, to ="idle"},
            {name ="move1",   from={"idle", "run" }, to ="walk"},         
      		{name ="move2",   from={"idle", "walk"}, to ="run"},
      		{name ="attack1", from={"idle", "walk", "run" }, to ="atk1"},
		{name ="attack2", from={"idle", "walk", "run", "atk1"}, to ="atk2"},
	      	{name ="attack3", from={"idle", "walk", "run", "atk2"}, to="atk3"},
	      	{name ="skills1", from={"idle", "walk", "run"}, to ="skill1"},
	      	{name ="skills2", from={"idle", "walk", "run"}, to ="skill2"},
	      	{name ="skills3", from={"idle", "walk", "run"}, to ="skill3"},
	      	{name ="injured", from={"idle", "walk", "run"}, to="floorhurt"},
	      	{name ="death", from={"idle", "walk", "run", "atk1", "atk2", "atk3","skill1","skill2","skill3"}, to ="die"},
		{name ="victory", from={"idle", "walk", "run", "atk1", "atk2"}, to ="win"},
        },--from和to後面跟的都是狀態,to後是跳轉之後的狀態
        callbacks={  --發生轉變時的回撥函式
	    	onenteridle=function ()
	    		self.hero:setAnimation(0,"idle",true)
			end,
	   		onenterwalk = function () 
	     		self.hero:setAnimation(0,"walk",true)  
	        end,  
	   		onenterrun = function ()  
	        	self.hero:setAnimation(0,"run",true)
	        end,
	        onenteratk1 = function ()  
	        	self.hero:setAnimation(0,"atk1",false) 
	        	self.jineng:setAnimation(0,"atk1",false)
	        	self.isPutSkills = true
	        	-- self.scheduler = scheduler.scheduleGlobal(handler(self, self.PengZhuangJianCe),0.1)
	        end,
	        onenteratk2 = function ()
	        	self.hero:setAnimation(0,"atk2",false)
	        	self.jineng:setAnimation(0,"atk2",false)
	        	self.isPutSkills = true
	        	-- self.scheduler = scheduler.scheduleGlobal(handler(self, self.PengZhuangJianCe),0.1)
	        end,
	        onenteratk3 = function ()
	        	self.hero:setAnimation(0,"atk3",false)
	        	self.jineng:setAnimation(0,"atk3",false)
	        	self.isPutSkills = true
	        	-- self.scheduler = scheduler.scheduleGlobal(handler(self, self.PengZhuangJianCe),0.1)
	        end,
	        onenterskill1 = function ()
	        	--先等待一會
	        	local a1 = cc.DelayTime:create(0.2)
	        	local a2 = cc.MoveBy:create(0.5,cc.p(480*(-self.hero:getScaleX()),0))
	        	-- local s = transition.sequence(a1,a2)
	        	local s = cc.Sequence:create(a1,a2,nil)
	        	self:runAction(s)
	        	self.hero:setAnimation(0,"skill1",false)
	        	self.jineng:setAnimation(0,"skill1",false)
	        	self.isPutSkills = true
	        end,
	        onenterskill2 = function ()
	        	self.hero:setAnimation(0,"skill2",false)
	        	self.jineng:setAnimation(0,"skill2",false)
	        	self.isPutSkills = true
	        end,
	        onenterskill3 = function ()
	        	self.hero:setAnimation(0,"skill3",false)
	        	self.jineng:setAnimation(0,"skill3",false)
	        	self.isPutSkills = true
	        end,
	        onenterfloorhurt = function ()
	        	self.hero:setAnimation(0,"floorhurt",false)

	        end,
	        onenterdie = function ()
	        	self.hero:clearTracks()
		        self.jineng:clearTracks()
	        	self.hero:setAnimation(0,"die",false)
	        	self.jineng:setAnimation(0,"die",false)
	        end,
	        onenterwin = function ()
	        	self.hero:setAnimation(0,"win",false)
	        	self.jineng:setAnimation(0,"win",false)
	        end,
      	},
		})
end

function Hero:doEvent(event)   --在其他的類中便可用spine精靈物件呼叫doEvent(“name”)函式實現狀態的轉換了
	--首先判斷此事件是否可以執行
	if self.fsm:canDoEvent(event) then
		self.fsm:doEvent(event)
	end
end


return Hero