Create a cpShape from a CGRect in cocos2d and chipmunk - cocos2d-iphone

I can't figure out how to create a cpShape that will fit a CGRect. Here is what I tried so far, without any success :
CGPoint p1 = rect.origin;
CGPoint p2 = CGPointMake(rect.origin.x + rect.size.width, rect.origin.y);
CGPoint p3 = CGPointMake(rect.origin.x, rect.origin.y + rect.size.height);
CGPoint p4 = CGPointMake(rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
int num = 4;
CGPoint verts[] = {p2, p1, p3, p4};
shape = cpPolyShapeNew(body, num, verts, cpvzero);
I don't understand why this doesn't fit perfectly my CGRect ?

Answered on behalf of user251552
Ok I figured this out:
//Converting points in chipmunk coordinates
CGPoint p1 = CGPointMake(-rect.size.width/2, -rect.size.height/2);
CGPoint p2 = CGPointMake(-rect.size.width/2, +rect.size.height/2);
CGPoint p3 = CGPointMake(+rect.size.width/2, +rect.size.height/2);
CGPoint p4 = CGPointMake(+rect.size.width/2, -rect.size.height/2);
int num = 4;
CGPoint verts[] = {p1, p2, p3, p4};
shape = cpPolyShapeNew(body, num, verts, cpvzero);

Related

How to do frustum culling in OpenGL with the view and projection matrix?

I'm trying to implement frustum culling to my voxel engine, basically I'm rendering chunks and I want to cull every chunk that is outside of the frustum of the camera. I tried a lot of different approaches and code that I found on the web, but yet I can't get it to work. The algorithm is in two parts:
• First I'm extracting the frustum planes from the projectionview matrix.
• Then I'm checking for each chunk if it is inside or colliding with the frustum.
The behavior is generally the same: when looking from the origin to positive direction it seems to work, but when looking to the negative direction it doesn't, and when I'm going away from the origin it starts breaking and doing non-sense. Also when looking up and down the culling is weird.
Here is my frustum plane extraction:
public static Plane[] frustumPlanes(Matrix4f mat, boolean normalize)
{
Plane[] p = new Plane[6];
p[0] = normalizePlane(mat.m30 + mat.m00, mat.m31 + mat.m01, mat.m32 + mat.m02, mat.m33 + mat.m03); // left
p[1] = normalizePlane(mat.m30 - mat.m00, mat.m31 - mat.m01, mat.m32 - mat.m02, mat.m33 - mat.m03); // right
p[2] = normalizePlane(mat.m30 - mat.m10, mat.m31 - mat.m11, mat.m32 - mat.m12, mat.m33 - mat.m13); // top
p[3] = normalizePlane(mat.m30 + mat.m10, mat.m31 + mat.m11, mat.m32 + mat.m12, mat.m33 + mat.m13); // bottom
p[4] = normalizePlane(mat.m30 + mat.m20, mat.m31 + mat.m21, mat.m32 + mat.m22, mat.m33 + mat.m23); // near
p[5] = normalizePlane(mat.m30 - mat.m20, mat.m31 - mat.m21, mat.m32 - mat.m22, mat.m33 - mat.m23); // far
return p;
}
public static Plane normalizePlane(float A, float B, float C, float D) {
float nf = 1.0f / (float)Math.sqrt(A * A + B * B + C * C);
return new Plane(new Vector3f(nf * A, nf * B, nf * C), nf * D);
}
mat is the projectionview matrix, here is the projection matrix:
private void createProjectionMatrix() {
float aspectRatio = (float) DisplayManager.WIDTH / (float) DisplayManager.HEIGHT;
float y_scale = (float) ((1f / Math.tan(Math.toRadians(FOV / 2f))));
float x_scale = y_scale / aspectRatio;
float frustum_length = FAR_PLANE - NEAR_PLANE;
projectionMatrix = new Matrix4f();
projectionMatrix.m00 = x_scale;
projectionMatrix.m11 = y_scale;
projectionMatrix.m22 = -((FAR_PLANE + NEAR_PLANE) / frustum_length);
projectionMatrix.m23 = -1;
projectionMatrix.m32 = -((2 * NEAR_PLANE * FAR_PLANE) / frustum_length);
projectionMatrix.m33 = 0;
}
Here is the view matrix:
public static Matrix4f createViewMatrix(Camera camera) {
Matrix4f viewMatrix = new Matrix4f();
viewMatrix.setIdentity();
Matrix4f.rotate((float) Math.toRadians(camera.getRotation().x), new Vector3f(1, 0, 0), viewMatrix, viewMatrix);
Matrix4f.rotate((float) Math.toRadians(camera.getRotation().y), new Vector3f(0, 1, 0), viewMatrix, viewMatrix);
Matrix4f.rotate((float) Math.toRadians(camera.getRotation().z), new Vector3f(0, 0, 1), viewMatrix, viewMatrix);
Vector3f cameraPos = camera.getPosition();
Vector3f negativeCameraPos = new Vector3f(-cameraPos.x,-cameraPos.y,-cameraPos.z);
Matrix4f.translate(negativeCameraPos, viewMatrix, viewMatrix);
return viewMatrix;
}
Here is the collision detection code aabb vs plane:
public static int boxToPlaneCollision(Plane plane, Vector3f[] minMax)
{
int result = 2; //Inside
// planes have unit-length normal, offset = -dot(normal, point on plane)
int nx = plane.normal.x > 0?1:0;
int ny = plane.normal.y > 0?1:0;
int nz = plane.normal.z > 0?1:0;
// getMinMax(): 0 = return min coordinate. 1 = return max.
float dot = (plane.normal.x*minMax[nx].x) + (plane.normal.y*minMax[nx].y) + (plane.normal.z*minMax[nx].z);
if ( dot < -plane.offset )
return 0; //Outside
float dot2 = (plane.normal.x*minMax[1-nx].x) + (plane.normal.y*minMax[1-nx].y) + (plane.normal.z*minMax[1-nx].z);
if ( dot2 <= -plane.offset )
result = 1; //Intersect
return result;
}
And finally here is where everything is called:
public boolean chunkInsideFrustum(Vector3f chunkPos) {
Vector3f chunkPosMax = new Vector3f(chunkPos.x + Terrain.CHUNK_SIZE, Terrain.CHUNK_HEIGHT, chunkPos.z + Terrain.CHUNK_SIZE);
for (int i = 0; i < 6; i++) {
if(Collider.boxToPlaneCollision(frustumPlanes[i], new Vector3f[] {chunkPos,chunkPosMax}) == 0)
return false;
}
return true;
}
I'm using openGL with LWJGL 2 (Java).
My questions are:
Where is the problem? In the frustum plane extraction code? In the collision detection?
and
I saw people calculating the frustum with projection and modelview matrix, what about this technique? is it better?
Thank you very much for your help!
EDIT:
for the second question, I saw here Extracting View Frustum Planes (Gribb & Hartmann method) someone posted that:
The missing part:
comboMatrix = projection_matrix * Matrix4_Transpose(modelview_matrix)
And then he did the exact same algorithm that I did to extract the planes, but what is modelview_matrix? What model should I use?

How to make stretch body(trigger) and apply physics on it in box2d in iphone?

I want to make trigger so that user can stretch the trigger and give the direction and then trigger hit to the ball and the ball will go accordingly.
The Ball speed and direction will depend on the trigger.
I am new in box2d.
Please check the link what I want.
http://dc694.4shared.com/img/Nw7YYLNL/s7/pool.png?async&0.2852371991612017
-(id) init
{
if( (self=[super init])) {
CGSize winSize = [CCDirector sharedDirector].winSize;
// Create a world
b2Vec2 gravity = b2Vec2(0.0f, 0.0f);
_world = new b2World(gravity);
// Create sprite and add it to the layer
CCSprite *Trigger = [CCSprite spriteWithFile:#"Trigger.png"];
Trigger.position = ccp(10, 50);
Trigger.tag = 1;
[self addChild:Trigger];
// Create Trigger body
b2BodyDef TriggerBodyDef;
TriggerBodyDef.type = b2_dynamicBody;
TriggerBodyDef.position.Set(127/PTM_RATIO, 210/PTM_RATIO);
TriggerBodyDef.userData = ball;
TriggerBody = _world->CreateBody(&TriggerBodyDef); // b2Body * ballBody
// Create circle shape
b2CircleShape circle;
circle.m_radius = 26.0/PTM_RATIO;
// Create shape definition and add to body
b2FixtureDef TriggerShapeDef;
TriggerShapeDef.shape = &circle;
TriggerShapeDef.density = 15.0f;
TriggerShapeDef.friction = 2.f;
TriggerShapeDef.restitution = 0.0f;
_TriggerFixture = TriggerBody->CreateFixture(&TriggerShapeDef);
b2Vec2 force = b2Vec2(10, -12);
TriggerBody->ApplyLinearImpulse(force, TriggerBodyDef.position);
///////////////////////// Ball ///////////////////////////////
// Create sprite and add it to the layer
CCSprite *ball = [CCSprite spriteWithFile:#"ball.png"];
ball.position = ccp(100, 200);
ball.tag = 1;
[self addChild:ball];
// Create ball body
b2BodyDef ballBodyDef;
ballBodyDef.type = b2_dynamicBody;
ballBodyDef.position.Set(127/PTM_RATIO, 210/PTM_RATIO);
ballBodyDef.userData = ball;
ballBody = _world->CreateBody(&ballBodyDef); // b2Body * ballBody
// Create circle shape
b2CircleShape circle;
circle.m_radius = 26.0/PTM_RATIO;
// Create shape definition and add to body
b2FixtureDef ballShapeDef;
ballShapeDef.shape = &circle;
ballShapeDef.density = 15.0f;
ballShapeDef.friction = 2.f;
ballShapeDef.restitution = 0.0f;
_ballFixture = ballBody->CreateFixture(&ballShapeDef);
b2Vec2 force = b2Vec2(73, -52);
ballBody->ApplyLinearImpulse(force, ballBodyDef.position);
//ballBody->SetLinearVelocity(b2Vec2(10,0)); // try
// ballBody->SetAngularVelocity(0); // try
///////////////////////// Ball ///////////////////////////////
// Create paddle and add it to the layer
CCSprite *paddle = [CCSprite spriteWithFile:#"paddle.png"];
paddle.position = ccp(winSize.width/2, 50);
[self addChild:paddle];
// Create paddle body
b2BodyDef paddleBodyDef;
paddleBodyDef.type = b2_staticBody; //b2_staticBody, b2_dynamicBody
paddleBodyDef.position.Set(winSize.width/2/PTM_RATIO, 50/PTM_RATIO);
paddleBodyDef.userData = paddle;
paddleBodyDef.angle = 75;
_paddleBody = _world->CreateBody(&paddleBodyDef);
// Create paddle shape
b2PolygonShape paddleShape;
paddleShape.SetAsBox(paddle.contentSize.width/PTM_RATIO/2, paddle.contentSize.height/ PTM_RATIO/2);
// Create shape definition and add to body
b2FixtureDef paddleShapeDef;
paddleShapeDef.shape = &paddleShape;
paddleShapeDef.density = 25.0f;
paddleShapeDef.friction = 1.1f;
paddleShapeDef.restitution = 0.1f;
_paddleFixture = _paddleBody->CreateFixture(&paddleShapeDef);
// Restrict paddle along the x axis
b2PrismaticJointDef jointDef;
b2Vec2 worldAxis(0.0f, 0.0f);
jointDef.collideConnected = true;
jointDef.Initialize(_paddleBody, _groundBody, _paddleBody->GetWorldCenter(), worldAxis);
_world->CreateJoint(&jointDef);
[self schedule:#selector(tick:)];
self.touchEnabled = YES;
}
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (_mouseJoint != NULL) return;
UITouch *myTouch = [touches anyObject];
CGPoint location = [myTouch locationInView:[myTouch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
b2Vec2 locationWorld = b2Vec2(location.x/PTM_RATIO, location.y/PTM_RATIO);
if (_paddleFixture->TestPoint(locationWorld)) {
b2MouseJointDef md;
md.bodyA = _groundBody;
md.bodyB = _paddleBody;
md.target = locationWorld;
md.collideConnected = true;
md.maxForce = 1000.0f * _paddleBody->GetMass();
_mouseJoint = (b2MouseJoint *)_world->CreateJoint(&md);
_paddleBody->SetAwake(true);
}
// [self kick];
}
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
if (_mouseJoint == NULL) return;
UITouch *myTouch = [touches anyObject];
CGPoint location = [myTouch locationInView:[myTouch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
b2Vec2 locationWorld = b2Vec2(location.x/PTM_RATIO, location.y/PTM_RATIO);
_mouseJoint->SetTarget(locationWorld);
}
I am not able to make trigger and not able to apply physics on trigger image. How to apply physics on trigger body? And how the ballbody will move according to trigger?
I have implemented this as follow:
HelloWorldLayer.h
#import "cocos2d.h"
#import "Box2D.h"
#define PTM_RATIO 32.0
#interface HelloWorldLayer : CCLayer {
b2World *_world;
b2Body *_body;
CCSprite *_ball;
CGPoint firstlocation;
CGPoint lastlocation;
b2Vec2 pre_velocity;
}
+ (id) scene;
- (void)kick;
#end
HelloWorldLayer.m
#import "HelloWorldLayer.h"
#implementation HelloWorldLayer
+ (id)scene {
CCScene *scene = [CCScene node];
HelloWorldLayer *layer = [HelloWorldLayer node];
[scene addChild:layer];
return scene;
}
- (id)init {
if ((self=[super init])) {
CGSize winSize = [CCDirector sharedDirector].winSize;
_ball = [CCSprite spriteWithFile:#"ball.png" rect:CGRectMake(0, 0, 52, 52)];
_ball.position = ccp(100, 100);
[self addChild:_ball];
//create world
b2Vec2 gravity = b2Vec2(0.0f, -8.0f);
_world = new b2World(gravity);
// Create ball body and shape
b2BodyDef ballBodyDef;
ballBodyDef.type = b2_dynamicBody;
ballBodyDef.position.Set(26/PTM_RATIO, 26/PTM_RATIO);
ballBodyDef.userData = _ball;
_body = _world->CreateBody(&ballBodyDef);
b2CircleShape circle;
circle.m_radius = 26.0/PTM_RATIO;
b2FixtureDef ballShapeDef;
ballShapeDef.shape = &circle;
ballShapeDef.density = 1.0f;
ballShapeDef.friction = 0.2f;
ballShapeDef.restitution = 0.8f;
_body->CreateFixture(&ballShapeDef);
//ground edge
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(0,0);
b2Body *groundBody = _world->CreateBody(&groundBodyDef);
b2EdgeShape groundEdge;
b2FixtureDef boxShapeDef;
boxShapeDef.shape = &groundEdge;
//wall definitions
groundEdge.Set(b2Vec2(0,0), b2Vec2(winSize.width/PTM_RATIO, 0));
groundBody->CreateFixture(&boxShapeDef);
groundEdge.Set(b2Vec2(0,0), b2Vec2(0,winSize.height/PTM_RATIO));
groundBody->CreateFixture(&boxShapeDef);
groundEdge.Set(b2Vec2(0, winSize.height/PTM_RATIO),
b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO));
groundBody->CreateFixture(&boxShapeDef);
groundEdge.Set(b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO),
b2Vec2(winSize.width/PTM_RATIO, 0));
groundBody->CreateFixture(&boxShapeDef);
[self schedule:#selector(tick:)];
// [self schedule:#selector(kick) interval:3.0];
self.isTouchEnabled = YES;
self.isAccelerometerEnabled = YES;
}
return self;
}
-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration{
b2Vec2 gravity(acceleration.y * 30, -acceleration.x * 30);
_world->SetGravity(gravity);
}
- (void)tick:(ccTime) dt {
_world->Step(dt, 10, 1);
for(b2Body *b = _world->GetBodyList(); b; b=b->GetNext()) {
if (b->GetUserData() != NULL) {
CCSprite *ballData = (CCSprite *)b->GetUserData();
ballData.position = ccp(b->GetPosition().x * PTM_RATIO,
b->GetPosition().y * PTM_RATIO);
ballData.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
}
}
}
- (void)kick {
b2Vec2 force = b2Vec2(-30, 30);
_body->ApplyLinearImpulse(force,_body->GetPosition());
}
- (void)ccTouchesBegan:(NSSet *)touch withEvent:(UIEvent *)event {
/* b2Vec2 force = b2Vec2(-30, -30);
_body->ApplyLinearImpulse(force, _body->GetPosition());*/
UITouch *touchpoint = [touch anyObject];
firstlocation = [touchpoint locationInView:[touchpoint view]];
firstlocation = [[CCDirector sharedDirector] convertToGL:firstlocation];
}
-(void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touchpoint = [touches anyObject];
lastlocation = [touchpoint locationInView:[touchpoint view]];
lastlocation = [[CCDirector sharedDirector] convertToGL:lastlocation];
//NSLog(#"start location %2f %2f",firstlocation.x,firstlocation.y);
//NSLog(#"last location %2f %2f",lastlocation.x,lastlocation.y);
GLfloat y = firstlocation.y - lastlocation.y;
GLfloat x = firstlocation.x - lastlocation.x;
GLfloat lengthOfFlick = sqrt(x*x + y*y);
NSLog(#"%2f",lengthOfFlick);
/* GLfloat basAngle = atan2(-x, -y);
GLfloat radians = (basAngle + (180/3.14));
//GLfloat angle = 180 + radians;*/
//GLfloat theta = atan2(y,x)* 180 / 3.14;
//NSLog(#"theta: %2f",theta);
float ratio = lengthOfFlick/90;
NSLog(#"%f",ratio);
if(ratio > 1){
ratio = 1;
}
NSLog(#"%f",ratio);
if(firstlocation.x > lastlocation.x){
if(firstlocation.y > lastlocation.y){
b2Vec2 force = b2Vec2((int)(45 * ratio),(int)(45 * ratio));
_body->ApplyLinearImpulse(force, _body->GetPosition());
}else{
b2Vec2 force = b2Vec2((int)( -1 * 45 * ratio), (int)(45 * ratio));
_body->ApplyLinearImpulse(force, _body->GetPosition());
}
}else{
if(firstlocation.y > lastlocation.y){
b2Vec2 force = b2Vec2((int)( -1 * 45 * ratio),(int)(45 * ratio));
_body->ApplyLinearImpulse(force, _body->GetPosition());
}else{
b2Vec2 force = b2Vec2((int)(-1* 45 * ratio),(int)(-1 * 45 * ratio));
_body->ApplyLinearImpulse(force, _body->GetPosition());
}
}
}
-(void)dealloc{
delete _world;
_body = NULL;
_world = NULL;
[super dealloc];
}
#end
Or you can download this code from:4shared.com/zip/PRv8c1Pz/BOX2D.html

Making sprite bounce in an angle in box2d

In the game I'm trying to make, I have a ball sprite which bounces thanks to box2d. Here's how my current code looks:
-(id)init
{
ball = [CCSprite spriteWithFile:#"ball.png"];
ball.position = ccp(150, winSize.height * 0.78);
[self addChild:ball];
ball.tag = 2;
b2BodyDef ballBodyDef;
ballBodyDef.type = b2_dynamicBody;
ballBodyDef.position.Set(150/PTM_RATIO, 450/PTM_RATIO);
ballBodyDef.userData = ball;
_body = _world->CreateBody(&ballBodyDef);
b2CircleShape circle;
circle.m_radius = 26.0/PTM_RATIO;
b2FixtureDef ballShapeDef;
ballShapeDef.shape = &circle;
ballShapeDef.density = 0.5f;
ballShapeDef.friction = 1.0f;
ballShapeDef.restitution = 1.0f;
_ballFixture = _body->CreateFixture(&ballShapeDef);
b2Vec2 force = b2Vec2(160, 375);
_body->ApplyLinearImpulse(force, ballBodyDef.position);}
- (void)update:(ccTime) dt {
if(_isPaused == FALSE)
{
_world->Step(dt, 10, 10);
for(b2Body *b = _world->GetBodyList(); b; b=b->GetNext()) {
if (b->GetUserData() != NULL) {
CCSprite *sprite = (CCSprite *)b->GetUserData();
if(sprite.tag == 2)
{
sprite.position = ccp(b->GetPosition().x * PTM_RATIO,
b->GetPosition().y * PTM_RATIO);
sprite.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
}
}
}}
Bouncing itself works fine, my problem is there are instances wherein the ball would bounce on a straight line so to speak, either vertically or horizontally continuously which I am trying to avoid. So my question is, how can I make my ball sprite bounce at an angle instead of a straight line so it wouldn't get stuck bouncing infinitely in the same direction?
You could apply a tiny force or gravity change to the body or the world, "randomly" or at equal intervals.

Get world coordinates from D3DXIntersectTri

I have a square area on which I have to determine where the mouse pointing.
With D3DXIntersectTri I can tell IF the mouse pointing on it, but I have trouble calculating the x,y,z coordinates.
The drawing from vertex buffer, which initialized with the vertices array:
vertices[0].position = D3DXVECTOR3(-10, 0, -10);
vertices[1].position = D3DXVECTOR3(-10, 0, 10);
vertices[2].position = D3DXVECTOR3( 10, 0, -10);
vertices[3].position = D3DXVECTOR3( 10, 0, -10);
vertices[4].position = D3DXVECTOR3(-10, 0, 10);
vertices[5].position = D3DXVECTOR3( 10, 0, 10);
I have this method so far, this is not giving me the right coordinates (works only on a small part of the area, near two of the edges and more less accurate inside):
BOOL Area::getcoord( Ray& ray, D3DXVECTOR3& coord)
{
D3DXVECTOR3 rayOrigin, rayDirection;
rayDirection = ray.direction;
rayOrigin = ray.origin;
float d;
D3DXMATRIX matInverse;
D3DXMatrixInverse(&matInverse, NULL, &matWorld);
// Transform ray origin and direction by inv matrix
D3DXVECTOR3 rayObjOrigin,rayObjDirection;
D3DXVec3TransformCoord(&rayOrigin, &rayOrigin, &matInverse);
D3DXVec3TransformNormal(&rayDirection, &rayDirection, &matInverse);
D3DXVec3Normalize(&rayDirection,&rayDirection);
float u, v;
BOOL isHit1, isHit2;
D3DXVECTOR3 p1, p2, p3;
p1 = vertices[3].position;
p2 = vertices[4].position;
p3 = vertices[5].position;
isHit1 = D3DXIntersectTri(&p1, &p2, &p3, &rayOrigin, &rayDirection, &u, &v, &d);
isHit2 = FALSE;
if(!isHit1)
{
p1 = vertices[0].position;
p2 = vertices[1].position;
p3 = vertices[2].position;
isHit2 = D3DXIntersectTri(&p1, &p2, &p3, &rayOrigin, &rayDirection, &u, &v, &d);
}
if(isHit1)
{
coord.x = 1 * ((1-u-v)*p3.x + u*p3.y + v*p3.z);
coord.y = 0.2f;
coord.z = -1 * ((1-u-v)*p1.x + u*p1.y + v*p1.z);
D3DXVec3TransformCoord(&coord, &coord, &matInverse);
}
if(isHit2)
{
coord.x = -1 * ((1-u-v)*p3.x + u*p3.y + v*p3.z);
coord.y = 0.2f;
coord.z = 1 * ((1-u-v)*p1.x + u*p1.y + v*p1.z);
D3DXVec3TransformCoord(&coord, &coord, &matWorld);
}
return isHit1 || isHit2;
}
Barycentric coordinates don't work the way you used them. u and v define the weight of the source vectors. So if you want to calculate the hit point, you will have to compute
coord = u * p1 + v * p2 + (1 - u - v) * p3
Alternatively you can use the d ray parameter:
coord = rayOrigin + d * rDirection
Both ways should result in the same coordinate.

Cocos2d draw a polygon using CCSprite

Can you help. Want to draw a polygon (beams at different angles) and apply box 2d body to it. Can you please let me know how to create a CCSprite with a polygon shape
Any examples would help
Cheers
Create Polygon body.
-(void) createDynamicPoly {
b2BodyDef bodyDefPoly;
bodyDefPoly.type = b2_dynamicBody;
bodyDefPoly.position.Set(3.0f, 10.0f);
b2Body *polyBody = world->CreateBody(&bodyDefPoly);
int count = 8;
b2Vec2 vertices[8];
vertices[0].Set(0.0f / PTM_RATIO,0.0f / PTM_RATIO);
vertices[1].Set(48.0f/PTM_RATIO,0.0f/PTM_RATIO);
vertices[2].Set(48.0f/PTM_RATIO,30.0f/PTM_RATIO);
vertices[3].Set(42.0f/PTM_RATIO,30.0f/PTM_RATIO);
vertices[4].Set(30.0f/PTM_RATIO,18.0f/PTM_RATIO);
vertices[5].Set(18.0f/PTM_RATIO,12.0f/PTM_RATIO);
vertices[6].Set(6.0f/PTM_RATIO,18.0f/PTM_RATIO);
vertices[7].Set(0.0f/PTM_RATIO,30.0f/PTM_RATIO);
b2PolygonShape polygon;
polygon.Set(vertices, count);
b2FixtureDef fixtureDefPoly;
fixtureDefPoly.shape = &polygon;
fixtureDefPoly.density = 1.0f;
fixtureDefPoly.friction = 0.3f;
polyBody->CreateFixture(&fixtureDefPoly);
}
Create your sprite
Attach your sprite to the Polygon body via Fixture and UserData
fixtureDefPoly.SetUserData() = spriteObject;
b2Fixture *fixture;
fixture = circleBody->CreateFixture(&fixtureDefPoly);
fixture->SetUserData(#"spriteObject");
Then Iterate the sprite to the body in your update method.
The easiest way is to open an image editor (such as paint for example or photoshop) and create the image you want. The use it in your program.
Also there is a helloWorld scene when creating an xcode application using cocos2d box2d template. It creates a set of squares with a texture.
CGPoint startPt = edge.start ;
CGPoint endpt = edge.end ;
//length of the stick body
float len = abs(ccpDistance(startPt, endpt))/PTM_RATIO;
//to calculate the angle and position of the body.
float dx = endpt.x-startPt.x;
float dy = endpt.y-startPt.y;
//position of the body
float xPos = startPt.x+dx/2.0f;
float yPos = startPt.y+dy/2.0f;
//width of the body.
float width = 1.0f/PTM_RATIO;
b2BodyDef bodyDef;
bodyDef.position.Set(xPos/PTM_RATIO, yPos/PTM_RATIO);
bodyDef.angle = atan(dy/dx);
NSLog([NSString stringWithFormat:#"Setting angle %f",bodyDef.angle]);
CCSprite *sp = [CCSprite spriteWithFile:#"material-wood.png" rect:CGRectMake(0, 0, 12, 12)];
//TODO: fix shape
[self addChild:sp z:1 ];
bodyDef.userData = sp;
bodyDef.type = b2_dynamicBody;
b2Body* body = world->CreateBody(&bodyDef);
b2PolygonShape shape;
b2Vec2 rectangle1_vertices[4];
rectangle1_vertices[0].Set(-len/2, -width/2);
rectangle1_vertices[1].Set(len/2, -width/2);
rectangle1_vertices[2].Set(len/2, width/2);
rectangle1_vertices[3].Set(-len/2, width/2);
shape.Set(rectangle1_vertices, 4);
b2FixtureDef fd;
fd.shape = &shape;
fd.density = 1.0f;
fd.friction = 0.300000f;
fd.restitution = 0.600000f;
body->CreateFixture(&fd);