Java – How do I pause and unpause threads in a game?

How do I pause and unpause threads in a game?… here is a solution to the problem.

How do I pause and unpause threads in a game?

I’m new to developing games, I’m trying to develop a simple shooting space game and everything is perfect. Now I want to create a dialog popup when the user clicks the back button, and the game should pause until the user presses resume. The game is paused, but when I click the resume button, the game is still pausingHere is my game loop class:

public class Game extends SurfaceView implements Runnable , SurfaceHolder.Callback {

public static  MyPreferences pref;
    public static Levels level;
    public static int SCREEN_W;
    public static int SCREEN_H;
    public static  boolean running;
    private static Thread thread = null;
    private SurfaceHolder holder;
    private Canvas canvas;
    private Paint p = new Paint();
    public static Handler handler = new Handler();
    public static Resources res;
    public static Timer timer;

public Game(Context context) {
        super(context);
        res = getResources();
        holder = getHolder();
        holder.addCallback(this);

level = new Levels();
        timer = new Timer();
        pref = new MyPreferences(context);
        System.out.println("Create Game instance");

}

public void run() {
        init();

long lastTime = System.nanoTime();
        double delta = 0;
        double ns = 1000000000.0 / 30.0;

System.out.println("Run method" + running);
        while (running) {
            System.out.println("+++++++++++++++++++++++++++++++++++");
            long now = System.nanoTime();
            delta+=(now - lastTime) / ns;
            lastTime = now;

if(!holder.getSurface().isValid()){continue; }

canvas = holder.lockCanvas();
            SCREEN_W = canvas.getWidth();
            SCREEN_H= canvas.getHeight();

while (delta >-1) {
                tick();
                delta--;
            }

level.level1();
            render(canvas); 
            holder.unlockCanvasAndPost(canvas);

if(ControlPanel.PLAYER_POWER <=0){
                System.out.println("Loose!");
                ControlPanel.PLAYER_POWER  = 100;
                stop();
                start();
            }
        }
    }

private void render(Canvas c) {
        handler.render(c);
        textOnScreen(c);
    }

public void tick(){
        handler.tick();
    }

public void init(){
        System.out.println("Init game...");
        ControlPanel.COINS = pref.getInt("coins");
        MainActivity.music.backgroundMusic();
        handler.addSpaceShip(new Player(500, 500, 10, 10, handler, Sprite.getSprite(0)));

      handler.addKing(new King(Game.SCREEN_W / 2, 100,
              40, 40, handler, Sprite.getSprite(18), 0));
    }

public  void start() {
        if(thread==null){
        System.out.println("Start thread");
        thread = new Thread(this);
        thread.start();     

timer.start();
        }
        if(!running)    running = true;
        System.out.println("Running = " + running);
    }

public static  void stop() {
        System.out.println("Stop thread");
        running = false;
        timer.stop();
        pref.putInt("coins", ControlPanel.COINS);
        System.out.println("Running = " + running);
    }

public  void destroyed() {
        System.out.println("Stop");
        running = false;
        try {
            thread.join(300);
            thread.interrupt();
        } catch (InterruptedException e) {
             TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

public void textOnScreen(Canvas c){
        p = new Paint();
        p.setColor(Color.YELLOW);
        p.setTextSize(50);
        c.drawText("POWER = " + ControlPanel.PLAYER_POWER, SCREEN_W / 2 ,50 , p);
        c.drawText("Time = " + timer.timeFormat(), 100  ,50 , p);
        c.drawText("Coins = " + ControlPanel.COINS, 10 ,SCREEN_H - 10 , p);
        p.setColor(Color.WHITE);
        c.drawText("Bullets = " +ControlPanel.BULLET, SCREEN_W - 390,SCREEN_H - 10 , p);
        p.setColor(Color.WHITE);
        c.drawText(ControlPanel.Distance + " km ", SCREEN_W  /2  - 200,SCREEN_H - 10 , p);
    }

@Override
    public void surfaceCreated(SurfaceHolder holder) {
System.out.println("###surface created!");

}

@Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        System.out.println("###surface Changed!");

}

@Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        System.out.println("###surface Destroid!");

}
} 

This is my conversation class:

public class DialogPause extends Dialog implements android.view.View.OnClickListener{

Button btn;

public DialogPause(Context context) {
        super(context);
        setContentView(R.layout.pause_game);
        Game.running = false;

btn = (Button) findViewById(R.id.resume);
        btn.setOnClickListener(this);
    }

@Override
    public void onClick(View v) {
if(v.getId() == R.id.resume){
    Game.running = true;

this.dismiss();
}
    }
}

and my MainActivity class:

  public class MainActivity extends Activity implements OnTouchListener {

public Game game;
    public static Music music;

@SuppressLint("ClickableViewAccessibility")
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Full screen
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

music = new Music(this);
        game = new Game(this);
        game.setOnTouchListener(this);
        setContentView(game);

}

protected void onStart() {
    game.start();
        super.onStart();
    }

@Override
    protected void onStop() {
        music. StopBackgroundMusic();
        game.destroyed();
        super.onStop();
    }

@Override
    public void onBackPressed() {
        new DialogPause(this).show();
    }

@SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        try {
            the x and y point 
            float x  = event.getX();
            float y = event.getY();

The w and h of the space ship
            int spaceShipW = Game.handler.spaceShip.get(0).getSprite().getWidth();
            int spaceShipH = Game.handler.spaceShip.get(0).getSprite().getWidth();

Moving 
            if( x > 10 || x > Game.SCREEN_W - spaceShipW ){
                Game.handler.spaceShip.get(0).setX((int) x - (spaceShipW / 2) - 64);
                Game.handler.spaceShip.get(0).setY((int) y -  (spaceShipH +200) );
            }

Shooting
            Bullet.shoot(y, x);

switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN :
                Change sprite image when click
                Game.handler.spaceShip.get(0).getSprite().setWhatColumnX(0);
                Game.handler.spaceShip.get(0).getSprite().setFramesToAnimate(2);

case MotionEvent.ACTION_MOVE :
                break;
            case MotionEvent.ACTION_UP :
                Change sprite image when release
                Game.handler.spaceShip.get(0).getSprite().setWhatColumnX(1);
                Game.handler.spaceShip.get(0).getSprite().setFramesToAnimate(0);

break;

default:
                break;
            }

} catch (Exception e) { 

}
        return true;

}

}

By the way, I’d like to hear more opinions about the game loop code I created because I sometimes crash when I exit the game.

And how do I use some asyncTask when the game finishes loading because the game takes 4 seconds to load.
Thank you to everyone who has helped me, I am very grateful!

Solution

Add a boolean value paused and toggle that value whenever the back button is pressed (paused = !paused; )

Add a condition in a loop before you call tick:

if(!paused) tick();

It’s best not to mess with threads.

Related Problems and Solutions