⑴ box2D 碰撞后两物体合并在一起怎么实现
是否是非弹性碰撞的问题,例如石子打入泥巴里面。
⑵ 如何使用box2d来做碰撞检测
当你使用cocos2d来制作一个游戏的时候,有时,你可能想使用cocos2d的action来移动游戏中的对象,而不是直接使用Box2d物理引擎来做。然而,这并不是说你不能使用box2d提供的强大的碰撞检测功能!
这个教程的目的,就是一步一步地向你展示如何仅使用box2d来做碰撞检测---没有物理效果。我们将创建一个简单的demo,里面有一辆车在屏幕上奔驰,当它撞到一只猫后就会放声大笑。是的,我明白,这样做太残忍了。
在这篇教程中,我们会引入一些新的、有趣的概念,比如使用sprite sheets,利用Zwoptex工具来制作它。还会涉及box2d的debug drawing和VertexHelper这个工具。
这个简单假设你已经阅读过前面的一系列的cocos2d和box2d的教程了(如果没有,最好把前面的教程先看一遍),或者你有相关经验也可以。
还有,在我忘记之前--特别要感谢Kim在评论中建议我写一篇这样的教程。
Sprites and Sprite Sheets
在我们开始之前,需要简单地介绍一下sprites和spritesheets。
目前为止,当我们使用cocos2d的时候,我们都是直接使用CCSprite类,然后传递一个精灵图片给它。但是,根据cocos2d最佳实践,如果使用spritesheet来做的话,那样会极大地提高效率。
上图就是一个spritesheet的样例,这个图在cocos2d的样例代码中可以找到。简言之,spritesheet就是一张大的图片,它能够被裁成许多小的子图片。为了指定spritesheet中的每个子图片的位置,你需要为每个图片指定一个坐标,通常是一个矩形。比如,下面的代码展示了,如何把spritesheet中前四张图片抠出来:
CCSpriteSheet *sheet = [CCSpriteSheet
spriteSheetWithFile:@"grossini_dance_atlas.jpg" capacity:1];
CCSprite *sprite1 = [CCSprite spriteWithTexture:sheet.texture rect:
CGRectMake(85*0, 121*1, 85, 121)];
CCSprite *sprite2 = [CCSprite spriteWithTexture:sheet.texture rect:
CGRectMake(85*1, 121*1, 85, 121)];
CCSprite *sprite3 = [CCSprite spriteWithTexture:sheet.texture rect:
CGRectMake(85*2, 121*1, 85, 121)];
CCSprite *sprite4 = [CCSprite spriteWithTexture:sheet.texture rect:
CGRectMake(85*3, 121*1, 85, 121)];
你可以会说,写一大堆硬编码的坐标太麻烦了,太烦人了!幸运的是,Robert Payne已经写好了一个非常方便地web工具,叫做Zwoptex,它可以创建精灵表单(spritesheet),同时会导出每个子图片的坐标,这样你在cocos2d里面使用这些子图片就会非常方便了。
制作精灵表单
在我们开始之前,你需要一张图片。你可以下载我老婆制作的车和猫的图片,或者使用你自己的。接下来,打开浏览器,加载Zwoptex主页。你将会看到下面的屏幕:
一旦加载完毕后,点击Zwoptex的File菜单,然后点Import Images。选择你刚刚下载的车和猫的图片,然后点click,这时,你的图片应该出现会互相重叠在一起。拖动其中一张,这样会看得更清楚一些。
注意,这些图片已经被自动地把图片周围的空白部分给去掉了。这并不是我们想要的(后面你会知道为什么),因此,用鼠标把这两张图片都框住,然后选择菜单Modify\Untrim Selected Images。
现在,我们的图片看起来非常好了。点击Arrange\Complex by Height(no spacing),然后它们会排列地更加整齐。
最后,让我们把画布(canvas)的大小调整为合适的大小。点击Modify\Canvas Width,并把它设置为128px。同样的,点击Modify\Canvas Height,然后把它设置为64px。你的屏幕最后看起来应该是下面这个样子。
最后,是时候导出sprite sheet和相应的坐标了!点击File\Export Texture,然后保存sprite sheet为“sprites.jpg”。然后点击File\Export Coordinates“并且保存为”sprites.plist“。注意,这里必须把spritesheet和坐标文件的名字取成相同的,因为,spritesheet为假设它的坐标文件为相应名字的plist文件。
接下来,打开sprites.plist。你会看到Zwopte已经自动地帮你把原图中每一个子图片的坐标计算出来了,并且存储成了一个plist文件。我们接下来就可以使用这些坐标,而不用手工去输入它们了!
从Sprite sheet中添加我们的精灵
好,是时候写一些代码了!
打开Xcode并创建一个新的工程,选择 cocos2d-0.99.1 Box2d Application template,取名为Box2DCollision。然后把自带的样例代码全部删除,你可能从弹球的教程中找到具体的做法。
当然,我们要在HelloWorldScene.mm的顶部加入下面一行代码:
#define PTM_RATIO 32.0
如果你不明白我在这里讲的是些什么,你可能需要看看弹球的教程来获取更多的信息。
接下来,让我们把sprite sheet和坐标plist文件都加入到工程中去。把sprites.jpg和sprites.plist文件都拖到Resouces文件夹中,同时确保 “Copy items into destination group’s folder (if needed)”被复选中。
然后,在HelloWorldScene.h文件的HelloWorld类中,添加下面的成员变量:
CCSpriteSheet *_spriteSheet;
现在,让我们修改HelloWorldScene.mm中的init方法来加载我们的spritesheet和plist文件。具体修改如下:
- (id)init {
if ((self=[super init])) {
// Create our sprite sheet and frame cache
_spriteSheet = [[CCSpriteSheet spriteSheetWithFile:@"sprites.jpg"
capacity:2] retain];
[[CCSpriteFrameCache sharedSpriteFrameCache]
addSpriteFramesWithFile:@"sprites.plist"];
[self addChild:_spriteSheet];
[self spawnCar];
[self schele:@selector(secondUpdate:) interval:1.0];
}
return self;
}
第一件事情就是创建一个spritesheet对象,它是一个可以用来高效地绘制它的所有的CCSprite结点的对象。很明显,这些CCSprite必须共享相同的纹理(texture)。当我们把车子和猫加入到场景中的时候,我们需要将它们当作spritesheet的孩子加进去。
然后,我们使用CCSpriteFrameCache类来加载坐标属性列表文件。这个函数会自动地查找一个与之同名的图片(即sprites.jpg).这也就是前面说的,为什么要把”sprites.jpg“和"sprites.plist”取成相同名字的原因。
在这之后,我们调用一个函数在场景中显示一辆车。同时,还设置一个计时器,每隔一秒调用一次secondUpdate函数。
接下来,让我们实现spawnCar方法。我们的做法是让车子永远地在屏幕中间做路径为三角形的运动。在init函数的上面添加下面函数代码:
- (void)spawnCar {
CCSprite *car = [CCSprite spriteWithSpriteFrameName:@"car.jpg"];
car.position = ccp(100, 100);
car.tag =2;
[car runAction:[CCRepeatForever actionWithAction:
[CCSequence actions:
[CCMoveTo actionWithDuration:1.0 position:ccp(300,100)],
[CCMoveTo actionWithDuration:1.0 position:ccp(200,200)],
[CCMoveTo actionWithDuration:1.0 position:ccp(100,100)],
nil]]];
[_spriteSheet addChild:car];
}
注意,这里创建sprite的时候,不是使用spriteWithFile,而是使用spriteWithSpriteFrameName。这里指的是使用spritesheet纹理中代表Car的图片来创建精灵。
还有一点需要注意,我们不是把Car作为HelloWorld层的函数添加进去,而是把Car作为Spritesheet的孙子添加进去的。
这个函数的后面部分你应该比较熟悉了。因此,让我们添加一些猫吧!在上面的spawnCar方法后面添加下面的方法:
- (void)spawnCat {
CGSize winSize = [CCDirector sharedDirector].winSize;
CCSprite *cat = [CCSprite spriteWithSpriteFrameName:@"cat.jpg"];
int minY = cat.contentSize.height/2;
int maxY = winSize.height - (cat.contentSize.height/2);
int rangeY = maxY - minY;
int actualY = arc4random() % rangeY;
int startX = winSize.width + (cat.contentSize.width/2);
int endX =-(cat.contentSize.width/2);
CGPoint startPos = ccp(startX, actualY);
CGPoint endPos = ccp(endX, actualY);
cat.position = startPos;
cat.tag =1;
[cat runAction:[CCSequence actions:
[CCMoveTo actionWithDuration:1.0 position:endPos],
[CCCallFuncN actionWithTarget:self
selector:@selector(spriteDone:)],
nil]];
[_spriteSheet addChild:cat];
}
- (void)spriteDone:(id)sender {
CCSprite *sprite = (CCSprite *)sender;
[_spriteSheet removeChild:sprite cleanup:YES];
}
- (void)secondUpdate:(ccTime)dt {
[self spawnCat];
}
你应该对上面的代码线路熟悉了,如果不熟悉,建议看相关的教程后再继续。编译并运行代码,如果一切ok,你将会看到一辆车在屏幕上来回动,同时有一只猫从右至左穿过屏幕。接下来,我们将添加一些碰撞检测的代码。
为这些精灵创建Box2d的body
接下来的一步就是为每个精灵创建一个body,这样box2d就能知道它们的位置了,这样的话,当碰撞发生的时候,我们就可以被告知了。下面所做的事情和之前的教程做法差不多。
然后,这一次,我们不是更新box2d的body,然后再更新sprite。这里,我们是先更新sprite(使用action或者别的),然后再更新box2d的body。
因此,让我们首先创建world。打开HelloWorldScene.h,并在文件顶部添加下面的代码:
#import"Box2D.h"
然后在HelloWorld类中添加下面的成员变量:
b2World *_world;
然后在HeloWorldScene.mm的init方法中加入下列代码:
b2Vec2 gravity = b2Vec2(0.0f, 0.0f);
bool doSleep =false;
_world =new b2World(gravity, doSleep);
未完 转载仅供参考,版权属于原作者。祝你愉快,满意请采纳哦
⑶ box2dweb碰撞接触点问题,怎么解决
画个半圆,在小球与碗接触的点上画出该半圆的外切线(从圆心连接接触点是圆的半径,从接触点画一条垂直于该半径的线即为外切线)
然后就是个简单的碰撞问题了
⑷ box2d中怎么让刚体移动到指定点,移动过程中伴随碰撞
用joint,把mouse和你的刚体连接起来
⑸ 如何设置Box2D中的碰撞销毁
只要收听了《问.道》官方微博,并在1月27日0时至2月13日24时之间发布微博
⑹ jbox2d 2.1.2 我创建的三角形不能与矩形或圆形正确模拟碰撞
2009-3-20 19:57 SS314107648 | 二级
当然是 傻 啦 赞同0| 评论 2009-3-20 19:58 裙带飘飘830 | 一级
方言:“二版气或二姑妈”,指多话,爱管权事或傻 赞同0| 评论 2009-3-20 20:01 热心网友
说人二就是说这个人250啊!!250应该 知道什么意思吧.二百五!!!! 赞同0| 评论 2009-3-20 20:01 sss905621014 | 一级
楼上说的对.‘2’是一个很严峻的问题.现在都不用‘2’了,都用‘Der’了啊. 赞同0| 评论 2009-3-20 20:59 xiaowawa007 | 二级
反正不是夸你的 不是好话 赞同0| 评论 2009-3-20 22:40 V柒尛 | 一级
北京的方言
说人很傻的意思. 赞同0| 评论
⑺ 怎么实现2D游戏的碰撞判定
无论是模型还是切片式骨骼动画都可以做。模型就普通碰撞体,切片式骨骼动画内就用Box2D。
序列帧动容画就比较麻烦了,因为是2d精灵图片,然后加碰撞体或者用Box2D都不现实。因为你想要的实际上是像素级碰撞检测。
序列帧动画又分为两种情况:第一种是一张张图片垒起来的,播放时就一张张切换。一种是一张大图,播放时切换精灵UV。无论哪种情况,主角在一帧中的的攻击判定实际上就只有武器的白刃部分。手动标出白刃部分的包围盒,然后通过配置文件记录下来。这样假设播放到第一帧,通过配置的碰撞盒文件得到这一帧碰撞盒在世界范围的坐标。然后,问题就转换成2d平面内的几何体碰撞检测问题。假如敌人是一个简单包围盒,就是两个规则几何体的碰撞检测。如果武器很细,就转换为线段与OBB相交测试。如果武器很厚,就是两个OBB相交测试,这个就麻烦了。如果武器是个球,就是球体和OBB相交测试。
⑻ 如何使用box2d来做碰撞检测
当你使用cocos2d来制作一个游戏的时候,有时,你可能想使用cocos2d的action来移动游戏中的对象,而不是直接使用Box2d物理引擎来做。然而,这并不是说你不能使用box2d提供的强大的碰撞检测功能!
这个教程的目的,就是一步一步地向你展示如何仅使用box2d来做碰撞检测---没有物理效果。我们将创建一个简单的demo,里面有一辆车在屏幕上奔驰,当它撞到一只猫后就会放声大笑。是的,我明白,这样做太残忍了。
在这篇教程中,我们会引入一些新的、有趣的概念,比如使用sprite sheets,利用Zwoptex工具来制作它。还会涉及box2d的debug drawing和VertexHelper这个工具。
这个简单假设你已经阅读过前面的一系列的cocos2d和box2d的教程了(如果没有,最好把前面的教程先看一遍),或者你有相关经验也可以。
⑼ BOX2D不能在碰撞检测的类里面销毁刚体的fixture吗
您好,我来为您解答:
虽然是很老的问题,但是依然现在有人被困扰,是的,内碰撞的过程中是无法删容除刚体的,原因是因为在碰撞的初始阶段,box2d会寄存aabb互相接触的对象,放到数组或链表里面,如果你在这个时候删除是很危险的,直接崩溃是必然的,这个时候采用开关方式最好,先改变filter为0,另其无法碰撞,然后统一处理所有filter为0的对象,移除掉。
如果我的回答没能帮助您,请继续追问。
⑽ Box2D的基本用法
-Testbed 设置(linux, windows, mac)
-Testbed 结构
-为testbed创建一个‘test’
-刚体体(Bodies)
-定制器(Fixtures)
-World设置
-自定义重力(Custom gravity)
-力与冲量(Forces and impulses)
-匀速运动(Moving at constant speed)
-让物体按指定角度旋转(Keeping a body rotated at given angle)
-跳跃(Jumping)
-使用debug draw
-画自己的物体(Drawing your own objects)
-User data
-碰撞剖析(Anatomy of a collision)
-碰撞回调(Collision callbacks)
-碰撞过滤(Collision filtering)
-传感器(Sensors)
-射线投射(Raycasting)
-查询World(World querying)
-移除物体(Removing bodies)
-“触地”问题(The ‘touching the ground’question)
-连接器(Joints)
-一些陷阱(Some gotchas)