`
zhangziyangup
  • 浏览: 1186389 次
文章分类
社区版块
存档分类
最新评论

cocos2d学习笔记(七)物理引擎box2d之一

 
阅读更多

一、准备工作

引入box2d包,在需要使用box2d的文件中加入box2d的头文件;由于box2d是c++编写的,所以要把引入box2d的所有文件后缀名都改为.mm

二、box2d中的一些重要参数

1、gravity,重力加速度,同现实世界中的g,向量

2、shape,形状,形状是有大小的

3、density,密度

4、friction,摩擦力

5、restitution,恢复,此参数用于碰撞,如果两个物体有不同的restitution,box2d总是选择比较大的restitution进行计算

6、meter,距离单位,灵活定义你的meter,当对象为0.1至10meters的时候,box2d可以很好的处理它们,

三、box2d之hello world

让我们先创建一个box2d项目。创建好之后运行:

每当我们点击屏幕时,会落下一个小方块,ok,然我们来详细看下生成的代码。

-(id) init
{
	// always call "super" init
	// Apple recommends to re-assign "self" with the "super" return value
	if( (self=[super init])) {
		
		// enable touches
		self.isTouchEnabled = YES;
		
		// enable accelerometer
		self.isAccelerometerEnabled = YES;
		
		CGSize screenSize = [CCDirector sharedDirector].winSize;
		CCLOG(@"Screen width %0.2f screen height %0.2f",screenSize.width,screenSize.height);
		
		// Define the gravity vector.
		b2Vec2 gravity;
		gravity.Set(0.0f, -10.0f);
		
		// Do we want to let bodies sleep?
		// This will speed up the physics simulation
		bool doSleep = true;
		
		// Construct a world object, which will hold and simulate the rigid bodies.
		world = new b2World(gravity, doSleep);
		
		world->SetContinuousPhysics(true);
		
		// Debug Draw functions
		m_debugDraw = new GLESDebugDraw( PTM_RATIO );
		world->SetDebugDraw(m_debugDraw);
		
		uint32 flags = 0;
		flags += b2DebugDraw::e_shapeBit;
//		flags += b2DebugDraw::e_jointBit;
//		flags += b2DebugDraw::e_aabbBit;
//		flags += b2DebugDraw::e_pairBit;
//		flags += b2DebugDraw::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.
		b2PolygonShape groundBox;		
		
		// bottom
		groundBox.SetAsEdge(b2Vec2(0,0), b2Vec2(screenSize.width/PTM_RATIO,0));
		groundBody->CreateFixture(&groundBox,0);
		
		// top
		groundBox.SetAsEdge(b2Vec2(0,screenSize.height/PTM_RATIO), b2Vec2(screenSize.width/PTM_RATIO,screenSize.height/PTM_RATIO));
		groundBody->CreateFixture(&groundBox,0);
		
		// left
		groundBox.SetAsEdge(b2Vec2(0,screenSize.height/PTM_RATIO), b2Vec2(0,0));
		groundBody->CreateFixture(&groundBox,0);
		
		// right
		groundBox.SetAsEdge(b2Vec2(screenSize.width/PTM_RATIO,screenSize.height/PTM_RATIO), b2Vec2(screenSize.width/PTM_RATIO,0));
		groundBody->CreateFixture(&groundBox,0);
		
		
		//Set up sprite
		
		CCSpriteBatchNode *batch = [CCSpriteBatchNode batchNodeWithFile:@"blocks.png" capacity:150];
		[self addChild:batch z:0 tag:kTagBatchNode];
		
		[self addNewSpriteWithCoords:ccp(screenSize.width/2, screenSize.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( screenSize.width/2, screenSize.height-50);
		
		[self schedule: @selector(tick:)];
	}
	return self;
}

init方法首先创建了重力加速度,加速度是一个向量,-10是因为加速度朝向y轴负方向。之后创建world以及word的四个边缘,防止物体跑出屏幕。再然后是创建精灵(这里用到了之前一篇博客的创建精灵方法,如果有疑问,传送门:http://blog.csdn.net/volcan1987/article/details/7727593)和一个label,然后schedule tick方法

创建body的步骤



创建fixture步骤


知道了这些,让我们来看看如何创建一个box2d世界中的物体

-(void) addNewSpriteWithCoords:(CGPoint)p
{
	CCLOG(@"Add sprite %0.2f x %02.f",p.x,p.y);
	CCSpriteBatchNode *batch = (CCSpriteBatchNode*) [self getChildByTag:kTagBatchNode];
	
	//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);
	CCSprite *sprite = [CCSprite spriteWithBatchNode:batch rect:CGRectMake(32 * idx,32 * idy,32,32)];
	[batch 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);
	
	// Define another box shape for our dynamic body.
	b2PolygonShape dynamicBox;
	dynamicBox.SetAsBox(.5f, .5f);//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;
	body->CreateFixture(&fixtureDef);
}

可以看到,代码中的步骤跟我们上面的步骤一样,唯一不同的就是多了一个userData,这个属性用来绑定精灵否则你会看到精灵在你点击的地方不动,而一个粉色的方块掉了下去。fixture是相对于body的位置来的

下面这段代码相对固定,可以先不管

-(void) draw
{
	// Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
	// Needed states:  GL_VERTEX_ARRAY, 
	// Unneeded states: GL_TEXTURE_2D, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
	glDisable(GL_TEXTURE_2D);
	glDisableClientState(GL_COLOR_ARRAY);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	
	world->DrawDebugData();
	
	// restore default GL states
	glEnable(GL_TEXTURE_2D);
	glEnableClientState(GL_COLOR_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);

}

接下来是tick方法

-(void) tick: (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);

	
	//Iterate over the bodies in the physics world
	for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
	{
		if (b->GetUserData() != NULL) {
			//Synchronize the AtlasSprites position and rotation with the corresponding body
			CCSprite *myActor = (CCSprite*)b->GetUserData();
			myActor.position = CGPointMake( b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO);
			myActor.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
		}	
	}
}

先说下step方法,velocityIterations和positionIterations这两个参数越大,box2d就能进行更好的模拟,但是性能就会下降,这两个参数你应该自己把握以适合你的游戏。

下面的循环是为了让你的sprite与box2d中的对象同步,你可以注释掉这段代码看下效果,你会发现粉方块掉下去了,你的sprite没掉下去。


ok,今天先这么多,没想到想着挺简单,却写了这么久,有时间继续!


分享到:
评论

相关推荐

    cocos2d 学习笔记

    Cocos2d是一款广泛使用的开源游戏开发框架,尤其在iOS平台上深受开发者喜爱。它提供了丰富的图形渲染、动画、物理模拟、...这份cocos2d学习笔记将引导你一步步探索这个精彩的世界,助你成为一名熟练的cocos2d开发者。

    瘸腿蛤蟆笔记39-cocos2d-x-3.2 Box2d物理引擎自由落体代码

    总的来说,这个笔记提供了一个学习如何在Cocos2d-x游戏中利用Box2D实现自由落体效果的实例。通过实践这些技巧,开发者可以创建更逼真、更具动态性的游戏体验。在Classes目录中,可能会有相关的类文件,例如游戏对象...

    瘸腿蛤蟆笔记38-cocos2d-x-3.2 Box2d物理引擎Ray-cast代码

    《瘸腿蛤蟆笔记38-cocos2d-x-3.2 Box2d物理引擎Ray-cast代码》 本文将深入探讨Cocos2d-x 3.2版本中Box2D物理引擎的Ray-cast(射线检测)功能。Box2D是一款广泛应用于2D游戏开发的开源物理引擎,它提供了强大的物理...

    ios游戏开发之cocos2d-oc笔记

    本笔记将深入探讨cocos2d-oc的核心概念、关键特性和实际应用,帮助开发者从零开始掌握这一强大的游戏引擎。 一、cocos2d-oc简介 cocos2d-oc是基于Objective-C的Cocos2d引擎版本,它提供了丰富的图形绘制、动画制作...

    Cocos2D-X2.2.3学习笔记3(内存管理)

    在Cocos2D-X2.2.3的学习过程中,内存管理是至关重要的一个环节,它直接影响到游戏的性能和稳定性。Cocos2D-X是一个跨平台的2D游戏开发框架,使用C++作为主要编程语言,并支持Lua和JavaScript。本笔记将深入探讨Cocos...

    Cocos2d-x实战 JS卷 Cocos2d-JS开发

    3. **物理引擎**:介绍Cocos2d-x内置的Box2D物理引擎,用于模拟游戏中的碰撞检测和物理行为。 4. **事件处理**:讲解如何处理用户输入、触摸事件以及游戏内的各种交互事件。 5. **游戏逻辑**:通过实例解析如何...

    Cocos2d-x学习笔记——完全掌握C++ API与游戏项目开发.zip

    1. Box2D物理引擎集成:Cocos2d-x支持Box2D,可用于实现物理碰撞检测、重力模拟等效果。 2. Particle系统:用于创建粒子效果,如火焰、烟雾、星光等。 3. 脚本支持:Cocos2d-x同时支持Lua和JavaScript,可选择使用...

    瘸腿蛤蟆笔记40-cocos2d-x-3.2 Box2d物理引擎实现作用力

    在本文中,我们将深入探讨Cocos2d-x游戏开发框架中的Box2D物理引擎,以及如何在其中实现作用力。Box2D是一个流行的2D物理模拟库,它为游戏开发者提供了构建真实感物理世界的能力。Cocos2d-x 3.2版本集成了Box2D,...

    地球人己阻止不了程序猿们学习cocos2d-x了-学习笔记04 .源码

    如果"FlyGame"涉及到物体碰撞或者物理行为,那么Cocos2d-x的Box2D物理引擎可能会被用到。这将帮助处理游戏中的碰撞检测、重力、弹跳等物理现象。 4. **事件处理(Event Handling)**: Cocos2d-x提供了事件系统,...

    Cocos2d-android-1学习笔记

    Cocos2d-x集成了Box2D物理引擎,使得开发者可以方便地创建物理模拟环境,实现碰撞检测和重力效果。理解如何设置物理世界、创建刚体和关节是构建动态游戏场景的关键。 内存管理和性能优化是每个开发者必须关注的方面...

    cocos2d-x学习笔记(20)-- box2d入门 .rar

    在本篇中,我们将深入探讨Cocos2d-x游戏引擎中的Box2D物理模拟库,这对于游戏开发,尤其是2D物理交互式游戏至关重要。Box2D是一个强大的开源库,专门用于2D物理模拟,它为开发者提供了实现物体碰撞、重力、弹性以及...

    cocos2d-x学习笔记(17)--简单游戏实例1--双枪手

    【cocos2d-x学习笔记(17)--简单游戏实例1--双枪手】 cocos2d-x是一款基于C++的开源游戏开发框架,广泛应用于2D游戏、UI界面和实时渲染场景。本笔记将围绕如何使用cocos2d-x构建一个简单的双枪手游戏实例进行深入...

    【Cocos2d-x游戏引擎开发笔记(13)】Tiled Map Editor(一)

    Cocos2d-x提供了一些内置的物理引擎接口,如Box2D,可以方便地与Tiled地图结合,实现动态物体的碰撞检测。此外,通过Tiled Map Editor的动画支持,你可以为每个瓷砖定义多个帧,然后在Cocos2d-x中播放这些动画。 ...

    cocos2d-x学习笔记(16)--spritesheet(精灵表单).rar

    本学习笔记主要围绕这个主题展开,旨在帮助开发者深入理解如何在cocos2d-x框架下有效地使用Spritesheet。 首先,Spritesheet是一种图像打包技术,它将多个独立的图片合并到一张大的图片(通常称为atlases或sheet)...

    cocos2d-x学习笔记(17)--简单游戏实例1--双枪手.rar

    cocos2d-x提供了物理引擎Box2D或Chipmunk,可以方便地进行碰撞检测。在本例中,我们可以创建物理世界,为子弹和敌人添加物理身体,然后通过物理引擎的碰撞回调函数来处理碰撞事件。 除了基本的游戏逻辑,我们还需要...

    cocos2dx-lua 笔记

    Cocos2d-x 是一个基于 C++ 的 2D 游戏开发框架,它提供了丰富的图形绘制、动画控制、物理引擎等功能,并支持多种平台,包括 iOS、Android、Windows 等。通过 Lua 与 C++ 的交互,开发者可以利用 Lua 的脚本能力快速...

    Cocos2d-x学习笔记之开发环境搭建

    通过学习cocos2d-x,我们将了解更多关于游戏开发的知识,比如lua脚本、Box2d物理引擎、代码设计思想等等。总之,我们并不局限于学习cocos2d-x本身,而是通过学习cocos2d-x,掌握更多的游戏开发经验和技巧。现在就来...

    Cocos2d-x学习笔记之Hello World!

    物理引擎常用的有Box2D和Chipmunk,而声音引擎可以增强游戏的互动性。 创建项目后,通常需要配置一些路径和包含目录。为了确保编译器能够找到Cocos2d-x的头文件和库文件,需要将Cocos2d-x的根目录和相关库目录添加...

    cocosCreator笔记

    9. **物理引擎**:Cocos Creator集成了Box2D物理引擎,用于实现重力、碰撞检测和刚体运动。笔记可能包括如何设置物理世界参数,创建物理体,以及编写物理相关的脚本。 10. **粒子系统**:Cocos Creator的粒子系统可...

Global site tag (gtag.js) - Google Analytics