Cocos2d-x 3.2 lua飞机大战开发实例(二)敌机类的封装,以及碰撞检测的实现

前端之家收集整理的这篇文章主要介绍了Cocos2d-x 3.2 lua飞机大战开发实例(二)敌机类的封装,以及碰撞检测的实现前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

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

1.敌机类的封装以及碰撞检测

--

Enemy的类中

require "Cocos2d"

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

return cc.Node:create()

end)

function Enemy:create(t,x,y)

local enemy=Enemy.new()

enemy:addChild(enemy:init(t,y))

return enemy

end

--构造

function Enemy:ctor()

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

self.ex=0

self.ey=0

self.type=0

self.dirH=true --真为rigth 假为left

self.dirV=true --false up truedown

self.flyWidth=30 --摇摆的幅度

self.flyX=0 --当前的摇摆值

self.count=0 --控制移动的逻辑执行的次数

end

--init()

function Enemy:init(t,y)

local layer=cc.Layer:create()

local sp=cc.Sprite:create()

layer:addChild(sp)

--敌机动画

if t==0 then

--动画的每一帧

local sf1=cc.SpriteFrame:create("fonts/Resources/ld1.png",cc.rect(0,0,87,100))

local sf2=cc.SpriteFrame:create("fonts/Resources/ld1.png",cc.rect(87,100))

local allf={sf1,sf2}

--创建动画

local animation=cc.Animation:createWithSpriteFrames(allf,0.1)

local animate=cc.Animate:create(animation)

sp:runAction(cc.RepeatForever:create(animate))

elseif t==1 then

local sf1=cc.SpriteFrame:create("fonts/Resources/ld1.png",0.1)

local animate=cc.Animate:create(animation)

sp:runAction(cc.RepeatForever:create(animate))

elseif t==2 then

local sf1=cc.SpriteFrame:create("fonts/Resources/ld2.png",100))

local sf2=cc.SpriteFrame:create("fonts/Resources/ld2.png",0.1)

local animate=cc.Animate:create(animation)

sp:runAction(cc.RepeatForever:create(animate))

end

--设置坐标

sp:setPosition(x,y)

self.ex=x

self.ey=y

self.type=t

--计划任务,然敌机自动向下飞

local function logic(t)

self.count=self.count+1 -—控制它的帧率

if self.count<5 then

return

else

self.count=0

end

if self.type==0 then

--自动向下飞

self.ey=self.ey-10

if self.ey<0 then

self:removeFromParent()--移除

return

end

elseif self.type==1 then

--左右摇摆向下飞

self.ey=self.ey-2

if self.ey<0 then

self:removeFromParent()--移除

return

end

--摇摆

if self.dirH then --向右摇摆

self.ex=self.ex+self.flyX--敌机的横坐标+摇摆的值

else

self.ex=self.ex-self.flyX--敌机的横坐标摇摆的值

end

self.flyX=self.flyX+3 --当前的摇摆值

if self.flyX>self.flyWidth then--如果当前的摇摆值大于摇摆的幅度

self.flyX=0 --摇摆值归0

self.dirH=not self.dirH --反向

end

elseif self.type==2 then

--飞到屏幕的中央向两侧飞行

if self.ey>=self.winsize.height/2 then

self.ey=self.ey-2--如果在屏幕中间的上方就让它不断乡下走

else

self.ex=self.ex+5--向右走

if self.ex>self.winsize.width then --如果大于屏幕的宽度

self:removeFromParent() --就移除

return

end

end

end

sp:setPosition(self.ex,self.ey) --敌机的坐标

end

sp:scheduleUpdateWithPriorityLua(logic,0) --让这个敌机执行它的计划任务

return layer

end

return Enemy

--这样我们就实现好了敌机类的封装,下面我们就从GameScene中再添加敌机

2.在GameScene的init()中

跟飞机产生子弹的原理一致,首先需要在构造函数添加一个计数器

self.countEnemy=0 --敌机产生的计数器

--添加敌机

--添加敌机

local function newEnemy(t)

self.countEnemy=self.countEnemy+1

if self.countEnemy>=120 then

--产生敌机

local newEnemy=require("nodes.Enemy")

--产生随机--type定义成随机

local num=math.random()*3--mathlua中的基本函数math.random()它产生的是0~1随机数,*3之后变成1~3随机

local etype=0 --敌机的类型

if num>2 and num<=3 then etype=2 end

if num>1 and num<=2 then etype=1 end

if num>0 and num<=1 then etype=0 end

--创建敌机--产生随机的类型--产生随机的飞机坐标

local ne=newEnemy:create(etype,math.random()*self.winsize.width,self.winsize.height)

layer:addChild(ne)

self.countEnemy=0

end

end

--给敌机计划任务

local node2=cc.Node:create()

layer:addChild(node2)

node2:scheduleUpdateWithPriorityLua(newEnemy,0)

--

3.碰撞检测的实现,首先要确定的是思路,我们该怎么取到子弹和敌机呢?这样做。。。

产生子弹时,我们不但要将子弹添加到layer中,还要定义table,将子弹添加到table中

在GameData全局数据中定义:

g_allBullet={}—保存所有的子弹

g_allEnemy={}—保存所有的敌机

我们在子弹类的构造函数中,定义:

self.indexInAllBullet=0 --当前这个子弹在table集合中的编号

在这里子弹节点删除时,还要将子弹从全局表中删除

table.remove(g_allBullet,self.indexInAllBullet)

--调整编号

for i=1,#g_allBullet do

if g_allBullet[i].indexInAllBullet>self.indexInAllBulletthen

g_allBullet[i].indexInAllBullet=g_allBullet[i].indexInAllBullet-1

end

end

self.unscheduleUpdate()

在GameScene中子弹产生,添加到layer的同时也要添加这个子弹到全局数据里

newb.indexInAllBullet=#g_allBullet+1 --记录当前这颗子弹在这个集合中的下标是几

g_allBullet[#g_allBullet+1]=newb --#号能够返回这个table中有多少个数据!+1是下标从1开始

--print("目前子弹的个数"..tostring(#g_allBullet))—-每产生一个子弹都再g_allBullet

--~~~~~~~~~~~~~~~~~~~~~~~~~~~~

同理,我们也需要将敌机做这样的处理

我们在敌机类的构造函数中,也需要加一个成员属性

self.indexInAllEnemy=0 --当前这个敌机在table集合中的编号

--在这里敌机节点删除时,还要将敌机从全局表中删除

table.remove(g_allEnemy,self.indexInAllEnemy) --删除这个表中的这个元素

--后续编号--

for i=1,#g_allEnemydo

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

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

end

end

self:unscheduleUpdate()

在GameScene中敌机产生,添加到layer的同时也要添加这个敌机到全局table里

--把这个敌机添加到全局的table

ne.indexOfAllEnemy=#g_allEnemy+1--记录当前这个敌机在这个集合中的下标是几 g_allEnemy[#g_allEnemy+1]=ne --#号能够返回这个table中有多少个数据!+1是下标从1开始

--print("目前敌机的数量"..tostring(#g_allEnemy))

--实际上我们的做到这里只是为了做碰撞检测的一个前提,我们已经把所有的敌机和子弹都转化成了table中的数据这样我们就可以实现访问敌机和子弹了接下来我们就该做碰撞检测了

4.碰撞检测

--增加碰撞检测逻辑

local function gamelogic(t)

--碰撞检测

--i就是第i个元素,v就是第i个元素的值,v,还可以写成nowbulletg_allBullet返回的是这个元素的编号

--for i,nowbullet in pairs(g_allBullet) do

-- for j,nowenemy inpairs(g_allEnemy) do

--

--

-- end

--end

for i=1,#g_allBullet do--i1循环到g_allbullet的长度

local nowbullet=g_allBullet[i] --获取i个子弹

for j=1,#g_allEnemy do

local nowe=g_allEnemy[j]

local rect1=cc.rect(nowbullet.bx,nowbullet.by,7,10)

local rect2=cc.rect(nowe.ex,nowe.ey,50)

--print(nowe.ex..","..nowe.ey..","..nowbullet.bx..","..nowbullet.by)

if cc.rectIntersectsRect(rect1,rect2) then

--子弹消失

table.remove(g_allBullet,nowbullet.indexInAllBullet)--从全局表里删除自己--table表中的第i个元素消失

--后续编号--

for i=1,#g_allBulletdo

if g_allBullet[i].indexInAllBullet>nowbullet.indexInAllBulletthen

g_allBullet[i].indexInAllBullet=g_allBullet[i].indexInAllBullet-1

end

end

nowbullet:unscheduleUpdate()

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

--敌机消失

table.remove(g_allEnemy,nowe.indexOfAllEnemy)

--后续编号--

for i=1,#g_allEnemydo

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

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

end

end

nowe:unscheduleUpdate()

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

break

end

end

end

end

local node3=cc.Node:create()

layer:addChild(node3)

node3:scheduleUpdateWithPriorityLua(gamelogic,0)

5.在子弹的类这敌机的类中我们也要对后续的table表中的编号进行重整

子弹类的init()的移除子弹处,中我们这样做:

--后续编号--

for i=1,#g_allBullet do

--要移除的是第i(self.indexInAllBullet)个子弹, 假如我们移除了第2个子弹,我们就让第3个子弹的编号变成2

if g_allBullet[i].indexInAllBullet>self.indexInAllBulletthen

g_allBullet[i].indexInAllBullet=g_allBullet[i].indexInAllBullet-1

end

end

self:unscheduleUpdate()

6.在敌机的类中我们都需要对移除敌机时进行后续编号的一个处理

在敌机类的init()移除敌机中时:

--后续编号--

for i=1,#g_allEnemydo

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

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

end

end

self:unscheduleUpdate()

--这样就基本上实现了子弹和敌机碰撞检测了,只是一些效果还没有添加

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