HitTestResult* hitTestStripRound(StripBodyNode* a, RoundBodyNode* b) { Point cb = b->getCenter(); float rb = b->getRadius(); Point ca = a->getCenter(); Vector2 ava = a->getEnd() - a->getBegin(); float ha = a->getWidth(); float wa = ccpLength(ava); float ra = a->getRadius(); Point rrp; ava = ava/wa; bool hit = isRoundCrossRect(cb, rb, ca, wa, ha, ava); if(hit) { Point hp; float distance; Point ba = a->getBegin(); Vector2 delta = ba - cb; float deltaLength = ccpLength(delta); hp = cb + delta/deltaLength * rb; distance = deltaLength - rb; return HitTestResult::create(HTRT_CROSS, hp, distance); } else { return HitTestResult::create(HTRT_NONE); } }
void AniNode::update(float delta) { if (ccpLength(aniNode_moveSpeed) != 0 || ccpLength(aniNode_accMoveSpeed) != 0) { CCPoint dis = ccpAdd(ccpMult(aniNode_moveSpeed, delta), ccpMult(aniNode_accMoveSpeed, 0.5 * delta * delta)); this->setPosition(ccpAdd(this->getPosition(), dis)); aniNode_moveSpeed = ccpAdd(aniNode_moveSpeed, ccpMult(aniNode_accMoveSpeed, delta)); } if (aniNode_rotateSpeed != 0 || aniNode_accRotateSpeed != 0) { float rot = aniNode_rotateSpeed * delta + 0.5 * aniNode_accRotateSpeed * delta * delta; this->setRotation(this->getRotation() + rot); aniNode_rotateSpeed = aniNode_rotateSpeed + aniNode_accRotateSpeed * delta; } }
void CCTwirl::update(float time) { int i, j; CCPoint c = m_position; for (i = 0; i < (m_sGridSize.width+1); ++i) { for (j = 0; j < (m_sGridSize.height+1); ++j) { ccVertex3F v = originalVertex(ccp(i ,j)); CCPoint avg = ccp(i-(m_sGridSize.width/2.0f), j-(m_sGridSize.height/2.0f)); float r = ccpLength(avg); float amp = 0.1f * m_fAmplitude * m_fAmplitudeRate; float a = r * cosf( (float)M_PI/2.0f + time * (float)M_PI * m_nTwirls * 2 ) * amp; CCPoint d = ccp( sinf(a) * (v.y-c.y) + cosf(a) * (v.x-c.x), cosf(a) * (v.y-c.y) - sinf(a) * (v.x-c.x)); v.x = c.x + d.x; v.y = c.y + d.y; setVertex(ccp(i ,j), v); } } }
void CCTwirl::update(ccTime time) { int i, j; CCPoint c = m_positionInPixels; for (i = 0; i < (m_sGridSize.x+1); ++i) { for (j = 0; j < (m_sGridSize.y+1); ++j) { ccVertex3F v = originalVertex(ccg(i ,j)); CCPoint avg = ccp(i-(m_sGridSize.x/2.0f), j-(m_sGridSize.y/2.0f)); CGFloat r = ccpLength(avg); CGFloat amp = 0.1f * m_fAmplitude * m_fAmplitudeRate; CGFloat a = r * cosf( (CGFloat)M_PI/2.0f + time * (CGFloat)M_PI * m_nTwirls * 2 ) * amp; CCPoint d; d.x = sinf(a) * (v.y-c.y) + cosf(a) * (v.x-c.x); d.y = cosf(a) * (v.y-c.y) - sinf(a) * (v.x-c.x); v.x = c.x + d.x; v.y = c.y + d.y; setVertex(ccg(i ,j), v); } } }
HitTestResult* hitTestRectRound(RectBodyNode* a, RoundBodyNode* b) { Point ca = a->getCenter(); float wa = a->getWidth(); float ha = a->getHeight(); float aa = CC_DEGREES_TO_RADIANS(-a->getAngle()); float ra = a->getRadius(); Point cb = b->getCenter(); float rb = b->getRadius(); bool hit = isRoundCrossRect(cb, rb, ca, wa, ha, ccpForAngle(aa)); if(hit) { Point hp; float distance; Vector2 delta = ca - cb; float deltaLength = ccpLength(delta); hp = cb + delta/deltaLength * rb; distance = deltaLength - rb; return HitTestResult::create(HTRT_CROSS, hp, distance); } else { return HitTestResult::create(HTRT_NONE); } }
void BWCircleBy::startWithTarget(CCNode *pTarget) { BWActionInterval::startWithTarget(pTarget); m_previousPosition = m_startPosition = pTarget->getPosition(); float fDis = ccpLength(m_dirPoint); m_fA = fDis*0.5; }
void CCMoveAccelBy::calcAccel() { //all scalars: s a v t float t = m_fDuration; s = ccpLength( m_delta ); a = (s - v * t) / (0.5f * t * t); }
void Solider::setTarget(CCPoint _target) { m_ID = MOVE; timeMove = 0; m_targetPos = _target; timeFinishMove = ccpLength(ccpSub(m_targetPos, m_pos))/ m_maxVelocity/60; }
void CircleBy::startWithTarget(CCNode *pTarget) { ActionInterval::startWithTarget(pTarget); m_startPosition = pTarget->getPosition(); float fDistance = ccpLength(m_dirPoint); m_fA = fDistance * 0.5; }
void LFTwirl::preCalculateDistance() { setPosition(m_pTarget->getPosition()); // gridDistanceArray = new float[ (m_sGridSize.x + 1) * (m_sGridSize.y + 1) ]; //Richard // 原先类型为int 现在CCSize为float 墙砖为int gridDistanceArray = new float[ ((int)m_sGridSize.width + 1) * ((int)m_sGridSize.height + 1) ]; int i, j; int index = 0; for (i = 0; i < m_sGridSize.width + 1; ++i) { for (j = 0; j < m_sGridSize.height + 1; ++j) { ccVertex3F v = originalVertex(ccp(i, j)); CCPoint relativedPos = ccp(v.x - m_position.x,v.y - m_position.y); float dis = ccpLength(relativedPos) + 1.0f; gridDistanceArray[index] = dis; index ++; } } // setPosition(m_pTarget->getPosition()); }
void CCCurl::startWithTarget(CCNode* pTarget) { CCActionInterval::startWithTarget(pTarget); // get start radius CCPoint v = ccpSub(pTarget->getPosition(), m_center); m_fromRadius = ccpLength(v); m_initAngle = v.getAngle(); }
//-------------------------------------------------------------------- void FKCW_Action_Curl::startWithTarget(CCNode* pTarget) { CCActionInterval::startWithTarget(pTarget); // 获取起始半径和角度 CCPoint v = ccpSub(pTarget->getPosition(), m_center); m_fromRadius = ccpLength(v); m_initAngle = v.getAngle(); }
void BWSineBy::startWithTarget(CCNode *pTarget) { BWActionInterval::startWithTarget(pTarget); m_previousPosition = m_startPosition = pTarget->getPosition(); float fDis = ccpLength(m_endPosition); m_fW = 2*M_PI/fDis; }
void CCLayerGradient::updateColor() { CCLayerColor::updateColor(); float h = ccpLength(m_AlongVector); if (h == 0) return; double c = sqrt(2.0); CCPoint u = ccp(m_AlongVector.x / h, m_AlongVector.y / h); // Compressed Interpolation mode if (m_bCompressedInterpolation) { float h2 = 1 / ( fabsf(u.x) + fabsf(u.y) ); u = ccpMult(u, h2 * (float)c); } float opacityf = (float)m_cOpacity / 255.0f; ccColor4B S = { (unsigned char) m_tColor.r, (unsigned char) m_tColor.g, (unsigned char) m_tColor.b, (unsigned char) (m_cStartOpacity * opacityf) }; ccColor4B E = { (unsigned char) m_endColor.r, (unsigned char) m_endColor.g, (unsigned char) m_endColor.b, (unsigned char) (m_cEndOpacity * opacityf) }; // (-1, -1) m_pSquareColors[0].r = (GLubyte) (E.r + (S.r - E.r) * ((c + u.x + u.y) / (2.0f * c))); m_pSquareColors[0].g = (GLubyte) (E.g + (S.g - E.g) * ((c + u.x + u.y) / (2.0f * c))); m_pSquareColors[0].b = (GLubyte) (E.b + (S.b - E.b) * ((c + u.x + u.y) / (2.0f * c))); m_pSquareColors[0].a = (GLubyte) (E.a + (S.a - E.a) * ((c + u.x + u.y) / (2.0f * c))); // (1, -1) m_pSquareColors[1].r = (GLubyte) (E.r + (S.r - E.r) * ((c - u.x + u.y) / (2.0f * c))); m_pSquareColors[1].g = (GLubyte) (E.g + (S.g - E.g) * ((c - u.x + u.y) / (2.0f * c))); m_pSquareColors[1].b = (GLubyte) (E.b + (S.b - E.b) * ((c - u.x + u.y) / (2.0f * c))); m_pSquareColors[1].a = (GLubyte) (E.a + (S.a - E.a) * ((c - u.x + u.y) / (2.0f * c))); // (-1, 1) m_pSquareColors[2].r = (GLubyte) (E.r + (S.r - E.r) * ((c + u.x - u.y) / (2.0f * c))); m_pSquareColors[2].g = (GLubyte) (E.g + (S.g - E.g) * ((c + u.x - u.y) / (2.0f * c))); m_pSquareColors[2].b = (GLubyte) (E.b + (S.b - E.b) * ((c + u.x - u.y) / (2.0f * c))); m_pSquareColors[2].a = (GLubyte) (E.a + (S.a - E.a) * ((c + u.x - u.y) / (2.0f * c))); // (1, 1) m_pSquareColors[3].r = (GLubyte) (E.r + (S.r - E.r) * ((c - u.x - u.y) / (2.0f * c))); m_pSquareColors[3].g = (GLubyte) (E.g + (S.g - E.g) * ((c - u.x - u.y) / (2.0f * c))); m_pSquareColors[3].b = (GLubyte) (E.b + (S.b - E.b) * ((c - u.x - u.y) / (2.0f * c))); m_pSquareColors[3].a = (GLubyte) (E.a + (S.a - E.a) * ((c - u.x - u.y) / (2.0f * c))); }
void CGradientView::updateColor() { CColorView::updateColor(); float h = ccpLength(m_tAlongVector); if( (int)h == 0 ) return; float c = sqrtf(2.0f); CCPoint u = CCPoint(m_tAlongVector.x / h, m_tAlongVector.y / h); // Compressed Interpolation mode if( m_bCompressedInterpolation ) { float h2 = 1 / ( fabsf(u.x) + fabsf(u.y) ); u = ccpMult(u, h2 * (float)c); } float opacityf = (float)_displayedOpacity / 255.0f; ccColor4F S = { _displayedColor.r / 255.0f, _displayedColor.g / 255.0f, _displayedColor.b / 255.0f, m_cStartOpacity * opacityf / 255.0f }; ccColor4F E = { m_tEndColor.r / 255.0f, m_tEndColor.g / 255.0f, m_tEndColor.b / 255.0f, m_cEndOpacity * opacityf / 255.0f }; // (-1, -1) m_pSquareColors[0].r = E.r + (S.r - E.r) * ((c + u.x + u.y) / (2.0f * c)); m_pSquareColors[0].g = E.g + (S.g - E.g) * ((c + u.x + u.y) / (2.0f * c)); m_pSquareColors[0].b = E.b + (S.b - E.b) * ((c + u.x + u.y) / (2.0f * c)); m_pSquareColors[0].a = E.a + (S.a - E.a) * ((c + u.x + u.y) / (2.0f * c)); // (1, -1) m_pSquareColors[1].r = E.r + (S.r - E.r) * ((c - u.x + u.y) / (2.0f * c)); m_pSquareColors[1].g = E.g + (S.g - E.g) * ((c - u.x + u.y) / (2.0f * c)); m_pSquareColors[1].b = E.b + (S.b - E.b) * ((c - u.x + u.y) / (2.0f * c)); m_pSquareColors[1].a = E.a + (S.a - E.a) * ((c - u.x + u.y) / (2.0f * c)); // (-1, 1) m_pSquareColors[2].r = E.r + (S.r - E.r) * ((c + u.x - u.y) / (2.0f * c)); m_pSquareColors[2].g = E.g + (S.g - E.g) * ((c + u.x - u.y) / (2.0f * c)); m_pSquareColors[2].b = E.b + (S.b - E.b) * ((c + u.x - u.y) / (2.0f * c)); m_pSquareColors[2].a = E.a + (S.a - E.a) * ((c + u.x - u.y) / (2.0f * c)); // (1, 1) m_pSquareColors[3].r = E.r + (S.r - E.r) * ((c - u.x - u.y) / (2.0f * c)); m_pSquareColors[3].g = E.g + (S.g - E.g) * ((c - u.x - u.y) / (2.0f * c)); m_pSquareColors[3].b = E.b + (S.b - E.b) * ((c - u.x - u.y) / (2.0f * c)); m_pSquareColors[3].a = E.a + (S.a - E.a) * ((c - u.x - u.y) / (2.0f * c)); }
void CCLens3D::update(ccTime time) { CC_UNUSED_PARAM(time); if (m_bDirty) { int i, j; for (i = 0; i < m_sGridSize.x + 1; ++i) { for (j = 0; j < m_sGridSize.y + 1; ++j) { ccVertex3F v = originalVertex(ccg(i, j)); CCPoint vect = ccpSub(m_positionInPixels, ccp(v.x, v.y)); CGFloat r = ccpLength(vect); if (r < m_fRadius) { r = m_fRadius - r; CGFloat pre_log = r / m_fRadius; if ( pre_log == 0 ) { pre_log = 0.001f; } float l = logf(pre_log) * m_fLensEffect; float new_r = expf( l ) * m_fRadius; if (ccpLength(vect) > 0) { vect = ccpNormalize(vect); CCPoint new_vect = ccpMult(vect, new_r); v.z += ccpLength(new_vect) * m_fLensEffect; } } setVertex(ccg(i, j), v); } } m_bDirty = false; } }
void CCLens3D::update(float time) { CC_UNUSED_PARAM(time); if (m_bDirty) { int i, j; for (i = 0; i < m_sGridSize.width + 1; ++i) { for (j = 0; j < m_sGridSize.height + 1; ++j) { ccVertex3F v = originalVertex(ccp(i, j)); CCPoint vect = ccpSub(m_tPoint, ccp(v.x, v.y)); float r = ccpLength(vect); if (r < m_fRadius) { r = m_fRadius - r; float pre_log = r / m_fRadius; if ( pre_log == 0 ) { pre_log = 0.001f; } float l = logf(pre_log) * m_fLensEffect; float new_r = expf( l ) * m_fRadius; if (ccpLength(vect) > 0) { vect = ccpNormalize(vect); CCPoint new_vect = ccpMult(vect, new_r); v.z += (m_bConcave ? -1.0f : 1.0f) * ccpLength(new_vect) * m_fLensEffect; } } setVertex(ccp(i, j), v); } } m_bDirty = false; } }
void CCBigImage::setPosition(const CCPoint &newPosition) { float significantPositionDelta = MIN(this->_screenLoadRectExtension.width, this->_screenLoadRectExtension.height) / 2.0f; if ( ccpLength(ccpSub(newPosition, this->getPosition())) > significantPositionDelta ) { this->_significantPositionChange = true; } CCNode::setPosition(newPosition); }
bool CircleBy::init(float t, CCPoint dirPoint,float fB) { if (ActionInterval::initWithDuration(t)) { m_dirPoint = dirPoint; m_fA = ccpLength(dirPoint); m_fB = fB; m_bClock = false; return true; } return false; }
CCPoint calculateCosASinAOfVec1ToVec2(const CCPoint&vec1,const CCPoint&vec2) //return {cos(vec1,vec2),sin(vec1,vec2)} { float cosA=ccpDot(vec1, vec2)/(ccpLength(vec1)*ccpLength(vec2)); float signalOfSinA; { float _vec1[3]={vec1.x,vec1.y,0}; float _vec2[3]={vec2.x,vec2.y,0}; float _rs[3]; __cross(_vec1, _vec2, _rs); if (_rs[2]==0) { signalOfSinA=0; }else if(_rs[2]>0){ signalOfSinA=1; }else{ signalOfSinA=-1; } } float sinA=signalOfSinA*sqrtf(MAX(0,1-cosA*cosA)); return CCPoint(cosA,sinA); }
void CCMotionStreak::update(ccTime delta) { CCPoint location = this->convertToWorldSpace(CCPointZero); m_pRibbon->setPosition(ccp(-1*location.x, -1*location.y)); float len = ccpLength(ccpSub(m_tLastLocation, location)); if (len > m_fSegThreshold) { m_pRibbon->addPointAt(location, m_fWidth); m_tLastLocation = location; } m_pRibbon->update(delta); }
HitTestResult* hitTestStripStrip(StripBodyNode* a, StripBodyNode* b) { Point Atop[4]; Point Btop[4]; a->getTops(Atop, Atop + 1, Atop + 2, Atop + 3); b->getTops(Btop, Btop + 1, Btop + 2, Btop + 3); int cpcount = 0; Point cp[12]; bool hit = isRectCrossRect(Atop[0], Atop[1], Atop[2], Atop[3], Btop[0], Btop[1], Btop[2], Btop[3], &cpcount, cp); if(hit) { if(cpcount < 0) cpcount = 0; Point ca = a->getCenter(); float wa = a->getWidth(); float ha = ccpDistance(a->getBegin(), a->getEnd()); Vector2 aa = ccpNormalize(a->getEnd() - a->getBegin()); for(int i = 0; i < 4; i++) { if(isPointInRect(Btop[i], ca, wa, ha, aa)) { cp[cpcount++] = Btop[i]; } } // use dot result for comparing directly // get true distance when receive a minimun dot result int iMin = 0; float dMin = 0; Vector2 direction = a->getEnd() - a->getBegin(); for(int i = 0; i < cpcount; i++) { float d = ccpDot(cp[i], direction); if( i == 0 && d < dMin) { dMin = d; iMin = i; } } dMin /= ccpLength(direction); return HitTestResult::create(HTRT_CROSS, cp[iMin], dMin); } else { return HitTestResult::create(HTRT_NONE); } }
void CCMotionStreak::OnTick(const TimeEvent* evt) { ccTime delta = evt->getDelta(); CCPoint location = this->convertToWorldSpace(CCPointZero); m_pRibbon->setPosition(ccp(-1*location.x, -1*location.y)); float len = ccpLength(ccpSub(m_tLastLocation, location)); if (len > m_fSegThreshold) { m_pRibbon->addPointAt(location, m_fWidth); m_tLastLocation = location; } m_pRibbon->updateRibbon(delta); }
void LFTwirl::update(float time) { //// 优化部分 //{ // flag ++; // if (flag % 2 != 0) // return; // flag = 0; //} int i, j; int index = 0; for (i = 0; i < m_sGridSize.width + 1; ++i) { for (j = 0; j < m_sGridSize.height + 1; ++j) { ccVertex3F v = originalVertex(ccp(i, j)); CCPoint relativedPos = ccp(v.x - m_position.x,v.y - m_position.y); CCPoint newPos; float dis = 0.0f; if (gridDistanceArray) { dis = gridDistanceArray[index];index++; }else { dis = ccpLength(relativedPos) + 1.0f; } // 基于相对中心坐标计算 { float tempAngle = mAngle; tempAngle = tempAngle / dis * (mRadius*10);// 跟半径成反比,半径越大,转动角度越小 newPos = ccpRotateByAngle(relativedPos,ccp(1,0),CC_DEGREES_TO_RADIANS(tempAngle)); newPos.x *= mScale; newPos.y *= mScale; } v.x = newPos.x + m_position.x ; v.y = newPos.y + m_position.y; setVertex(ccp(i, j), v); } } mScale *= mScaleFactor; mAngle += mAngleFactor; }
/* 普通攻击 */ void MCEnemy::attackTarget(MCRole *aTargetRole, CCObject *aTarget, SEL_CallFuncO aSelector, CCObject *anUserObject) { if (! canAttackTarget(aTargetRole)) { attackDidFail(); return; } MCRole::attackTarget(aTargetRole); ai_->lockState(); /* 检测攻击距离 */ MCRoleEntity *selfEntity = getEntity(); MCOBB targetOBB = aTargetRole->getEntity()->getOBB(); MCOBB selfOBB = selfEntity->getOBB(); CCPoint offset = ccpSub(targetOBB.center, selfOBB.center); float distance = ccpLength(offset) / selfOBB.width - 1; if (distance > (float) distance_) { /* 太远了干不了,需要走过去 */ target_ = aTarget; attackDidFinishSelector_ = aSelector; userObject_ = anUserObject; /* approachTargetAndKeepDistance版本不能保持距离和approachTarget效果一样,暂时放弃 */ // selfEntity->approachTargetAndKeepDistance(aTarget, // this, // callfuncO_selector(MCHero::roleDidApproachTarget), // aTarget, // weapon->distance); selfEntity->approachTarget(aTargetRole, this, callfuncO_selector(MCRole::roleDidApproachTarget), aTargetRole); return; } /* 进入攻击判断 */ // printf("进入攻击判断\n"); pp_ -= consume_; MCDungeonMaster::sharedDungeonMaster()->roleAttackTarget(this, aTargetRole); ai_->unlockState(); if (aTarget) { (aTarget->*aSelector)(anUserObject ? anUserObject : this); } target_ = NULL; attackDidFinishSelector_ = NULL; userObject_ = NULL; }
void BWSineBy::update(float time) { if (m_pTarget) { //CCLog("%f",time); CCPoint dir = m_endPosition ; float fDis = ccpLength(m_endPosition); float fOldX = fDis * time; float fOldY = m_fA * sinf(m_fW * fOldX); float fOldC = sqrtf(powf(fOldX, 2)+powf(fOldY, 2)); float fRotRadian = atanf(fOldY/fOldX) + atanf(dir.y/dir.x); if(m_endPosition.x < 0) fRotRadian += M_PI; float fRotOldX = fOldC * cos(fRotRadian); float fRotOldY = fOldC * sin(fRotRadian); float fNewX = fRotOldX + m_startPosition.x; float fNewY = fRotOldY + m_startPosition.y; CCPoint currentPos = m_pTarget->getPosition(); CCPoint newPos = ccp( fNewX, fNewY); m_pTarget->setPosition(newPos); if(m_bRotHead) { CCPoint dirPoint = ccpSub(newPos, currentPos); float fRadian = atanf(dirPoint.y/dirPoint.x); if((dirPoint.y > 0 && dirPoint.x > 0) || (dirPoint.y < 0 && dirPoint.x > 0)) { fRadian = M_PI_2 - fRadian; } else if((dirPoint.y < 0 && dirPoint.x < 0)|| (dirPoint.y > 0 && dirPoint.x < 0)) { fRadian = -M_PI_2 - fRadian; } float m_fRotation = fRadian*180.0/M_PI; m_pTarget->setRotation(m_fRotation); } } }
void SineBy::adjustTargetPosition(float time) { float fX = ccpLength(m_endPosition) * time; float fY = m_fA * sinf(m_fW * fX); //float fC = sqrtf(fX * fX + fY * fY); //float fRadian = (m_endPosition.x < 0) ? \ // atanf(fY / fX) + atanf(m_endPosition.y / m_endPosition.x) + float(M_PI) :\ // atanf(fY / fX) + atanf(m_endPosition.y / m_endPosition.x); //float fRadian = ccpAngleSigned(m_endPosition, CCPointMake(-1, 0)); double fRadian = M_PI_2; //CCPoint targetPos = ccp(fC * cos(fRadian) + m_startPosition.x, fC * sin(fRadian) + m_startPosition.y); CCPoint targetPos = ccpAdd(m_startPosition, ccp(fX,fY)).rotateByAngle(m_startPosition, fRadian); m_pTarget->setPosition(targetPos); }
void PaintLayer::ccTouchMoved(CCTouch* touch, CCEvent* event) { const CCPoint point = CCDirector::sharedDirector()->convertToGL(touch->getLocationInView()); //! skip points that are too close float eps = 1.5; if (points->count() > 0) { float length = ccpLength(ccpSub(((LinePoint *)points->lastObject())->pos, point)); if (length < eps) { return; } } this->addPoint(point, lineWidth); }
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(); } }
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); } } }