我如何使用Thread.sleep()?

问题描述 投票:1回答:3

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

当玩家返回两张牌时,程序会检查它们是否相同。如果他们不是,那么他们面朝下。由于程序几乎立即完成,我想暂停,以便玩家有时间看第二张牌。问题是休息时间是在卡片转动之前

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)之前工作,我不明白为什么。我不知道如何解决我的问题,如果你们能帮助我,我会非常感激:)

java android thread-sleep
3个回答
2
投票

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

如果你想在这样的延迟上做点什么,有两种选择:

1)而不是睡觉,使用postDelayed将Runnable发布到主循环,因此runnable将在您将来指定的时间运行。

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


0
投票

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

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


0
投票

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

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) {}
        } 
    } 

} 

我在我的主要课堂上称之为:

@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,因为必须使用它。有何评论?

© www.soinside.com 2019 - 2024. All rights reserved.