c#-等待MoveTo *** 作完成的正确方法是什么?

c#-等待MoveTo *** 作完成的正确方法是什么?,第1张

概述我使用CocosSharp创建了一个本质上是糖果迷恋的应用程序,这是我第一次真正使用的东西,与C#和Xamarin相同.为了执行动画,我使用了提供的MoveTo方法,但是我不确定在继续执行代码之前应该如何等待动画完成.目前,我正在使用awaitTask.Delay()结合while循环来完成此 *** 作,但是这种“感觉

我使用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 *** 作完成的正确方法是什么?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1120797.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存