首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Javafx -同步延迟卡翻转

Javafx -同步延迟卡翻转
EN

Stack Overflow用户
提问于 2013-12-28 01:41:29
回答 1查看 329关注 0票数 3

我实际上在做一个记忆游戏,我被困在应该写游戏的地方--游戏的一部分。所以:我有一个Nobjects数组。每个对象都有一个名为cardNum的属性--一个标识符。我认为我应该在这个数组上写一个actionListener,所以当我翻转一个卡片时,它将翻转卡片的cardNum放在一个由两个元素组成的数组中,如果数组的两个元素相等,就会找到一对。问题是,我只是不知道如何得到最后一张翻转卡的cardNum。任何帮助都将不胜感激。

我试过的方式如下:

代码语言:javascript
复制
private void easyGame(Card[] cards) {
    int flippedCards = 0;
    int card1;

    while(flippedCards != 24) {
        for(int i=0; i<cards.length; i++) {
            if(cards[i].getIsFlipped())
                flippedCards ++;
        }
        if(flippedCards % 2 == 0 && flippedCards > 0)
            for(int i=0; i<cards.length; i++) {
                card1 = getCardIndByCardNum(cards[i].getCardNum(), cards, i);

                if(!cards[card1].getIsFlipped()) {
                    for(int j=0; j<cards.length; j++) {
                        if(cards[i].getIsFlipped())
                            cards[i].flip();
                    }
                    flippedCards = 0;
                    break;
                }
            }
    }
}

问题是,如果我调用这个方法,游戏就不会被画出来。我可以用线程吗?

编辑

下面是如何获取单击卡片的索引,并在UI中将其称为:

代码语言:javascript
复制
private void setCardHandlers() {
    for(final Card card : cards) {

        card.setOnMouseClicked(new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent t) {
                clickedCardInd = getChildren().indexOf(card)-1;
            }
        });
    }
}

比我现在是如何使用它:

代码语言:javascript
复制
setOnMouseReleased(new EventHandler<MouseEvent> () {

        @Override
        public void handle(MouseEvent t) {
            int cardIndex = clickedCardInd; // get index of what user clicked
            clickedCardInd = -1;
            if (cardIndex != -1 && moveRequestedFlag) { // our controller waits for the move
                // get the position and report
                moveRequestedFlag = false; // we handled the move
                //System.out.println(cardIndex);
                nextMove.setMove(cardIndex); // this will unblock controller's thread
            }
        }

    });

它对翻转卡片有延迟,在easyGame中,requestMove方法也将两个索引设置为相同。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-12-28 12:41:50

我建议将您的责任划分为Model/View/Controller模块,最简单的情况是:

  • 模型-您的游戏当前状态和数据,即卡阵列Cards mCards = new Cards[24];
  • 视图-您的UI,它可以反映主线程屏幕上mCards(模型)的当前状态。
  • 控制器-你的主要游戏逻辑。这是最复杂的部分,负责

代码语言:javascript
复制
1. requesting/handling user move, 
2. updating mCards(model) based on user move, 
3. Requesting UI to re-draw.

Contoroller的代码(easyGame方法)应该在单独的线程上运行,以避免阻塞UI。

下面我概述了一个应该适合您的需求的基本代码:

代码语言:javascript
复制
class Game {

    /*
     * controller - main logic
     */
    void startEasyGame() {
        // initialize cards array, shuffle if needed

        // we start with zero cards flipped
        int flippedCards = 0;

        // main loop
        while (flippedCards != mCards.length) {
            // 1. show updated UI
            mBoard.showUpdatedCards();

            // 2. request player move 
            // and block current thread to wait till move is done
            // the result of the move - index of the card
            int index1 = requestMove();
            // temporarily flip first card face-up
            mCards[index1].flip();
            // show it on screen
            mBoard.showUpdatedCards();

            // same for second card
            int index2 = requestMove();
            mCards[index2].flip();
            mBoard.showUpdatedCards();


            // 3. check the result
            if (mCards[index1].getCardNum() == mCards[index2].getCardNum()) {
                // hooray, correct guess, update count
                // possibly show some encouraging feedback to user
                flippedCards += 2;
            } else {
                // incorrect, flip cards back face down
                mCards[index1].flip();
                mCards[index2].flip();
            }

        } // end of while loop

        // game ended -> show score and time
        mBoard.showResult();    
    }

}

编辑

关于如何等待UI线程的结果的详细信息:

代码语言:javascript
复制
int requestMove() {
    // 1. show user prompt to make a move
    // ...

    // 2. construct latch to wait for move done on UI thread
    mBoard.moveRequestedFlag = true;
    NextMove nextMove = new NextMove();
    mBoard.nextMove = nextMove;

    // 3. await for move and get the result
    return nextMove.getMove();
}

然后,在UI代码中的某个位置:

代码语言:javascript
复制
// handling card onClick somewhere on UI thread
if (mBoard.moveRequestedFlag) { // our controller waits for the move
    // get the position and report
    int cardIndex = ... // get index of what user clicked
    mBoard.moveReqestedFlag = false; // we handled the move
    mBoard.nextMove.setMove(cardIndex); // this will unblock controller's thread
}

和用于同步线程的NextMove实用程序类:

代码语言:javascript
复制
public class NextMove {
    private volatile int mCardIndex;
    private final CountDownLatch mMoveReady = new CountDownLatch(1);

    public int getMove() throws InterruptedException {
        mMoveReady.await();
        return mCardIndex;
    }

    public synchronized void setMove(int selectedCardIndex) {
        if (mMoveReady.getCount() > 0) {
            mCardIndex = selectedCardIndex;
            mMoveReady.countDown();
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20810113

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档