示例#1
0
Item* ObjectFactory::createContainerItem(ItemDTO* itemDTO, b2World* world)
{
    ContainerItem* containerItem = ContainerItem::create();
    containerItem->setlistSubItem(itemDTO->listSubItemStruct);
    //
    containerItem->setPrepareToAppearAnimation(DataCollector::getInstance()->getAnimationObjectByKey(string(itemDTO->animation + item_prepareToAppear).c_str()));
    containerItem->setAppearAnimation(DataCollector::getInstance()->getAnimationObjectByKey(string(itemDTO->animation + item_appear).c_str()));
    containerItem->setprepareToDisappearAnimation(DataCollector::getInstance()->getAnimationObjectByKey(string(itemDTO->animation + item_prepareToDisappear).c_str()));
    //sprite
    CCSprite* sprite = CCSprite::createWithSpriteFrameName(itemDTO->imageName.c_str());
    //body
    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;
    bodyDef.angle = ccpToAngle(ccp(0,0));
    bodyDef.fixedRotation = true;
    
    b2Body *body = world->CreateBody(&bodyDef);
    
    gbox2d::GB2ShapeCache *sc =  gbox2d::GB2ShapeCache::sharedGB2ShapeCache();
    sc->addFixturesToBody(body, itemDTO->bodyName.c_str());
    containerItem->setSkin(body, sprite);
    
    containerItem->setSpriteAnchorPoint(sc->anchorPointForShape(itemDTO->bodyName.c_str()));
    containerItem->getSprite()->setAnchorPoint(sc->anchorPointForShape(itemDTO->bodyName.c_str()));
    
    containerItem->setPositionInPixel(ccp(itemDTO->positionX,itemDTO->positionY));
    containerItem->setGroup(ITEM_GROUP);
    
    containerItem->setLifeTime(itemDTO->lifeTime);
    containerItem->setSoundData(itemDTO->soundData);
    containerItem->onCreate();
    
    return containerItem;
}
示例#2
0
MapObject* ObjectFactory::createMapObject(const char *idMapObject, b2World *world)
{
    MapObject* mapObject = NULL;
    
    mapObject = new MapObject();
    
    //sprite
    const char* nameSprite = (std::string( idMapObject) + std::string(".png")).c_str();
    
    CCSprite* sprite=CCSprite::createWithSpriteFrameName(nameSprite);
    
    //body
    b2BodyDef bodyDef;
    bodyDef.type = b2_staticBody;
    bodyDef.angle = ccpToAngle(ccp(0,0));
    
    b2Body *body = world->CreateBody(&bodyDef);
    
    gbox2d::GB2ShapeCache *sc =  gbox2d::GB2ShapeCache::sharedGB2ShapeCache();
    sc->addFixturesToBody(body, idMapObject);
    sprite->setAnchorPoint(sc->anchorPointForShape(idMapObject));
    
    mapObject->setSkin(body, sprite);
    mapObject->onCreate();
    
    return mapObject;
    
}
示例#3
0
void Bird::update( float dt )
{
	const float limited = 3.0f;
	this->setPosition(_body->GetPosition().x * PTM_RATIO, _body->GetPosition().y * PTM_RATIO);
	b2Vec2 vel = _body->GetLinearVelocity();
	if (_awake && vel.x < limited)
		_body->SetLinearVelocity(b2Vec2(limited + 1, 0));

	limitVelocity();

	CCLOG("Position: %f", this->getPositionX());
	//CCLOG("Angle: %f | %f", vel.x, vel.y);
	b2Vec2 weightedVel = vel;
	const int NUM_PREV_VELS = 5;
	queue<b2Vec2> quue;
	for(int i = 0; i < _prevVels.size(); ++i) {
		weightedVel += _prevVels[i];
	}
	weightedVel = b2Vec2(weightedVel.x/NUM_PREV_VELS, weightedVel.y/NUM_PREV_VELS);
	_prevVels.push_back(vel);
	if (_prevVels.size() >= NUM_PREV_VELS)
		_prevVels.clear();
	vel = weightedVel;
	if (vel.x < 0) {
		vel.x = - vel.x;
		vel.y = - vel.y;
	}
	float angle = -1 * CC_RADIANS_TO_DEGREES(ccpToAngle(ccp(vel.x, vel.y)));
	angle = MIN(90, angle);
	angle = MAX(-90, angle);
	if (_awake)
		this->setRotation(angle);
}
示例#4
0
void VRope::createRope(cocos2d::CCPoint pointA, cocos2d::CCPoint pointB, float ropeLenght) {
    
    float distance;
    if (ropeLenght < 0) {
        distance = ccpDistance(pointA,pointB);
    }else{
        distance = ropeLenght;
    }
    
	int segmentFactor = RopeSegmentFactor; //increase value to have less segments per rope, decrease to have more segments
	numPoints = distance/segmentFactor;
    
    mRopeLength = segmentFactor * numPoints;
    
	CCPoint diffVector = ccpSub(pointB,pointA);
	float multiplier = distance / (numPoints-1);
	antiSagHack = 0.1f; //HACK: scale down rope points to cheat sag. set to 0 to disable, max suggested value 0.1
    
	for(int i=0;i<numPoints;i++) {
		CCPoint tmpVector = ccpAdd(pointA, ccpMult(ccpNormalize(diffVector),multiplier*i*(1-antiSagHack)));
		VPoint* tmpPoint = new VPoint;
        tmpPoint->setPos(tmpVector.x, tmpVector.y);
        vPoints.insert(vPoints.end(), tmpPoint);
	}
    
	for(int i=0;i<numPoints-1;i++) {
        VStick tmpStick;
        tmpStick.initWith(vPoints[i], vPoints[i+1]);
		vSticks.insert(vSticks.end(), tmpStick);
	}
    
	if(spriteSheet!=NULL) {
		for(int i=0;i<numPoints-1;i++) {
            VPoint* point1 = vSticks[i].getPointA();
            VPoint* point2 = vSticks[i].getPointB();
			CCPoint stickVector = ccpSub(ccp(point1->x,point1->y),ccp(point2->x,point2->y));
			float stickAngle = ccpToAngle(stickVector);
            
            CCTexture2D* texture = spriteSheet->getTexture();
            RecordSprite* tmpSprite = new RecordSprite;
			tmpSprite->setTag(Tag_Box_RopeBatchSprite);
			tmpSprite->autorelease();
			tmpSprite->initWithTexture(texture, CCRectMake(0,0,multiplier,texture->getContentSize().height));
			ccTexParams params = {GL_LINEAR,GL_LINEAR,GL_REPEAT,GL_REPEAT};
            tmpSprite->getTexture()->setTexParameters(&params);
            tmpSprite->setPosition(ccpMidpoint(ccp(point1->x,point1->y),ccp(point2->x,point2->y)));
            tmpSprite->setRotation(-1 * CC_RADIANS_TO_DEGREES(stickAngle));
            spriteSheet->addChild(tmpSprite);
            ropeSprites.insert(ropeSprites.end(), tmpSprite);
		}

		//// LiFeng 添加
		//ropeSprites[ropeSprites.size()-1]->setOpacity(100);
	}else{
        CCAssert(false, "not init");
    }
    
}
示例#5
0
文件: Ball.cpp 项目: DangoXJ/TuJinZhi
void Ball::collideWithPaddle(Paddle* paddle)
{
    CCRect paddleRect = paddle->rect();
    paddleRect.origin.x += paddle->getPosition().x;
    paddleRect.origin.y += paddle->getPosition().y;
    
    float lowY = CCRect::CCRectGetMinY(paddleRect);
    float midY = CCRect::CCRectGetMidY(paddleRect);
    float highY = CCRect::CCRectGetMaxY(paddleRect);
    
    float leftX = CCRect::CCRectGetMinX(paddleRect);
    float rightX = CCRect::CCRectGetMaxX(paddleRect);
    
    if (getPosition().x > leftX && getPosition().x < rightX) {
    
        bool hit = false;
        float angleOffset = 0.0f; 
        
        if (getPosition().y > midY && getPosition().y <= highY + radius()) 
        {
            setPosition( CCPointMake(getPosition().x, highY + radius()) );
            hit = true;
            angleOffset = (float)M_PI / 2;
        }
        else if (getPosition().y < midY && getPosition().y >= lowY - radius()) 
        {
            setPosition( CCPointMake(getPosition().x, lowY - radius()) );
            hit = true;
            angleOffset = -(float)M_PI / 2;
        }
        
        if (hit) 
        {
            float hitAngle = ccpToAngle(ccpSub(paddle->getPosition(), getPosition())) + angleOffset;
            
            float scalarVelocity = ccpLength(m_velocity) * 1.05f;
            float velocityAngle = -ccpToAngle(m_velocity) + 0.5f * hitAngle;
            
            m_velocity = ccpMult(ccpForAngle(velocityAngle), scalarVelocity);
        }
    }    
} 
示例#6
0
JS_CLASS_METHOD( JsPointBinding,ToAngle) {
	if(argc == 1) {
		JSObject *objA;
		JS_ConvertArguments(context, argc, JS_ARGV(cx, vp), "o", &objA);
		CCPoint *p1 = static_cast<CCPoint*>(JS_GetPrivate(context,objA));
		CGFloat result = ccpToAngle(*p1);
		JS_SET_RVAL(cx, vp, DOUBLE_TO_JSVAL(result));
	}
	return JS_TRUE;

}
示例#7
0
void Creep::creepLogic(float dt)
{ 
	DataModel *m=DataModel::getModel();// Rotate creep to face next waypoint
	WayPoint * waypoint=this->getCurrentWaypoint();
	CCPoint waypointVector=ccpSub(waypoint->getPosition(),this->getPosition());
	CGFloat waypointAngle=ccpToAngle(waypointVector);
	CGFloat cocosAngle=CC_RADIANS_TO_DEGREES((- 1*waypointAngle));
	float rotateSpeed=0.5/M_PI;
	// 1/2 second to roate 180 degrees
	float rotateDuration=fabs((waypointAngle*rotateSpeed));
	this->runAction(CCSequence::actions(CCRotateTo::actionWithDuration(rotateDuration,cocosAngle),NULL));
}
示例#8
0
void CCClipOut::startWithTarget(CCNode *pTarget) {
    CCAssert(dynamic_cast<CCClippingNode*>(pTarget) != NULL, "CCClipOut target must be a CCClippingNode instance");
    
    CCActionInterval::startWithTarget(pTarget);
    
    // ensure the stencil of clipper is CCDrawNode
    CCClippingNode* clipper = (CCClippingNode*)pTarget;
    CCNode* stencil = clipper->getStencil();
    if(dynamic_cast<CCDrawNode*>(stencil) == NULL) {
        clipper->setStencil(CCDrawNode::create());
    }
    
    // direction radian
    // treat is like a clip in
    float r = ccpToAngle(ccp(-m_direction.x, -m_direction.y));
    m_cos = cosf(r);
    m_sin = sinf(r);
    
    // max distance along direction
    const CCSize& size = pTarget->getContentSize();
    m_distance = size.width * fabsf(m_cos) + size.height * fabsf(m_sin);
    
    // calculate fixed edge endpoints
    if(r > M_PI_2) {
        float p1Len = size.width * cosf(r - M_PI_2);
        m_p1.x = size.width - p1Len * cosf(r - M_PI_2);
        m_p1.y = -p1Len * sinf(r - M_PI_2);
        float p2Len = size.height * sinf(r - M_PI_2);
        m_p2.x = size.width + p2Len * cosf(r - M_PI_2);
        m_p2.y = p2Len * sinf(r - M_PI_2);
    } else if(r >= 0) {
        float p1Len = size.height * m_cos;
        m_p1.x = p1Len * cosf(r + M_PI_2);
        m_p1.y = p1Len * sinf(r + M_PI_2);
        float p2Len = size.width * m_sin;
        m_p2.x = p2Len * cosf(r - M_PI_2);
        m_p2.y = p2Len * sinf(r - M_PI_2);
    } else if(r < -M_PI_2) {
        float p1Len = size.height * sinf(-r - M_PI_2);
        m_p1.x = size.width + p1Len * cosf(-r - M_PI_2);
        m_p1.y = size.height - p1Len * sinf(-r - M_PI_2);
        float p2Len = size.width * cosf(-r - M_PI_2);
        m_p2.x = size.width - p2Len * cosf(-r - M_PI_2);
        m_p2.y = size.height + p2Len * sinf(-r - M_PI_2);
    } else {
        float p1Len = size.width * sinf(-r);
        m_p1.x = p1Len * cosf(r + M_PI_2);
        m_p1.y = size.height + p1Len * sinf(r + M_PI_2);
        float p2Len = size.height * cosf(-r);
        m_p2.x = -p2Len * cosf(r + M_PI_2);
        m_p2.y = size.height - p2Len * sinf(r + M_PI_2);
    }
}
示例#9
0
void ObjectFactory::createHero(Hero* hero, HeroDTO* heroDTO)
{
    if(hero != NULL)
    {
        b2World* world = GameManager::getInstance()->getGameplayHolder().worldHolder;
        hero->setOriginCharacterData(heroDTO->data);
        
        //Create Animation
        string run = heroDTO->animation;
        string attack = heroDTO->animation;
        string idle = heroDTO->animation;
        string fall = heroDTO->animation;
        string fly = heroDTO->animation;
        string jump = heroDTO->animation;
        string skill = heroDTO->animation;
        string die = heroDTO->animation;

        hero->runAnimation = DataCollector::getInstance()->getAnimationObjectByKey(string(std::string(run) + std::string(RUN)).c_str());
        hero->attackAnimation = DataCollector::getInstance()->getAnimationObjectByKey(attack.append(ATTACK).c_str());
        hero->jumpAnimation = DataCollector::getInstance()->getAnimationObjectByKey(jump.append(JUMP).c_str());
        hero->idleAnimation = DataCollector::getInstance()->getAnimationObjectByKey(idle.append(IDLE).c_str());
        hero->fallAnimation = DataCollector::getInstance()->getAnimationObjectByKey(fall.append(FALL).c_str());
        hero->flyAnimation = DataCollector::getInstance()->getAnimationObjectByKey(fly.append(FLY).c_str());
        hero->skill1Animation = DataCollector::getInstance()->getAnimationObjectByKey(skill.append(SKILL).c_str());
        hero->dieAnimation = DataCollector::getInstance()->getAnimationObjectByKey(die.append(DIE).c_str());
        hero->attackAnimation->setDelayPerUnit(hero->getOriginCharacterData().getAttackSpeed());
        
        
        //Create body
        b2BodyDef bodyDef;
        bodyDef.type = b2_dynamicBody;
        bodyDef.angle = ccpToAngle(ccp(0,0));
        bodyDef.fixedRotation = true;
        
        b2Body *body = world->CreateBody(&bodyDef);
        
        gbox2d::GB2ShapeCache *sc =  gbox2d::GB2ShapeCache::sharedGB2ShapeCache();
        sc->addFixturesToBody(body, heroDTO->body.c_str());
        hero->setSpriteAnchorPoint(sc->anchorPointForShape(heroDTO->body.c_str()));
        hero->getSprite()->setAnchorPoint(sc->anchorPointForShape(heroDTO->body.c_str()));
        hero->setSkin(body, hero->getSprite());
        
        hero->setSkill(NORMAL_ATTACK, SkillFactory::createSkill(heroDTO->data.getSkill0().c_str(), world, hero, true, SKILL_0_BTN));
        hero->setSkill(SKILL_1, SkillFactory::createSkill(heroDTO->data.getSkill1().c_str(), world, hero, true, SKILL_1_BTN));
        hero->setSkill(SKILL_2, SkillFactory::createSkill(heroDTO->data.getSkill2().c_str(), world, hero, true, SKILL_2_BTN));
        hero->setIsControlled(true);
        
        hero->setSoundData(SoundManager::loadCharacterSoundData(heroDTO->soundId.c_str()));
        
        hero->onCreate();
    }
}
示例#10
0
SensorObject* ObjectFactory::createSensorObject(b2Vec2 dumb,b2World *world, CCPoint position)
{
    
    SensorObject* sensorObject = NULL;
    sensorObject = SensorObject::create();
    
    b2EdgeShape edge;
    
    edge.Set(b2Vec2(0,0),dumb);
    
    // edge.SetAsBox(1/PTM_RATIO, 4);
    
    b2FixtureDef fixDef;
    fixDef.shape = &edge;
    fixDef.isSensor = true;
    
    //set data id
    PhysicData* data = new PhysicData();
    data->bodyId = MAP_SENSOR;
    data->data = sensorObject;
    
    fixDef.userData = data;
    
    b2BodyDef bodyDef;
    bodyDef.type = b2_staticBody;
    bodyDef.angle = ccpToAngle(ccp(0,0));
    bodyDef.bullet = true;
    bodyDef.position.Set(10, 3);
    
    b2Body *body = world->CreateBody(&bodyDef);
    body->CreateFixture(&fixDef);
    
    
    
    //    //set data id
    //    PhysicData* data = new PhysicData();
    //    data->BodyId = MAP_SENSOR;
    //    data->Data = sensorObject;
    //
    //    body->SetUserData(data);
    
    
    sensorObject->setSkin(body, NULL);
    
    sensorObject->setPositionInPixel(position);
    sensorObject->setGroup(TERRAIN);
    
    return sensorObject;
}
示例#11
0
void CBJumpBy::update(float time) {
    // old and new position
    CCPoint oldPos = m_previousPos;
    CCJumpBy::update(time);
    CCPoint newPos = m_pTarget->getPosition();
    
    // auto head on
    if(m_autoHeadOn) {
        CCPoint v = ccpSub(newPos, oldPos);
        float r = ccpToAngle(v);
        float d = -CC_RADIANS_TO_DEGREES(r);
        d += m_initAngle;
        m_pTarget->setRotation(d);
    }
}
示例#12
0
SensorObject* ObjectFactory::createSensorObject(SensorObjectDTO* sensorObjectDTO, b2World* world)
{
    SensorObject* sensorObject = SensorObject::create();
    
    sensorObject->setJumpHeight(sensorObjectDTO->jumpHeight);
    sensorObject->setMoveSpeed(sensorObjectDTO->moveSpeed);
    sensorObject->setIsBack(sensorObjectDTO->isBack);
    sensorObject->setMustStop(sensorObjectDTO->mustStop);
    sensorObject->flipDirection(sensorObjectDTO->direction);
    sensorObject->listLaneID = sensorObjectDTO->listLaneID;
    
    b2EdgeShape edge;
    
    edge.Set(b2Vec2(0,0),b2Vec2(sensorObjectDTO->edge_x/PTM_RATIO,sensorObjectDTO->edge_y/PTM_RATIO));
    
    // edge.SetAsBox(1/PTM_RATIO, 4);
    
    b2FixtureDef fixDef;
    fixDef.shape = &edge;
    fixDef.isSensor = true;
    
    PhysicData* data = new PhysicData();
    data->bodyId = MAP_SENSOR;
    data->data = sensorObject;
    fixDef.userData = data;
    
    
    b2BodyDef bodyDef;
    bodyDef.type = b2_staticBody;
    bodyDef.angle = ccpToAngle(ccp(0,0));
    bodyDef.bullet = true;
    
    b2Body *body = world->CreateBody(&bodyDef);
    body->CreateFixture(&fixDef);
    
    //set data id
    //    PhysicData* data = new PhysicData();
    //    data->BodyId = MAP_SENSOR;
    //    data->Data = sensorObject;
    
    //    body->SetUserData(data);
    
    sensorObject->setSkin(body, NULL);
    sensorObject->setPositionInPixel(ccp(sensorObjectDTO->x,sensorObjectDTO->y));
    sensorObject->setGroup(TERRAIN);
    
    return sensorObject;
}
示例#13
0
MapObject* ObjectFactory::createMapObject(MapObjectDTO* mapObjectDTO, b2World *world)
{
    
    
    
    MapObject* mapObject = NULL;
    
    //sprite
    CCSprite* sprite = CCSprite::createWithSpriteFrameName(mapObjectDTO->imageName.c_str());
    
    gbox2d::GB2ShapeCache *sc =  gbox2d::GB2ShapeCache::sharedGB2ShapeCache();
    if(sc->isBodyExisted(mapObjectDTO->bodyName.c_str()))
    {
        //body
        b2BodyDef bodyDef;
        bodyDef.type = b2_staticBody;
        bodyDef.angle = ccpToAngle(ccp(0,0));
        //        bodyDef.bullet = true;
//        PhysicData* data = new PhysicData();
//        data->bodyId = MAP_BASE;
//        data->gameObjectID = MAP_OBJECT;
//        data->fixtureId = MAP_OBJECT_FIXTURE;
        //
        b2Body *body = world->CreateBody(&bodyDef);
        sc->addFixturesToBody(body, mapObjectDTO->bodyName.c_str());
        
        sprite->setAnchorPoint(sc->anchorPointForShape(mapObjectDTO->bodyName.c_str()));
        
        mapObject = MapObject::create();
        mapObject->setSkin(body, sprite);
        mapObject->setCanPass(mapObjectDTO->canPass);
        mapObject->onCreate();
        
    }
    else
    {
        mapObject = NoBodyMapObject::create();
        sprite->setAnchorPoint(ccp(0,0));
        mapObject->setSkin(NULL, sprite);
        mapObject->setGroup(TERRAIN);
    }
    
    mapObject->setPositionInPixel(ccp(mapObjectDTO->x,mapObjectDTO->y));
    
    return mapObject;
    
}
示例#14
0
void CCMissile::step(float dt) {
    // position of target and aimed
    CCNode* target = getTarget();
    CCPoint t = target->getPosition();
    CCPoint a = m_aimed->getPosition();
    
    // position vector degree
    CCPoint v = ccpSub(a, t);
    float r = ccpToAngle(v);
    float d = -CC_RADIANS_TO_DEGREES(r);
    d -= m_presetDegree;
    
    // save dest degree
    if(m_dstDegree != d) {
        m_dstDegree = d;
    }
    
    // rotate to dst degree gradually
    if(m_dstDegree > target->getRotation()) {
        float cur = MIN(m_dstDegree, target->getRotation() + dt * ANGULAR_VELOCITY);
        target->setRotation(cur);
    } else if(m_dstDegree < target->getRotation()) {
        float cur = MAX(m_dstDegree, target->getRotation() - dt * ANGULAR_VELOCITY);
        target->setRotation(cur);
    }
    
    // move target by velocity
    float move = m_velocity * dt;
    float distance = ccpLength(v);
    if(move >= distance) {
        target->setPosition(a);
    } else {
        t.x += move * cosf(r);
        t.y += move * sinf(r);
        target->setPosition(t);
    }
	
	// is done?
	m_done = getTarget()->getPositionX() == m_aimed->getPositionX() &&
		getTarget()->getPositionY() == m_aimed->getPositionY();
	
	// done callback
	if(m_done && m_doneCallFunc) {
		m_doneCallFunc->execute();
	}
}
示例#15
0
void Hero::update()
{
	this->setPosition(ccp(_body->GetPosition().x*PTM_RATIO, _body->GetPosition().y*PTM_RATIO));
	b2Vec2 vel = _body->GetLinearVelocity();
	b2Vec2 weightedVel = vel;

	for (int i = 0; i < NUM_PREV_VELS; ++i) {
		weightedVel += _prevVels[i];
	}
	weightedVel = b2Vec2(weightedVel.x / NUM_PREV_VELS, weightedVel.y / NUM_PREV_VELS);
	_prevVels[_nextVel++] = vel;
	if (_nextVel >= NUM_PREV_VELS) _nextVel = 0;

	float angle = ccpToAngle(ccp(weightedVel.x, weightedVel.y));
	if (_awake) {
		this->setRotation(-1 * CC_RADIANS_TO_DEGREES(angle));
	}
}
示例#16
0
Item* ObjectFactory::createBonusItem(ItemDTO* itemDTO, b2World* world)
{
    BonusItem* item = BonusItem::create();
    item->setTitleNotification(itemDTO->titleNotification);
    vector<EffectData> listEffectData;
    
    for(int i = 0; i < itemDTO->listAffectID.size(); i++)
    {
        listEffectData.push_back(*EffectFactory::createEffectData(itemDTO->listAffectID[i].c_str()));
    }
    
    item->setListEffectData(listEffectData);
    //sprite
    CCSprite* sprite = CCSprite::createWithSpriteFrameName(itemDTO->imageName.c_str());
    
    item->setPrepareToAppearAnimation(DataCollector::getInstance()->getAnimationObjectByKey(string(itemDTO->animation + item_prepareToAppear).c_str()));
    item->setAppearAnimation(DataCollector::getInstance()->getAnimationObjectByKey(string(itemDTO->animation + item_appear).c_str()));
    item->setprepareToDisappearAnimation(DataCollector::getInstance()->getAnimationObjectByKey(string(itemDTO->animation + item_prepareToDisappear).c_str()));
    
    //body
    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;
    bodyDef.angle = ccpToAngle(ccp(0,0));
    bodyDef.fixedRotation = true;
    
    b2Body *body = world->CreateBody(&bodyDef);
    
    gbox2d::GB2ShapeCache *sc =  gbox2d::GB2ShapeCache::sharedGB2ShapeCache();
    sc->addFixturesToBody(body, itemDTO->bodyName.c_str());
    item->setSkin(body, sprite);
    
    item->setSpriteAnchorPoint(sc->anchorPointForShape(itemDTO->bodyName.c_str()));
    item->getSprite()->setAnchorPoint(sc->anchorPointForShape(itemDTO->bodyName.c_str()));
    
    item->setPositionInPixel(ccp(itemDTO->positionX,itemDTO->positionY));
    item->setGroup(ITEM_GROUP);
    
    item->setLifeTime(itemDTO->lifeTime);
    item->setSoundData(itemDTO->soundData);
    item->onCreate();
    
    return item;
    
}
示例#17
0
void VRope::updateSprites() {
	if(spriteSheet!=NULL) {
		for(int i=0;i<numPoints-1;i++) {
            VPoint* point1 = vSticks[i].getPointA();
			//VPoint *point1 = [[vSticks objectAtIndex:i] getPointA];
            VPoint* point2 = vSticks[i].getPointB();
			//VPoint *point2 = [[vSticks objectAtIndex:i] getPointB];
			CCPoint point1_ = ccp(point1->x,point1->y);
			CCPoint point2_ = ccp(point2->x,point2->y);
			float stickAngle = ccpToAngle(ccpSub(point1_,point2_));
            RecordSprite* tmpSprite = ropeSprites[i];
			//CCSprite *tmpSprite = [ropeSprites objectAtIndex:i];

            tmpSprite->setPosition(ccpMidpoint(point1_,point2_));
			//[tmpSprite setPosition:ccpMidpoint(point1_,point2_)];
            tmpSprite->setRotation(-CC_RADIANS_TO_DEGREES(stickAngle));
			//[tmpSprite setRotation: -CC_RADIANS_TO_DEGREES(stickAngle)];
		}
	}	
}
示例#18
0
void Towers::towerLogic(float dt) {
	//    if(_target==NULL){
	_target = getClosestTarget();
	//    }


	if (_target != NULL) {

		//rotate the tower to face the nearest creep
		CCPoint shootVector = ccpSub(_target->getPosition(), getPosition());
		float shootAngle = ccpToAngle(shootVector);
		float cocosAngle = CC_RADIANS_TO_DEGREES(-1 * shootAngle);

		float rotateSpeed = 0.5 / M_PI; // 1/2 second to roate 180 degrees
		float rotateDuration = fabs(shootAngle * rotateSpeed);

		runAction(CCSequence::create(CCRotateTo::create(rotateDuration,cocosAngle),
			CCCallFunc::create(this,callfunc_selector(Towers::finishFiring)),NULL));
	}
}
示例#19
0
void GameWorld::ccTouchesMoved(CCSet* set, CCEvent* event)
{
	// don't accept touch when clown is in these states
	if(clown_->GetState() == E_CLOWN_ROCKET ||
		clown_->GetState() == E_CLOWN_BALLOON ||
		clown_->GetState() == E_CLOWN_UP)
		return;

	CCTouch* touch = (CCTouch*)(*set->begin());
	CCPoint touch_point = touch->getLocationInView();
	touch_end_ = CCDirector::sharedDirector()->convertToGL(touch_point);

	// manipulate anchor point so the platform is correctly oriented
	platform_->setAnchorPoint( touch_end_.x >= touch_start_.x ? ccp(0, 0.5f) : ccp(1, 0.5f) );
	float length = ccpDistance(touch_end_, touch_start_);
	// scale the platform according to user input
	platform_->setScaleX(length / platform_->getContentSize().width);
	// manipulate rotation so that platform doesn't appear upside down
	float angle = CC_RADIANS_TO_DEGREES(-1 * ccpToAngle(ccpSub(touch_end_, touch_start_)));
	platform_->setRotation( touch_end_.x >= touch_start_.x ? angle : angle + 180 );
}
示例#20
0
Wall* ObjectFactory::createWall(WallDTO* wallDTO, b2World* world)
{
    Wall* wall = Wall::create();
    wall->setDeadWall(wallDTO->deadWall);
    
    b2EdgeShape edge;
    edge.Set(b2Vec2(0,0),b2Vec2(wallDTO->edge_x/PTM_RATIO,wallDTO->edge_y/PTM_RATIO));
    
    // edge.SetAsBox(1/PTM_RATIO, 4);
    
    b2FixtureDef fixDef;
    fixDef.shape = &edge;
    fixDef.friction = 0;
    
    
    PhysicData* data = new PhysicData();
    data->gameObjectID = WALL;
    data->bodyId = WALL_BODY;
    data->data = wall;
    
    fixDef.userData = data;
    
    b2BodyDef bodyDef;
    bodyDef.type = b2_staticBody;
    bodyDef.angle = ccpToAngle(ccp(0,0));
    
    b2Body *body = world->CreateBody(&bodyDef);
    body->CreateFixture(&fixDef);
    
    for (b2Fixture* f = body->GetFixtureList(); f; f = f->GetNext())
    {
        Util::setFixtureGroup(f, GROUP_WALL);
    }
    
    wall->setSkin(body, NULL);
    wall->setPositionInPixel(ccp(wallDTO->x, wallDTO->y));
    wall->setGroup(TERRAIN);

    return wall;
}
示例#21
0
    HitTestResult* hitTestRoundStrip(RoundBodyNode* a, StripBodyNode* b)
    {
        Point ca = a->getCenter();
        float ra = a->getRadius();
        Point cb = b->getCenter();
        Vector2 avb = b->getEnd() - b->getBegin();
        float hb = b->getWidth();
        float wb = ccpLength(avb); 
        float rb = b->getRadius();
        Point rrp;

        avb = avb/wb;
        bool hit = isRoundCrossRect(ca, ra, cb, wb, hb, avb, &rrp);
        if(hit)
        {
            float distance;
            float angle = ccpToAngle(rrp);
            Point hp = ccp(cos(angle), sin(angle)) * rb;

            if(hp.x > wb/2)
                hp.x = wb/2;
            else if(hp.x < -wb/2)
                hp.x = -wb/2;

            if(hp.y > hb/2)
                hp.y = hb/2;
            else if(hp.y < -hb/2)
                hp.y = -hb/2;

            hp = ccpRotate(hp, avb) + cb;
            distance = ccpDistance(ca, hp);
            return HitTestResult::create(HTRT_CROSS, hp, distance);
        }
        else
        {
            return HitTestResult::create(HTRT_NONE);
        }
    }
示例#22
0
    HitTestResult* hitTestRoundRect(RoundBodyNode* a, RectBodyNode* b)
    {
        Point ca = a->getCenter();
        float ra = a->getRadius();
        Point cb = b->getCenter();
        float wb = b->getWidth();
        float hb = b->getHeight();
        float ab = CC_DEGREES_TO_RADIANS(-b->getAngle());
        float rb = b->getRadius();
        Point rrp;
        bool hit = isRoundCrossRect(ca, ra, cb, wb, hb, ccpForAngle(ab), &rrp);

        if( hit )
        {
            float distance;
            float angle = ccpToAngle(rrp);
            Point hp = ccp(cos(angle), sin(angle)) * rb;

            if(hp.x > wb/2)
                hp.x = wb/2;
            else if(hp.x < -wb/2)
                hp.x = -wb/2;

            if(hp.y > hb/2)
                hp.y = hb/2;
            else if(hp.y < -hb/2)
                hp.y = -hb/2;

            hp = cb + ccpRotateByAngle(hp, POINT_ZERO, ab);
            distance = ccpDistance(ca, hp);
            return HitTestResult::create(HTRT_CROSS, hp, distance);
        }
        else
        {
            return HitTestResult::create(HTRT_NONE);
        }
    }
示例#23
0
void Joystick::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)
{
    if (!_enabled) {
        return;
    }

    if (_state==jsTouched||_state==jsTouchMoved) {
        if (ccpDistance(_touchedPoint, pTouch->getLocation())<_maxResponseDistance) {
            _vector=ccpSub(pTouch->getLocation(),_touchedPoint);
            if (_delegate) {
                float angle=CC_RADIANS_TO_DEGREES(ccpToAngle(_vector));
                ysDirection direction=ysdLeft;
                if ((angle>=157.5&&angle<=180)||(angle>=-180&&angle<=-157.5)) {
                    direction=ysdLeft;
                }
                else if (angle<=157.5&&angle>=112.5) {
                    direction=ysdLeftUp;
                }
                else if (angle>=67.5&&angle<=112.5) {
                    direction=ysdUp;
                }
                else if (angle>=22.5&&angle<=67.5) {
                    direction=ysdRightUp;
                }
                else if(angle>=-22.5&&angle<=22.5) {
                    direction=ysdRight;
                }
                else if (angle>=-67.5&&angle<=-22.5) {
                    direction=ysdRightDown;
                }
                else if (angle>=-112.5&&angle<=-67.5) {
                    direction=ysdDown;
                }
                else if (angle>=-157.5&&angle<=112.5) {
                    direction=ysdLeftDown;
                }
                _delegate->onRock(direction,_vector);
            }
            _state=jsTouchMoved;
            
            if (_touchedJoystick) {
                _touchedJoystick->setVisible(false);
            }
            if (_movedJoystick) {
                _movedJoystick->setVisible(true);
                CCPoint point=pTouch->getLocation();
                if (ccpDistance(_touchedPoint, pTouch->getLocation())>_maxMoveDistance) {
                    point=ccpMult(ccpNormalize(pTouch->getLocation()),_maxMoveDistance);
                }
                _movedJoystick->setPosition(this->convertToNodeSpace(point));
                _movedJoystick->setRotation(CC_RADIANS_TO_DEGREES(ccpToAngle(ccp(_vector.y,_vector.x))));
            }
        }
        else {
            _state=jsNone;
            if (_delegate) {
                _delegate->onRockEnd();
            }
            if (_bgNormal) {
                _bgNormal->setVisible(true);
            }
            if (_bgHighlighted) {
                _bgHighlighted->setVisible(false);
            }
            if (_touchedJoystick) {
                _touchedJoystick->setVisible(false);
            }
        }
    }
}
示例#24
0
void StartScene::FollowPath(Node *sender)
{
    DataModel *m = DataModel::getModel();
    Creep* creep = (Creep *)sender;
    WayPoint* curWaypoint = creep->getCurrentWaypoint();
    WayPoint* waypoint = creep->getNextWaypoint();
    if (waypoint!=nullptr) {
        Point moveVector = waypoint->getPosition()-curWaypoint->getPosition();
        float angle = ccpToAngle(moveVector);
        float cocosAngle = CC_RADIANS_TO_DEGREES(angle);
//        std::ostringstream text("angle = ");
//        text<<std::to_string(cocosAngle)<<" curPoint("<<std::to_string(curWaypoint->getPosition().x)<<","<<std::to_string(curWaypoint->getPosition().y)<<") nextPoint("<<std::to_string(waypoint->getPosition().x)<<","<<std::to_string(waypoint->getPosition().y)<<")";
//        log(text.str().c_str());
        if (cocosAngle==0) {
            if (creep->inverse) {
                cocosAngle += 180;
                creep->lifeBar->setPosition(creep->sprite->getPosition().x, creep->sprite->getPosition().y-60);
            } else
                creep->lifeBar->setPosition(creep->sprite->getPosition().x, creep->sprite->getPosition().y+60);
            creep->emptyLifeBar->setPosition(creep->lifeBar->getPosition());
        } else if(cocosAngle==180) {
            if (creep->inverse) {
                cocosAngle += 180;
                creep->lifeBar->setPosition(creep->sprite->getPosition().x, creep->sprite->getPosition().y+60);
            } else
                creep->lifeBar->setPosition(creep->sprite->getPosition().x, creep->sprite->getPosition().y-60);
            creep->emptyLifeBar->setPosition(creep->lifeBar->getPosition());
        } else {
            if (!creep->inverse)
                cocosAngle += 180;
        }
        sender->setRotation(cocosAngle);
        int moveDuration = creep->moveDuration;
        auto actionMove = MoveTo::create(moveDuration, waypoint->getPosition());
        auto actionMoveDone = CallFuncN::create(this, callfuncN_selector(StartScene::FollowPath));
        creep->stopAllActions();
//        creep->lifeBar->stopAllActions();
        creep->runAction(Sequence::create(actionMove, actionMoveDone, NULL));
//        creep->lifeBar->runAction(Sequence::create(lifeBarActionMove, NULL));
    } else {
        m->home->homeHP--;
        life->setText(to_string(m->home->homeHP));
        CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("blast.wav");
        m->targets.eraseObject(creep);
        this->removeChild(creep);
        CCParticleSystem* particleSystem = CCParticleExplosion::create();
        particleSystem->setTexture(CCTextureCache::sharedTextureCache()->addImage("bullet2.png"));
        particleSystem->setPosition(creep->getPosition());
        particleSystem->setScale(0.15);
        particleSystem->setLife(1);
        this->addChild(particleSystem);
        if (m->home->homeHP<=0) {
            m->home->removeAllChildren();
            m->home->sprite = Sprite::create("destroy.png");
            m->home->sprite->setScale(0.7);
            m->home->addChild(m->home->sprite,0);
            Size visibleSize = Director::getInstance()->getVisibleSize();
            Point origin = Director::getInstance()->getVisibleOrigin();
            auto losePic = Sprite::create("over.png");
            losePic->setPosition(Point(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
            this->addChild(losePic,3);
            widget = dynamic_cast<Layout*>(cocostudio::GUIReader::getInstance()->widgetFromJsonFile("OverUi_1/LoseUi_1.json"));
            widget->setPosition(Point(visibleSize.width/2 + origin.x -widget->getContentSize().width/2, visibleSize.height/2 + origin.y - widget->getContentSize().height/2));
            this->addChild(widget,2);
            auto restartButton = dynamic_cast<Button*>(widget->getChildByName("RestartBTN"));
            auto mainMenuButton = dynamic_cast<Button*>(widget->getChildByName("MainMenuBTN"));
            restartButton->addTouchEventListener(this, toucheventselector(StartScene::restartEvent));
            mainMenuButton->addTouchEventListener(this, toucheventselector(StartScene::mainMenuEvent));
            this->cleanup();
        } else {
            std::string home = to_string(m->home->homeHP) + ".png";
            m->home->removeAllChildren();
            m->home->sprite = Sprite::create(home);
            m->home->sprite->setScale(0.7);
            m->home->addChild(m->home->sprite,0);
        }
    }
}
示例#25
0
void Joystick::drawArrow()
{
    CCPoint point=ccpAdd(_touchedPoint, _vector);
    ccVertex2F vertices[4]={{point.x,point.y},{point.x-25,point.y-15},{point.x,point.y+35},{point.x+25,point.y-15}};
    for (int i=0; i<4; ++i) {
        CCPoint tempPoint=ccpRotateByAngle(ccp(vertices[i].x,vertices[i].y), ccp(point.x,point.y),-1*ccpToAngle(ccp(_vector.y,_vector.x)));
        vertices[i]=vertex2(tempPoint.x, tempPoint.y);
    }
    ccColor4F colors[4]={{0,0,0,1},{0,0,0,1},{0,0,0,1},{0,0,0,1}};
    ccGLEnableVertexAttribs(kCCVertexAttribFlag_Position|kCCVertexAttribFlag_Color);
    glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertices);
    glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_FLOAT, GL_FALSE, 0, colors);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
示例#26
0
// adds a new segment to the ribbon
void CCRibbon::addPointAt(CCPoint location, float width)
{
    location.x *= CC_CONTENT_SCALE_FACTOR();
    location.y *= CC_CONTENT_SCALE_FACTOR();

    width = width * 0.5f;
    // if this is the first point added, cache it and return
    if (!m_bPastFirstPoint)
    {
        m_fLastWidth = width;
        m_tLastLocation = location;
        m_bPastFirstPoint = true;
        return;
    }

    CCPoint sub = ccpSub(m_tLastLocation, location);
    float r = ccpToAngle(sub) + (float)M_PI_2;
    CCPoint p1 = ccpAdd(this->rotatePoint(ccp(-width, 0), r), location);
    CCPoint p2 = ccpAdd(this->rotatePoint(ccp(+width, 0), r), location);
    float len = sqrtf(powf(m_tLastLocation.x - location.x, 2) + powf(m_tLastLocation.y - location.y, 2));
    float tend = m_fTexVPos + len/m_fTextureLength;
    CCRibbonSegment* seg;
    // grab last segment
    seg = m_pSegments->getLastObject();
    // lets kill old segments
    if (m_pSegments && m_pSegments->count()>0)
    {
        CCMutableArray<CCRibbonSegment*>::CCMutableArrayIterator it;
        for (it = m_pSegments->begin(); it != m_pSegments->end(); ++it)
        {
            if (*it != seg && (*it)->m_bFinished)
            {
                m_pDeletedSegments->addObject(*it);
            }
        }
    }

    m_pSegments->removeObjectsInArray(m_pDeletedSegments);
    // is the segment full?
    if (seg->m_uEnd >= 50)
    {
        m_pSegments->removeObjectsInArray(m_pDeletedSegments);
    }
    // grab last segment and append to it if it's not full
    seg = m_pSegments->getLastObject();
    // is the segment full?
    if (seg->m_uEnd >= 50)
    {
        CCRibbonSegment* newSeg;
        // grab it from the cache if we can
        if (m_pDeletedSegments->count() > 0)
        {
            newSeg = m_pDeletedSegments->getObjectAtIndex(0);
            newSeg->retain();							// will be released later
            m_pDeletedSegments->removeObject(newSeg);
            newSeg->reset();
        }
        else
        {
            newSeg = new CCRibbonSegment(); // will be released later
            newSeg->init();
        }

        newSeg->m_pCreationTime[0] = seg->m_pCreationTime[seg->m_uEnd- 1];
        int v = (seg->m_uEnd-1)*6;
        int c = (seg->m_uEnd-1)*4;
        newSeg->m_pVerts[0] = seg->m_pVerts[v];
        newSeg->m_pVerts[1] = seg->m_pVerts[v+1];
        newSeg->m_pVerts[2] = seg->m_pVerts[v+2];
        newSeg->m_pVerts[3] = seg->m_pVerts[v+3];
        newSeg->m_pVerts[4] = seg->m_pVerts[v+4];
        newSeg->m_pVerts[5] = seg->m_pVerts[v+5];

        newSeg->m_pCoords[0] = seg->m_pCoords[c];
        newSeg->m_pCoords[1] = seg->m_pCoords[c+1];
        newSeg->m_pCoords[2] = seg->m_pCoords[c+2];
        newSeg->m_pCoords[3] = seg->m_pCoords[c+3];
        newSeg->m_uEnd++;
        seg = newSeg;
        m_pSegments->addObject(seg);
        newSeg->release();// it was retained before
    }
    if (seg->m_uEnd == 0)
    {
        // first edge has to get rotation from the first real polygon
        CCPoint lp1 = ccpAdd(this->rotatePoint(ccp(-m_fLastWidth, 0), r), m_tLastLocation);
        CCPoint lp2 = ccpAdd(this->rotatePoint(ccp(+m_fLastWidth, 0), r), m_tLastLocation);
        seg->m_pCreationTime[0] = m_fCurTime - m_fDelta;
        seg->m_pVerts[0] = lp1.x;
        seg->m_pVerts[1] = lp1.y;
        seg->m_pVerts[2] = 0.0f;
        seg->m_pVerts[3] = lp2.x;
        seg->m_pVerts[4] = lp2.y;
        seg->m_pVerts[5] = 0.0f;
        seg->m_pCoords[0] = 0.0f;
        seg->m_pCoords[1] = m_fTexVPos;
        seg->m_pCoords[2] = 1.0f;
        seg->m_pCoords[3] = m_fTexVPos;
        seg->m_uEnd++;
    }

    int v = seg->m_uEnd*6;
    int c = seg->m_uEnd*4;
    // add new vertex
    seg->m_pCreationTime[seg->m_uEnd] = m_fCurTime;
    seg->m_pVerts[v] = p1.x;
    seg->m_pVerts[v+1] = p1.y;
    seg->m_pVerts[v+2] = 0.0f;
    seg->m_pVerts[v+3] = p2.x;
    seg->m_pVerts[v+4] = p2.y;
    seg->m_pVerts[v+5] = 0.0f;


    seg->m_pCoords[c] = 0.0f;
    seg->m_pCoords[c+1] = tend;
    seg->m_pCoords[c+2] = 1.0f;
    seg->m_pCoords[c+3] = tend;

    m_fTexVPos = tend;
    m_tLastLocation = location;
    m_tLastPoint1 = p1;
    m_tLastPoint2 = p2;
    m_fLastWidth = width;
    seg->m_uEnd++;
}
示例#27
0
Tower* ObjectFactory::createTower(TowerStructDTO* towerStructDTO, b2World* world)
{
    TowerDTO* towerDTO = DataCollector::getInstance()->getTowerDTOByKey(towerStructDTO->id.c_str());
    Tower* tower = NULL;
    if(strcasecmp(towerStructDTO->type.c_str(), "main") == 0)
    {
        tower = MainCrystal::create();
//        CCLOG("main");
    }
    else
    {
        tower = Tower::create();
//        CCLOG("tower");
    }
    
    
    tower->setOriginCharacterData(towerDTO->data);
    
    //Create Animation
    string run = towerDTO->animation;
    string attack = towerDTO->animation;
    string idle = towerDTO->animation;
    string fall = towerDTO->animation;
    string fly = towerDTO->animation;
    string jump = towerDTO->animation;
    string die = towerDTO->animation;
    
    tower->runAnimation = DataCollector::getInstance()->getAnimationObjectByKey(run.append(RUN).c_str());
    tower->attackAnimation = DataCollector::getInstance()->getAnimationObjectByKey(attack.append(ATTACK).c_str());
    tower->jumpAnimation = DataCollector::getInstance()->getAnimationObjectByKey(jump.append(JUMP).c_str());
    tower->idleAnimation = DataCollector::getInstance()->getAnimationObjectByKey(idle.append(IDLE).c_str());
    tower->fallAnimation = DataCollector::getInstance()->getAnimationObjectByKey(fall.append(FALL).c_str());
    tower->flyAnimation = DataCollector::getInstance()->getAnimationObjectByKey(fly.append(FLY).c_str());
    tower->dieAnimation = DataCollector::getInstance()->getAnimationObjectByKey(die.append(DIE).c_str());
    tower->setSoundData(SoundManager::loadCharacterSoundData(towerDTO->soundId.c_str()));
//    if( tower->attackAnimation != NULL)
//    {
//        tower->attackAnimation->getAnimation()->setDelayPerUnit(tower->getOriginCharacterData().getAttackSpeed());
//    }
    
    
    //body
    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;
    bodyDef.angle = ccpToAngle(ccp(0,0));
    bodyDef.fixedRotation=true;
    
    b2Body *body = world->CreateBody(&bodyDef);
    
    gbox2d::GB2ShapeCache *sc =  gbox2d::GB2ShapeCache::sharedGB2ShapeCache();
    sc->addFixturesToBody(body,  towerDTO->body.c_str());
    tower->setSpriteAnchorPoint(sc->anchorPointForShape(towerDTO->body.c_str()));
    tower->getSprite()->setAnchorPoint(sc->anchorPointForShape(towerDTO->body.c_str()));
    tower->setSkin(body, tower->getSprite());
    
    //
    tower->setSensor(towerDTO->towerSensorId.c_str());
    
    tower->setSkill(NORMAL_ATTACK, SkillFactory::createSkill(towerDTO->data.getSkill0().c_str(), world, tower, false, SKILL_0_BTN));
    //    tower->setSkill1(SkillFactory::createSkill(towerDTO->data.getSkill1().c_str(), world, tower, false, SKILL_1_BUTTON));
    //    tower->setSkill2(SkillFactory::createSkill(towerDTO->data.getSkill2().c_str(), world, tower, false, SKILL_2_BUTTON));
    
    tower->setPositionInPixel(ccp(towerStructDTO->positionX,towerStructDTO->positionY));
    tower->setGroup(towerStructDTO->group);
    
    tower->setSoundData(SoundManager::loadCharacterSoundData(towerDTO->soundId.c_str()));
    
    tower->onCreate();
    return tower;
}
void CCCatmullRomSprite::updateAtlas() {
    // populate points
    populatePoints(m_controlPoints, m_points);
    
    // clear
	m_atlas->removeAllQuads();
    m_segmentQuadIndices.clear();
    
    // basic check, at least we need two points
    int pc = m_points.getCount();
    if(pc < 2)
        return;
    
    // append a point to avoid losting last segment
    CCPoint pLast0 = m_points.getPointAt(pc - 1);
    CCPoint pLast1 = m_points.getPointAt(pc - 2);
    CCPoint pAppend = ccpAdd(pLast0, ccpSub(pLast0, pLast1));
    m_points.addPoint(pAppend);
    pc++;
    
    // first two points
    CCPoint p0 = m_points.getPointAt(0);
    CCPoint p1 = m_points.getPointAt(1);
    
    // half width of pattern
    float halfWidth = m_patternWidth / 2;

    // bl and br of first quad
    CCPoint bl, tl;
    {
        CCPoint v01 = ccpSub(p1, p0);
        float r01 = ccpToAngle(v01);
        bl.x = p0.x + halfWidth * sinf(r01);
        bl.y = p0.y - halfWidth * cosf(r01);
        tl.x = p0.x - halfWidth * sinf(r01);
        tl.y = p0.y + halfWidth * cosf(r01);
    }
    
    // current length
    float texStartP = 0;
	float texEndP;
	float headPos = 0;
    
    // populate quads
    int segIndex = 0;
    for(int i = 2; i < pc; i++) {
        // save quad index
        if(m_segmentPointIndices[segIndex] == i - 2) {
            m_segmentQuadIndices.push_back(m_atlas->getTotalQuads());
            segIndex++;
        }
        
        // third point
        CCPoint p2 = m_points.getPointAt(i);
        
        // 3 vectors, from 0 to 1, from 1 to 2, from 1 to 0
        CCPoint v01 = ccpSub(p1, p0);
        CCPoint v12 = ccpSub(p2, p1);
        CCPoint v10 = ccpSub(p0, p1);
        
        // angle in center of v01 and v12, then rotate 90 degrees
        float r = (ccpToAngle(v01) + ccpToAngle(v12)) / 2 - M_PI_2;
        
        // the vector of center divider
        CCPoint m = ccp(cosf(r), sinf(r));
        
        // angle between center and v10
        float rm01 = ccpToAngle(m) - ccpToAngle(v10);
        
        // the actual base width of joint
        // but we must prevent the base width to be too large
        float s = sinf(rm01);
        float w = MAX_FLOAT;
        if(s != 0)
            w = fabsf(halfWidth / s);
        w = MIN(halfWidth * 2, w);
        
        // a corner situation when v01 is in third quadrant and v12 is in fourth quadrant
        if(v01.x < 0 && SIGN(v01.x) == SIGN(v12.x) && SIGN(v01.y) != SIGN(v12.y)) {
            r = M_PI + r;
        }
		
		// populate tl and tr
		CCPoint br, tr;
        br.x = p1.x + w * cosf(r);
        br.y = p1.y + w * sinf(r);
        tr.x = p1.x - w * cosf(r);
        tr.y = p1.y - w * sinf(r);

        // calculate texcoords pencentage
        float segLen = ccpLength(v01);
		float remainLen = segLen;
        float initVerP = 0;
        float stepVerP = m_patternLength / segLen;
        while(remainLen > m_patternLength) {
            texEndP = texStartP;
            float p = (1 - texStartP) / (1 - texStartP + texEndP);
            populateQuad(bl, br, tl, tr, texStartP, 1, initVerP, initVerP + stepVerP * p);
            populateQuad(bl, br, tl, tr, 0, texEndP, initVerP + stepVerP * p, initVerP + stepVerP);
            initVerP += stepVerP;
            
            // cut pattern length
            remainLen -= m_patternLength;
        }
        
        // remaining length
		headPos += segLen;
		headPos = fmodf(headPos, m_patternLength);
        texEndP = headPos / m_patternLength;
        stepVerP = remainLen / segLen;
        if(texEndP <= texStartP) {
            float p = (1 - texStartP) / (1 - texStartP + texEndP);
            populateQuad(bl, br, tl, tr, texStartP, 1, initVerP, initVerP + stepVerP * p);
            populateQuad(bl, br, tl, tr, 0, texEndP, initVerP + stepVerP * p, initVerP + stepVerP);
        } else {
            populateQuad(bl, br, tl, tr, texStartP, texEndP, initVerP, 1);
        }
        
        // move forward
        p0 = p1;
        p1 = p2;
        bl = br;
        tl = tr;
        texStartP = texEndP;
    }
}