-2

Trying to enable pause/resume, but it won't work.
My code is

package dev.android.gamex;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.view.MotionEventCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import java.util.Random;

public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {


    Button button;
    CatchGame cg;
    public TextView textView;
    public LinearLayout mainLayout;
    String[] spinnerValue = {"Rookie", "Advanced", "Expert", "Master"};


    public void onItemSelected(AdapterView<?> parent, View view,
                               int pos, long id) {
        // An item was selected. You can retrieve the selected item using
        Log.d("myTag", "This is my message" + parent.getItemAtPosition(pos));
        String name = "Jamie";
        String str = parent.getItemAtPosition(pos).toString();
        if (str.equals("Rookie")) {
            cg = new CatchGame(this, 3, name, onScoreListener);
            setContentView(cg);
            getSupportActionBar().hide();
            setContentView(mainLayout);
            Log.d("game", "Started Rookie game");

        } else if (str.equals("Advanced")) {
            mainLayout = new LinearLayout(this);
            mainLayout.setOrientation(LinearLayout.VERTICAL);

            LinearLayout menuLayout = new LinearLayout(this);
            menuLayout.setBackgroundColor(Color.parseColor("#FFFFFF"));

            textView = new TextView(this);
            textView.setVisibility(View.VISIBLE);
            str = "Score: 0";
            textView.setText(str);
            menuLayout.addView(textView);

            Button button = new Button(this);
            button.setText("Pause");
            //button.setId(1);
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    togglePausePlay();
                }
            });
            menuLayout.addView(button);


            // menuLayout.addView(button);


            Spinner spinner2 = new Spinner(this);
            spinner2.setOnItemSelectedListener(this);
            ArrayAdapter<String> adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, spinnerValue);
            spinner2.setAdapter(adapter);
            menuLayout.addView(spinner2);

            mainLayout.addView(menuLayout);

            cg = new CatchGame(this, 5, "Jamie", onScoreListener);
            cg.setBackground(getResources().getDrawable(R.drawable.bg_land_mdpi));
            mainLayout.addView(cg);
            //                getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
            getSupportActionBar().hide();
            setContentView(mainLayout);
            Log.d("game", "Started Advanced game");
        } else if (str.equals("Expert")) {
            cg = new CatchGame(this, 7, name, onScoreListener);
            setContentView(cg);
            getSupportActionBar().hide();
            setContentView(mainLayout);
        }
    }

    public void onNothingSelected(AdapterView<?> parent) {
        // Another interface callback
    }

    private void togglePausePlay() {
        if (cg.paused) {
            // play and change text to pause
            Log.d("msg", "play selected");
            button.setText("Pause");
            cg.paused = false;
        } else {
            // pause and change text to play
            Log.d("psm", "pause selected");
            button.setText("Play");
            cg.pause();//cg.paused = true;
        }
    }

    // start app
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mainLayout = new LinearLayout(this);
        mainLayout.setOrientation(LinearLayout.VERTICAL);

        LinearLayout menuLayout = new LinearLayout(this);
        menuLayout.setBackgroundColor(Color.parseColor("#FFFFFF"));

        textView = new TextView(this);
        textView.setVisibility(View.VISIBLE);
        String str = "Score: 0";
        textView.setText(str);
        menuLayout.addView(textView);

        button = new Button(this);
        button.setText("Pause");
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                togglePausePlay();
            }
        });

        menuLayout.addView(button);


        Spinner spinner2 = new Spinner(this);
        spinner2.setOnItemSelectedListener(this);
        ArrayAdapter<String> adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, spinnerValue);
        spinner2.setAdapter(adapter);
        menuLayout.addView(spinner2);

        mainLayout.addView(menuLayout);

        cg = new CatchGame(this, 5, "Jamie", onScoreListener);
        cg.setBackground(getResources().getDrawable(R.drawable.bg_land_mdpi));
        mainLayout.addView(cg);
        getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
        getSupportActionBar().hide();
        setContentView(mainLayout);
    }


    private OnScoreListener onScoreListener = new OnScoreListener() {
        @Override
        public void onScore(int score) {
            textView.setText("Score: " + score);
        }
    };

    interface OnScoreListener {
        void onScore(int score);
    }

    class CatchGame extends View {
        int NBRSTEPS; // number of discrete positions in the x-dimension; must be uneven
        String heroName;
        int screenW;
        int screenH;
        int[] x; // x-coordinates for falling objects
        int[] y; // y-coordinates for falling objects
        int[] hero_positions; // x-coordinates for hero
        Random random = new Random();
        int ballW; // width of each falling object
        int ballH; // height of ditto
        float dY; //vertical speed
        Bitmap falling, hero, jamie2, jamieleft, jamieright, falling2;
        int heroXCoord;
        int heroYCoord;
        int xsteps;
        int score;
        int offset;
        boolean gameOver; // default value is false
        boolean toastDisplayed;
        boolean paused = false;

        OnScoreListener onScoreListener;

        // constructor, load images and get sizes
        public CatchGame(Context context, int difficulty, String name, OnScoreListener onScoreListener) {
            super(context);
            NBRSTEPS = difficulty;
            heroName = name;
            this.onScoreListener = onScoreListener;

            x = new int[NBRSTEPS];
            y = new int[NBRSTEPS];
            hero_positions = new int[NBRSTEPS];
            int resourceIdFalling = 0;
            int resourceIdFalling2 = 0;
            int resourceIdHero = 0;
            if (heroName.equals("Jamie")) {
                resourceIdFalling = R.mipmap.falling_object2;
                resourceIdFalling2 = R.drawable.coconut_hdpi;
                resourceIdHero = R.drawable.left_side_hdpi;
                setBackground(getResources().getDrawable(R.mipmap.background));
            }
            falling = BitmapFactory.decodeResource(getResources(), resourceIdFalling); //load a falling image
            falling2 = BitmapFactory.decodeResource(getResources(), resourceIdFalling2); //load a falling image
            hero = BitmapFactory.decodeResource(getResources(), resourceIdHero); //load a hero image
            jamieleft = BitmapFactory.decodeResource(getResources(), R.drawable.left_side_hdpi); //load a hero image
            jamieright = BitmapFactory.decodeResource(getResources(), R.drawable.right_side_hdpi); //load a hero image
            ballW = falling.getWidth();
            ballH = falling.getHeight();
        }

        public void pause() {
            paused = true;
        }

        // set coordinates, etc.
        void initialize() {
            if (!gameOver) { // run only once, when the game is first started
                int maxOffset = (NBRSTEPS - 1) / 2;
                for (int i = 0; i < x.length; i++) {
                    int origin = (screenW / 2) + xsteps * (i - maxOffset);
                    x[i] = origin - (ballW / 2);
                    hero_positions[i] = origin - hero.getWidth();
                }
                int heroWidth = hero.getWidth();
                int heroHeight = hero.getHeight();

                hero = Bitmap.createScaledBitmap(hero, heroWidth * 2, heroHeight * 2, true);
                hero = Bitmap.createScaledBitmap(hero, heroWidth * 2, heroHeight * 2, true);
                jamieleft = Bitmap.createScaledBitmap(jamieleft, jamieleft.getWidth() * 2, jamieright.getWidth() * 2, true);
                jamieright = Bitmap.createScaledBitmap(jamieright, jamieright.getWidth() * 2, jamieright.getWidth() * 2, true);

                heroYCoord = screenH - 2 * heroHeight; // bottom of screen

            }
            for (int i = 0; i < y.length; i++) {
                y[i] = -random.nextInt(1000); // place items randomly in vertical direction
            }

            offset = (NBRSTEPS - 1) / 2; // place hero at centre of the screen
            heroXCoord = hero_positions[offset];

            // initialize or reset global attributes
            dY = 2.0f;
            score = 0;
            gameOver = false;
            toastDisplayed = false;
        }

        // method called when the screen opens
        @Override
        public void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            screenW = w;
            screenH = h;
            xsteps = w / NBRSTEPS;
            initialize();
        }

        // method called when the "game over" toast has finished displaying
        void restart(Canvas canvas) {

            toastDisplayed = true;
            initialize();
            draw(canvas);
        }

        // update the canvas in order to display the game action
        @Override
        public void onDraw(Canvas canvas) {
            if (toastDisplayed) {
                restart(canvas);
                return;
            }
            super.onDraw(canvas);

            int heroHeight = hero.getHeight();
            int heroWidth = hero.getWidth();
            int heroCentre = heroXCoord + heroWidth / 2;

            Context context = this.getContext();
            Log.d("log", "is paused" + paused);
            // compute locations of falling objects
            for (int i = 0; i < y.length; i++) {
                if (!paused) {
                    y[i] += (int) dY;
                }
                // if falling object hits bottom of screen
                if (y[i] > (screenH - ballH) && !gameOver) {
                    dY = 0;
                    gameOver = true;
                    paused = true;
                    int duration = Toast.LENGTH_SHORT;

                    final Toast toast = Toast.makeText(context, "GAME OVER!\nScore: " + score, duration);
                    toast.show();
                    Handler handler = new Handler();
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            toast.cancel();
                            toastDisplayed = true;
                        }
                    }, 3000);
                    //Vibrator v = (Vibrator) context.getSystemService(context.VIBRATOR_SERVICE);
                    // Vibrate for 3000 milliseconds
                    //v.vibrate(3000);

                }
                // if the hero catches a falling object
                if (x[i] < heroCentre && x[i] + ballW > heroCentre &&
                        y[i] > screenH - ballH - heroHeight) {

                    y[i] = -random.nextInt(1000); // reset to new vertical position
                    score += 1;
                    onScoreListener.onScore(score);
                }

            }
            canvas.save(); //Save the position of the canvas.

            for (int i = 0; i < y.length; i++) {
                if (i % 2 == 0)
                    canvas.drawBitmap(falling2, x[i], y[i], null); //Draw the falling on the canvas.
                else
                    canvas.drawBitmap(falling, x[i], y[i], null); //Draw the falling on the canvas.
            }
            canvas.drawBitmap(hero, heroXCoord, heroYCoord, null); //Draw the hero on the canvas.

            canvas.restore();
            //Call the next frame.
            invalidate();
        }

        // event listener for when the user touches the screen
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            if (paused) {
                paused = false;
            }
            int action = MotionEventCompat.getActionMasked(event);
            if (action != MotionEvent.ACTION_DOWN || gameOver) { // non-touchdown event or gameover
                return true; // do nothing
            }
            int coordX = (int) event.getX();
            int xCentre = (screenW / 2) - (hero.getWidth() / 2);
            int maxOffset = hero_positions.length - 1; // can't move outside right edge of screen
            int minOffset = 0; // ditto left edge of screen

            if (coordX < xCentre && offset > minOffset) { // touch event left of the centre of screen
                offset--; // move hero to the left

                if (coordX < heroXCoord)// + heroWidth / 2)
                    hero = Bitmap.createScaledBitmap(jamieleft, jamieleft.getWidth(), jamieleft.getHeight(), true);

            }
            if (coordX > xCentre && offset < maxOffset) { // touch event right of the centre of screen
                offset++; // move hero to the right

                if (coordX > heroXCoord)
                    hero = Bitmap.createScaledBitmap(jamieright, jamieright.getWidth(), jamieright.getHeight(), true);

            }
            heroXCoord = hero_positions[offset];

            return true;
        }
    }
}

Why won't it work? The button text does change, but the pause variable seems not to work.
What's going on?

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Niklas Rosencrantz
  • 25,640
  • 75
  • 229
  • 424

1 Answers1

1

Try calling cg.invalidate() in your togglePausePlay().

private void togglePausePlay() {
    if (cg.paused) {
        // play and change text to pause
        Log.d("msg", "play selected");
        button.setText("Pause");
        cg.paused = false;
    } else {
        // pause and change text to play
        Log.d("psm", "pause selected");
        button.setText("Play");
        cg.pause();//cg.paused = true;
    }
    cg.invalidate();
}

It should fire the onDraw method.

Roberto Martucci
  • 1,237
  • 1
  • 13
  • 21
  • It is supposed to be levels of difficulties. – Niklas Rosencrantz Nov 29 '17 at 17:54
  • 1
    In some levels you set as content view your gc view and then soon after your main layout. While in other levels you add the gc view to the main layout. I think you do well in this last case. Is it normal? – Roberto Martucci Nov 29 '17 at 17:56
  • Could you please elaborate? I'm not sure that I understand. – Niklas Rosencrantz Nov 30 '17 at 08:26
  • 1
    You call setContentView several times to set your layout in your onItemSelected in order to set the current game level. It is not properly doing this way; setContentView should be called just once. In some other cases instead you before create your CatchGame view and then you add it to the main layout, that it's the right way to do. Probably this can be the reason why your view doesn't refresh. See here https://stackoverflow.com/a/22228157/3172725 to better understand my point. – Roberto Martucci Nov 30 '17 at 09:56