帮助移动CGPoint(cocos2d)

时间:2011-04-19 16:00:42

标签: cocos2d-iphone

我不知道如何解释我想要做的最好的方法,但我会试一试。 所以我在屏幕上有一个足球,当我触摸屏幕时,我可以将手指拖过屏幕,通过使用CCProgressTimer,我可以看到投掷​​的力量。换句话说,就像在屏幕上有一个音量条,当我触摸屏幕并从音量条拖出时,它开始增加,向音量条拖动会减小它。所以我的问题是,当我触摸屏幕时,我正在记录我的触摸,而触摸是所有计算所依据的,但是我想要一些如何能够无论我在屏幕上的哪个位置都能够减少或增加。它现在的工作方式是,我无法开始降低投掷的力量,直到我达到记录的触摸。是否有可能让它工作,当电源处于%100时,无论我在屏幕上的哪个位置,如果我向屏幕上的原始触摸之前向后拖向足球以使其减小。这是我的代码。

    footballPath = [CCProgressTimer progressWithFile:@"footballPath.png"];
            footballPath.visible = NO;
            footballPath.percentage = 0;
            footballPath.type = kCCProgressTimerTypeHorizontalBarLR;
            footballPath.anchorPoint = ccp(0, 0.5);
            [self addChild:footballPath];

-(BOOL)ccTouchBegan:(UITouch*)touch withEvent:(UIEvent *)event {

    cachedTouchPt = [self convertTouchToNodeSpace:touch];

    if (!self.currentFootball.footballHasEmbarked) {
        footballPath.percentage = 0;
        [self updateArrowWithTouch:touch];
        arrow.visible = YES;
        footballPath.visible = YES;

        return YES; 
    }
    else {
        return NO;
    }

}

-(void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event {

    [self updateArrowWithTouch:touch];

}

-(void) ccTouchEnded:(UITouch*)touch withEvent:(UIEvent *)event {

    const float max = 100;
    CGPoint touchPt = [self convertTouchToNodeSpace:touch];
    if (touchPt.x > self.currentFootball.position.x) {
        touchPt = ccp(self.currentFootball.position.x, touchPt.y);
    }

    arrow.visible = NO;
    footballPath.visible = NO;
    self.currentFootball.footballHasEmbarked = YES;
    self.currentFootball.spiraling = YES;

    if (self.currentFootball) {
        [smgr morphShapeToActive:self.currentFootball.shape mass:25];
    }

    diff = ccpSub(touchPt, self.currentFootball.position);

    if (diff.x == 0 && diff.y == 0) {
        diff = ccp(1, 1);
    }
    float len = footballPath.percentage;
    CGPoint norm = ccpNormalize(diff);

    if (len > max){
        len = max;
    }

    [self.currentFootball applyImpulse:ccpMult(norm, (len * 245))];

    pos = self.currentFootball.position.y;

    [self schedule:@selector(newFootball)]; 

}

- (void) updateArrowWithTouch: (UITouch*) touch {

    const float distFromFb = 100;
    CGPoint touchPt = [self convertTouchToNodeSpace:touch];
    if (touchPt.x > self.currentFootball.position.x) {
        touchPt = ccp(self.currentFootball.position.x, touchPt.y);
    }

    CGPoint fpt = self.currentFootball.position;

    CGPoint vect = ccpSub(touchPt, fpt);
    float dist = ccpLength(vect);
    CGPoint vect2 = ccpSub(touchPt, cachedTouchPt);
    float dist2 = ccpLength(vect2);
    float degrees = -CC_RADIANS_TO_DEGREES(ccpToAngle(vect));
    float factor = dist2;
    CGPoint normalVect = ccpMult(vect, 1/dist);

    factor = distFromFb;

    CGPoint newPoint = ccpAdd(fpt, ccpMult(normalVect, factor));
    if (newPoint.x < self.currentFootball.position.x+1) {
        arrow.rotation = degrees; 
        arrow.position = newPoint;

        self.currentFootball.rotation = -CC_RADIANS_TO_DEGREES (ccpToAngle(ccpSub(touchPt, self.currentFootball.position)));
        footballPath.rotation = self.currentFootball.rotation;
        footballPath.position = fpt;
    }   

    float percentage = dist - ccpLength(ccpSub(cachedTouchPt, self.currentFootball.position));

    if (percentage < 0.0f){

        percentage = 0.0f;
    }

//  CCLOG(@"cachedDist = %f", cachedDist);
    CCLOG(@"percentage = %f", percentage);

        diff = vect2;
        footballPath.percentage = percentage;

}

cachedTouchPt = [self convertTouchToNodeSpace:touch];是我所说的原始点。因此,当我触摸屏幕时,它会创建一个新点并将其存储在cachedTouchPt中,因此在达到cachedTouchPt的X和Y之前,我无法降低功率/ CCProgressTimer。如果我没有理解我想说的话。我需要能够降低功率/ CCProgressTimer而无需处于原始点。有没有办法重置这一点,这样无论我在屏幕上的哪个位置,我都可以向足球方向拖动,让它减少,与增加相同。

1 个答案:

答案 0 :(得分:0)

我会通过向您展示数学来回答您的问题,但您需要自己将其转换为代码。

首先,你需要决定(你可能已经做过)触摸需要移动多长时间(以点为单位)以将掷骰的力量从0增加到1.让我们将此值称为D.

然后,让我们将触摸开始的坐标称为Tx和Ty。

然后,当触摸移动到新坐标Ux和Uy时,您使用公式触摸距离(Tx,Ty)的距离:

E = sqrt( pow( Ux - Tx, 2 ) + pow( Uy - Ty, 2 ) )

然后使用公式计算功率:

P = E / D

到目前为止,我认为您的代码已经在进行所有这些计算。但接下来会发生的事情是,如果玩家仍然触摸距离触摸开始点超过距离D,也就是说E > D,那么你将如何处理。

首先,放一个IF块:

if (E > D) { ... }

所以,现在你要修改Tx和Ty值(即触摸开始点),以便从当前触摸位置到该坐标的距离为D.这是神奇的公式:

angle = atan2( Uy - Ty, Ux - Tx )
Ty = Uy - D * sin( angle )
Tx = Ux - D * cos( angle )

此时您可能希望将功率值修改为1:

P = 1
E = D

就是这样!公式将触摸开始点移动到当前触摸位置以保持E <= D的条件。当然,玩家将触摸移动到触摸开始点的情况也是如此。

祝你好运!