Помогите с перемещением CGPoint (cocos2d) - PullRequest
0 голосов
/ 19 апреля 2011

Я не знаю, как лучше всего объяснить, что я пытаюсь сделать, но я попробую. Итак, у меня есть футбольный мяч на экране, и когда я касаюсь экрана, я могу провести пальцем по экрану, который с помощью 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, и поэтому я не могу уменьшить power / CCProgressTimer, пока не достигну X и Y cachedTouchPt. Если бы я не понимал, что я пытался сказать. Мне нужно иметь возможность уменьшить мощность / CCProgressTimer без необходимости быть в исходной точке. Есть ли способ сбросить точку так, чтобы независимо от того, где я нахожусь на экране, я мог перетащить мяч в сторону футбола и уменьшить его, так же, как и при увеличении.

1 Ответ

0 голосов
/ 20 апреля 2011

Я отвечу на ваш вопрос, показывая вам математику, но вам нужно преобразовать ее в коды самостоятельно.

Во-первых, вам нужно решить (вы, вероятно, сделали), как долго (в пунктах) нужно перемещать касание, чтобы увеличить силу броска с 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. Естественно, случай, когда игрок перемещает касание к точке начала касания, рассматривается.

Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...