2010-07-13 113 views
0

我有一個精靈(一個球的圖像),我可以使用觸摸和移動來移動它。我還根據滑動週期確定了該精靈的位置(x軸,y軸)的變化率。ipad:如何通過滑動移動精靈,並根據滑動速度繼續前進

現在我需要繼續按照它的速度和方向繼續這個精靈。這裏是我的代碼 -

Touch Event 

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

    CGPoint location = [touch locationInView: [touch view]]; 
    CGPoint convertedLocation = [[CCDirector sharedDirector] convertToGL:location]; 

    self.touchStartTime = [event timestamp]; 
    self.touchStartPosition = location; 

    if (YES == [self isItTouched:self.striker touchedAt:convertedLocation]) { 
    self.striker.isInTouch = YES; 
    } 

    return YES; 
} 

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

    CGPoint location = [touch locationInView: [touch view]]; 
    CGPoint convertedLocation = [[CCDirector sharedDirector] convertToGL:location]; 

    self.touchLastMovedTime = [event timestamp]; 
    self.touchMovedPosition = convertedLocation; 


    if(self.striker.isInTouch == YES){ 
    self.striker.position = self.touchMovedPosition; 
    } 

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

    CGPoint location = [touch locationInView: [touch view]]; 
    CGPoint convertedLocation = [[CCDirector sharedDirector] convertToGL:location]; 

    self.touchEndTime = [event timestamp]; 
    self.touchEndPosition = location; 

    if(self.striker.isInTouch == YES 
    && (self.touchEndTime - self.touchLastMovedTime) <= MAX_TOUCH_HOLD_DURATION) 
    { 
    float c = sqrt(pow(self.touchStartPosition.x - self.touchEndPosition.x, 2) 
     + pow(self.touchStartPosition.y - self.touchEndPosition.y, 2)); 

    self.striker.speedx = (c - (self.touchStartPosition.y - self.touchEndPosition.y)) 
         /((self.touchEndTime - self.touchStartTime) * 1000); 

    self.striker.speedy = (c - (self.touchStartPosition.x - self.touchEndPosition.x)) 
      /((self.touchEndTime - self.touchStartTime) * 1000); 

    self.striker.speedx *= 4; 
    self.striker.speedy *= 4; 

    self.striker.isInTouch = NO; 
    [self schedule:@selector(nextFrame) interval:0.001]; 

    } 

} 

Scheduled Method to move Sprite 

- (void) nextFrame { 

    [self setPieceNextPosition:self.striker]; 
    [self adjustPieceSpeed:self.striker]; 

    if(abs(self.striker.speedx) <= 1 && abs(self.striker.speedy) <= 1){ 
    [self unschedule:@selector(nextFrame)]; 
    } 
} 

SET next Position 

- (void) setPieceNextPosition:(Piece *) piece{ 

    CGPoint nextPosition; 
    float tempMod; 
    tempMod = (piece.position.x + piece.speedx)/SCREEN_WIDTH; 
    tempMod = (tempMod - (int)tempMod)*SCREEN_WIDTH; 
    nextPosition.x = tempMod; 

    tempMod = (piece.position.y + piece.speedy)/SCREEN_HEIGHT; 
    tempMod = (tempMod - (int)tempMod)*SCREEN_HEIGHT; 
    nextPosition.y = tempMod; 

    piece.position = nextPosition; 
} 

Set new Speed 

- (void) adjustPieceSpeed:(Piece *) piece{ 

    piece.speedx =(piece.speedx>0)? piece.speedx-0.05:piece.speedx+0.05; 
    piece.speedy =(piece.speedy>0)? piece.speedy-0.05:piece.speedy+0.05; 
} 

雖然,目前我使用靜態速度調整技術,但我希望讓它動視初始速度(我明白任何想法)

+0

爲進一步信息,請讓我知道 – Sadat 2010-07-13 08:46:54

回答

0

謝謝@all。 我有我的解決方案,如下─

//in adjustSpeed method 
    piece.speedx -= piece.speedx * DEACCLERATION_FACTOR; 
    piece.speedy -= piece.speedy * DEACCLERATION_FACTOR; 

//and simply, free the sprite to move from ccTouchMoved method not ccTouchEnd 
    if(self.striker.isInTouch == YES && distance_passed_from_touch_start>=a_threashold){ 
    //calculate speed and position here as it was in ccTouchEnd method 
    self.striker.isInTouch = NO; 
    [self schedule:@selector(nextFrame) interval:0.001]; 

    } 
0

看起來你有它八九不離十。您正在調度觸摸板上的選擇器,計算速度,並根據該速度移動精靈,直到它消失,所以所有機械碎片都在那裏。

看起來iffy是物理學。例如,你用速度來做一些奇怪的事情來減慢球的速度,這些球看起來並不現實。

你想要做的是找到手指擡起時精靈的「速度矢量」。雖然你可以嘗試爲此做一個瞬間速度,但我發現它可以更好地回溯到幾個週期,並對它們進行平均以獲得最終速度。

然後,一旦你已經得到了矢量(它看起來像一個x和y的速度,像你現在),你想要做這樣的事情(提前未經考驗的僞代碼),以抑制速度:

float speed = sqrt(speedx * speedx + speedy * speedy); 
if (speed == 0) { 
    // kill motion here, unschedule or do whatever you need to 
} 
// Dampen the speed. 
float newSpeed = speed * .9; 
if (newSpeed < SOME_THRESHOLD) newSpeed = 0; 
speedx = speedx * newSpeed/speed; 
speedy = speedy * newSpeed/speed; 
// Move sprite according to the new speed 

這樣可以使球沿着與釋放時相同的方向運動,逐漸減速直至停止。欲瞭解更多信息,特別是如果你想做一些反彈或任何事情,谷歌的矢量代數的介紹。

+0

感謝@cc,我會盡快嘗試,讓你知道。 – Sadat 2010-07-14 05:51:08

+0

@cc如果我沒看錯,這類似於 「 speedx = speedx * 0.9; 快速=快速* 0.9; 」 那麼我爲什麼要使用newSpeed還是那些計算? 請讓我知道如果你有任何其他解釋。 – Sadat 2010-07-14 06:02:09

+0

除了您想要知道當前速度的部分以便將速度降至明確爲零以外,情況並不相同。通常,當你從「非零速度」轉變爲「零速度」時,你會想做一些特殊的事情,所以這就是我一直使用的框架。在上面的例子中,我只是將速度設置爲零,但是很可能,您還將不想調度您選擇的選擇器或設置其他「靜止」標誌。當然,你可以用「如果speedx 2010-07-14 23:13:28