// // HelloWorldScene.cpp // ___PROJECTNAME___ // // Created by ___FULLUSERNAME___ on ___DATE___. // Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. // #include "HelloWorldScene.h" #include "SimpleAudioEngine.h" using namespace cocos2d; using namespace CocosDenshion; enum { kTagParentNode = 1, }; // callback to remove Shapes from the Space void removeShape( cpBody *body, cpShape *shape, void *data ) { cpShapeFree( shape ); } ChipmunkPhysicsSprite::ChipmunkPhysicsSprite() : _body(NULL) { } ChipmunkPhysicsSprite::~ChipmunkPhysicsSprite() { cpBodyEachShape(_body, removeShape, NULL); cpBodyFree( _body ); } void ChipmunkPhysicsSprite::setPhysicsBody(cpBody * body) { _body = body; } // this method will only get called if the sprite is batched. // return YES if the physics values (angles, position ) changed // If you return NO, then nodeToParentTransform won't be called. bool ChipmunkPhysicsSprite::isDirty(void) { return true; } CCAffineTransform ChipmunkPhysicsSprite::nodeToParentTransform(void) { float x = _body->p.x; float y = _body->p.y; if ( isIgnoreAnchorPointForPosition() ) { x += _anchorPointInPoints.x; y += _anchorPointInPoints.y; } // Make matrix float c = _body->rot.x; float s = _body->rot.y; if( ! _anchorPointInPoints.equals(CCPointZero) ){ x += c*-_anchorPointInPoints.x + -s*-_anchorPointInPoints.y; y += s*-_anchorPointInPoints.x + c*-_anchorPointInPoints.y; } // Rot, Translate Matrix _transform = CCAffineTransformMake( c, s, -s, c, x, y ); return _transform; } HelloWorld::HelloWorld() { } HelloWorld::~HelloWorld() { // manually Free rogue shapes for( int i=0;i<4;i++) { cpShapeFree( _walls[i] ); } cpSpaceFree( _space ); } CCScene* HelloWorld::scene() { // 'scene' is an autorelease object. CCScene *scene = CCScene::create(); // 'layer' is an autorelease object. HelloWorld *layer = HelloWorld::create(); // add layer as a child to scene scene->addChild(layer); // return the scene return scene; } bool HelloWorld::init() { if (!CCLayer::init()) { return false; } // enable events setTouchEnabled(true); setAccelerometerEnabled(true); CCSize s = CCDirector::sharedDirector()->getWinSize(); // title CCLabelTTF *label = CCLabelTTF::create("Multi touch the screen", "Marker Felt", 36); label->setPosition(ccp( s.width / 2, s.height - 30)); this->addChild(label, -1); // init physics initPhysics(); #if 1 // Use batch node. Faster CCSpriteBatchNode *parent = CCSpriteBatchNode::create("grossini_dance_atlas.png", 100); _spriteTexture = parent->getTexture(); #else // doesn't use batch node. Slower _spriteTexture = CCTextureCache::sharedTextureCache()->addImage("grossini_dance_atlas.png"); CCNode *parent = CCNode::node(); #endif addChild(parent, 0, kTagParentNode); addNewSpriteAtPosition(ccp(200,200)); scheduleUpdate(); return true; } void HelloWorld::initPhysics() { CCSize s = CCDirector::sharedDirector()->getWinSize(); // init chipmunk cpInitChipmunk(); _space = cpSpaceNew(); _space->gravity = cpv(0, -100); // // rogue shapes // We have to free them manually // // bottom _walls[0] = cpSegmentShapeNew( _space->staticBody, cpv(0,0), cpv(s.width,0), 0.0f); // top _walls[1] = cpSegmentShapeNew( _space->staticBody, cpv(0,s.height), cpv(s.width,s.height), 0.0f); // left _walls[2] = cpSegmentShapeNew( _space->staticBody, cpv(0,0), cpv(0,s.height), 0.0f); // right _walls[3] = cpSegmentShapeNew( _space->staticBody, cpv(s.width,0), cpv(s.width,s.height), 0.0f); for( int i=0;i<4;i++) { _walls[i]->e = 1.0f; _walls[i]->u = 1.0f; cpSpaceAddStaticShape(_space, _walls[i] ); } } void HelloWorld::update(float delta) { // Should use a fixed size step based on the animation interval. int steps = 2; float dt = CCDirector::sharedDirector()->getAnimationInterval()/(float)steps; for(int i=0; iinitWithTexture(_spriteTexture, CCRectMake(posx, posy, 85, 121)); sprite->autorelease(); parent->addChild(sprite); sprite->setPosition(pos); int num = 4; cpVect verts[] = { cpv(-24,-54), cpv(-24, 54), cpv( 24, 54), cpv( 24,-54), }; cpBody *body = cpBodyNew(1.0f, cpMomentForPoly(1.0f, num, verts, cpvzero)); body->p = cpv(pos.x, pos.y); cpSpaceAddBody(_space, body); cpShape* shape = cpPolyShapeNew(body, num, verts, cpvzero); shape->e = 0.5f; shape->u = 0.5f; cpSpaceAddShape(_space, shape); sprite->setPhysicsBody(body); } void HelloWorld::ccTouchesEnded(CCSet* touches, CCEvent* event) { //Add a new body/atlas sprite at the touched location CCSetIterator it; CCTouch* touch; for( it = touches->begin(); it != touches->end(); it++) { touch = (CCTouch*)(*it); if(!touch) break; CCPoint location = touch->getLocationInView(); location = CCDirector::sharedDirector()->convertToGL(location); addNewSpriteAtPosition( location ); } } void HelloWorld::didAccelerate(CCAcceleration* pAccelerationValue) { static float prevX=0, prevY=0; #define kFilterFactor 0.05f float accelX = (float) pAccelerationValue->x * kFilterFactor + (1- kFilterFactor)*prevX; float accelY = (float) pAccelerationValue->y * kFilterFactor + (1- kFilterFactor)*prevY; prevX = accelX; prevY = accelY; CCPoint v = ccp( accelX, accelY); v = ccpMult(v, 200); _space->gravity = cpv(v.x, v.y); }