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(¶ms); 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"); } }
void VRope::resetWithPoints(cocos2d::CCPoint pointA, cocos2d::CCPoint pointB) { float distance = ccpDistance(pointA,pointB); CCPoint diffVector = ccpSub(pointB,pointA); float multiplier = distance / (numPoints - 1); for(int i=0;i<numPoints;i++) { CCPoint tmpVector = ccpAdd(pointA, ccpMult(ccpNormalize(diffVector),multiplier*i*(1-antiSagHack))); VPoint* tmpPoint = vPoints[i]; tmpPoint->setPos(tmpVector.x, tmpVector.y); } }
VRope* VRope::cutRopeInStick(int nPoint, VStick* stick, b2Body* newBodyA, b2Body* newBodyB) { auto range = NSRange{nPoint, numPoints-nPoint-1}; std::vector< VStick *> newRopeSticks( vSticks.begin() + range.location, vSticks.begin() + range.location + range.length ); vSticks.erase(vSticks.begin() + range.location, vSticks.begin() + range.location + range.length); std::vector<Sprite*> newRopeSprites(ropeSprites.begin() + range.location, ropeSprites.begin() + range.location + range.length); ropeSprites.erase(ropeSprites.begin() + range.location, ropeSprites.begin() + range.location + range.length); range.length += 1; std::vector<VPoint*> newRopePoints(vPoints.begin() + range.location, vPoints.begin() + range.location + range.length); vPoints.erase(vPoints.begin() + range.location, vPoints.begin() + range.location + range.length); VPoint *pointOfBreak = newRopePoints.at(0); VPoint *newPoint = new VPoint(); newPoint->setPos(pointOfBreak->x, pointOfBreak->y); vPoints.push_back(newPoint); VStick *lastStick = vSticks.back(); lastStick->setPointB(newPoint); float cutRatio = (float)nPoint / (numPoints - 1); numPoints = nPoint + 1; b2Vec2 newBodiesPosition = b2Vec2(pointOfBreak->x / PTM_RATIO, pointOfBreak->y / PTM_RATIO); b2World *world = newBodyA->GetWorld(); b2RopeJointDef jd; jd.bodyA = joint->GetBodyA(); jd.bodyB = newBodyB; jd.localAnchorA = joint->GetLocalAnchorA(); jd.localAnchorB = b2Vec2(0, 0); jd.maxLength = joint->GetMaxLength() * cutRatio; newBodyB->SetTransform(newBodiesPosition, 0.0); b2RopeJoint *newJoint1 = (b2RopeJoint *)world->CreateJoint(&jd); //create joint jd.bodyA = newBodyA; jd.bodyB = joint->GetBodyB(); jd.localAnchorA = b2Vec2(0, 0); jd.localAnchorB = joint->GetLocalAnchorB(); jd.maxLength = joint->GetMaxLength() * (1 - cutRatio); newBodyA->SetTransform(newBodiesPosition, 0.0); b2RopeJoint *newJoint2 = (b2RopeJoint *)world->CreateJoint(&jd); world->DestroyJoint(joint); joint = newJoint1; VRope* newRope = new VRope(newJoint2,spriteSheet,newRopePoints,newRopeSticks,newRopeSprites); return newRope; }
void VRope::createRope(const CCPoint& pointA, const CCPoint& pointB, float distance) { // float distance = ccpDistance(pointA,pointB); int segmentFactor = 12; // 16; //12; //increase value to have less segments per rope, decrease to have more segments numPoints = (int) distance/segmentFactor; 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.push_back(tmpPoint); } for(int i=0;i<numPoints-1;i++) { VStick* tmpStick = new VStick(vPoints[i], vPoints[i+1]); vSticks.push_back(tmpStick); } if(spriteSheet) { 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); float f = spriteSheet->getTextureAtlas()->getTexture()->getPixelsHigh() / CC_CONTENT_SCALE_FACTOR(); CCRect r = CCRectMake(0, 0, multiplier, f); Sprite* tmpSprite = Sprite::createWithTexture(spriteSheet->getTexture(), r); Texture2D::TexParams params = {GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT}; tmpSprite->getTexture()->setTexParameters(¶ms); 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.push_back(tmpSprite); } } }