当红色小车来不及躲避的时候发生碰撞游戏结束,那么如何判断俩辆小车碰撞了呢,我们可以通过俩辆小车的位置来确定,比如当他们的x和y坐标相同的时候就是发生了碰撞,再精确一点就是y坐标相同,x坐标的距离是俩辆小车的宽度之和的一半。甚么时候代表俩辆小车同向运动错开行驶了呢,y坐标有一个差值,x坐标和上边的一样。实际在运用的时候发现在lua中比较数字是否相同是不太好的,因为lua中只有浮点类型,转化为整形可以使用floor或者ceil函数,不过我采用的方法是先判断是否在同一个轨道,在前几篇的博客中当小车变轨的时候我设置了小车的switch变量,通过这个变量的真假来判断小车是在内圈还是外圈。这样y方向的判断我们就用这个变量,而x方向的判断我用的就是数字,判断俩车的距离。
在运用黄色小车的switch变量的时候,发现bug,所以我们先来修正这个bug,让黄色小车的switch跟随他的内外圈运动而变,修正后的代码如下,是在上一篇博客的基础上改的。
1 | function MainGameScene:runYelloCar(car) |
4 | local function getAction() |
6 | local y1 = self.track_size.height*0.445 |
8 | local point1 = cc.p(self.track_size.width*0.245,self.car_bottomy) |
9 | local point2 = cc.p(self.track_size.width*0.745,self.car_topy) |
12 | local switch = self.yello_switch |
15 | y1 = self.track_size.height*0.335 |
17 | point1 = cc.p(self.track_size.width*0.245,self.track_size.height*0.171) |
18 | point2 = cc.p(self.track_size.width*0.745,self.track_size.height*0.844) |
22 | local rate = GlobalData.rate |
24 | local tm = math.pi *y1/rate |
26 | local tm2 = (self.track_size.width*0.5)/rate |
29 | local circle1 = tt.CircleBy:create(tm,{x=0,y=y1},180) |
30 | local spawn1 = cc.Spawn:create(circle1:reverse(),cc.RotateBy:create(tm,-180)) |
31 | local move2 = cc.MoveTo:create(tm2,{x=point1.x,y=point2.y}) |
32 | local circle2 = tt.CircleBy:create(tm,{x=0,y=y2},180) |
33 | local spawn2 = cc.Spawn:create(circle2:reverse(),cc.RotateBy:create(tm,-180)) |
34 | local move1 = cc.MoveTo:create(tm2,{x=point2.x,y=point1.y}) |
36 | return tm,tm2,spawn1,move2,spawn2,move1 |
39 | local tm,tm2,spawn1,move2,spawn2,move1 = getAction() |
42 | local switch= self.yello_switch |
45 | math.randomseed ( os.time ()) |
46 | local r = math.random (0,100) |
48 | if r > 50 and (self.yello_switch == false ) then |
50 | local circle1 = cc.Spawn:create(tt.CircleBy:create(tm/2,{x=-30,y=self.track_size.height*0.4},-90),cc.RotateBy:create(tm/2,-90)) |
51 | local circle2 = cc.Spawn:create(tt.CircleBy:create(tm/2,{x=-162,y=self.track_size.height*0.0015},-90),cc.RotateBy:create(tm/2,-90)) |
53 | spawn1 = cc.Sequence:create( |
54 | circle1,cc.CallFunc:create( function ()self.yello_switch = true end ), |
58 | self.yello_switch = true |
59 | tm,tm2,_,move2,spawn2,_ = getAction() |
62 | r = math.random (0,100) |
63 | if r > 50 and (self.yello_switch == true ) then |
65 | local circle1 = cc.Spawn:create(tt.CircleBy:create(tm/2,{x=-25,y=-self.track_size.height*0.4},-90),cc.RotateBy:create(tm/2,-90)) |
66 | local circle2 = cc.Spawn:create(tt.CircleBy:create(tm/2,{x=225,y=self.track_size.height*0.02},-90),cc.RotateBy:create(tm/2,-90)) |
67 | spawn2 = cc.Sequence:create( |
68 | circle1,cc.CallFunc:create( function ()self.yello_switch = false end ), |
72 | self.yello_switch = false |
76 | local callfunc = cc.CallFunc:create( function () |
77 | self:runYelloCar(self.car_yello) |
81 | local action_yello = cc.Sequence:create(move1,spawn1,move2,spawn2,callfunc) |
82 | action_yello:setTag(2) |
85 | self.yello_switch = switch |
86 | car:runAction(action_yello) |
接下来就完成碰撞检测的逻辑,代码注释写的很清楚了,大家看注释吧!
2 | function MainGameScene:collision(layer) |
6 | local collistion_update = function () |
8 | local red_x,red_y = self.car_red:getPosition() |
9 | local yello_x,yello_y = self.car_yello:getPosition() |
10 | local red_width = self.car_red:getContentSize().width |
11 | local yello_width = self.car_yello:getContentSize().width |
13 | if self.red_switch == self.yello_switch and math.abs (red_x-yello_x)<(red_width+yello_width)/2 then |
15 | self.car_red:stopAllActions() |
16 | self.car_yello:stopAllActions() |
19 | SoundDeal:playEffect(EffectType.Crash) |
20 | cc.Director:getInstance():getScheduler():unschedulenoxssEntry(self.schedule_update) |
23 | elseif self.red_switch ~= self.yello_switch and math.abs (red_x-yello_x)<(red_width+yello_width)/2 then |
27 | elseif math.abs (red_x-yello_x)>(red_width+yello_width)/2 and isYes then |
32 | self.score:setString(GlobalData.score) |
33 | self.score:setScale(0.1) |
34 | self.score:runAction(cc.EaseElasticOut:create(cc.ScaleTo:create(0.2,1))) |
38 | self.schedule_update = cc.Director:getInstance():getScheduler():schedulenoxssFunc(collistion_update,0, false ) |
接下来就是调用了,在调用之前完成一个开始按钮,当用户点击了开始按钮的时候小车运动,在这个过程中不断的进行碰撞检测。
1 | function MainGameScene:setButton(imageName,layer) |
2 | local play = cc.MenuItemImage:create(imageName, "" , "" ) |
3 | play:setPosition(self.size.width/2,self.size.height/2) |
5 | local menu = cc.Menu:create(play) |
6 | menu:setPosition(cc.p(0,0)) |
10 | local play_callback = function () |
12 | SoundDeal:playEffect(EffectType.Start) |
13 | play:runAction(cc.Sequence:create(cc.ScaleTo:create(0.05,1.3),cc.RemoveSelf:create())) |
14 | self:runRedCar(self.car_red) |
15 | self:runYelloCar(self.car_yello) |
19 | play:registernoxssTapHandler(play_callback) |
代码中涉及到的对声音和数据的处理先不用管,下篇博客再添加。上边的代码有一个新的变量是play,这个变量是用来控制游戏是否在进行的,如果游戏没有开始,用户的触摸事件也是无效的,所以我们需要在触摸处理的回调函数中对这个变量进行判断,什么位置添加我想大家都应该很清楚吧。
游戏结束以后的处理正如代码中看到的那样,调用了一个gameOver函数,下面是这个函数的实现,涉及到数据和声音的部分不用管。
1 | function MainGameScene:gameOver(layer) |
2 | self:setButton( "retry.png" ,layer) |
5 | self.score:setString( "0" ) |