2013-04-25 3 views
0

Привет, хорошие люди переполнения стека Я стою перед вами сегодня с (не очень большой) проблемой cocos2d.Как постоянно проверять столкновения в черепичных тилей в CCMoveTo

Как я могу проверить столкновение WHILE в действии вместо проверки целевой плитки? Я работаю с tilemap, у которого есть мета-слой, где есть мозаичные плитки. Следующий код работает, когда я нажимаю на скользящую плитку, но не тогда, когда я нажимаю на нее, если это произойдет, он просто будет ходить прямо.

В настоящее время я обнаружить столкновения с этим кодом:

-(void)setPlayerPosition:(CGPoint)position { 
CGPoint tileCoord = [self tileCoordForPosition:position]; 
int tileGid = [_meta tileGIDAt:tileCoord]; 
if (tileGid) { 
    NSDictionary *properties = [_tileMap propertiesForGID:tileGid]; 
    if (properties) { 
     NSString *collision = properties[@"Collidable"]; 
     if (collision && [collision isEqualToString:@"True"]) { 
      return; 
     } 
    } 
} 

float speed = 10; 
CGPoint currentPlayerPos = _player.position; 
CGPoint newPlayerPos = position; 
double PlayerPosDifference = ccpDistance(currentPlayerPos, newPlayerPos)/24; 
int timeToMoveToNewPostition = PlayerPosDifference/speed; 
id moveTo = [CCMoveTo actionWithDuration:timeToMoveToNewPostition position:position]; 
[_player runAction:moveTo]; 

//_player.position = position; 
} 

Кстати, это вызывается из этого метода:

-(void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event 
{ 
[_player stopAllActions]; 
CGPoint touchLocation = [touch locationInView:touch.view]; 

touchLocation = [[CCDirector sharedDirector] convertToGL:touchLocation]; 
touchLocation = [self convertToNodeSpace:touchLocation]; 

CGPoint playerPos = _player.position; 
CGPoint diff = ccpSub(touchLocation, playerPos); 

int diffx = diff.x; 
int diffy = diff.y; 
int adiffx = diffx/24; 
int adiffy = diffy/24; //Porque my tile size is 24  

if (abs(diff.x) > abs(diff.y)) { 
    if (diff.x > 0) { 
     playerPos.x = playerPos.x + adiffx * 24; 
    } else { 
     playerPos.x = playerPos.x + adiffx * 24; 
    } 
} else { 
    if (diff.y > 0) { 
     playerPos.y = playerPos.y + adiffy * 24; 
    }else{ 
     playerPos.y = playerPos.y + adiffy * 24; 
    } 
} 
[self setPlayerPosition:playerPos]; 
} 

Я попытался

[self schedule:@selector(setPlayerPosition:) interval:0.5]; 

Без удачи , что сразу же разбило приложение на

NSAssert(pos.x < _layerSize.width && pos.y < _layerSize.height && pos.x >=0 && pos.y >=0, @"TMXLayer: invalid position"); И я не могу обвинить его в сбоях.

Как я могу постоянно проверять наличие столкновений с металлизированными мета-плитами во время работы CCMoveTo?

+0

Вы только проверку плитки в положении прикосновения. Поддерживаете ли вы массив всех плиток? Если это так, тогда вы можете запланировать метод «детектора столкновения», который активно проверяет любые столкновения между игроком и всеми плитками. –

+0

Нет, я не знаю, потому что я не знаю, как: D Можете ли вы просветить меня, отлично @SmugbitStudios –

ответ

0

В вашей инициализации, запланировать метод столкновения обнаружения:

[self schedule:@selector(checkCollisions:)]; 

Затем определить его следующим образом:

-(void)checkCollisions:(ccTime)dt 
{ 
    CGPoint currentPlayerPos = _player.position; 
    CGPoint tileCoord = [self tileCoordForPosition:currentPlayerPos]; 
    int tileGid = [_meta tileGIDAt:tileCoord]; 
    if (tileGid) 
    { 
     NSDictionary *properties = [_tileMap propertiesForGID:tileGid]; 
     if (properties) 
     { 
      NSString *collision = properties[@"Collidable"]; 
      if (collision && [collision isEqualToString:@"True"]) 
      { 
       [_player stopAllActions]; 
       return; 
      } 
     } 
    } 
} 
+0

Отлично, спасибо! Это (kinda) работает!Кроме того, он застревает внутри плитки, когда он сталкивается с ними. Как и на полпути. Любой метод, чтобы просто заставить его не ходить, когда есть что-то на его пути? –

+0

Выполнение этого способа останавливает спрайт только после того, как они находятся внутри стены. – dqhendricks

+0

вы должны проверять столкновение перед тем, как двигаться, и остановить движение, если движение поместит вас внутрь стены. – dqhendricks

-1

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

Я выясню, каково будет потенциальное новое положение, затем я узнаю, какая позиция плитки находится во всех четырех углах спрайта в этом новом положении, затем я просматриваю все плитки, на которых будет находиться спрайт, и если являются обдираемыми, я останавливаю спрайт.

На самом деле я делаю еще один шаг и проверяю, перемещает ли только x, или только y изменяет результаты, а затем переместится в эту позицию, если это произойдет.

+0

Это кажется умным, но я действительно не на уровне, чтобы реализовать свои собственные методы CCMoveTo. Можете ли вы привести пример/объяснить бит больше indepth о том, как начать? –

+0

Я держу это просто, но использую одно комплексное математическое уравнение. Вместо того, чтобы говорить о переходе в позицию foo, я говорю, двигаюсь в направлении foo со скоростью бара. Затем я использую математику для определения того, какая следующая позиция кадров будет основана на направлении и скорости. Как только я узнаю, какова будет новая позиция, я могу проверить упомянутое выше. Кроме того, чтобы ограничить это движение, я говорю о движении в направлении foo со скоростью бара с продолжительностью baz. Затем я отслеживаю общее эллипсовое время и останавливаю движение, как только заданная продолжительность закончена. – dqhendricks

+0

Похоже на умный способ. Вам будет интересно разместить свой код? Пожалуйста: D –

Смежные вопросы