(四)Lua小游戏别撞车——实现小车AI

发表于2015-06-27
评论0 1.9k浏览

游戏的一个重要逻辑就是黄色小车变换轨道,红色小车在玩家的控制下避开黄色小车以免发生碰撞,红色小车变轨是玩家控制的,而黄色小车是自动变轨的。上篇博客我们将红色小车和黄色小车的运动分开做了处理,本篇博客就实现一下黄色小车的运动,使黄色小车可以自动变轨。我们将黄色小车的变轨放到固定的俩个点处,一个是由外圈轨道进入到内圈轨道处,另一个是由内圈轨道进入到外圈轨道处。小车在运动的过程中,通过概率来计算是否要进入到内圈轨道,在内圈轨道的时候同样通过概率来决定是否要出去到外圈的轨道处,整个代码和红色小车相比真是简单多了。

Lua小游戏别撞车——实现小车AI

1function MainGameScene:runYelloCar(car)
2 
3    --返回执行里圈轨道或者外圈轨道的动作
4    local function getAction()
5        --初始化运动过程中需要的成员变量 代表外圈的轨道
6        local y1 = self.track_size.height*0.445
7        local y2 = -y1
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)
10 
11        --判断执行里圈的轨道还是外圈的轨道
12        local switch = self.yello_switch
13        --代表里圈的轨道
14        if switch then
15            y1 = self.track_size.height*0.335
16            y2 = -y1
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)
19        end
20 
21        --[[根据速率计算小车需要运动的时间--]]
22        local rate = math.pi*self.track_size.height*0.3
23        --圆周运动的时间
24        local tm = math.pi*y1/rate
25        --直线运动的时间
26        local tm2 = (self.track_size.width*0.5)/rate
27 
28        --创建动作
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})
35 
36        return tm,tm2,spawn1,move2,spawn2,move1
37    end
38 
39    local tm,tm2,spawn1,move2,spawn2,move1 = getAction()
40 
41    --获得一个随机数
42    math.randomseed(os.time())
43    local r = math.random(0,100)
44    --只有当小车在外部的轨道,并且满足概率的时候才会进入内部的轨道
45    if r > 50 and (self.yello_switch == falsethen
46        --变轨固定在这个点 进入内部的轨道
47        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))
48        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))
49        spawn1 = cc.Sequence:create(circle1,circle2)
50        --代表里圈轨道
51        self.yello_switch = true
52        tm,tm2,_,move2,spawn2,_ = getAction()
53    end
54 
55    r = math.random(0,100)
56    if r > 50 and (self.yello_switch == truethen
57        --变轨固定在这个点 转到外部的轨道
58        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))
59        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))
60        spawn2 = cc.Sequence:create(circle1,circle2)
61        --代表外圈轨道
62        self.yello_switch = false
63    end
64 
65    --执行完毕一圈以后重新执行动作,这样轨道就是随机的
66    local callfunc = cc.CallFunc:create(function()
67        self:runYelloCar(self.car_yello)
68    end)
69 
70    --动作序列
71    local action_yello = cc.Sequence:create(move1,spawn1,move2,spawn2,callfunc)
72    action_yello:setTag(2)
73 
74    car:runAction(action_yello)
75end

小车是否变轨是通过随机数来判断的,这里获取随机数是使用了Lua中的数学库,同样先设置一个随机数种子,然后获取随机数,math.random(0,100)的含义是获取0-100之间的一个随机数,包括0和100。如果确定了变轨,我们会新创建一个动作来取代原来的半圆周运动,这个新的圆周运动其实是俩个四分之一的圆周运动叠加起来的,这里所有的参数都是我自己调节的,可能不是非常准确,不过最后的效果还算可以。最后小车执行的动作系列并不是repeat的,而是在执行完毕当前的动作序列以后重新调用runYelloCar函数,这样是否变轨就是随机了。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引