首页 > 解决方案 > 刽子手新游戏如何重置内存?

问题描述

我正在做一个刽子手游戏。游戏正常运行,只是当我开始新游戏时,我无法清除前一游戏中存储的数据。因此,在用户单击“再次播放”后,它给了我一个如下所示的屏幕。

刽子手游戏的屏幕截图 - 单击“再次播放”后的外观

点击“重玩”后的刽子手游戏截图

如何重置数据以便执行 startNewGame 方法后的 textview 和按钮?

尝试使用 textView.setText("") 进行重置,但它不起作用。感谢您是否可以为我提供一些启发。谢谢!

我的代码如下。

package com.desmondwong.hangmangame;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.GridLayout;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewSwitcher;

import java.util.Random;

public class GameActivity extends AppCompatActivity {

    //To reference the components
    ImageSwitcher imageSwitcher;
    TextView textView;
    TextView textViewScore;
    Button btn [] = new Button[26];

    //Images for the hangman
    int img [] = {R.drawable.img0,
            R.drawable.img1,
            R.drawable.img2,
            R.drawable.img3,
            R.drawable.img4,
            R.drawable.img5,
            R.drawable.img6,
            R.drawable.img7,
            R.drawable.img8};

    AlertDialog helpAlert;

    //Variables
    String strSecret = "", strGuess="", strText="";

    String strWords[] = {"APPLE", "ORANGE","BANANA"};

    int intError = 0; //Error made by player

    int livesRemaining = 8; //Lives remaining by player

    int numCorr = 0; //Correct letter guess by player

    Random random = new Random(); //Random generator


    public void startNewGame(){

        intError = 0; //Error made by player

        livesRemaining = 8; //Lives remaining by player

        numCorr = 0; //Correct letter guess by player

        imageSwitcher.removeAllViews();



        //textViewScore.setText(String.valueOf(livesRemaining));

        //textView.setText("");

        setupImageSwitcher();
        setup26Buttons();
        getSecretWord();

    }


    //To create help icon at top right
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    //To create help icon at top right
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            //case android.R.id.home:
               // NavUtils.navigateUpFromSameTask(this);
                //return true;
            case R.id.action_help:
                showHelp();
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);

        //Retrieve the reference
        imageSwitcher = findViewById(R.id.imageSwitcher);
        textView = findViewById(R.id.textView);
        textViewScore = findViewById(R.id.textViewScore);
        textViewScore.setText(String.valueOf(livesRemaining));

        setupImageSwitcher();
        setup26Buttons();
        getSecretWord();

    }


    private void setup26Buttons() {

        GridLayout g = findViewById(R.id.gridLayout);


        //to create 26 buttons
        for(int i = 0; i<btn.length; i++) {

            btn[i] = new Button(this, null, R.attr.buttonStyleSmall); //Buttonsytlesmall so that it fits the screen
            btn[i].setText(""+(char)('A'+i)); //need to set back to char, as +i will set it back to integer. "" to set this to a String so it is sync to setText
            btn[i].setTag(""+(char)('A'+i));
            btn[i].setOnClickListener(new View.OnClickListener() {
                @SuppressLint("ResourceAsColor")
                @Override
                public void onClick(View v) {

                    strGuess += v.getTag(); //Get letter that the player guessed and keep adding on to strGuess
                    v.setEnabled(false); //disable pressed button since the player already press
                    v.setBackgroundColor(android.R.color.black);

                    //Check for error guess. If the letter is not inside the strSecret, it will return less than 0
                    if (strSecret.indexOf(v.getTag().toString())<0){

                        intError++; //your error is added
                        int livesRemaining = 8;
                        livesRemaining -= intError; // Countdown based on errors recorded
                        textViewScore.setText(String.valueOf(livesRemaining));
                        imageSwitcher.setImageResource(img[intError]); //set the img no. to follow the error
                    }

                    else {

                        numCorr++;
                    }

                    boolean playerWin = true;
                    //Display all correct guesses
                    strText = ""; //reset the display

                    for (int i = 0 ; i<strSecret.length();i++){

                        char ch = strSecret.charAt(i); // get each character from strSecret

                        //To check if this letter can be found in strGuess
                        if(strGuess.indexOf(ch)>=0){
                            //found
                            strText += ch;

                        }

                        else{

                            //Not found
                            strText += "-";
                            playerWin=false;
                        }

                    }

                    textView.setText(strText);

                    if (playerWin) {

                        if (numCorr == strSecret.length()) {

                            //Toast.makeText(getApplicationContext(), "You won", Toast.LENGTH_LONG).show();

                            //let user know they have won, ask if they want to play again
                            AlertDialog.Builder winBuild = new AlertDialog.Builder(GameActivity.this);
                            winBuild.setTitle("Amazing! You save Batman!");

                            winBuild.setMessage("The Hangman\'s favourite fruit is:\n\n" + strSecret);

                            winBuild.setPositiveButton("Play Again",
                                    new DialogInterface.OnClickListener() {
                                        public void onClick(DialogInterface dialog, int id) {
                                            GameActivity.this.startNewGame();

                                        }
                                    });

                            winBuild.setNegativeButton("Exit",
                                    new DialogInterface.OnClickListener() {
                                        public void onClick(DialogInterface dialog, int id) {
                                            GameActivity.this.finish();

                                        }
                                    });
                            winBuild.show();

                        }

                    } else if (livesRemaining > 0) {

                        //still have lives remaining. do nothing
                    }

                    else {

                        //Toast.makeText(getApplicationContext(), "You Lost",Toast.LENGTH_LONG).show();

                        // Display Alert Dialog
                        AlertDialog.Builder loseBuild = new AlertDialog.Builder(GameActivity.this);
                        loseBuild.setTitle("Batman got executed!");
                        loseBuild.setMessage("You lose!\n\nThe answer was:\n\n"+ strSecret);
                        loseBuild.setPositiveButton("Play Again",
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int id) {
                                        GameActivity.this.startNewGame();
                                    }});

                        loseBuild.setNegativeButton("Exit",
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int id) {
                                        GameActivity.this.finish();
                                    }});

                        loseBuild.show();

                    }

                }

            });

            g.addView(btn[i]);

        }

    }



    private void getSecretWord() {

        int index = random.nextInt(strWords.length);
        strSecret = strWords[index];

        for(int i=0; i<strSecret.length(); i++) {

            strText += "-"; //to create multiple - for the unknown word

        }

        textView.setText(strText);


    }

    private void setupImageSwitcher() {

        //https://www.tutorialspoint.com/android/android_imageswitcher.htm
        imageSwitcher.setFactory(new ViewSwitcher.ViewFactory() {

            @Override
            public View makeView() {

                ImageView imageView = new ImageView(getApplicationContext());

                imageView.setImageResource(R.drawable.img0);

                return imageView;
            }
        });

        Animation aniOut = AnimationUtils.loadAnimation(this, android.R.anim.slide_out_right);

        Animation aniIn = AnimationUtils.loadAnimation(this, android.R.anim.slide_in_left);

        imageSwitcher.setOutAnimation(aniOut);

        imageSwitcher.setOutAnimation(aniIn);
    }

    //show help information
    public void showHelp(){
        AlertDialog.Builder helpBuild = new AlertDialog.Builder(this);
        helpBuild.setTitle("Help");
        helpBuild.setMessage("Whisper the password (Hangman's favourite fruit) to save Batman\n\n"
                + "You only have 8 tries!");
        helpBuild.setPositiveButton("OK",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        helpAlert.dismiss();
                    }});
        helpAlert = helpBuild.create();
        helpBuild.show();
    }

}

标签: javaandroid

解决方案


你的问题是每次你打电话给startNewGame你:

  • 向现有值添加新文本strText而不是设置新文本
  • btn数组中添加新按钮(不删除旧按钮)

因此,您需要确保startNewGame摆脱为之前的游戏创建的所有内容,并且不再需要这些内容。

编辑

一种方法是拥有一个“游戏”对象来存储所有内容(strSecret、strGuess、...),而不是将它们放在 Activity 中。每次startNewGame调用时,您myGame = new Game();都会确定之前的所有数据都已消失。

编辑 2

快速解决方法是:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_game);

    //Retrieve the reference
    imageSwitcher = findViewById(R.id.imageSwitcher);
    textView = findViewById(R.id.textView);
    textViewScore = findViewById(R.id.textViewScore);
    textViewScore.setText(String.valueOf(livesRemaining));


    // ** QUICK FIX **
    btn = new Button[26];
    strText = "";

    setupImageSwitcher();
    setup26Buttons();
    getSecretWord();
}

编辑 3(工作改进示例)

主要活动

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.DrawableRes;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.GridLayout;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.ViewSwitcher;

import java.util.Random;

public class GameActivity extends AppCompatActivity {

    // Constants

    //Images for the hangman
    @DrawableRes
    private final static int img[] = {R.drawable.img0, // Img0 is when the player is dead
            R.drawable.img1,
            R.drawable.img2,
            R.drawable.img3,
            R.drawable.img4,
            R.drawable.img5,
            R.drawable.img6,
            R.drawable.img7,
            R.drawable.img8};

    private final static String strWords[] = {"APPLE", "ORANGE", "BANANA"};
    private final static Random random = new Random(); //Random generator

    // To reference the components
    private ImageSwitcher imageSwitcher;
    private TextView textView;
    private TextView textViewScore;

    // Other private fields
    private Game mGame;

    public void startNewGame() {
        mGame = new Game(img.length - 1); // The max lives is the size of the array - 1
        setup26Buttons();
        initSecretWord();
        imageSwitcher.reset();
        imageSwitcher.setImageResource(img[mGame.livesRemaining]);
        textViewScore.setText(String.valueOf(mGame.livesRemaining));
        textView.setText(mGame.hiddenWord);
    }

    //To create help icon at top right
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    //To create help icon at top right
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_help:
                showHelpDialog();
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);

        //Retrieve the reference
        imageSwitcher = findViewById(R.id.imageSwitcher);
        textView = findViewById(R.id.textView);
        textViewScore = findViewById(R.id.textViewScore);

        // Init the view components
        initImageSwitcher();

        // Start the game
        startNewGame();
    }

    private void setup26Buttons() {

        final GridLayout g = findViewById(R.id.gridLayout);
        g.removeAllViews(); // clear the children views (if exist)

        //to create 26 buttons
        final int maxLetters = 26;
        Button btn;
        for (int i = 0; i < maxLetters; i++) {

            btn = new Button(this, null, R.attr.buttonStyleSmall); //Buttonsytlesmall so that it fits the screen
            btn.setText(Character.toString((char) ('A' + i))); // Set the letter
            btn.setOnClickListener(listener);

            g.addView(btn);
        }
    }

    private final View.OnClickListener listener = new View.OnClickListener() {
        @SuppressLint("ResourceAsColor")
        @Override
        public void onClick(View v) {

            String guess = (((Button) v).getText()).toString();
            v.setEnabled(false); //disable pressed button since the player already press
            v.setBackgroundColor(android.R.color.black);

            // Check if the current letter is in the secret word
            if (!mGame.secretWord.contains(guess)) {
                mGame.livesRemaining--; // Remove a live
                imageSwitcher.setImageResource(img[mGame.livesRemaining]); //set the img no. to follow the error
                textViewScore.setText(String.valueOf(mGame.livesRemaining));

                if (mGame.livesRemaining == 0) {
                    showEndGameDialog("Batman got executed!", "You lose!\n\nThe answer was:\n\n" + mGame.secretWord);
                }
            } else {
                mGame.correctGuess += guess; // Add the letter to the ones correctly guessed
                //Display all correct guesses
                final StringBuilder sb = new StringBuilder();
                final char[] chars = mGame.secretWord.toCharArray();
                for (int i = 0; i < mGame.secretWord.length(); i++) {
                    //To check if this letter can be found in correctGuess
                    sb.append((mGame.correctGuess.contains(Character.toString(chars[i])))
                            ? chars[i] //found
                            : "-");
                }
                mGame.hiddenWord = sb.toString();
                textView.setText(mGame.hiddenWord);

                // If all the unique letters in the word have been found, it's a win
                if (mGame.correctGuess.length() == mGame.maxLetters) {
                    showEndGameDialog("Amazing! You save Batman!", "The Hangman\'s favourite fruit is:\n\n" + mGame.secretWord);
                }
            }
        }
    };

    private void showEndGameDialog(String title, String message) {
        new AlertDialog.Builder(GameActivity.this)
                .setTitle(title)
                .setMessage(message)
                .setPositiveButton("Play Again",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                GameActivity.this.startNewGame();
                            }
                        })
                .setNegativeButton("Exit",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                GameActivity.this.finish();
                            }
                        })
                .show();
    }

    private void initSecretWord() {

        int index = random.nextInt(strWords.length);
        String secretWord = strWords[index];
        // Replace all the letters by '-' ('\p{L}' matches any letter)
        String hiddenWord = secretWord.replaceAll("\\p{L}", "-");

        mGame.maxLetters = countUniqueLettersInWord(secretWord);
        mGame.secretWord = secretWord;
        mGame.hiddenWord = hiddenWord;
    }

    /**
     * Calculate the number of unique letter in the word
     * E.g BANANA has 3 unique letters (B,A,N)
     *
     * @param word The word to count the unique letter in
     * @return The total of unique letters
     */
    private static int countUniqueLettersInWord(final String word) {
        char[] chars = word.toCharArray();
        int count = 0;
        char curr;
        boolean contains;
        for (int i = 0; i < chars.length; i++) {
            curr = chars[i];
            // Check if the same letter exists in the visited letters (from pos 0 to current letter)
            contains = false;
            for (int j = 0; j < i; j++) {
                if (curr == chars[j]) {
                    contains = true;
                    break; // Don't need to continue if the letter already exists.
                }
            }
            if (!contains)
                count++;
        }

        return count;
    }

    private void initImageSwitcher() {

        //https://www.tutorialspoint.com/android/android_imageswitcher.htm
        imageSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
            @Override
            public View makeView() {
                return new ImageView(getApplicationContext());
            }
        });

        Animation aniOut = AnimationUtils.loadAnimation(this, android.R.anim.slide_out_right);
        Animation aniIn = AnimationUtils.loadAnimation(this, android.R.anim.slide_in_left);

        imageSwitcher.setOutAnimation(aniOut);
        imageSwitcher.setOutAnimation(aniIn);
    }

    //show help information
    public void showHelpDialog() {
        new AlertDialog.Builder(this)
                .setTitle("Help")
                .setMessage("Whisper the password (Hangman's favourite fruit) to save Batman\n\n"
                        + "You only have 8 tries!")
                .setPositiveButton("OK",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                dialog.dismiss();
                            }
                        })
                .show();
    }
}

游戏课

public class Game {

    String secretWord, correctGuess, hiddenWord;

    //Lives remaining by player
    int livesRemaining;

    public int maxLetters;

    public Game(int lives) {
        secretWord = "";
        correctGuess = "";
        hiddenWord = "";
        livesRemaining = lives;
    }
}

推荐阅读