Cocos2d-x 3.2 lua飞机大战开发实例(三)道具的掉落,碰撞检测,声音,分数,爆炸效果,完善游戏的功能细节

本文介绍使用Cocos2d-x 3.2和Lua开发飞机大战游戏的第三部分,详细讲解了如何添加爆炸效果、更新分数、实现道具掉落、碰撞检测以及完善游戏功能的细节。通过创建Boom类实现爆炸动画,随机生成道具并检测与飞机的碰撞,碰撞后执行相应操作,如增加分数、更换子弹类型等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       Cocos2d-X 3.2  lua语言飞机大战开发实例(三)


7.添加声音,更新分数,添加爆炸效果,道具的掉落、道具的碰撞检测等完善游戏功能


 爆炸的效果添加


首先需要在GameData的全局数据中定义所有道具的表

       g_allTools={} --所有道具的表


接下来定义一个爆炸类

--

require "Cocos2d"

local Boom=class("Boom",function ()

return cc.Node:create()


end)


--

function Boom:create(x,y)

local bm=Boom.new()

bm:addChild(bm:init(x,y))

return bm


end


--

function Boom:ctor()

end


--init()

function Boom:init(x,y)

   local layer=cc.Layer:create()

  

   local boom=cc.ParticleSystemQuad:create("boom.plist")

   layer:addChild(boom)

   boom:setPosition(x,y)

   --一秒钟之后消失

   local act1=cc.DelayTime:create(1)

   local function killme()

        self:removeFromParent()

   end

   local act2=cc.CallFunc:create(killme)

   --执行动作序列

   layer:runAction(cc.Sequence:create({act1,act2}))

   return layer

end

return Boom

--定义好了爆炸的类,我们该在GameScene中添加爆炸的效果了

      --爆炸效果

                local boom=require("nodes.Boom")

                local bm=boom:create(nowe.ex,nowe.ey)

         layer:addChild(bm)


8.道具的掉落,

--我们确定哪架敌机可以产生道具,所以我们需要产生随机数,确定哪个敌机可以产生道具

--在敌机类文件中

--确定这架飞机含有没有道具

local num=math.random(10--产生的是110 的随机数,没有0

if num<=4 then

self.haveTools=num --这样数字是几,道具的类型就是几

else

self.haveTools=0

end

--

 --定义道具的类文件

require "Cocos2d"

local Tools=class("Tools",function ()

return cc.Node:create()

end)


function Tools:create(t,x,y)

   local tool=Tools.new()

   tool:addChild(tool:init(t,x,y))

return tool

end


function Tools:ctor()

   self.type=0

   self.dirW=true   --水平的方向

   self.dirH=true   --竖直方向

   self.tx=0

   self.ty=0

   self.btimes=0  --反弹

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

   self.indexOfAllTools=0  --记录道具在table表中的编号

   

   

end



function Tools:init(t,x,y)

local layer=cc.Layer:create()

    self.type=t

local sp=nil

if t==1 then

sp=cc.Sprite:create("tooljia.png")--加血

elseif t==2 then

    sp=cc.Sprite:create("toolj.png")--激光

elseif t==3 then

    sp=cc.Sprite:create("tools.png")--散弹

elseif t==4  then

    sp=cc.Sprite:create("toob.png")--全品爆炸

   

end

 

sp:setPosition(x,y)

self.tx=x

self.ty=y

layer:addChild(sp)

 

--设置计划任务,让道具反弹6次后消失

local function update(t)

--改变坐标

if self.dirW==true then

self.tx=self.tx+5

else

self.tx=self.tx-5

end

if self.dirH==true then

self.ty=self.ty+5

else

    self.ty=self.ty-5

end

     

     --改变方向

     if self.tx>self.winsize.width or self.tx<0 then

     self.dirW=not self.dirW   --打返

     self.btimes=self.btimes+1

     end

     if self.ty>self.winsize.height or self.ty<0 then

     self.dirH=not self.dirH

     self.btimes=self.btimes+1

     end 

     

     sp:setPosition(self.tx,self.ty)--sp重新的设置坐标、

     --判断是否自动的消失

     if self.btimes>5 then

     --那么我们就将它从table表中删除

     table.remove(g_allTools,self.indexOfAllTools)

     --调整后续的编号

     for i=1, #g_allTools do

        if g_allTools[i].indexOfAllTools>self.indexOfAllTools then

          g_allTools[i].indexOfAllTools=g_allTools[i].indexOfAllTools-1

        end

     

     end

     self:unscheduleUpdate()

     self:removeFromParent()

     end

     

end

layer:scheduleUpdateWithPriorityLua(update,0)

return layer

end



return Tools 


--- 在子弹和敌机产生碰撞检测处,我们添加道具的产生

--产生道具

                if nowe.haveTools>0 then

                local tool=require("nodes.Tools")

                local too=tool:create(nowe.haveTools,nowe.ex,nowe.ey)

                layer:addChild(too)

                --再设置一下在table中的编号

                too.indexOfAllTools=#g_allTools+1

                g_allTools[#g_allTools+1]=too

--这样我们在打落敌机的时候就会随机的产生道具了,但是现在还没有做道具的碰撞检测呢,

9.接下来我们就做道具的碰撞检测。依然在碰撞逻辑的gamelogic中添加一个道具的碰撞检测,

假如我们吃到道具就要执行相应的一系列的操作,换子弹,加血,加分数,全屏爆炸等,所以我们这里用cocosui编辑器做了一个分数显示表,以及在全局的数据类中定义了相应了数据



--增加道具和我方飞机的碰撞检测      

         for i=1 ,#g_allTools do    --遍历道具的table

         local nowTools=g_allTools[i]   --取到这个道具

         local rectTools=cc.rect(nowTools.tx,nowTools.ty,30,30)

         if cc.rectContainsPoint(rectTools,cc.p(g_px+15,g_py+15)) then

         --飞机已经碰到道具了

         if nowTools.type==1 then   --加血

            g_hp=g_hp+1

            local textHp=top:getChildByTag(5)

            textHp:setString(string.format("x%d",g_hp))

             elseif  nowTools.type==2 then --全屏爆炸

                --让所有的敌机消失

                while #g_allEnemy>0 do

                  --需要在敌机的位置爆炸,消失,加分

                  local nowe=g_allEnemy[1--取到所有的敌机

                  --天机分数

                  if nowe.type==0 then

                  g_score=g_score+100

                  elseif nowe.type==1 then

                    g_score=g_score+200

                  elseif nowe.type==2 then

                    g_score=g_score+300

                    

                  end

                  --更新ui

                  local textScore=top:getChildByTag(6)

                  textScore:setString(tostring(g_score))

                  --添加音乐

                  cc.SimpleAudioEngine:getInstance():playEffect("boom.wav")

                  --添加爆炸的效果

                  local boom=require("nodes.Boom")

                  local bt=boom:create(nowe.ex,nowe.ey)

                  layer:addChild(bt)

                  --添加道具

                  if nowe.haveTools>0 then

                  local tool=require("nodes.Tools")

                  local too=tool:create(nowe.haveTools,nowe.ex,nowe.ey)

                  layer:addChild(too)

                  too.indexOfAllTools=#g_allTools+1

                  g_allTools[#g_allTools+1]=too

                      end

                  --敌机消失

                  table.remove(g_allEnemy,nowe.indexOfAllEnemy)

                  --更新后续的编号

                  for i=1 ,#g_allEnemy do

                  if g_allEnemy[i].indexOfAllEnemy>nowe.indexOfAllEnemy then

                  g_allEnemy[i].indexOfAllEnemy=g_allEnemy[i].indexOfAllEnemy-1

                  end

                  end

                  nowe:unscheduleUpdate()

                  nowe:removeFromParent()

                 return

                  

                end

             elseif  nowTools.type==3 then   --激光

              ---在这里我们做了对飞机子弹类的一个扩展,添加了一个子弹的类型需要在GameData中添加一个             当前子弹的类型

              g_bulletType=0

         elseif  nowTools.type==4  then  --散弹

               g_bulletType=1

         end

  --移除道具

  table.remove(g_allTools,nowTools.indexOfAllTools)

         --调整后续的编号

         for i=1,#g_allTools do

         if g_allTools[i].indexOfAllTools >nowTools.indexOfAllTools then

         g_allTools[i].indexOfAllTools=g_allTools[i].indexOfAllTools-1

         end

         end

         nowTools:unscheduleUpdate()

nowTools:removeFromParent()

         break

         end

         end

--这样的话我们就实现了道具的碰撞检测的的效果,

10.接下来我们该让飞机和敌机做碰撞检测了,假如,飞机碰撞到敌机,敌机就爆炸,飞机的hp—

当飞机的hp<=0的时候,证明飞机死亡,就让跳转场景。游戏结束。

在碰撞检测gamelogic的逻辑中,添加飞机和敌机的碰撞检测

--增加敌机和我方飞机的碰撞检测

        for i=1,#g_allEnemy do

        local nowenemy=g_allEnemy[i]

        local rect1=cc.rect(nowenemy.ex,nowenemy.ey,87,50)

        if cc.rectContainsPoint(rect1,cc.p(g_px+15,g_py+15)) then

        

                g_hp=g_hp-1

                local textHp=top:getChildByTag(5)

                textHp:setString(string.format("x%d",g_hp))  

                if g_hp<=0 then

                   

                    table.remove(g_allEnemy)

                    nowenemy:unscheduleUpdate()

                    nowenemy:removeFromParent() 

                    

                    

                    local scene=require("GameOver")

                    local ms=scene:create()

                    local tms=cc.TransitionFade:create(0.5,ms)

                    cc.Director:getInstance():replaceScene(tms)

                end

                --爆炸效果

                local boom=require("nodes.Boom")

                local bm=boom:create(nowenemy.ex,nowenemy.ey)

                layer:addChild(bm)

                

                --敌机消失

                table.remove(g_allEnemy,nowenemy.indexOfAllEnemy)

                --后续编号--

                for  i=1,#g_allEnemy do

                    if g_allEnemy[i].indexOfAllEnemy>nowenemy.indexOfAllEnemy then

                        g_allEnemy[i].indexOfAllEnemy=g_allEnemy[i].indexOfAllEnemy-1

                    end

                end

                nowenemy:unscheduleUpdate()

                nowenemy:removeFromParent() --将本节点删除

                return

        end

        end



--这样我们就基本上实现了这个游戏的一个基本的流程,再需要做的就是完善游戏的各个细节部分了,游戏测试效果



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值