【唠叨】

    当时学Lua的时候,我将《战神传说》用Lua也写了一遍。

    C++版的《战神传说》参考这篇:

【源码】

    


【学习心得】

1、继承自cc.Sprite后,设置自身纹理图片的方式

-- 【方式一】通过精灵帧设置	cc.SpriteFrameCache:getInstance():addSpriteFrames("123.plist")	local frame = cc.SpriteFrameCache:getInstance():getSpriteFrame("1.png")	self:setSpriteFrame(frame)	-- 【方式二】通过图片纹理	local texture = cc.Director:getInstance():getTextureCache():addImage("ship01.png")	local frame = cc.SpriteFrame:createWithTexture(texture, cc.rect(0, 0, 60, 38))	self:setSpriteFrame(frame)

2、混合模式

-- local cbl = {GL_SRC_ALPHA, GL_ONE}	self:setBlendFunc(GL_SRC_ALPHA, GL_ONE)

3、定时器

-- 【默认定时器】	self:scheduleUpdateWithPriorityLua(update, priority)	self:unscheduleUpdate()	-- 【自定义定时器】schedule	local dt = 0	function GameLayer:addUpdate()		local function update(_dt) 			dt = _dt 		end		self:scheduleUpdateWithPriorityLua(update, 0)	end		function GameLayer:xxxxx()		local function func()			print(dt)		end		schedule(self, func, 1.0 / 60.0)	end

4、按钮回调

-- registerScriptTapHandler	local function turnToLoadingScene(tag, sender)		self:turnToLoadingScene()	end	local backlb = cc.Label:createWithBMFont("Font/bitmapFontTest.fnt", "Go Back")	local pback = cc.MenuItemLabel:create(backlb)	pback:registerScriptTapHandler(turnToLoadingScene)

5、触摸事件

-- registerScriptHandler	-- 【单点触摸】	local dispatcher = self:getEventDispatcher()	local listener = cc.EventListenerTouchOneByOne:create()	listener:registerScriptHandler(onTouchBegan, cc.Handler.EVENT_TOUCH_BEGAN)	listener:registerScriptHandler(onTouchMoved, cc.Handler.EVENT_TOUCH_MOVED)	listener:registerScriptHandler(onTouchEnded, cc.Handler.EVENT_TOUCH_ENDED)	dispatcher:addEventListenerWithSceneGraphPriority(listener, self)	-- 【吞噬触摸】	listener:setSwallowTouches(true)

6、单例类

Effect = class("Effect", function()		return cc.Node:create()	end)	local _effect = nil	function Effect:getInstance()		if nil == _effect then			_effect = clone(Effect) -- 用clone() ,好像用.new()有问题			_effect:init()		end		return _effect	end

7、贝塞尔曲线运动

local bezier = {		cc.p(sgn * dx, 0),		-- controlPoint_1		cc.p(sgn * dx, -dy),	-- controlPoint_1		cc.p(0, -dy),			-- bezier.endPosition	}	local b0 = cc.BezierBy:create(dt, bezier)

8、动画

-- 【方式一】通过精灵帧创建	local arr = {}	for i=1, 34 do		local str = string.format("explosion_%02d.png" , i)		-- getSpriteFrameByName -> getSpriteFrame		local frame = cc.SpriteFrameCache:getInstance():getSpriteFrame(str)		table.insert(arr, frame)	end	local animation = cc.Animation:createWithSpriteFrames(arr, 0.02)	cc.AnimationCache:getInstance():addAnimation(animation, "Explosion")		-- 【方式二】通过图片纹理	local texture = cc.Director:getInstance():getTextureCache():addImage("ship01.png")	local sp1 = cc.SpriteFrame:createWithTexture(texture, cc.rect(0, 0, 60, 38))	local sp2 = cc.SpriteFrame:createWithTexture(texture, cc.rect(60, 0, 60, 38))	local animation = cc.Animation:create()	an:addSpriteFrame(sp1)	an:addSpriteFrame(sp2)	an:setDelayPerUnit(0.1)	an:setRestoreOriginalFrame(true)	self:runAction(cc.RepeatForever:create(cc.Animate:create(animation)))

9、背景滚动

-- 【1】添加背景	function GameLayer:addBG()		self.bg1 = cc.Sprite:create("bg01.jpg")		self.bg2 = cc.Sprite:create("bg01.jpg")		self.bg1:setAnchorPoint(cc.p(0, 0))		self.bg2:setAnchorPoint(cc.p(0, 0))		self.bg1:setPosition(0, 0)		self.bg2:setPosition(0, self.bg1:getContentSize().height)		self:addChild(self.bg1, -10)		self:addChild(self.bg2, -10)	end	-- 【2】背景滚动	function GameLayer:moveBG()		local height = self.bg1:getContentSize().height		local function updateBG()			self.bg1:setPositionY(self.bg1:getPositionY() - 1)			self.bg2:setPositionY(self.bg1:getPositionY() + height)			if self.bg1:getPositionY() <= -height then				self.bg1, self.bg2 = self.bg2, self.bg1				self.bg2:setPositionY(WIN_SIZE.height)			end		end		schedule(self, updateBG, 0)	end

10、物理碰撞

    > 碰撞事件 & 条件

(1)b1.CategoryBitmask 与 b2.ContactTestBitmask 进行按位与

(2)b2.CategoryBitmask 与 b1.ContactTestBitmask 进行按位与

只有(1)、(2)都不为0的时候,触发碰撞检测事件。

    > 物体碰撞 & 条件

(1)b1.CategoryBitmask 与 b2.CollisionBitmask 进行按位与

(2)b2.CategoryBitmask 与 b1.CollisionBitmask 进行按位与

只有(1)、(2)都不为0的时候,触发物体碰撞。

-- 设置场景物理信息	scene:getPhysicsWorld():setGravity(cc.p(0, 0))	scene:getPhysicsWorld():setDebugDrawMask(cc.PhysicsWorld.DEBUGDRAW_ALL)		-- 创建物体	b1 = cc.Sprite:create("123.png")	-- 半径、材质(密度、弹性、摩擦力)、偏移量	local body = cc.PhysicsBody:createCircle(3, cc.PhysicsMaterial(0.1, 1, 0), cc.p(0, 16)) 	b1:setPhysicsBody(body)	b1:getPhysicsBody():setCategoryBitmask(2)	b1:getPhysicsBody():setCollisionBitmask(3)	b1:getPhysicsBody():setContactTestBitmask(12)		-- 注册碰撞事件	local function onContactBegin(contact)		local a = contact:getShapeA():getBody():getNode()		local b = contact:getShapeB():getBody():getNode()		if a ~= nil and b ~= nil then			a:setPosition(0, 0)			b:setPosition(0, 0)		end		return true	end	local dispatcher = self:getEventDispatcher()	local contactListener = cc.EventListenerPhysicsContact:create()	contactListener:registerScriptHandler(onContactBegin, cc.Handler.EVENT_PHYSICS_CONTACT_BEGIN)	dispatcher:addEventListenerWithSceneGraphPriority(contactListener, self)

11、程序结束

-- 【方式一】	cc.Director:getInstance():endToLua()	-- 【方式二】	os.exit(0)

12、问题集

-- 【敌人管理器】	-- 不加入层中,好像就调用不了enemyManager的方法	self.enemyManager = EnemyManager:create(self)	self:addChild(self.enemyManager)