#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"
#include "cocos2d.h"
using namespace cocos2d;
using namespace CocosDenshion;
#define PTM_RATIO 32
enum {
kTagParentNode = 1,
};
PhysicsSprite::PhysicsSprite()
: m_pBody(NULL) {}
void PhysicsSprite::setPhysicsBody(b2Body * body)
{
m_pBody = body;
}
bool PhysicsSprite::isDirty(void)
{
return true;
}
HelloWorld::HelloWorld()
{
setTouchEnabled( true );
setAccelerometerEnabled( true );
CCSize s = CCDirector::sharedDirector()->getWinSize();
// init physics
this->initPhysics();
CCSpriteBatchNode *parent = CCSpriteBatchNode::create("blocks.png", 100);
m_pSpriteTexture = parent->getTexture();
addChild(parent, 0, kTagParentNode);
this->addcartoonbody();
bodybelow=this->SetBodyToSprite(ccp(150,58), 0);
bodyarm=this->SetBodyToSprite(ccpAdd(ccp(185,58),ccp(PTM_RATIO,PTM_RATIO)),2);
this->addPrismaticJoint();
this->addRevoluteJoint();
this->addObstacles();
scheduleUpdate();
}
HelloWorld::~HelloWorld()
{
delete world;
world = NULL;
}
void HelloWorld::initPhysics()
{
CCSize s = CCDirector::sharedDirector()->getWinSize();
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);
//GLESDebugDraw* 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
groundBody = world->CreateBody(&groundBodyDef);//不能定义成b2body* groundBody,类的私有成员里已定义了b2body* groundbody
// 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);
}
b2Body* HelloWorld::addNewSpriteAtPosition(CCPoint p)
{
CCNode* parent = getChildByTag(kTagParentNode);
int idx = (CCRANDOM_0_1() > .5 ? 0:1);
int idy = (CCRANDOM_0_1() > .5 ? 0:1);
PhysicsSprite* sprite= new PhysicsSprite();
sprite->initWithTexture(m_pSpriteTexture, CCRectMake(PTM_RATIO * idx,PTM_RATIO * idy,PTM_RATIO,PTM_RATIO));
sprite->autorelease();
parent->addChild(sprite);
sprite->setPosition( CCPointMake( p.x, p.y) );
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.userData = sprite;//这句话很重要,为这个刚体分配精灵,没有这句话,小方块不会往下落
bodyDef.position.Set(p.x/PTM_RATIO, p.y/PTM_RATIO);
b2Body *body = world->CreateBody(&bodyDef);
// Define another box shape for our dynamic body.
b2PolygonShape dynamicBox;
dynamicBox.SetAsBox(0.5f, 0.5f);
// Define the dynamic body fixture.
b2FixtureDef fixtureDef;
fixtureDef.shape = &dynamicBox;
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.3f;
body->CreateFixture(&fixtureDef);
sprite->setPhysicsBody(body);
return body;
}
void HelloWorld::addcartoonbody()//添加机器人
{
CCSprite *sprite = CCSprite::create("green.png");
sprite->setPosition(ccp(150,58));
this->addChild(sprite,0,0);
CCSprite *child = CCSprite::create("head.png");
child->setPosition(ccp(52,164));
sprite->addChild(child);
CCRotateBy *rotateBy1 = CCRotateBy::create(3, 360);
CCRepeatForever *repeat1 = CCRepeatForever::create(rotateBy1);
CCSprite *childOfChild1= CCSprite::create("Icon-Small.png");
childOfChild1->setScale(.5f);
childOfChild1->setPosition(ccp(25, 70));
child->addChild(childOfChild1);
childOfChild1->runAction(repeat1);
CCRotateBy *rotateBy2 = CCRotateBy::create(3, 360);
CCRepeatForever *repeat2 = CCRepeatForever::create(rotateBy2);
CCSprite *childOfChild2= CCSprite::create("Icon-Small.png");
childOfChild2->setScale(0.5f);
childOfChild2->setPosition(ccp(55, 70));
child->addChild(childOfChild2);
childOfChild2->runAction(repeat2);
CCSprite* arm=CCSprite::create("arm.png");
arm->setPosition(ccp(240, 60));
this->addChild(arm,0,2);
}
b2Body* HelloWorld::SetBodyToSprite(CCPoint p,int tag)
{
CCSprite* sprite=(CCSprite*)this->getChildByTag(tag);
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);
b2PolygonShape dynamicBox;
if (tag==0)
{
dynamicBox.SetAsBox(104.0f/2/32, 116.0f/2/32);//必须是浮点数
}
else if(tag==2)
{
dynamicBox.SetAsBox(48.0f/32/2, 56.0f/32/2);
}
b2FixtureDef fixtureDef;
fixtureDef.shape = &dynamicBox;
fixtureDef.density = 110.0f;
fixtureDef.friction = 0.9f;
body->CreateFixture(&fixtureDef);
return body;
}
void HelloWorld::addPrismaticJoint()
{
b2PrismaticJointDef jointDef;
b2Vec2 worldAxis(1,0);
jointDef.Initialize(bodybelow, groundBody, bodybelow->GetWorldCenter(), worldAxis);
jointDef.lowerTranslation=-2.9f;
jointDef.upperTranslation=3.2f;
jointDef.enableLimit=true;
jointDef.motorSpeed=0.0f;
jointDef.enableMotor=true;
world->CreateJoint(&jointDef);
}
void HelloWorld::addRevoluteJoint()
{
b2RevoluteJointDef jointDef;
jointDef.Initialize(bodybelow, bodyarm,bodyarm->GetWorldCenter());
jointDef.lowerAngle=-0.10f * b2_pi;
jointDef.upperAngle=0.35f * b2_pi;
jointDef.enableLimit=true;
jointDef.maxMotorTorque=10.0f;
jointDef.motorSpeed=1.0f;
jointDef.enableMotor=true;
world->CreateJoint(&jointDef);
}
void HelloWorld::draw()
{
CCLayer::draw();
ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );
kmGLPushMatrix();
world->DrawDebugData();
kmGLPopMatrix();
}
void HelloWorld::BeginContact(b2Contact* contact)
{
CCSprite * sp1 = (CCSprite *)contact->GetFixtureA()->GetBody()->GetUserData();
CCSprite * sp2 = (CCSprite *)contact->GetFixtureB()->GetBody()->GetUserData();
if (sp1 != NULL && sp2 != NULL) {
sp1->setColor(ccRED);
sp2->setColor(ccRED);
}
}
void HelloWorld::EndContact(b2Contact* contact)
{
b2Body* bodyA=contact->GetFixtureA()->GetBody();
b2Body* bodyB=contact->GetFixtureA()->GetBody();
CCSprite* spriteA=(CCSprite*)bodyA->GetUserData();
CCSprite* spriteB=(CCSprite*)bodyB->GetUserData();
if (spriteA!=NULL && spriteB!=NULL)
{
spriteA->setColor(ccWHITE);
spriteB->setColor(ccWHITE);
}
}
void HelloWorld::update(float 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
int velocityIterations = 8;
int 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->setPosition( CCPointMake( b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO) );
myActor->setRot