2014-01-04 4 views
0

Я знаю, что это было задано много раньше, но я не могу найти решение. У меня есть CCSprite на экране, плеер, который управляется акселерометром. Затем поверх экрана другие CCSprites разворачиваются каждые 2 секунды, враги. Я хочу, чтобы все враги следовали за игроком, если игрок перемещает игрока, враги должны менять направление и идти к этому CCSprite. Это мой код далеко:Сделать CCSprite двигаться в направлении другого CCSprite

- (void)spawnEnemies 
{ 
    monsterTxt = [[CCTexture2D alloc] initWithCGImage:[UIImage imageNamed:@"obj.png"].CGImage resolutionType:kCCResolutionUnknown]; 
    monster = [CCSprite spriteWithTexture:monsterTxt]; 

    ... 
    //random spawn position etc. 


    CCMoveTo *movemonster = [CCMoveTo actionWithDuration:7.0 position:ccp(_rocket.boundingBox.origin.x, _rocket.boundingBox.origin.y)]; 
    [monster runAction:[CCSequence actions:movemonster, nil]]; 

    [_monsters addObject:monster]; //adds the sprite to a mutable array     
} 

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration 
{ 
    ... 
    //determines new position and move sprite there 

    [monster stopAllActions]; 

    CCMoveTo *movemonster = [CCMoveTo actionWithDuration:7.0 position:ccp(_rocket.boundingBox.origin.x, _rocket.boundingBox.origin.y)]; 
    [monster runAction:[CCSequence actions:movemonster, nil]]; 

} 

Теперь, когда я начинаю игру спрайты собираются к игроку, но когда игрок перемещает врагов не обновляет их назначения, они просто продолжают вниз и останавливается на y-координата игрока. И через некоторое время приложение падает. Что я делаю не так?

+0

1. Вы уверены, что ваш метод adAccelerate вызывается? 2.Вы действительно должны внести изменения в действия в функции обновления ... сохранить данные из обратного вызова didAccelerate в переменной класса. Вы можете получать много звонков, чтобы делатьAccelerate. – FuzzyBunnySlippers

+0

Если ваш блок CCCallBlockN выполняет «некоторое время спустя», откуда вы получаете «монстра» из вашего метода didAccelerate. Похоже, что блок удаляет его из родителя ..., который отменит его. Если бы вы получили доступ к нему в didAccelerate, он бы все еще существовал (не могу сказать, что я вижу здесь). – FuzzyBunnySlippers

+0

жаль, что я наклеил старый код. Этот блок не должен быть там вообще. Но это ничего не меняет, просто враги останавливаются на игроках y-value. – user3139210

ответ

0

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

В v2.1 от Cocos2d, чтобы получить измерения акселерометра в вашем слое:

сделать это в INIT или onEnterTransitionDidFinish вызова:

self.accelerometerEnabled = YES; 

И перегружать является метод:

-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration 
{ 
    CCLOG(@"Acceleration (%f,%f,%f)", 
     acceleration.x, 
     acceleration.y, 
     acceleration.z); 
    // Do something meaningful...you probably want to send a notification to 
    // some other scene/layer/logic. It should cache that the acceleration value 
    // and then do something on an update(...) call with it. Then reset it so that 
    // it does not get used the next update cycle untila new value comes in (here). 
} 

Кажется, у вас есть это ... и вы указали, что получаете их ... так что я немного смущен.

SO (SANITY ПРОВЕРКА ВРЕМЯ) ...

Я создал пример проект (here), который имеет одиночный спрайт гонится несколько спрайтами монстров. Когда пользователь прикасается к экрану (я не использовал акселерометр), игровой спрайт меняет место, а спрайты «преследуют» его. Я добавил случайное смещение к их целевым позициям, чтобы они не все кластеры поверх игрока.

Вот код (наиболее важные части) файл, который представляет собой модифицированный вариант HellowWorldLayer, который поставляется с проектом cocos2d v2.1 (я создал его из шаблона):

-(void)createPlayer 
{ 
    playerMoved = NO; 

    if(self.player != nil) 
    { 
     [self removeChild:player]; 
     self.player = nil; 
    } 
    CGSize scrSize = [[CCDirector sharedDirector] winSize]; 
    CCSprite* playerSprite = [CCSprite spriteWithFile:@"Icon.png"]; 
    playerSprite.scale = 2.0; 
    playerSprite.position = ccp(scrSize.width/2,scrSize.height/2); 
    [self addChild:playerSprite]; 
    self.player = playerSprite; 
} 

-(void)createMonsters 
{ 
    const int MAX_MONSTERS = 4; 
    if(self.monsters.count > 0) 
    { // Get rid of them 
     for(CCSprite* sprite in monsters) 
     { 
     [self removeChild:sprite]; 
     } 
     [self.monsters removeAllObjects]; 
    } 
    CGSize scrSize = [[CCDirector sharedDirector] winSize]; 
    for(int idx = 0; idx < MAX_MONSTERS; idx++) 
    { 
     CCSprite* sprite = [CCSprite spriteWithFile:@"Icon.png"]; 
     float randomX = (arc4random()%100)/100.0; 
     float randomY = (arc4random()%100)/100.0; 
     sprite.scale = 1.0; 
     sprite.position = ccp(scrSize.width*randomX,scrSize.height*randomY); 
     [self addChild:sprite]; 
     [monsters addObject:sprite]; 
    } 
} 

-(void)update:(ccTime)delta 
{ 
    if(playerMoved) 
    { // Modify all the actions on all the monsters. 
     CGPoint playerPos = player.position; 
     for(CCSprite* sprite in monsters) 
     { 
     float randomX = (1.0)*(arc4random()%50); 
     float randomY = (1.0)*(arc4random()%50); 
     CGPoint position = ccp(playerPos.x+randomX,playerPos.y+randomY); 
     [sprite stopAllActions]; 
     [sprite runAction:[CCMoveTo actionWithDuration:3.0 position:position]]; 
     } 
     playerMoved = NO; 
    } 
} 

У меня есть сохраненный массив объектов CCSprite * (монстров) и CCSprite * для игрока. У меня есть флаг, чтобы сказать мне, изменился ли игрок (перемещен игрок). В цикле обновления, если игрок переместился, остановите все действия над монстрами и обновите их.

На экране это выглядит следующим образом:

enter image description here

А потом, когда я двигаюсь главный спрайт ...

enter image description here

Они следуют за это ...

enter image description here

Было ли это полезно?

+0

Это работает, но я хочу, чтобы подвижный спрайт управлялся с помощью джойстика (Sneakiness/sneakinput). Я удалил touchlayers и те 2 последних метода в helloWorldLayer.m och вместо этого связал спрайт с джойстиком. Теперь враги просто перемещаются в первое место, но затем они не двигаются. Я попытался создать свойство 'playerMoved' bool a и присвоить его' YES' в классе джойстика в 'ccTouchesBegan', но враги все еще не анимируются больше, чем в первый раз. – user3139210

+0

@ user3139210 Если вы берете код, который я разместил, и изменяйте его, чтобы позиция менялась с использованием скрытого ввода вместо нажатия пальца, он должен работать. В вашем методе «Обновить», если джойстик поднят, увеличьте y позицию на N единиц и установите ее. Аналогично для других направлений. – FuzzyBunnySlippers

+0

ok, но где бы я положил 'playerMoved = YES'? Спасибо за вашего пациента – user3139210

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