cocos2d-x lua 黑人小心了 项目实践

前端之家收集整理的这篇文章主要介绍了cocos2d-x lua 黑人小心了 项目实践前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

利用工作之余学习了cocos2d-x lua,现在把之前学习的知识运用一下,做个小游戏,用的是cocos2d-x 3.2 lua 开发工具是 cocos ide


看看效果



开始编写吧


1、项目结构


2、编写游戏的开始场景 StartGame.lua


--游戏启动场景

StartGame=class("StartGame",function ()
	return cc.Scene:create()
end)

function StartGame:createScene()

local scene=StartGame.new()

scene:startMenu()

return scene
	
end

function StartGame:startMenu()

    local layer=cc.LayerColor:create(cc.c4b(255,255,255))
self:addChild(layer)

local size=cc.Director:getInstance():getWinSize()

local start=cc.MenuItemFont:create("开始")
    start:setColor(cc.c3b(0,0))
    start:setPosition(size.width/2,size.height/2)
    start:registerScriptTapHandler(function(sender)

--跳到游戏场景
cc.Director:getInstance():replaceScene(GameScene:createScene())

end)

    local exit=cc.MenuItemFont:create("退出")
    exit:setScale(0.5)
    exit:setColor(cc.c3b(0,0))
    exit:setPosition(size.width-50,50)
    exit:registerScriptTapHandler(function(sender)

            cc.Director:getInstance():endToLua()

    end)

    local menu=cc.Menu:create(start,exit)
menu:setPosition(0,0)
layer:addChild(menu)


	
end

return StartGame

开始场景只有一个开始按钮和结束按钮,比较简单


3、编写游戏中的 小黑人精灵,小黑人精灵是一个精灵动画,并为小黑人创建一个矩形的刚体,用于碰撞检测

Hero.lua

--英雄精灵

Hero=class("Hero",function ()
	return cc.Sprite:create()
end)


function Hero:createHero()

    ---
    --@return cc.Sprite sp
local sp=Hero.new()

sp:init()

return sp;
	
end

function Hero:init()

    local width = 50
    local height = 55

--设置精灵的显示大小
    self:setContentSize(width,height)
	
--	self:setTexture(Res.hero)
    self:setScale(0.5)
    self:setName("hero")
    self:setTag(1)
    
    --创建一个矩形body
    local heroBody=cc.PhysicsBody:createBox(cc.size(width,height))
    
    self:setPhysicsBody(heroBody)
--  self:getPhysicsBody():setDynamic(false)
    self:getPhysicsBody():setRotationEnable(false)
    --设置不受重力的影响
--    self:getPhysicsBody():setGravityEnable(false)

--设置碰撞掩码
    heroBody:setCategoryBitmask(0x03)
    heroBody:setContactTestBitmask(0x01)
    heroBody:setCollisionBitmask(0x01)
   
   --加载小黑人纹理
    local cache=cc.SpriteFrameCache:getInstance()
    cache:addSpriteFrames(Res.heroPlist,Res.heroPng)
    
    --小黑人动画
    local animFrames={}
    
    for i=1,8 do
    	
    	local frame=cache:getSpriteFrame(string.format("hero_%d.png",i))
    	animFrames[i]=frame
    	
    end
    
    local animation=cc.Animation:createWithSpriteFrames(animFrames,0.1)
    local animate=cc.Animate:create(animation)
    self:runAction(cc.RepeatForever:create(animate))
    
    
end

return Hero

4、编写游戏中的障碍物

Block.lua

--障碍物精灵
Block=class("Block",function ()
	return cc.Sprite:create()
end)

function Block:createBlock(blockSpeed)

    local sp=Block.new()
    
    sp:init(blockSpeed)
    
    return sp
	
end

function Block:init(blockSpeed)

--随机障碍物的大小
    local width = math.random(0,20) + 5
    local height = math.random(0,100) + 20

--设置障碍物精灵在最最右边出现
--    self:setPositionX(cc.Director:getInstance():getVisibleSize().width)

--    self:setContentSize(width,height)
    self:setTextureRect(cc.rect(0,width,height))
    self:setColor(cc.c3b(0,0))
    
    --设置为静态刚体
    local blockBody=cc.PhysicsBody:createBox(cc.size(width,height))
    self:setPhysicsBody(blockBody)
    self:getPhysicsBody():setDynamic(false)
    blockBody:setCategoryBitmask(0x03) --类别掩码 默认值为0xFFFFFFFF
    blockBody:setContactTestBitmask(0x02) --接触掩码 默认值为 0x00000000
    blockBody:setCollisionBitmask(0x02) --碰撞掩码 默认值为0xFFFFFFFF
    
    
    self:scheduleUpdateWithPriorityLua(function(dt)
    
    --不断改变x的位置
            self:setPositionX(self:getPositionX()-blockSpeed)
            
            if self:getPositionX() < 0 then
            
           --移除自身
                self:unscheduleUpdate()
            	self:removeFromParent()
            end
            
    
    end,0)
	
end


return Block


5、编写游戏中的宝石精灵

Gem.lua

--宝石精灵类
Gem=class("Gem",function ()
	return cc.Sprite:create()
end)

function Gem:ctor()
	
	--宝石的移动速度
	self.gemSpeed=1
	
end

function Gem:cretateGem()

local sp=Gem.new()

    sp:init()

	return sp
	
end

function Gem:init()

local size=cc.Director:getInstance():getWinSize()

   self:setName("gem")
   
	
	--取整1、2、3
    math.randomseed(os.time())
    local index=math.floor(math.random(1,3))
    
    local cache=cc.SpriteFrameCache:getInstance()
    
    
    --绿宝石
    if 1 == index then
    
        self:setSpriteFrame(cache:getSpriteFrame("green.png"))
        self:setScale(0.25)
        self:setTag(21)
    
        --紫宝石	
    elseif 2 == index then
    
        self:setSpriteFrame(cache:getSpriteFrame("purple.png"))
        self:setScale(0.25)
        self:setTag(22)
    
    --红宝石
    elseif 3 == index then
    
        self:setSpriteFrame(cache:getSpriteFrame("red.png"))
        self:setScale(0.25)
        self:setTag(23)
    
    end
    
   
    local gemBody=cc.PhysicsBody:createEdgeBox(cc.size(25,25))
    gemBody:setCategoryBitmask(0x01) --类别掩码 默认值为0xFFFFFFFF
    gemBody:setContactTestBitmask(0x01) --接触掩码 默认值为 0x00000000
    gemBody:setCollisionBitmask(0x01) --碰撞掩码 默认值为0xFFFFFFFF

    self:setPhysicsBody(gemBody)
   
    
    self:scheduleUpdateWithPriorityLua(function(dt)

            --不断改变x的位置
            self:setPositionX(self:getPositionX()-self.gemSpeed)

            if self:getPositionX() < 0 then

                --移除自身
                self:unscheduleUpdate()
                self:removeFromParent()
                
            end


    end,0)
	
end


--设置宝石移动的速度
function Gem:setGemSpeed(speed)
	self.gemSpeed=speed
end

function Gem:getGemSpeed(speed)
    return self.gemSpeed
end

return Gem


6、编写游戏中的控制类,这里控制了精灵的出现和碰撞

Control.lua

--控制精灵的动作
Control=class("Control")

function Control:create(layer,positionY)

   local control=Control.new()

    control:init(layer,positionY)

return control
	
end

function Control:ctor()

self.size=nil

    self.layer = nil
    self.positionY=nil
    
    self.effectLabel=nil

    --移动的速度
    self.blockSpeed=2
--控制什么时候创建 障碍物精灵
self.createBlockHero=nil
self.nextBlockHero=nil

--控制什么时候创建宝石
self.createGem=nil
self.nextGem=nil
	
end

---
--@param cc.Layer layer
function Control:init(layer,positionY)

    self.size=cc.Director:getInstance():getWinSize()

   self.layer=layer
   self.positionY=positionY
	
	--创建一个英雄精灵
	local hero=Hero:createHero()
    print(self.positionY+hero:getContentSize().height / 2)
    hero:setPosition(50,self.positionY+hero:getContentSize().height / 2)
    self.layer:addChild(hero)
    

--跳跃按钮
    local itemControl=cc.MenuItemImage:create(Res.control_n,Res.control_p)
    itemControl:setScale(0.35)
    itemControl:setPosition( self.size.width-40,30)
    itemControl:registerScriptTapHandler(function()

            if hero:getPositionY() < hero:getContentSize().height + self.positionY then

                hero:getPhysicsBody():setVelocity(cc.p(0,500))

            end
           

    end)

    local menu=cc.Menu:create(itemControl)
    menu:setPosition(0,0)
    self.layer:addChild(menu)
    
    
    --速度变化特效
    self.effectLabel=cc.Label:createWithTTF("","fonts/Marker Felt.ttf",32)
    self.effectLabel:setColor(cc.c3b(0,0))
    self.effectLabel:enableGlow(cc.c4b(0,0))
    self.effectLabel:setPosition(self.size.width-50,self.positionY+self.size.height/2-self.effectLabel:getContentSize().height/2)
    self.layer:addChild(self.effectLabel)
--    self.effectLabel:setVisible(false)
    
    --初始化计数参数
    self:reset()
	
end

 ---
    --@param touch cc.Touch
    --@param event cc.Event
--   function Control:r(touch,event)
--  
--   end
    

function Control:reset()

    self.createBlockHero=0
    self.nextBlockHero=math.random(0,99)+120
	
end

--创建障碍物精灵 score分数
function Control:updateBlock(score)

    --createBlockHero计数增加
    self.createBlockHero=self.createBlockHero+1
    
	
--	随机时间生成障碍物
    if self.createBlockHero >= self.nextBlockHero then
    
       
		--控制障碍物移动的速度
        ---
        --@param cc.Sprite blockSprite
        local blockSprite=Block:createBlock(self.blockSpeed)
       
        if score >=20 and score < 50 then
           
            print("blockSpeed:",self.blockSpeed)
            if self.blockSpeed < 3 then
        		
                self:test("+3")
               self.blockSpeed=3
        		
        	end
        	
           
        	
        elseif score >=50 and score < 80 then


            if self.blockSpeed < 3 then
                self:test("+5")
                self.blockSpeed=5
            end
          
        	
        elseif score >=80 and score < 100 then

            if self.blockSpeed < 5 then
                self:test("+6")
                self.blockSpeed=6
            end
            
            
        elseif score >=100 and score < 150 then

            if self.blockSpeed < 6 then
                self:test("+7")
                self.blockSpeed=7
            end
            
        elseif score >=150 and score < 180 then

            if self.blockSpeed < 7 then
                self:test("+8")
                self.blockSpeed=8
            end
        	
        elseif score >=180 and score < 250 then
        
            if self.blockSpeed < 8 then
                self:test("+10")
                self.blockSpeed=10
            end
        
        elseif score >= 250 and score < 320 then
        
            if self.blockSpeed < 10 then
                self:test("+12")
                self.blockSpeed=12
            end
            
        elseif score >= 320 and score < 400 then

            if self.blockSpeed < 12 then
                self:test("+15")
                self.blockSpeed=15
            end
            
        elseif score >= 400 then

            if self.blockSpeed < 15 then
                self:test("+18")
                self.blockSpeed=18
            end
        
        end
        
        --取整0、2
        math.randomseed(os.time())
        local index1=math.floor(math.random(0,1))
        local positionX1=self.size.width
        local positionY1=math.random(self.positionY+120+10,self.size.height-35)
        
        
if index1 >= 1 then

            for i=0,index1 do

                local gem=Gem:cretateGem()
                gem:setPosition(positionX1,positionY1)
                self.layer:addChild(gem)

                gem:setGemSpeed(1)
                positionX1=positionX1-25

            end
	
end
        
        
		
        --取整0、2
        math.randomseed(os.time())
        local index2=math.floor(math.random(0,2))
        local positionX2=self.size.width;
        
        if index2 >= 1 then
        
            for i=0,index2 do

                local gem=Gem:cretateGem()
                gem:setPosition(positionX2,self.positionY+gem:getContentSize().height / 5)
                self.layer:addChild(gem)
                gem:setGemSpeed(self.blockSpeed)

                positionX2=positionX2+25

            end
        	
        end
       
		
        blockSprite:setPosition(positionX2+10,self.positionY+blockSprite:getContentSize().height / 2)
        self.layer:addChild(blockSprite)
		
		
		--重新计数
		self:reset()
		
	end
end


function Control:test(effectType)
    self.effectLabel:setString(effectType)
    self.effectLabel:setVisible(true)
    print("effectLabel")
    self.effectLabel:runAction(cc.Sequence:create(cc.ScaleTo:create(1,2),cc.CallFunc:create(function(sender)
        sender:setVisible(false)
    end)))
	
end


function Control:setBlockSpeed(speed)
    self.blockSpeed=speed
end

function Control:getBlockSpeed()
    return self.blockSpeed
end


return Control

7、编写游戏层GameLayer.lua

GameLayer=class("GameLayer",function ()

        return cc.LayerColor:create(cc.c4b(255,255))
	
end)


function GameLayer:ctor()

--控制类
self.control=nil
	
self.score=0

self.gem=0    	
	
end

function GameLayer:createLayer()
	local layer=GameLayer.new()
	
	layer:bg()
	
	return layer
end


--游戏背景图
function GameLayer:bg()

    local size=cc.Director:getInstance():getWinSize()

    --创建一个围绕屏幕四周的物理边界
    local node=cc.Node:create()
    node:setPhysicsBody(cc.PhysicsBody:createEdgeBox(cc.size(size.width,size.height),cc.PHYSICSBODY_MATERIAL_DEFAULT,5))
    node:setPosition(size.width/2,size.height/2+50)
    self:addChild(node)
	
	
	
--	地面(一条线)
    local edgeSprite=cc.Sprite:create()
    edgeSprite:setTextureRect(cc.rect(0,size.width,2))
    edgeSprite:setColor(cc.c3b(125,125,0))
    edgeSprite:setPosition(size.width/2,50)
    self:addChild(edgeSprite)
    
    --分数
    local labelscore=cc.Label:createWithTTF("",20)
    labelscore:setColor(cc.c3b(0,0))
    labelscore:setString(self.score)
    labelscore:setPosition(size.width-80,size.height-35)
    self:addChild(labelscore)
    
    --宝石个数
    local labelGem=cc.Label:createWithTTF("",28)
    labelGem:setColor(cc.c3b(0,0))
    labelGem:setString(self.gem)
    labelGem:setPosition(size.width-180,size.height-35)
    self:addChild(labelGem)
    
    --宝石
    local cache=cc.SpriteFrameCache:getInstance()
    cache:addSpriteFrames(Res.gemPlist,Res.gemPng)
    
    
    
    self.control=Control:create(self,50)
    
    local spGem=cc.Sprite:createWithSpriteFrameName("green.png")
    spGem:setPosition(size.width-220,size.height-35)
    spGem:setScale(0.5)
    self:addChild(spGem)
	
    self:scheduleUpdateWithPriorityLua(function(dt)
    
    --分数
            self.score = self.score + dt
            labelscore:setString(string.format("%#.2f",self.score))
           
    
            self.control:updateBlock(self.score)
    
    end,0)
    
    
    --一个body的CategoryBitmask和另一个body的ContactTestBitmask的逻辑与的结果不等于0时,接触事件将被发出,否则不发送。
    --一个body的CategoryBitmask和另一个body的CollisionBitmask的逻辑与结果不等于0时,他们将碰撞,否则不碰撞
    --需要两个body相互位与运算的值都是大于0时才会发生碰撞检测和发送接触事件通知  
    
    --  碰撞监听
    local conListener=cc.EventListenerPhysicsContact:create();
    conListener:registerScriptHandler(function(contact)

            print("---contact-碰撞了--")
            
            --    处理游戏中精灵碰撞逻辑
            local node1=contact:getShapeA():getBody():getNode()
            local name1=node1:getName()
            local tag1=node1:getTag()
            print("name1:",name1)
          

            local node2=contact:getShapeB():getBody():getNode()
            local name2=node2:getName()
            local tag2=node2:getTag()
            print("name2:",name2)
            
            --英雄碰到宝石
            if name1 == "gem" then
            
            local x,y=node1:getPosition()
            
                self.gem=self.gem+1
                labelGem:setString(string.format("%s",self.gem))
                
                labelGem:runAction(cc.Sequence:create(cc.ScaleTo:create(0.2,1.5),cc.CallFunc:create(
                function (sender)
                	
                        sender:runAction(cc.ScaleTo:create(0.1,1))
                	
                end)))
                
                if nil ~= node1 then
                    self:removeChild(node1,true)
                end
              
            
--                node1:runAction(cc.Sequence:create(cc.Spawn:create(cc.MoveTo:create(0.1,cc.p(node1:getPositionX(),node1:getPositionY()+50)),cc.ScaleTo:create(0.1,0.5),cc.FadeOut:create(0.1)),--                cc.CallFunc:create(function(sender)
--                    self:removeChild(sender,true)
--                    end)))
            
            --英雄碰到障碍物死亡	
            elseif name1 == "hero" then
            
                local x,y=node2:getPosition()
                
                cc.Director:getInstance():replaceScene(StartGame:createScene())
                
            elseif name2 == "hero" then

                local x,y=node2:getPosition()

                cc.Director:getInstance():replaceScene(StartGame:createScene())
            
            end
            
            return true
    end,cc.Handler.EVENT_PHYSICS_CONTACT_BEGIN)

    cc.Director:getInstance():getEventDispatcher():addEventListenerWithSceneGraPHPriority(conListener,self)
	
end

return GameLayer

8、编写游戏场景GameScene.lua

--游戏场景
GameScene=class("GameScene",function ()
    return cc.Scene:createWithPhysics()
	
end)

function GameScene:createScene()

    local scene=GameScene.new()

    --  设置调试
--    scene:getPhysicsWorld():setDebugDrawMask(cc.PhysicsWorld.DEBUGDRAW_ALL)
    scene:getPhysicsWorld():setGravity(cc.p(0,-1000))

    local layer=GameLayer:createLayer()

    scene:addChild(layer)
   
    return scene

end


return GameScene

9、这里我用类把图片和加载的lua文件封装了

Require.lua 游戏加载的lua文件

--引入lua类
require("Cocos2d")
require("Cocos2dConstants")
require("bitExtend")

require("src/game/res/Res")
require("src/game/start/StartGame")
require("src/game/scene/GameScene")
require("src/game/scene/GameLayer")
require("src/game/sprite/Block")
require("src/game/sprite/Hero")
require("src/game/sprite/Control")
require("src/game/sprite/Gem")

Res.lua 游戏用到的图片资源
--图片资源类
Res={}

--开始按钮
Res.start_n="qq_n.png"
Res.start_p="qq_p.png"

Res.heroPng="hero.png"
Res.heroPlist="hero.plist"

Res.control_n="control_n.png"
Res.control_p="control_p.png"

Res.gemPlist="gem.plist"
Res.gemPng="gem.png"

10、修改main.lua
--引入lua文件
require "src/game/res/Require"

-- cclog
local cclog = function(...)
    print(string.format(...))
end

-- for CCLuaEngine traceback
function __G__TRACKBACK__(msg)
    cclog("----------------------------------------")
    cclog("LUA ERROR: " .. tostring(msg) .. "\n")
    cclog(debug.traceback())
    cclog("----------------------------------------")
    return msg
end

local function main()
    collectgarbage("collect")
    -- avoid memory leak
    collectgarbage("setpause",100)
    collectgarbage("setstepmul",5000)
    
    cc.FileUtils:getInstance():addSearchPath("src")
    cc.FileUtils:getInstance():addSearchPath("res")
    
    cc.FileUtils:getInstance():addSearchPath("src/game/res")
    cc.FileUtils:getInstance():addSearchPath("src/game/start")
    cc.FileUtils:getInstance():addSearchPath("src/game/scene")
    cc.FileUtils:getInstance():addSearchPath("src/game/sprite")
    
    
    cc.FileUtils:getInstance():addSearchPath("res/game")
    cc.FileUtils:getInstance():addSearchPath("res/game/hero")
    cc.FileUtils:getInstance():addSearchPath("res/game/gem")
        
    cc.Director:getInstance():getOpenGLView():setDesignResolutionSize(480,320,0)
    cc.Director:getInstance():setDisplayStats(false)
    
    --进入游戏场景
    local scene = require("StartGame")
    local gameScene =scene:createScene()

    
    if cc.Director:getInstance():getRunningScene() then
        cc.Director:getInstance():replaceScene(gameScene)
    else
        cc.Director:getInstance():runWithScene(gameScene)
    end

end


local status,msg = xpcall(main,__G__TRACKBACK__)
if not status then
    error(msg)
end

11、这里发布到android上,ide提供了一键发布,非常的好用,需要设置下环境



然后选择项目打包





等待几分钟就会看到打包成功了



呵呵,是不是很方便? 小弟也是新手,很多地方写的可能不好,我也是刚学lua不久,学习学习了


黑人小心了 源码

猜你在找的Cocos2d-x相关文章