Quick-cocos2d-x3.3 Study (十五)--------- 为小鸟添加一个物理加速度

一下代码是:

创建一个物理边界;

创建3个小鸟;

将三个小鸟添加到一个table表中;

在GameScene:ctor()函数中添加如下代码:

 1     -- 创建物理世界的边界
 2     -- 创建物理世界的上边界
 3     -- 通过设置两个点来创建一条带物理效果的线条
 4     local top = display.newNode()
 5     local topBody = cc.PhysicsBody:createEdgeSegment( 
 6         -- 第一个点的位置
 7         cc.p( 100, display.top - 100 ),
 8         -- 第二个点的位置
 9         cc.p( display.right - 100, display.top - 200)
10     )
11     -- 添加物理特效
12     top:setPhysicsBody( topBody )
13     -- 添加到场景中
14     self:addChild( top )
15 
16     -- 添加物理世界的左边界
17     local left = display.newNode();
18     local leftBody = cc.PhysicsBody:createEdgeSegment(
19         cc.p( 100, display.top - 100 ),
20         cc.p( 300, display.bottom + 100)
21     )
22     left:setPhysicsBody( leftBody )
23     self:addChild( left )
24 
25     -- 添加物理世界的右边界
26     local right = display.newNode();
27     local rightBody = cc.PhysicsBody:createEdgeSegment(
28         cc.p( display.right - 100, display.top - 100 ),
29         cc.p( display.right - 100, display.bottom + 100)
30     )
31     right:setPhysicsBody( rightBody )
32     self:addChild( right )
33 
34 
35     -- 添加物理世界的下边界
36     local bottom = display.newNode();
37     local bottomBody = cc.PhysicsBody:createEdgeSegment(
38         cc.p( 100, display.bottom + 100 ),
39         cc.p( display.right - 100, display.bottom + 100)
40     )
41     bottom:setPhysicsBody( bottomBody )
42     self:addChild( bottom )
43 
44 
45     -- 添加可以飞行的小鸟,并添加到物理引擎中
46     self.bird = {}
47     -- 设置物体的密度、反弹力、摩擦力,
48     -- 将其都设置为 0 是为了在碰撞的时候不发生任何物理变化
49     local MATERIAL_DEFAULT = cc.PhysicsMaterial( 0.0, 0.0, 0.0 )
50     -- 创建第一个冰蘑菇
51     self.sprite1 = display.newSprite( "image/animations/binggu_01.png" )
52     self.sprite1:pos( display.right - 200, display.top * 0.75 )
53     self.sprite1:addTo( self )
54     local sprite1Body = cc.PhysicsBody:createCircle( 
55         self.sprite1:getContentSize().width / 2, MATERIAL_DEFAULT 
56     )
57     -- 为物体添加物理引擎
58     self.sprite1:setPhysicsBody( sprite1Body )
59     -- 屏蔽物理世界中的刚体收到重力的影响
60     self.sprite1:getPhysicsBody():setGravityEnable(false)
61     -- 添加到table表中
62     table.insert( self.bird, self.sprite1 )
63     -- 创建第二个冰蘑菇
64     self.sprite2 = display.newSprite( "image/animations/binggu_02.png" )
65         :pos( display.right - 200, display.top * 0.55 )
66         :addTo( self )
67     local sprite2Body = cc.PhysicsBody:createCircle( 
68         self.sprite2:getContentSize().width / 2, MATERIAL_DEFAULT 
69     )
70     -- 为物体添加物理引擎
71     self.sprite2:setPhysicsBody( sprite2Body )
72     -- 屏蔽物理世界中的刚体收到重力的影响
73     self.sprite2:getPhysicsBody():setGravityEnable(false)
74     table.insert(self.bird, self.sprite2)
75     -- 创建第三个冰蘑菇
76     self.sprite3 = display.newSprite( "image/animations/binggu_03.png" )
77         :pos( display.right - 200, display.top * 0.25 )
78         :addTo( self )
79     local sprite3Body = cc.PhysicsBody:createCircle( 
80         self.sprite3:getContentSize().width / 2, MATERIAL_DEFAULT 
81     )
82     -- 为物体添加物理引擎
83     self.sprite3:setPhysicsBody( sprite3Body )
84     -- 屏蔽物理世界中的刚体收到重力的影响
85     self.sprite3:getPhysicsBody():setGravityEnable(false)
86     table.insert(self.bird, self.sprite3)

 

在重新创建一个函数:

遍历table中的对象

 1 -- 给小鸟添加一个物理加速度
 2 function GameScene:addVelocityToBird()
 3 
 4     -- 遍历表中的所有对象,对其添加飞行动画
 5     local dict = nil
 6     local i = 0
 7     local len = table.getn(self.bird)
 8 
 9     for i = 0, len - 1, 1 do
10         dict = self.bird[ i + 1 ]
11         print("----  dict  ----" , dict)
12         -- 如果表中没有对象了就跳出循环
13         if dict == nil then 
14             break;
15         end
16         -- 获取图片的x轴位置
17         local x = dict:getPositionX()
18         -- 如果图片的位置还在屏幕中
19         if x <= display.right then
20             if dict:getPhysicsBody():getVelocity().x == 0 then
21                 dict:getPhysicsBody():setVelocity( cc.p( -70, math.random( -40, 40 ) ) )
22             else
23                 table.remove( self.bird, i + 1 )
24                 print("----  remove  ----", i + 1)
25             end
26         end
27     end
28 end

 

在该函数中,我们遍历 self.bird 数组中的所有 Bird 对象,

当检测到某个 Bird 对象刚好要进入屏幕,且还没给过它任何速度时,

我们会给它一个向左的速度,这个速度的范围从(-70, -40)到(-70, 40)。

通俗一点就是说:

Bird 对象将在横坐标上有一个大小为70,方向向左的速度;

在纵坐标上有一个大小在(-40, 40)之间,方向不定的速度。

 

其中math.random(-40, 40)可以产生-40到40的随机数。

为了不产生相同的随机数,我们需要在MyApp:run()中“种”一棵随机数种子,即添加如下的一行代码:

 1 math.randomseed(os.time())  

 

当已经给过某些 Bird 对象速度时,我们要把该对象从 self.bird 数组中移除,

这样可以减短遍历数组的时间。table.remove(table, pos)函数将删除并返回 table 数组中位于 pos 位置上的元素。

总的来讲,addVelocityToBird 函数的目的就是在小鸟进入屏幕时给它一个速度,让它朝着游戏角色冲过来。

 

最后,因为我们需要不停的遍历 self.bird 数组、不停的检测是否给小鸟加上速度,

所以我们需要在刷新屏幕时调用以上的 addVelocityToBird() 函数。

那就偷个懒,直接在 scrollBackgrounds(dt) 函数的最后面添加下列函数:

 1 self:addVelocityToBird() 

 

 

效果图:

 

 

 

补充

因为游戏中的Player、Heart、Airship、Bird都是刚体,

所以现在把这些刚体放在同一个物理世界是很容易发生碰撞、反弹、旋转、被挤出场景等等问题的。

所以,这里我们要补充的就是怎样有效的解决这些问题,

当然,制定具体的解决方案还需要结合碰撞检测来做。

 

setDynamic(dynamic):如果你想你的刚体固定不动,那么你可以调用该函数。

如游戏中的心心,它在物理世界中就是个相对固定不动的对象,

所以我们可以设置它的刚体属性dynamic为false,即 body:setDynamic(false) 。

 

setRotationEnable(enable):如果你想你的刚体不旋转,那么你可以调用该函数。

如 Player、Airship 和 Bird 对象,它们在物理世界中是 Dynamic(动态)的,

但我们不希望它们在动的过程中重心不稳发生旋转,

所以,我们可以给 Player 刚体添加这样的属性加以约束,即:body:setRotationEnable(false)。

 

posted @ 2015-09-20 13:33  silent-bobo  阅读(320)  评论(0编辑  收藏  举报