Esempio n. 1
0
void Mage::specialAttack()
{
	_specialAttackChance = MageValues._specialAttackChance;
	_angry = ActorCommonValues._angry;
	struct MESSAGE_ANGRY_CHANGE angryChange = { _name, _angry, _angryMax };
	MessageDispatchCenter::getInstance()->dispatchMessage(ANGRY_CHANGE, this);
	
	experimental::AudioEngine::play2d(MageProperty.specialAttackShout, false, 0.5);
	experimental::AudioEngine::play2d(MageProperty.ice_special, false, 1);

	//mage will create 3 ice spikes on the ground
	auto pos1 = getPosTable(this);
	auto pos2 = pos1;
	auto pos3 = pos2;
	pos1.x += 130;
	pos2.x += 330;
	pos3.x += 530;
	pos1 = ccpRotateByAngle(pos1, _myPos, _curFacing);
	pos2 = ccpRotateByAngle(pos2, _myPos, _curFacing);
	pos3 = ccpRotateByAngle(pos3, _myPos, _curFacing);
	MageIceSpikes::CreateWithPos(pos1, _curFacing, _specialAttack, this);
	auto spike2 = [&]() {
		experimental::AudioEngine::play2d(MageProperty.specialAttackShout, false, 0.5);
		MageIceSpikes::CreateWithPos(pos2, _curFacing, _specialAttack, this);
	};
	auto spike3 = [&]() {
		experimental::AudioEngine::play2d(MageProperty.specialAttackShout, false, 0.5);
		MageIceSpikes::CreateWithPos(pos3, _curFacing, _specialAttack, this);
	};
	auto wait2 = DelayTime::create(0.25);
	this->runAction(Sequence::create(wait2, CallFunc::create(spike2), wait2->clone(), CallFunc::create(spike3), NULL));
	//this->runAction(Sequence::create(wait3, CallFunc::create(spike3), NULL));
}
Esempio n. 2
0
void f1(CCPoint p1, CCPoint p2, float d, CCPoint *o1, CCPoint *o2)
{
	float l = ccpDistance(p1, p2);
	float angle = fangle(ccpSub(p2, p1));
	*o1 = ccpRotateByAngle(ccp(p1.x + l,p1.y + d), p1, angle);
	*o2 = ccpRotateByAngle(ccp(p1.x + l,p1.y - d), p1, angle);
}
Esempio n. 3
0
	Point Terrain::movingRevision(const Point& last, const Point& updated) {
		CC_UNUSED_PARAM(last);
		if (isInStandGround(updated)) {
			return ccp(0.0f, 0.0f);
		}
		BorderNode* pSgmt = borderEntry;
		Point wallVect, nextWallVect, sgmtStart, sgmtEnd, nextEnd, dividerVect;
		Point revised;
		do {
			sgmtStart = ccp(tileSize * pSgmt->segment.start.col, tileSize * pSgmt->segment.start.row);
			sgmtEnd = ccp(tileSize * pSgmt->segment.end.col, tileSize * pSgmt->segment.end.row);
			nextEnd = ccp(tileSize * pSgmt->next->segment.end.col, tileSize * pSgmt->next->segment.end.row);
			wallVect = ccpRotateByAngle(sgmtEnd - sgmtStart, ccp(0, 0), CC_DEGREES_TO_RADIANS(-90));
			nextWallVect = ccpRotateByAngle(nextEnd - sgmtEnd, ccp(0, 0), CC_DEGREES_TO_RADIANS(-90));
			if (ccpCross(sgmtEnd - sgmtStart, nextEnd - sgmtEnd) > 0) // 凸角
			{
				if (pointOnLineSide(updated, sgmtStart, sgmtEnd) == POS_ON_THE_RIGHT
					&& pointOnLineSide(updated, sgmtStart, sgmtStart + wallVect) == POS_ON_THE_LEFT
					&& pointOnLineSide(updated, sgmtEnd, sgmtEnd + wallVect) == POS_ON_THE_RIGHT)
				{
					// 作个垂线修正..
					revised = sgmtStart + ccpProject(updated - sgmtStart, sgmtEnd - sgmtStart);
					break;
				}
				else if (pointOnLineSide(updated, sgmtEnd, sgmtEnd + wallVect) == POS_ON_THE_LEFT
					&& pointOnLineSide(updated, sgmtEnd, sgmtEnd + nextWallVect) == POS_ON_THE_RIGHT)
				{
					// 修正到当前边末端的凸角点..
					revised = sgmtEnd;
					break;
				}
			}
			else // 凹角
			{
				dividerVect = ccpNormalize(nextEnd - sgmtEnd) - ccpNormalize(sgmtEnd - sgmtStart);
				if (pointOnLineSide(updated, sgmtStart, sgmtEnd) == POS_ON_THE_RIGHT
					&& pointOnLineSide(updated, sgmtStart, sgmtStart + wallVect) == POS_ON_THE_LEFT
					&& pointOnLineSide(updated, sgmtEnd, sgmtEnd + dividerVect) == POS_ON_THE_RIGHT)
				{
					// 作个垂线修正..
					revised = sgmtStart + ccpProject(updated - sgmtStart, sgmtEnd - sgmtStart);
					break;
				}
			}
			pSgmt = pSgmt->next;
		} while (pSgmt != borderEntry);
		return (revised - updated);
	}
Esempio n. 4
0
void RippleNode::draw()
{
    CCNodeRGBA::draw();
    
    ccGLBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
    ccDrawInit();
    
    ccDrawColor4B(getColor().r, getColor().g, getColor().b, getOpacity());
    
    glLineWidth(3.f * SCREEN_SCALE());
    ccPointSize(3.f * SCREEN_SCALE() * 0.5f);
    
    Rig rig;
    rig.reserve(RIG_VERTEXES());
    for(int i = 0; i < RIG_VERTEXES(); i++)
    {
        CCPoint vertex = ccpRotateByAngle(CCPointMake(0, 200.f * SCREEN_SCALE()), CCPointZero, M_PI * 2 * i / RIG_VERTEXES() + getRotation());
        rig.push_back(vertex);
    }
    
    ccDrawPoly(&rig[0], rig.size(), true);
    
    ccDrawPoint(CCPointZero);
    
    ccDrawFree();
    
    ccGLBlendFunc(CC_BLEND_SRC, CC_BLEND_DST);
    
    CC_INCREMENT_GL_DRAWS(1);
}
Esempio n. 5
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);
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
void RigRandom(Rig& targetRig, int vertexes)
{
    //Other implementations can be found at:
    //http://pastebin.com/wdKmSrL3
    
    //Let's create the goal polygon first.
    //Due to preventing intersections, one more vertex maybe created that stated over here.
    unsigned int vertexNum = vertexes;
    
    //Now that we have the number of vertexes, let's create the number of angles needed.
    std::vector<float> angles;
    angles.reserve(vertexNum);
    for(int angleIter = 0; angleIter < vertexNum; angleIter++)
    {
        //angles.push_back(angleIter * (angleSize + CCRANDOM_0_1()));
        angles.push_back(GetRandomAngle());
    }
    
    std::sort(angles.begin(), angles.end());
    
    //Iterate over the angles, create a vertexes stack.
    targetRig.reserve(vertexNum);
    for(std::vector<float>::iterator iter = angles.begin(); iter != angles.end(); iter++)
    {
        float angle = (*iter);
        CCPoint highPoint = ccp(0, RIG_MIN_RADIUS() + (RIG_MAX_RADIUS()-RIG_MIN_RADIUS()) * CCRANDOM_0_1());
        targetRig.push_back(ccpRotateByAngle(highPoint, CCPointZero, angle));
    }
    
    //Make sure the first and last point doesn't intersect.
    for(int i = 0; i < targetRig.size()-1; i++) {
        CCPoint startPoint = targetRig[i];
        CCPoint endPoint = targetRig[i+1];
        if(ccpSegmentIntersect(startPoint, endPoint, targetRig.front(), targetRig.back())) {
            targetRig.push_back(CCPointZero);
            break;
        }
    }
}
Esempio n. 8
0
void CArmySprite::fireBullet(float fEscapeTime)
{
	CCNode *m_pTarget = (CCNode*)(getParent()->getChildByTag(PALYER_TYPE));
	m_fTime += fEscapeTime;
	if (m_sCurData.mKind == AK_MISSILEARMY && m_fTime > 1.5f)
	{
		BULLET_DATA mData;
		mData.mAttack = m_sCurData.mAttack * 2;
		mData.mKind = BK_TARCKROCKET;
		mData.mMoveSpeed = 200.0f;
		mData.mDirection = ccpNormalize(ccpSub(m_pTarget->getPosition(), getPosition()));
		CBullet *pBullet = CBullet::createBullet(ENEMY_BULLET, mData, BK_TARCKROCKET);
		pBullet->setPosition(ccp(getPositionX(), getPositionY()));
		getParent()->addChild(pBullet, ABULLET_ZORDER);
	}
	if (m_fTime > 0.5f)
	{
		if (m_nBulletNum >= 2)
		{
			m_fFireCoolTime = 0.0f;
			m_nBulletNum = 0;
		}
		m_fTime = 0.0f;
		m_nBulletNum ++;
		BULLET_DATA mData;
		mData.mAttack = m_sCurData.mAttack;
		if (m_sCurData.mKind != AK_MISSILEARMY)
		{
			mData.mDirection = ccpNormalize(ccpSub(m_pTarget->getPosition(), getPosition()));
			mData.mKind = BK_ARMY01;
			mData.mMoveSpeed = 300.0f;
			CBullet *pBullet = CBullet::createBullet(ENEMY_BULLET, mData, BK_ARMY01);
			CCPoint mPos = ccpRotateByAngle(ccp(0, -48), ccp(0,0), -CC_DEGREES_TO_RADIANS(m_pTurretSprite->getRotation()));
			pBullet->setPosition(ccp(getPositionX() + mPos.x, getPositionY() + mPos.y));
			getParent()->addChild(pBullet, ABULLET_ZORDER);
		}

	}
}
Esempio n. 9
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);
        }
    }
Esempio n. 10
0
///
//    Update does the work of mapping the texture onto the triangles
//    It now doesn't occur the cost of free/alloc data every update cycle.
//    It also only changes the percentage point but no other points if they have not
//    been modified.
//    
//    It now deals with flipped texture. If you run into this problem, just use the
//    sprite property and enable the methods flipX, flipY.
///
void CCProgressTimer::updateRadial()
{
    if (!m_pSprite) {
        return;
    }
    float alpha = m_fPercentage / 100.f;

    float angle = 2.f*((float)M_PI) * ( m_bReverseDirection ? alpha : 1.0f - alpha);

    //    We find the vector to do a hit detection based on the percentage
    //    We know the first vector is the one @ 12 o'clock (top,mid) so we rotate
    //    from that by the progress angle around the m_tMidpoint pivot
    CCPoint topMid = ccp(m_tMidpoint.x, 1.f);
    CCPoint percentagePt = ccpRotateByAngle(topMid, m_tMidpoint, angle);


    int index = 0;
    CCPoint hit = CCPoint::zero;

    if (alpha == 0.f) {
        //    More efficient since we don't always need to check intersection
        //    If the alpha is zero then the hit point is top mid and the index is 0.
        hit = topMid;
        index = 0;
    } else if (alpha == 1.f) {
        //    More efficient since we don't always need to check intersection
        //    If the alpha is one then the hit point is top mid and the index is 4.
        hit = topMid;
        index = 4;
    } else {
        //    We run a for loop checking the edges of the texture to find the
        //    intersection point
        //    We loop through five points since the top is split in half

        float min_t = FLT_MAX;

        for (int i = 0; i <= kProgressTextureCoordsCount; ++i) {
            int pIndex = (i + (kProgressTextureCoordsCount - 1))%kProgressTextureCoordsCount;

            CCPoint edgePtA = boundaryTexCoord(i % kProgressTextureCoordsCount);
            CCPoint edgePtB = boundaryTexCoord(pIndex);

            //    Remember that the top edge is split in half for the 12 o'clock position
            //    Let's deal with that here by finding the correct endpoints
            if(i == 0){
                edgePtB = ccpLerp(edgePtA, edgePtB, 1-m_tMidpoint.x);
            } else if(i == 4){
                edgePtA = ccpLerp(edgePtA, edgePtB, 1-m_tMidpoint.x);
            }

            //    s and t are returned by ccpLineIntersect
            float s = 0, t = 0;
            if(ccpLineIntersect(edgePtA, edgePtB, m_tMidpoint, percentagePt, &s, &t))
            {

                //    Since our hit test is on rays we have to deal with the top edge
                //    being in split in half so we have to test as a segment
                if ((i == 0 || i == 4)) {
                    //    s represents the point between edgePtA--edgePtB
                    if (!(0.f <= s && s <= 1.f)) {
                        continue;
                    }
                }
                //    As long as our t isn't negative we are at least finding a
                //    correct hitpoint from m_tMidpoint to percentagePt.
                if (t >= 0.f) {
                    //    Because the percentage line and all the texture edges are
                    //    rays we should only account for the shortest intersection
                    if (t < min_t) {
                        min_t = t;
                        index = i;
                    }
                }
            }
        }

        //    Now that we have the minimum magnitude we can use that to find our intersection
        hit = ccpAdd(m_tMidpoint, ccpMult(ccpSub(percentagePt, m_tMidpoint),min_t));

    }


    //    The size of the vertex data is the index from the hitpoint
    //    the 3 is for the m_tMidpoint, 12 o'clock point and hitpoint position.

    bool sameIndexCount = true;
    if(m_nVertexDataCount != index + 3){
        sameIndexCount = false;
        CC_SAFE_FREE(m_pVertexData);
        m_nVertexDataCount = 0;
    }


    if(!m_pVertexData) {
        m_nVertexDataCount = index + 3;
        m_pVertexData = (ccV2F_C4B_T2F*)malloc(m_nVertexDataCount * sizeof(ccV2F_C4B_T2F));
        CCAssert( m_pVertexData, "CCProgressTimer. Not enough memory");
    }
    updateColor();

    if (!sameIndexCount) {

        //    First we populate the array with the m_tMidpoint, then all
        //    vertices/texcoords/colors of the 12 'o clock start and edges and the hitpoint
        m_pVertexData[0].texCoords = textureCoordFromAlphaPoint(m_tMidpoint);
        m_pVertexData[0].vertices = vertexFromAlphaPoint(m_tMidpoint);

        m_pVertexData[1].texCoords = textureCoordFromAlphaPoint(topMid);
        m_pVertexData[1].vertices = vertexFromAlphaPoint(topMid);

        for(int i = 0; i < index; ++i){
            CCPoint alphaPoint = boundaryTexCoord(i);
            m_pVertexData[i+2].texCoords = textureCoordFromAlphaPoint(alphaPoint);
            m_pVertexData[i+2].vertices = vertexFromAlphaPoint(alphaPoint);
        }
    }

    //    hitpoint will go last
    m_pVertexData[m_nVertexDataCount - 1].texCoords = textureCoordFromAlphaPoint(hit);
    m_pVertexData[m_nVertexDataCount - 1].vertices = vertexFromAlphaPoint(hit);

}
Esempio n. 11
0
///***************************************************************************************
/// CalcIK_2D_CCD
/// Given a bone chain located at the origin, this function will perform a single cyclic
/// coordinate descent (CCD) iteration. This finds a solution of bone angles that places
/// the final bone in the given chain at a target position. The supplied bone angles are
/// used to prime the CCD iteration. If a valid solution does not exist, the angles will
/// move as close to the target as possible. The user should resupply the updated angles 
/// until a valid solution is found (or until an iteration limit is met).
///  
/// returns: CCD_Result.Success when a valid solution was found.
///          CCD_Result.Processing when still searching for a valid solution.
///          CCD_Result.Failure when it can get no closer to the target.
///***************************************************************************************
CCD_Result CalcIK_CCD(Bone *startBone, Bone *endBone, CCPoint &targetPoint, float arrivalDist)
{

	double arrivalDistSqr = arrivalDist * arrivalDist;

	//===
	// Track the end effector position (the final bone)
	CCPoint endPoint = ccp(startBone->m_tWorldTransform.tx, startBone->m_tWorldTransform.ty);
	
	CCPoint currentPoint = ccp(0, 0); 

	//===
	// Perform CCD on the bones by optimizing each bone in a loop 
	// from the final bone to the root bone
	bool modifiedBones = false;

	Bone *currentBone = startBone->getParentBone();
	Bone *lastCurrentBone = startBone;

	while(!currentBone->getParentBone() == NULL)
	{
		currentPoint = ccp(currentBone->m_tWorldTransform.tx, currentBone->m_tWorldTransform.ty);

		// Get the vector from the current bone to the end effector position.
 		double curToEndX = endPoint.x - currentPoint.x;
		double curToEndY = endPoint.y - currentPoint.y;
		double curToEndMag = ccpDistance(endPoint, currentPoint);

		// Get the vector from the current bone to the target position.
		double curToTargetX = targetPoint.x - currentPoint.x;
		double curToTargetY = targetPoint.y - currentPoint.y;
		double curToTargetMag = ccpDistance(targetPoint, currentPoint);

		// Get rotation to place the end effector on the line from the current
		// joint position to the target postion.
		double cosRotAng;
		double sinRotAng;
		double endTargetMag = (curToEndMag*curToTargetMag);
		if( endTargetMag <= epsilon )
		{
			cosRotAng = 1;
			sinRotAng = 0;
		}
		else
		{
			cosRotAng = (curToEndX*curToTargetX + curToEndY*curToTargetY) / endTargetMag;
			sinRotAng = (curToEndX*curToTargetY - curToEndY*curToTargetX) / endTargetMag;
		}

        
		// Clamp the cosine into range when computing the angle (might be out of range
		// due to floating point error).
		double rotAng = acos( MAX(-1, MIN(1, cosRotAng) ) );
		if( sinRotAng < 0.0 )
			rotAng = -rotAng;

		// Rotate the end effector position.
		endPoint.x = currentPoint.x + cosRotAng*curToEndX - sinRotAng*curToEndY;
		endPoint.y = currentPoint.y + sinRotAng*curToEndX + cosRotAng*curToEndY;

#if CS_DEBUG_FOR_EDIT
		// Rotate the current bone in local space (this value is output to the user)
		if (dynamic_cast<EditorTween*>(currentBone->getTween()) != 0)
		{


			EditorTween *tween = ((EditorTween*)currentBone->getTween());

			if(currentBone == endBone || currentBone->getChildren()->count() > 1)
			{
				CCPoint p = ccpRotateByAngle(ccp(lastCurrentBone->m_tWorldTransform.tx, lastCurrentBone->m_tWorldTransform.ty), currentPoint, rotAng);

				((EditorDisplayManager*)currentBone->getDisplayManager())->convertPointToSpace(p);

				((EditorTween*)lastCurrentBone->getTween())->editPosition(p.x, p.y);
			}
			else
			{
				rotAng = tween->getRotation() - rotAng;
				rotAng = simplifyAngle(rotAng);

				((EditorTween*)currentBone->getTween())->editRotation(rotAng);
			}



		}
		else
		{
// 			if(currentBone == endBone || currentBone->getChildren()->count() > 1)
// 			{
// 				CCPoint p = rotatePointByPoint(currentPoint, ccp(lastCurrentBone->m_tWorldTransform.tx, lastCurrentBone->m_tWorldTransform.ty), rotAng);
// 				lastCurrentBone->setPosition(p.x, p.y);
// 			}
// 			else
// 			{
// 				currentBone->setRotation(simplifyAngle(currentBone->getRotation() - rotAng));
// 			}
			
		}
#endif
		

		// Check for termination
		double endToTargetX = (targetPoint.x-endPoint.x);
		double endToTargetY = (targetPoint.y-endPoint.y);
		if( endToTargetX*endToTargetX + endToTargetY*endToTargetY <= arrivalDistSqr )
		{
			// We found a valid solution.
			return Success;
		}

		// Track if the arc length that we moved the end effector was
		// a nontrivial distance.
		if( !modifiedBones && fabsf(rotAng)*curToEndMag > trivialArcLength )
		{
			modifiedBones = true;
		}

		if (currentBone == endBone || currentBone->getChildren()->count() > 1)
		{
			break;
		}

		lastCurrentBone = currentBone;
		currentBone = currentBone->getParentBone();
	}


	// We failed to find a valid solution during this iteration.
	if( modifiedBones )
		return Processing;
	else
		return Failure;

}