⑴ 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)