2014-12-24 5 views
0

Можете ли вы, ребята, сказать мне, как я могу выполнить функцию updateTiles() ТОЛЬКО после завершения действий всех узлов в функции slideTiles (String s)? Я попытался добавить некоторый цикл while, но он замораживает всю программу. После запуска функций один за другим анимация просто не появляется.Как выполнять функцию ТОЛЬКО после завершения всех действий в Cocos2d

public boolean ccTouchesEnded(MotionEvent event) 
{ 
CGPoint location = CCDirector.sharedDirector().convertToGL(CGPoint.ccp(event.getX(), event.getY())); 
x2=location.x; y2=location.y; 

float diffY = y1-y2; 
float diffX = x1-x2; 

if (Math.abs(diffX)>Math.abs(diffY)&&diffX<0) 
    move="right"; 
else if (Math.abs(diffX)>Math.abs(diffY)&&diffX>=0) 
    move="left"; 
else if (Math.abs(diffX)<=Math.abs(diffY)&&diffY<0) 
    move="up"; 
else if (Math.abs(diffX)<=Math.abs(diffY)&&diffY>=0) 
    move="down"; 

int row=(int)(y1/TILE_SQUARE_SIZE); 
int column=(int)(x1/TILE_SQUARE_SIZE); 

slideTiles(move); 

//wait for animations to finish 
int sum=0; 
boolean actionDone=false; 
while (!actionDone) 
{ 
    for (CCNode c : tilesNode.getChildren()) 
    { 
     sum+=c.numberOfRunningActions(); 
    } 

    //String s=sum+""; 
    //statusLabel.setString(s); 

    if (sum==0){ 
     actionDone=true; 
     break; 
    } 

    sum=0; 
} 

updateTiles(); 




return true; 
} 

//////

public void slideTiles(String move) 
{ 
// Increment the moves label and animate the tile 
CCBitmapFontAtlas moveslabel = (CCBitmapFontAtlas) getChildByTag(MOVES_LABEL_TAG); 
moves++; 

    moveslabel.runAction(CCSequence.actions(
      //CCDelayTime.action(0.25f), 
      CCScaleTo.action(0.2f, 6/5f), 
      //CCDelayTime.action(0.25f), 
      CCScaleTo.action(0.2f, 5/6f) 
      )); 
    moveslabel.setString("Moves:\n " + CCFormatter.format("%03d", moves)); 

    if (move.equals("up")) 
    { 
     for (int start=NUM_COLUMNS; start<2*NUM_COLUMNS; start++) 
     for (int y=start; y<NUM_COLUMNS*NUM_ROWS; y+=NUM_COLUMNS) 
     { 
      if (tileNumbers[y]!=EMPTY) 
      { 
       for (int f=start-NUM_COLUMNS; f<y; f+=NUM_COLUMNS) 
       { 
        if (tileNumbers[f]==EMPTY) 
        { 
         //y->f 
         CGPoint moveTo = tilesNode.getChildByTag(f).getPosition(); 
         CCMoveTo movetile = CCMoveTo.action(0.25f, moveTo); 
         CCSequence movetileSeq = CCSequence.actions(movetile);//CCCallFunc.action(this,"stopAction")); 
         tilesNode.getChildByTag(y).runAction(movetileSeq); 

         tileNumbers[f]=tileNumbers[y]; 
         tileNumbers[y]=EMPTY; 

         break; 
        } 
       } 
      } 
     } 
    } 

Edit: Является ли это своего рода решение правильным? Он работает на удивление хорошо.

public boolean ccTouchesEnded(MotionEvent event) 
{ 

... 
... 

slideTiles(move); 

float time = 0.25f+0.05f; //0.25f is time of moveTo action for each tile 
CCDelayTime delay = CCDelayTime.action(time); 
CCCallFunc cA = CCCallFunc.action(this, "updateTiles"); 
CCSequence se = CCSequence.actions(delay, cA); 
runAction(se); 

return true; 

} 

ответ

0

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

Чтобы выполнить эту работу, вы должны использовать Thread.

new Thread(new Runnable() { 
     @Override 
     public void run() { 
      while(true){ 
       //here you wait forever doesn't matter the UI thread. 
       if(everythingDone) {//here to add your condition 
         new Handler().post(new Runable() { 
          @Override 
          public void run() { 
           //Here you can do what you want and will be done in UI Thread 
          } 
         }); 
       } 
      } 
     } 
}).start();