box2d collision
程序员文章站
2024-03-16 16:40:04
...
//
// HelloWorldLayer.mm
// maliaobox2d
//
// Created by ivt on 6/3/13.
// Copyright __MyCompanyName__ 2013. All rights reserved.
//
// Import the interfaces
#import "HelloWorldLayer.h"
// Needed to obtain the Navigation Controller
#import "AppDelegate.h"
#import "PhysicsSprite.h"
#import "CAnimationHelper.h"
#import <vector>
#import <algorithm>
#import "MyContactListener.h"
enum {
kTagParentNode = 1,
};
#pragma mark - HelloWorldLayer
@interface HelloWorldLayer()
-(void) initPhysics;
-(void) addNewSpriteAtPosition:(CGPoint)p;
-(void) createMenu;
@end
@implementation HelloWorldLayer
+(CCScene *) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
HelloWorldLayer *layer = [HelloWorldLayer node];
// add layer as a child to scene
[scene addChild: layer];
// return the scene
return scene;
}
-(void) menuItem1Touched:(id)sender{
}
-(id) init
{
if( (self=[super init])) {
// enable events
self.isTouchEnabled = YES;
self.isAccelerometerEnabled = YES;
CGSize s = [CCDirector sharedDirector].winSize;
// init physics
[self initPhysics];
// create reset button
[self createMenu];
// CCTMXTiledMap *map = [CCTMXTiledMap tiledMapWithTMXFile:@"map.tmx"];
//[self addChild:map];
//Set up sprite
#if 1
// Use batch node. Faster
CCSpriteBatchNode *parent = [CCSpriteBatchNode batchNodeWithFile:@"blocks.png" capacity:100];
spriteTexture_ = [parent texture];
#else
// doesn't use batch node. Slower
spriteTexture_ = [[CCTextureCache sharedTextureCache] addImage:@"blocks.png"];
CCNode *parent = [CCNode node];
#endif
[self addChild:parent z:0 tag:kTagParentNode];
[self addNewSpriteAtPosition:ccp(s.width/2, s.height/2)];
CCLabelTTF *label = [CCLabelTTF labelWithString:@"Tap screen" fontName:@"Marker Felt" fontSize:32];
[self addChild:label z:0];
[label setColor:ccc3(0,0,255)];
label.position = ccp( s.width/2, s.height-50);
[self scheduleUpdate];
_contactListener =new MyContactListener();
world->SetContactListener(_contactListener);
}
return self;
}
-(void) dealloc
{
delete world;
world = NULL;
delete m_debugDraw;
m_debugDraw = NULL;
[super dealloc];
}
-(void) createMenu
{
// Default font size will be 22 points.
[CCMenuItemFont setFontSize:22];
// Reset Button
CCMenuItemLabel *reset = [CCMenuItemFont itemWithString:@"Reset" block:^(id sender){
[[CCDirector sharedDirector] replaceScene: [HelloWorldLayer scene]];
}];
// Achievement Menu Item using blocks
CCMenuItem *itemAchievement = [CCMenuItemFont itemWithString:@"Achievements" block:^(id sender) {
GKAchievementViewController *achivementViewController = [[GKAchievementViewController alloc] init];
achivementViewController.achievementDelegate = self;
AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
[[app navController] presentModalViewController:achivementViewController animated:YES];
[achivementViewController release];
}];
// Leaderboard Menu Item using blocks
CCMenuItem *itemLeaderboard = [CCMenuItemFont itemWithString:@"Leaderboard" block:^(id sender) {
GKLeaderboardViewController *leaderboardViewController = [[GKLeaderboardViewController alloc] init];
leaderboardViewController.leaderboardDelegate = self;
AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
[[app navController] presentModalViewController:leaderboardViewController animated:YES];
[leaderboardViewController release];
}];
CCMenuItemFont* right= [CCMenuItemFont itemFromString:@"right!"
block:^(id sender){
b2Vec2 v=maliaobody->GetLinearVelocity();
v.x=5.0f;
maliaobody->SetLinearVelocity(v);
}];
CCMenuItemFont* left= [CCMenuItemFont itemFromString:@"left"
block:^(id sender){
b2Vec2 v=maliaobody->GetLinearVelocity();
v.x=-5.0f;
maliaobody->SetLinearVelocity(v);
}];
CCMenuItemFont* jump= [CCMenuItemFont itemFromString:@"jump"
block:^(id sender){
b2Vec2 v=maliaobody->GetLinearVelocity();
v.y=8.0f;
maliaobody->SetLinearVelocity(v);
}];
CCMenu *menu = [CCMenu menuWithItems:itemAchievement, reset, right,left,jump, nil];
[menu alignItemsVertically];
CGSize size = [[CCDirector sharedDirector] winSize];
[menu setPosition:ccp( size.width/2, size.height/2)];
[self addChild: menu z:-1];
}
-(void) initPhysics
{
CGSize s = [[CCDirector sharedDirector] winSize];
b2Vec2 gravity;
gravity.Set(0.0f, -10.0f);
world = new b2World(gravity);
// Do we want to let bodies sleep?
world->SetAllowSleeping(true);
world->SetContinuousPhysics(true);
_contactListener =new MyContactListener();
world->SetContactListener(_contactListener);
m_debugDraw = new GLESDebugDraw( PTM_RATIO );
world->SetDebugDraw(m_debugDraw);
uint32 flags = 0;
flags += b2Draw::e_shapeBit;
// flags += b2Draw::e_jointBit;
// flags += b2Draw::e_aabbBit;
// flags += b2Draw::e_pairBit;
// flags += b2Draw::e_centerOfMassBit;
m_debugDraw->SetFlags(flags);
// Define the ground body.
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(0, 0); // bottom-left corner
// Call the body factory which allocates memory for the ground body
// from a pool and creates the ground box shape (also from a pool).
// The body is also added to the world.
b2Body* groundBody = world->CreateBody(&groundBodyDef);
// Define the ground box shape.
b2EdgeShape groundBox;
// bottom
groundBox.Set(b2Vec2(0,0), b2Vec2(s.width/PTM_RATIO,0));
groundBody->CreateFixture(&groundBox,0);
/* // top
groundBox.Set(b2Vec2(0,s.height/PTM_RATIO), b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO));
groundBody->CreateFixture(&groundBox,0);
*/
// left
groundBox.Set(b2Vec2(0,s.height/PTM_RATIO), b2Vec2(0,0));
groundBody->CreateFixture(&groundBox,0);
// right
groundBox.Set(b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO), b2Vec2(s.width/PTM_RATIO,0));
groundBody->CreateFixture(&groundBox,0);
//利用帧缓存中的文件名创建动作
[[CCSpriteFrameCache sharedSpriteFrameCache]addSpriteFramesWithFile:@"game.plist"];
PhysicsSprite *mySpriteByF =[PhysicsSprite spriteWithSpriteFrameName:@"Frame0.swf"];
mySpriteByF.tag=10;
[self addChild:mySpriteByF];
CCAnimation *anim=[CCAnimation animationWithFrame:@"Frame" frameCount:5 delay:0.1];
CCAnimate *animate = [CCAnimate actionWithAnimation:anim];
CCSequence *seq = [CCSequence actions:animate,nil];
CCRepeatForever *repeat = [CCRepeatForever actionWithAction:seq];
[mySpriteByF runAction:repeat];
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(0.5,1);
bodyDef.userData=mySpriteByF;
maliaobody = world->CreateBody(&bodyDef);
maliaobody->SetFixedRotation(true);
// Define another box shape for our dynamic body.
b2PolygonShape dynamicBox;
dynamicBox.SetAsBox(.1f, .2f);//These are mid points for our 1m box
// Define the dynamic body fixture.
b2FixtureDef fixtureDef;
fixtureDef.shape = &dynamicBox;
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.3f;
maliaobody->CreateFixture(&fixtureDef);
[mySpriteByF setPhysicsBody:maliaobody];
[[CCSpriteFrameCache sharedSpriteFrameCache]addSpriteFramesWithFile:@"game1.plist"];
m_Score=[CCSprite spriteWithSpriteFrameName:@"Score0.swf"];
m_Score.position=ccp(80,s.height*0.5);
[self addChild:m_Score];
CCAnimation *anim1=[CCAnimation animationWithFrame:@"Score" frameCount:25 delay:0.1];
CCAnimate *animate1= [CCAnimate actionWithAnimation:anim1];
CCSequence *seq1 = [CCSequence actions:animate1,nil];
CCRepeatForever *repeat1 = [CCRepeatForever actionWithAction:seq1];
[m_Score runAction:repeat1];
}
-(void) draw
{
//
// IMPORTANT:
// This is only for debug purposes
// It is recommend to disable it
//
[super draw];
ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );
kmGLPushMatrix();
world->DrawDebugData();
kmGLPopMatrix();
}
-(void) addWallSpriteAtPosition
{
//CCLOG(@"Add sprite %0.2f x %02.f",p.x,p.y);
CCNode *parent = [self getChildByTag:kTagParentNode];
//We have a 64x64 sprite sheet with 4 different 32x32 images. The following code is
//just randomly picking one of the images
int idx = (CCRANDOM_0_1() > .5 ? 0:1);
int idy = (CCRANDOM_0_1() > .5 ? 0:1);
PhysicsSprite *sprite = [PhysicsSprite spriteWithTexture:spriteTexture_ rect:CGRectMake(32 * idx,32 * idy,32,32)];
sprite.tag=11;
[parent addChild:sprite];
sprite.position = ccp( 3,3);
// Define the dynamic body.
//Set up a 1m squared box in the physics world
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(3,3);
bodyDef.userData=sprite;
b2Body *body = world->CreateBody(&bodyDef);
// Define another box shape for our dynamic body.
b2PolygonShape dynamicBox;
dynamicBox.SetAsBox(.5f, 0.5f);//These are mid points for our 1m box
// Define the dynamic body fixture.
b2FixtureDef fixtureDef;
fixtureDef.shape = &dynamicBox;
fixtureDef.density = 100.0f;
fixtureDef.friction = 0.3f;
body->CreateFixture(&fixtureDef);
[sprite setPhysicsBody:body];
}
-(void) addNewSpriteAtPosition:(CGPoint)p
{
CCLOG(@"Add sprite %0.2f x %02.f",p.x,p.y);
CCNode *parent = [self getChildByTag:kTagParentNode];
//We have a 64x64 sprite sheet with 4 different 32x32 images. The following code is
//just randomly picking one of the images
int idx = (CCRANDOM_0_1() > .5 ? 0:1);
int idy = (CCRANDOM_0_1() > .5 ? 0:1);
PhysicsSprite *sprite = [PhysicsSprite spriteWithTexture:spriteTexture_ rect:CGRectMake(32 * idx,32 * idy,32,32)];
sprite.tag=2;
[parent addChild:sprite];
sprite.position = ccp( p.x, p.y);
// Define the dynamic body.
//Set up a 1m squared box in the physics world
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(p.x/PTM_RATIO, p.y/PTM_RATIO);
bodyDef.userData=sprite;
b2Body *body = world->CreateBody(&bodyDef);
body->SetGravityScale(0);
// Define another box shape for our dynamic body.
b2PolygonShape dynamicBox;
dynamicBox.SetAsBox(.5f, 0.5f);//These are mid points for our 1m box
// Define the dynamic body fixture.
b2FixtureDef fixtureDef;
fixtureDef.shape = &dynamicBox;
fixtureDef.density = 100.0f;
fixtureDef.friction = 0.3f;
body->CreateFixture(&fixtureDef);
[sprite setPhysicsBody:body];
}
-(void) update: (ccTime) dt
{
//It is recommended that a fixed time step is used with Box2D for stability
//of the simulation, however, we are using a variable time step here.
//You need to make an informed choice, the following URL is useful
//http://gafferongames.com/game-physics/fix-your-timestep/
int32 velocityIterations = 8;
int32 positionIterations = 1;
// Instruct the world to perform a single step of simulation. It is
// generally best to keep the time step and iterations fixed.
world->Step(dt, velocityIterations, positionIterations);
std::vector<b2Body *>toDestroy;
std::vector<MyContact>::iterator pos;
for(pos = _contactListener->_contacts.begin();
pos != _contactListener->_contacts.end(); ++pos) {
MyContact contact =*pos;
b2Body *bodyA = contact.fixtureA->GetBody();
b2Body *bodyB = contact.fixtureB->GetBody();
if (bodyA->GetUserData() != NULL && bodyB->GetUserData() != NULL) {
CCSprite *spriteA = (CCSprite *) bodyA->GetUserData();
CCSprite *spriteB = (CCSprite *) bodyB->GetUserData();
if (spriteA.tag ==10&& spriteB.tag ==2) {
NSLog(@"collision");
b2Vec2 v=bodyB->GetLinearVelocity();
//v.y=50.0f;
// v.x=50.0f;
bodyB->SetLinearVelocity(v);
// toDestroy.push_back(bodyA);
} else if (spriteA.tag ==2&& spriteB.tag ==10) {
NSLog(@"collision");
// toDestroy.push_back(bodyB);
}
}
}
std::vector<b2Body *>::iterator pos2;
for(pos2 = toDestroy.begin(); pos2 != toDestroy.end(); ++pos2) {
b2Body *body =*pos2;
if (body->GetUserData() != NULL) {
CCSprite *sprite = (CCSprite *) body->GetUserData();
//[_spriteSheet removeChild:sprite cleanup:YES];
}
// world->DestroyBody(body);
}
}
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
//Add a new body/atlas sprite at the touched location
for( UITouch *touch in touches ) {
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL: location];
[self addNewSpriteAtPosition: location];
}
}
#pragma mark GameKit delegate
-(void) achievementViewControllerDidFinish:(GKAchievementViewController *)viewController
{
AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
[[app navController] dismissModalViewControllerAnimated:YES];
}
-(void) leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController
{
AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
[[app navController] dismissModalViewControllerAnimated:YES];
}
@end
转载于:https://my.oschina.net/u/942328/blog/135331
上一篇: 排序检测算法
推荐阅读
-
box2d collision
-
安装Box2D
-
使用Box2D制作AS3游戏2.1a版本Hello World Box2D
-
box2d源码解析 一
-
使用Box2D制作AS3游戏2.1a版本Hello World Box2D
-
Box2d 物理引擎
-
Android下2d物理引擎Box2d用法简单实例
-
Box2D 的 Delphi 实现
-
(转载)BOX2D V2.3.0 用户手册中文版(第2章)-Hello Box2D
-
《UnityAPI.Collision碰撞》(Yanlz+Unity+SteamVR+云技术+5G+AI+VR云游戏+Collision+collider+rigidbody+立钻哥哥++OK++)