我使用CocosSharp创建了一个本质上是糖果迷恋的应用程序,这是我第一次真正使用的东西,与C#和Xamarin相同.为了执行动画,我使用了提供的Moveto方法,但是我不确定在继续执行代码之前应该如何等待动画完成.目前,我正在使用await Task.Delay()结合while循环来完成此 *** 作,但是这种“感觉”并看起来“肮脏”.我想知道等待动画完成的正确方法是什么?
这是我编写的一些代码:
// Checks to see if a swap is possible, if it is then it will do so // otherwise it will call for a Failed swap animation public async voID trySwap(int horzDelta, int vertDelta, int fromrow, int fromCol) { //deBUGLabel.Text = "checking to see if a swap is possible."; int toRow = fromrow + vertDelta; int toCol = fromCol + horzDelta; // Make sure that the user dIDn't swipe out of the grID as there isn't any candIEs to swap with out there if (toRow < 0 || toRow >= grIDRows) { return; } if (toCol < 0 || toCol >= grIDColumns) { return; } candy toCandy = candyAt(toRow, toCol); candy fromCandy = candyAt(fromrow, fromCol); //deBUGLabel.Text = "Switching candy at [" + fromrow + ", " + fromCol + "] with candy at [" + toRow + ", " + toCol + "]."; Swap swap = new Swap(); swap.candyA = fromCandy; swap.candyB = toCandy; if (isSwapPossible(swap)) { // Swap them animateSwap(swap); await Task.Delay(300); // Wait for the swap animation to finish before continuing dropped = false; // Sets dropped to false, it will be used to check if the game finished dropPing all of the candIEs filledAgain = false; finishedRemoving = false; do { // My reason to add the while loops with the awaits is that the App seems to come back to this do while even before the // the method completely finish running. I'm guessing that awaits in the methods is forcing the App to continue running while it's awaiting // to continue within the method. It's possible that the called methods are running on a separate threads from the thread that is running this // method, so while those threads are put on hold, the App jumps back to this thread. After putting in while loops the app does seems to work like // I want it to so I'm probably on the right track, thought there must be a better way to accomplish as the current way looks ugly. removeMatches(); // Remove the matches while (!finishedRemoving) { await Task.Delay(50); } dropCandIEs(); // Move the candIEs down while (!dropped) // As long as the dropCandIEs method isn't finished it will keep adding an await { await Task.Delay(50); } fillUpColumns(); // Fill the grID back up while (!filledAgain) { await Task.Delay(50); } detectPossibleSwap(); // Need to update the List of possible swaps await Task.Delay(300); } while (deleteChains.Count != 0); decrementMoves(); // In the case that grID ends up with no possible swaps, we need to refill the grID new candIEs if (possibleSwaps.Count == 0 && movesleft != 0) { reshuffle(); while (!doneshuffling) { await Task.Delay(50); } } } else { // FailedSwapAnimation only needs to run if there's valID candIEs if (swap.candyA != null && swap.candyB != null) { // Swap is not possible so run the Failed swap animation FailedSwapAnimation(swap); // Waiting to make sure the animation has been completed await Task.Delay(300); } else { // The method enables the user interaction again and returns the call point without any type of animation // as the user trIEd to do a swap with an empty location enableListeners(); return; } } // Turn user interaction back on as all of the matches were removed and the grID filled back up if (movesleft != 0) { enableListeners(); } }
这是实际调用Moveto方法的方法:
// Visually animates the swap using the CCMoveto function provIDed by CocosSharp, // also updates the grID location of the candIEs private voID animateSwap(Swap swap) { const float timetoTake = 0.3f; // in seconds CCFiniteTimeAction coreAction = null; // Store the positions of the candIEs to be used to swap them CCPoint positionA = new CCPoint(swap.candyA.position); CCPoint positionB = new CCPoint(swap.candyB.position); // Animate the swapPing of the candIEs coreAction = new CCMoveto(timetoTake, positionB); swap.candyA.AddAction(coreAction); coreAction = new CCMoveto(timetoTake, positionA); swap.candyB.AddAction(coreAction); // Update the row and column positions for each candy swap.candyA.setposition(convertYToRow(positionB.Y), convertXToColumn(positionB.X)); swap.candyB.setposition(convertYToRow(positionA.Y), convertXToColumn(positionA.X)); // Update the position of the candIEs within the grID grID[swap.candyA.getRow(), swap.candyA.getColumn()] = swap.candyA; grID[swap.candyB.getRow(), swap.candyB.getColumn()] = swap.candyB; } // Animation for a Failed swap private async voID FailedSwapAnimation(Swap swap) { const float timetoTake = 0.1f; // in seconds CCFiniteTimeAction coreAction = null; CCFiniteTimeAction secondAction = null; // Store the positions of the candIEs to be used to swap them CCPoint positionA = new CCPoint(swap.candyA.position); CCPoint positionB = new CCPoint(swap.candyB.position); // Animate moving the candIEs back and forth coreAction = new CCMoveto(timetoTake, positionB); secondAction = new CCMoveto(timetoTake, positionA); swap.candyA.RunActions(coreAction, secondAction); coreAction = new CCMoveto(timetoTake, positionA); secondAction = new CCMoveto(timetoTake, positionB); swap.candyB.RunActions(coreAction, secondAction); // Wait for the animation to complete before moving on await Task.Delay(300); } // Method to find all chains in the grID private voID removeMatches() { List<Chain> horizontalChains = detectHorizontalMatches(); List<Chain> verticalChains = detectVerticalMatches(); // Logic to remove the candIEs from the grID goes here, possibly call a method that takes the List of chains to work with // Don't forget that candIEs have to be removed from the grID and then afterwards the Sprites need to be removed from the screen separately // which can be handle by another method foreach (Chain item in verticalChains) { horizontalChains.Add(item); } deleteChains = horizontalChains; removeCandIEs(horizontalChains); } // Remove the candy objects from the screen and the grID private async voID removeCandIEs(List<Chain> chains) { if (finishedRemoving != false) { finishedRemoving = false; } foreach (Chain chain in chains) { foreach (candy candy in chain.candIEs) { // Remove the candy from the grID grID[candy.getRow(), candy.getColumn()] = null; CCSprite removeCandy = candy.getSprite(); if (removeCandy != null) { const float timetoTake = 0.3f; // in seconds CCFiniteTimeAction coreAction = null; CCAction easing = null; coreAction = new CCScaleto(timetoTake, 0.3f); easing = new CCEaSEOut(coreAction, 0.1f); removeCandy.RunAction(coreAction); await Task.Delay(50); // Wait for the scaling animation to show a bit before continuing on to remove the candy //pointGone = false; //pointLabel(candy.getRow(), candy.getColumn()); //while (!pointGone) //{ // await Task.Delay(1); //} removeCandy.RemoveFromParent(); // This should remove the candy from the screen handlePoints(); } } // Wait for all of the candIEs to be removed before moving on to the next chain in the List of chains await Task.Delay(300); } // Since the method is finished removing all of chains, needed to set the finishedRemoving bool variable to true // so the calling method can get out of it's await loop finishedRemoving = true; } // Drops the candIEs down private async voID dropCandIEs() { // Makes sure that dropped bool variable is set false before continuing if (dropped != false) { dropped = false; } for (int col = 0; col < grIDColumns; coL++) { for (int row = 8; row > 0; row--) { if (level.tiles[row, col] == 1) { candy Candy = candyAt(row, col); if (Candy == null) { // Find which row number to drop the candy from int tempRow = row - 1; while (tempRow >= 0 && grID[tempRow, col] == null) { tempRow--; } // Only runs if there's a row that has a candy in it if (tempRow >= 0) { CCPoint position = new CCPoint(70 + (62 * col), 810 - (70 * row)); Candy = candyAt(tempRow, col); Candy.AddAction(new CCEaSEOut(new CCMoveto(0.3f, position), 0.3f)); Candy.setposition(row, col); // Update the row and column of the candy grID[row, col] = Candy; // Update the position of the candy within the grID grID[tempRow, col] = null; // Wait for the candy to drop before moving to on the next candy await Task.Delay(50); } } } } } // Since the method should have gone through the entire grID and finished dropPing the candIEs // need to set dropped to true so the calling method can get out of the await loop dropped = true; } // Fill the holes at the top of the of each column private voID fillUpColumns() { int candyType = 0; if (filledAgain != false) { filledAgain = false; } for (int col = 0; col < grIDColumns; coL++) { // Starting at the top and working downwards, add a new candy where it's needed for (int row = 0; row < grIDRows && grID[row, col] == null; row++) { if (level.tiles[row, col] == 1) { int newCandyType = 0; // Have to first create a new candy outsIDe of the while loop or otherwise the IDE won't let me use the variable newCandy // as it will be seen as using an unassigned variable, even though it will be assigned a new candy in the while loop candy newCandy = new candy(rand, row, col); newCandyType = newCandy.getType(); // Make sure that each candy that is being added isn't the same as the one that was added prevIoUsly while (newCandyType == candyType) { newCandy = new candy(rand, row, col); newCandyType = newCandy.getType(); } candyType = newCandyType; grID[row, col] = newCandy; // Once all of the candy is created to fill the grID back up // Use an animation to add it to the screen animateAddingNewCandIEs(row, col); } } } // Since the entire grID was filled back up with candIEs, need to set the filledAgain bool variable to true // so the calling method can get out the await loop filledAgain = true; }
对于那些希望查看完整代码以更好地理解问题的人,我可以在此处发布github链接.我现在不包括它,因为我不确定是否真正允许这样做.对某些评论感到抱歉,因为其中一些只是我当时写下的想法.
解决方法:
我将使用CCMoveto和CCCallFunc的序列
var moveAction = new CCMoveto(1.0f, someplace);var moveCompletedAction = new CCCallFunc(this.FunctionToCallWhenMoveIsComplete);CCSequence mySequence = new CCSequence(moveAction, moveCompletedAction);mysprite.RunAction(mySequence);....voID FunctionToCallWhenMoveIsComplete (){ // run your post move code here}
总结 以上是内存溢出为你收集整理的c#-等待MoveTo *** 作完成的正确方法是什么?全部内容,希望文章能够帮你解决c#-等待MoveTo *** 作完成的正确方法是什么?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)