如何使用 Thread.sleep()?

How can I use Thread.sleep()?

我正在为一个学校项目创建一个备忘录游戏,但我的 Thread.sleep 有问题。

当玩家 returns 两张牌时,程序会检查它们是否相同。如果不是,则他们脸朝下。由于程序几乎是立即完成的,我想暂停一下,以便玩家有时间看到第二张牌。问题是break是在翻牌前

if (deck1.contains(carte)) {
    if (carte.getEtat() == 0) {
        carte.setEtat(1);
        cartesRetournees1.add(carte);
        majAffichage(carte);

        try {
            Thread.sleep(500);
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        }
    }
    if (cartesRetournees1.size() == 2) {
        int nouveauEtat = 0;
        if (cartesRetournees1.get(0).getMotif() == cartesRetournees1.get(1).getMotif()) {
            nouveauEtat = -1;
            this.nbPairsTrouvees++;
        }

        cartesRetournees1.get(0).setEtat(nouveauEtat);
        cartesRetournees1.get(1).setEtat(nouveauEtat);

        majAffichage(cartesRetournees1.get(0));
        majAffichage(cartesRetournees1.get(1));
        cartesRetournees1.remove(1);
        cartesRetournees1.remove(0);

        if (nbPairsTrouvees == this.plateau.size()) System.out.println("GAGNE !");
    }
}

在我的游戏中,Thread.sleep 在 majAffichage(carte) 之前工作,我不明白为什么。 我不知道如何解决我的问题,如果你们能帮助我,我将不胜感激:)

首先,您不会暂停主线程,而是暂停后台线程,因为您不想冻结整个应用程序。

其次,使用 System.sleep() 而不是 Thread.sleep() 因为第一个不会抛出异常。

这是因为 UI 和绘图的工作原理。在主线程的 android 框架中,有一个巨大的事件循环处理消息。其中一条消息是绘制消息。只有在处理该消息时才会绘制屏幕。消息只能在循环的顶部处理。因此,如果线程休眠,它在休眠期间永远不会处理新消息,屏幕也不会更新。

如果你想像这样延迟做某事,有两个选择:

1) post 主循环的 Runnable 与 postDelayed 不同,而不是休眠,因此 运行nable 在您指定的时间为 运行未来。

2) 使用第二个线程和 运行 那里的所有游戏逻辑,当 UI 事件发生时将消息传递给它,并在需要绘制时将事件传递回主线程。

谢谢您的回答! 我创建了第二个线程。

package com.example.jeudumemo;

import android.graphics.Canvas;

public class GameLoopThread extends Thread
{
    private final static int FRAMES_PER_SECOND = 30;

    private final static int SKIP_TICKS = 1000 / FRAMES_PER_SECOND;

    private final Game view; 
    private boolean running = false; 

    public GameLoopThread(Game view) {
        this.view = view;
    }

    public void setRunning(boolean run) {
        running = run;
    }

    @Override
    public void run()
    {
        long startTime;
        long sleepTime;

        while (running)
        {
            startTime = System.currentTimeMillis();

            synchronized (view.getHolder()) {view.update();}

            Canvas c = null;
            try {
                c = view.getHolder().lockCanvas();
                synchronized (view.getHolder()) {view.draw(c);}
            }
            finally
            {
                try {
                    if (c != null) {
                        view.getHolder().unlockCanvasAndPost(c);
                    }
                } catch(IllegalArgumentException iae) { iae.printStackTrace(); }
            }
            sleepTime = SKIP_TICKS-(System.currentTimeMillis() - startTime);
            try {
                if (sleepTime >= 0) {sleep(sleepTime);}
            }
            catch (Exception e) {}
        } 
    } 

} 

我在主 class 中这样称呼它:

@Override
    public void surfaceCreated(SurfaceHolder holder) {
        if(gameLoopThread.getState()==Thread.State.TERMINATED) {
            gameLoopThread=new GameLoopThread(this);
        }
        gameLoopThread.setRunning(true);
        gameLoopThread.start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        boolean retry = true;
        gameLoopThread.setRunning(false);
        while (retry) {
            try {
                gameLoopThread.join();
                retry = false;
            }
            catch (InterruptedException e) {}
        }
    }

public void controleJeu(Carte carte) {
        if(deck1.contains(carte)) {
            if (carte.getEtat() == 0) {
                carte.setEtat(1);
                cartesRetournees1.add(carte);
                majAffichage(carte);

            }
            if (cartesRetournees1.size() == 2) {
                try {
                    gameLoopThread.sleep(500);
                }catch(InterruptedException ie) { ie.printStackTrace(); }
                int nouveauEtat = 0;
                if (cartesRetournees1.get(0).getMotif() == cartesRetournees1.get(1).getMotif()) {
                    nouveauEtat = -1;
                    this.nbPairsTrouvees++;
                }

                cartesRetournees1.get(0).setEtat(nouveauEtat);
                cartesRetournees1.get(1).setEtat(nouveauEtat);

                majAffichage(cartesRetournees1.get(0));
                majAffichage(cartesRetournees1.get(1));
                cartesRetournees1.remove(1);
                cartesRetournees1.remove(0);
            }
        }
        else if(deck2.contains(carte)) {
            if (carte.getEtat() == 0) {
                carte.setEtat(1);
                cartesRetournees2.add(carte);
                majAffichage(carte);
            }
            if (cartesRetournees2.size() == 2) {
                try {
                    gameLoopThread.sleep(500);
                }catch(InterruptedException ie) { ie.printStackTrace(); }
                int nouveauEtat = 0;
                if (cartesRetournees2.get(0).getMotif() == cartesRetournees2.get(1).getMotif()) {
                    nouveauEtat = -1;
                    this.nbPairsTrouvees++;
                }

                cartesRetournees2.get(0).setEtat(nouveauEtat);
                cartesRetournees2.get(1).setEtat(nouveauEtat);

                majAffichage(cartesRetournees2.get(0));
                majAffichage(cartesRetournees2.get(1));
                cartesRetournees2.remove(1);
                cartesRetournees2.remove(0);
            }
        }
        if (nbPairsTrouvees == nbDeck*6) { showPopupVictoire(this); this.victory = true; }
        System.out.println(nbDeck);
    }

我的问题仍然存在。我想我没有使用我的 GameLoopThread,因为它必须被使用。有什么意见吗?