(三)Lua小游戏别撞车——小车变换轨道——续

发表于2015-06-27
评论0 989浏览
1--小车变道
2function MainGameScene:switchTrace(car)
3    --变轨
4    local circleCenter1,circleCenter2,point1,point2 = self:isSwitch(car)
5 
6    --设置运动参数
7    local tm1,tm2,tm3,tm4,degree1,degree2 = self:setParam(car,circleCenter1,point1,point2)
8 
9    --执行最后的动作
10    self:switch(car,tm1,tm2,tm3,tm4,degree1,degree2,circleCenter1,circleCenter2,point1,point2)
11end
12 
13--根据是否变轨,返回不同的运动参数
14function MainGameScene:isSwitch(car)
15    --以下的代码用来决定是否变轨
16 
17    --初始化运动过程中需要的成员变量 代表外圈的轨道
18    local circleCenter1 = self.track_size.height*0.445
19    local circleCenter2 = -circleCenter1
20    local point1 = cc.p(self.track_size.width*0.245,self.car_bottomy)
21    local point2 = cc.p(self.track_size.width*0.745,self.car_topy)
22 
23    --改变变轨的变量
24    local switch = true
25    if car:getTag() == 1 then
26        switch = self.red_switch
27        self.red_switch = not switch
28    end
29 
30    --决定是否变轨
31    if switch == false then
32        --代表里圈的轨道
33        circleCenter1 = self.track_size.height*0.335
34        circleCenter2 = -circleCenter1
35        point1 = cc.p(self.track_size.width*0.245,self.track_size.height*0.171)
36        point2 = cc.p(self.track_size.width*0.745,self.track_size.height*0.844)
37    end
38 
39    --因为小车使用的里外圈轨道是不一样的,所以需要重新设置小车的位置和一些运动参数
40    if car:getTag() == 1 then
41        --根据小车所处的位置不同,来决定如何位置已经相关参数
42        local x = car:getPositionX()
43        --左圆周运动
44        if x < self.track_size.width*0.245 then
45            --首先需要计算圆周运动已经转过的弧度数,这个值等于x方向的值除以半径,也就是一个cos值
46            local radians
47            --circleCenter代表圆心的绝对位置
48            local circleCenter = cc.pAdd(point1,{x=0,y=circleCenter1})
49            --计算出弧度数
50            radians = math.acos((point1.x-x)/self._radius)
51            --根据弧度数计算出需要旋转的度数
52            if car:getPositionY() > circleCenter.y then
53                --_degree中保存圆周运动需要旋转的度数
54                self._degree = 90-math.deg(radians)
55                --设置变轨以后的坐标
56                car:setPosition({x=circleCenter.x-circleCenter1*math.cos(radians),y=circleCenter.y+circleCenter1*math.sin(radians)})
57            else
58                self._degree = 90+math.deg(radians)
59                --设置变轨以后的坐标
60                car:setPosition({x=circleCenter.x-circleCenter1*math.cos(radians),y=circleCenter.y-circleCenter1*math.sin(radians)})
61            end
62            --设置相对于当前坐标点的圆心位置
63            circleCenter1 = cc.pSub(circleCenter,{x=car:getPositionX(),y=car:getPositionY()})
64            circleCenter2 = {x=0,y=circleCenter2}
65        elseif x > self.track_size.width*0.745 then
66            --首先需要计算圆周运动已经转过的弧度数,这个值等于x方向的值除以半径,也就是一个cos值
67            local radians
68            --circleCenter代表圆心的绝对位置
69            local circleCenter = cc.pAdd(point2,{x=0,y=circleCenter2})
70            --计算出弧度数
71            radians = math.acos((x-point2.x)/self._radius)
72            --根据弧度数计算出需要旋转的度数
73            if car:getPositionY() > circleCenter.y then
74                --_degree中保存圆周运动需要旋转的度数
75                self._degree = 90+math.deg(radians)
76                --设置变轨以后的坐标
77                car:setPosition({x=circleCenter.x+circleCenter1*math.cos(radians),y=circleCenter.y+circleCenter1*math.sin(radians)})
78            else
79                self._degree = 90-math.deg(radians)
80                --设置变轨以后的坐标
81                car:setPosition({x=circleCenter.x+circleCenter1*math.cos(radians),y=circleCenter.y-circleCenter1*math.sin(radians)})
82            end
83            --设置相对于当前坐标点的圆心位置
84            circleCenter1 = {x=0,y=circleCenter1}
85            circleCenter2 = cc.pSub(circleCenter,{x=car:getPositionX(),y=car:getPositionY()})
86        elseif car:getPositionY() > self.track_size.height*0.5 then
87            circleCenter1 = {x=0,y=circleCenter1}
88            circleCenter2 = {x=0,y=circleCenter2}
89            car:setPositionY(point2.y)
90        else
91            circleCenter1 = {x=0,y=circleCenter1}
92            circleCenter2 = {x=0,y=circleCenter2}
93            car:setPositionY(point1.y)
94        end
95    end
96 
97    --将本次圆周运动的半径保存下来
98    self._radius = math.sqrt(math.pow(circleCenter1.x,2)+math.pow(circleCenter1.y,2))
99 
100    --返回相对的圆心点以及绝对的point点
101    return circleCenter1,circleCenter2,point1,point2
102end
103 
104--设置运动的参数
105function MainGameScene:setParam(car,circleCenter1,point1,point2)
106    --根据速率计算小车需要运动的时间
107    local rate = math.pi*self.track_size.height*0.3
108    --圆周运动的半径
109    local radius = self._radius
110    --以下的变量代表的含义是,左圆周运动时间,上直线运动时间,右圆周运动时间,下直线运动时间,左圆周运动弧度数,右圆周运动的弧度数
111    local tm1,tm2,tm3,tm4,degree1,degree2
112    --根据小车位置的不同,计算不同的位移时间
113    local x = car:getPositionX()
114    if x < self.track_size.width*0.245 then
115        tm1 = self._degree*2*math.pi/360*radius/rate
116        tm2 = (point2.x-point1.x)/rate
117        tm3 = math.pi*radius/rate
118        tm4 = (point2.x-point1.x)/rate
119        degree1 = self._degree
120        degree2 =180
121    elseif x > self.track_size.width*0.745 then
122        tm1 = math.pi*radius/rate
123        tm2 = (point2.x-point1.x)/rate
124        tm3 = self._degree*2*math.pi/360*radius/rate
125        tm4 = (point2.x-point1.x)/rate
126        degree1 = 180
127        degree2 = self._degree
128    elseif car:getPositionY() > self.track_size.height*0.5 then
129        tm1 = math.pi*radius/rate
130        tm2 = (point2.x-x)/rate
131        tm3 = math.pi*radius/rate
132        tm4 = (point2.x-point1.x)/rate
133        degree1 = 180
134        degree2 = 180
135    else
136        tm1 = math.pi*radius/rate
137        tm2 = (point2.x-point1.x)/rate
138        tm3 = math.pi*radius/rate
139        tm4 = (x-point1.x)/rate
140        degree1 = 180
141        degree2 = 180
142    end
143 
144    return tm1,tm2,tm3,tm4,degree1,degree2
145end
146 
147--变轨
148function MainGameScene:switch(car,tm1,tm2,tm3,tm4,degree1,degree2,circleCenter1,circleCenter2,point1,point2)
149    --停止动作的执行
150    car:stopAllActions()
151 
152    --创建第一个动作
153    local circle1 = tt.CircleBy:create(tm1,circleCenter1,degree1)
154    local spawn1 = cc.Spawn:create(circle1,cc.RotateBy:create(tm1,degree1))
155    spawn1 = cc.Sequence:create(spawn1,cc.RotateTo:create(0,180))
156    --右圆周运动
157    local circle2 = tt.CircleBy:create(tm3,circleCenter2,degree2)
158    local spawn2 = cc.Spawn:create(circle2,cc.RotateBy:create(tm3,degree2))
159    spawn2 = cc.Sequence:create(spawn2,cc.RotateTo:create(0,360))
160    --下边的直线运动
161    local move1 = cc.MoveTo:create(tm4,point1)
162    --上边的直线运动
163    local move2 = cc.MoveTo:create(tm2,point2)
164    --动作执行完毕调用的函数
165    local callfunc = cc.CallFunc:create(function()
166        self:runRedCar(self.car_red)
167    end)
168 
169    --设置动作执行的顺序
170    local sequence
171    --根据小车所在位置的不同,执行不同的动作序列
172    local x = car:getPositionX()
173    if x <= self.track_size.width*0.245 then
174        sequence = {spawn1,move2,spawn2,move1,callfunc}
175    elseif x >= self.track_size.width*0.745 then
176        sequence = {spawn2,move1,spawn1,move2,callfunc}
177    elseif car:getPositionY() > self.track_size.height*0.5 then
178        sequence = {move2,spawn2,move1,spawn1,callfunc}
179    else
180        sequence = {move1,spawn1,move2,spawn2,callfunc}
181    end
182 
183    local action_red = cc.Sequence:create(sequence)
184    action_red:setTag(1)
185 
186    --执行动作
187 
188    --红色小车
189    if car:getTag() == 1 then
190        car:runAction(action_red)
191    end
192end

在switchTrace中将runRedCar()函数的工作拆分为三部分来完成,isSwitch函数是获得变轨以后动作的俩个圆心和俩个点,setParam就是用来设置执行动作的一些参数的,包括时间以及圆周运动的角度,最后的switch函数完成变轨动作,注意动作执行完毕以后调用了runRedCar函数,这样红色小车的整个变轨逻辑就完成了,最后看一下效果吧。

Lua小游戏别撞车——小车变换轨道

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