Android实例——2048游戏

项目简介

选择难度,生成随机数字,通过上下左右滑动,合并相同的数字,直到达到目标数字即可通关游戏,选择界面如下

在这里插入图片描述

游戏界面如下

在这里插入图片描述

项目结构如下

在这里插入图片描述

Config

在AndroidManifest.xml指定application属性android:name=“.Config”

public class Config extends Application {

    private static SharedPreferences mSp;

    @Override
    public void onCreate() {
        super.onCreate();
        mSp = getSharedPreferences(Constants.SP_GAME, MODE_PRIVATE);
    }

    public int getTargetScore() {
        return mSp.getInt(Constants.KEY_Target_Score, Score.Score2048.getValue());
    }

    public void setTargetScore(int targetScore) {
        SharedPreferences.Editor editor = mSp.edit();
        editor.putInt(Constants.KEY_Target_Score, targetScore);
        editor.apply();
    }

    public int getGameLines() {
        return mSp.getInt(Constants.KEY_GAME_LINES, GameLines.GameLines4.getValue());
    }

    public void setGameLines(int gameLines) {
        SharedPreferences.Editor editor = mSp.edit();
        editor.putInt(Constants.KEY_GAME_LINES, gameLines);
        editor.apply();
    }

    public int getHighestScore() {
        return mSp.getInt(Constants.KEY_HIGHEST_SCORE, 0);
    }

    public void setHighestScore(int highestScore) {
        SharedPreferences.Editor editor = mSp.edit();
        editor.putInt(Constants.KEY_HIGHEST_SCORE, highestScore);
        editor.apply();
    }
}

Constants

public class Constants {
    public static final String PARA_GAME_LINES = "para_game_lines";
    public static final String PARA_TARGET_SCORE = "para_target_score";


    public static final String SP_GAME = "sp_game";
    public static final String KEY_HIGHEST_SCORE = "key_highest_score";
    public static final String KEY_GAME_LINES = "key_game_lines";
    public static final String KEY_Target_Score = "key_target_score";


    public static final GameLines DEFAULT_GAME_LINES = GameLines.GameLines4;
    public static final Score DEFAULT_SCORE = Score.Score2048;

    public enum GameLines {
        GameLines4(4), GameLines5(5);

        private int value;

        GameLines(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }
    }

    public enum Score {
        Score2048(2048), Score4049(4096);

        private int value;

        Score(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }
    }

    public enum STATE {
        FAILED, NORMAL, SUCCESS
    }
}

GameActivity

public class GameActivity extends AppCompatActivity implements View.OnClickListener, GameView.GameCallBack {

    private TextView mCurrentScore;
    private TextView mHighestScore;
    private TextView mTargetScore;
    private Button mRevert;
    private Button mRestart;
    private GameView mGame;
    private Config mConfig;
    private boolean isRevert = true;

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

    private void initView() {
        mCurrentScore = findViewById(R.id.current_score);
        mHighestScore = findViewById(R.id.highest_score);
        mTargetScore = findViewById(R.id.target_score);
        mRevert = findViewById(R.id.revert);
        mRestart = findViewById(R.id.restart);
        mGame = findViewById(R.id.game);
    }

    private void initData() {
        mConfig = new Config();
        mRevert.setOnClickListener(this);
        mRestart.setOnClickListener(this);
        mGame.setOnGameCallBack(this);

        mCurrentScore.setText("当前分数: " + 0);
        mHighestScore.setText("最高分数: " + mConfig.getHighestScore());
        mTargetScore.setText("目标分数: " + mConfig.getTargetScore());
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.revert:
                if (isRevert) {
                    mGame.revertGame();
                    isRevert = false;
                } else {
                    Toast.makeText(this, "只能撤销一次", Toast.LENGTH_SHORT).show();
                }
                break;
            case R.id.restart:
                mGame.restartGame();
                break;
        }
    }

    @Override
    public void onScoreChange(int currentScore) {
        mCurrentScore.setText("当前分数: " + currentScore);
        mHighestScore.setText("最高分数: " + mConfig.getHighestScore());
    }

    @Override
    public void onCheckGameFinish(Constants.STATE state) {
        switch (state) {
            case SUCCESS:
                showFinishDialog("成功通关");
                break;
            case FAILED:
                showFinishDialog("挑战失败");
                break;
            case NORMAL:
                break;
        }
    }

    @Override
    public void onOpenRevert() {
        isRevert = true;
    }

    private void showFinishDialog(String msg) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage(msg);
        builder.setCancelable(false);
        builder.setNegativeButton("再来一次", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                mGame.restartGame();
                dialog.dismiss();
            }
        });
        builder.setPositiveButton("退出游戏", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                finish();
            }
        });
        builder.show();
    }
}

GameItem

public class GameItem extends FrameLayout {
    private int mNum;
    private TextView mNumCard;
    private LayoutParams mParams;
    private Config mConfig;

    public GameItem(@NonNull Context context) {
        this(context, null);
    }

    public GameItem(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public GameItem(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public GameItem(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initCardItem();
    }

    private void initCardItem() {
        mConfig = new Config();
        setBackgroundColor(Color.GRAY);
        mNumCard = new TextView(getContext());
        switch (mConfig.getGameLines()) {
            case 4:
                mNumCard.setTextSize(35);
                break;
            case 5:
                mNumCard.setTextSize(25);
                break;
            default:
                mNumCard.setTextSize(20);
                break;
        }
        TextPaint tp = mNumCard.getPaint();
        tp.setFakeBoldText(true);
        mNumCard.setGravity(Gravity.CENTER);
        mParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        mParams.setMargins(5, 5, 5, 5);
        addView(mNumCard, mParams);
    }

    public void setNum(int num) {
        this.mNum = num;
        if (num == 0) {
            mNumCard.setText("");
        } else {
            mNumCard.setText(String.valueOf(num));
        }
        switch (num) {
            case 0:
                mNumCard.setBackgroundColor(0x00000000);
                break;
            case 2:
                mNumCard.setBackgroundColor(0xffeee5db);
                break;
            case 4:
                mNumCard.setBackgroundColor(0xffeee0ca);
                break;
            case 8:
                mNumCard.setBackgroundColor(0xfff2c17a);
                break;
            case 16:
                mNumCard.setBackgroundColor(0xfff59667);
                break;
            case 32:
                mNumCard.setBackgroundColor(0xfff38c6f);
                break;
            case 64:
                mNumCard.setBackgroundColor(0xfff66e3c);
                break;
            case 128:
                mNumCard.setBackgroundColor(0xffedcf74);
                break;
            case 256:
                mNumCard.setBackgroundColor(0xffedcc64);
                break;
            case 512:
                mNumCard.setBackgroundColor(0xffedc854);
                break;
            case 1024:
                mNumCard.setBackgroundColor(0xffedc54f);
                break;
            case 2048:
                mNumCard.setBackgroundColor(0xffedc32e);
                break;
            default:
                mNumCard.setBackgroundColor(0xff3c4a34);
                break;
        }
    }

    public int getNum() {
        return mNum;
    }
}

GameView

public class GameView extends GridLayout implements View.OnTouchListener {

    private static final String TAG = "GameView";
    private int mHistoryScore;
    private int mCurrentScore;
    private int mGameLines;
    private GameItem[][] mGameMatrix;
    private int[][] mGameMatrixHistory;
    private ArrayList<Point> mBlankItem;
    private int mStartX;
    private int mStartY;
    private int mEndX;
    private int mEndY;
    private int mTargetScore;
    private Config mConfig;
    private GameCallBack mCallBack;
    private int mHistoryHighestScore;

    public GameView(Context context) {
        this(context, null);
    }

    public GameView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public GameView(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public GameView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initConfig();
        initView();
        initData();
        initGame();
    }

    private void initConfig() {
        mConfig = new Config();
        mGameLines = mConfig.getGameLines();
        mTargetScore = mConfig.getTargetScore();

        Log.d(TAG, "initConfig: mGameLines = " + mGameLines);
        Log.d(TAG, "initConfig: mTargetScore = " + mTargetScore);
    }

    private void initView() {
        removeAllViews();
        setColumnCount(mGameLines);
        setRowCount(mGameLines);
        setOnTouchListener(this);
    }

    private void initData() {
        mGameMatrix = new GameItem[mGameLines][mGameLines];
        mGameMatrixHistory = new int[mGameLines][mGameLines];
        mBlankItem = new ArrayList<Point>();
    }

    private void initGame() {
        GameItem item;
        for (int i = 0; i < mGameLines; i++) {
            for (int j = 0; j < mGameLines; j++) {
                item = new GameItem(getContext());
                item.setNum(0);
                addView(item, ScreenUtils.getScreenWidthPixels(getContext()) / mGameLines, ScreenUtils.getScreenWidthPixels(getContext()) / mGameLines);
                mGameMatrix[i][j] = item;
                mBlankItem.add(new Point(i, j));
            }
        }
        addRandomNum();
        addRandomNum();
        updateScore();
    }

    private void addRandomNum() {
        getBlanks();
        if (mBlankItem.size() > 0) {
            int randomNum = (int) (Math.random() * mBlankItem.size());
            Point randomPoint = mBlankItem.get(randomNum);
            mGameMatrix[randomPoint.x][randomPoint.y].setNum(Math.random() > 0.2d ? 2 : 4);
            animCreate(mGameMatrix[randomPoint.x][randomPoint.y]);
        }
    }

    private void addSuperNum(int superNum) {
        getBlanks();
        if (mBlankItem.size() > 0) {
            int randomNum = (int) (Math.random() * mBlankItem.size());
            Point randomPoint = mBlankItem.get(randomNum);
            mGameMatrix[randomPoint.x][randomPoint.y].setNum(superNum);
            animCreate(mGameMatrix[randomPoint.x][randomPoint.y]);
        }
    }

    private void animCreate(GameItem item) {
        ScaleAnimation sa = new ScaleAnimation(0.1f, 1, 0.1f, 1,
                Animation.RELATIVE_TO_SELF, 0.5f,
                Animation.RELATIVE_TO_SELF, 0.5f);
        sa.setDuration(100);
        item.startAnimation(sa);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Log.d(TAG, "onTouch: ");
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mStartX = (int) event.getX();
                mStartY = (int) event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_UP:
                mEndX = (int) event.getX();
                mEndY = (int) event.getY();
                Log.d(TAG, "onTouch: start = (" + mStartX + "," + mStartY + ")");
                Log.d(TAG, "onTouch: end = (" + mEndX + "," + mEndY + ")");
                judgeDirection(mEndX - mStartX, mEndY - mStartY);
                if (isMoved()) {
                    updateScore();
                }
                break;
            default:
                break;
        }
        return true;
    }

    private void updateScore() {
        for (GameItem[] gameMatrix : mGameMatrix) {
            for (GameItem matrix : gameMatrix) {
                if (matrix.getNum() > mCurrentScore) {
                    mCurrentScore = matrix.getNum();
                }
            }
        }
        if (mCurrentScore > mConfig.getHighestScore()) {
            mConfig.setHighestScore(mCurrentScore);
        }
        if (mCallBack != null) {
            mCallBack.onOpenRevert();
            mCallBack.onScoreChange(mCurrentScore);
            mCallBack.onCheckGameFinish(checkCompleted());
        }
    }

    private void judgeDirection(int offsetX, int offsetY) {
        Log.d(TAG, "judgeDirection: offsetX = " + offsetX);
        Log.d(TAG, "judgeDirection: offsetY = " + offsetY);
        int density = ScreenUtils.getScreenMetrics(getContext());
        int slideDis = 5 * density;
        int maxDis = ScreenUtils.getScreenWidthPixels(getContext()) - 50;
        Log.d(TAG, "judgeDirection: slideDis = " + slideDis);
        Log.d(TAG, "judgeDirection: maxDis = " + maxDis);
        boolean flagNormal = (Math.abs(offsetX) > slideDis || Math.abs(offsetY) > slideDis)
                && Math.abs(offsetX) < maxDis
                && Math.abs(offsetY) < maxDis;
        boolean flagSuper = Math.abs(offsetX) > maxDis || Math.abs(offsetY) > maxDis;
        Log.d(TAG, "judgeDirection: flagNormal = " + flagNormal);
        Log.d(TAG, "judgeDirection: flagSuper = " + flagSuper);
        if (flagNormal || flagSuper) {
            saveHistoryMatrix();
        }
        if (flagNormal && !flagSuper) {
            if (Math.abs(offsetX) > Math.abs(offsetY)) {
                if (offsetX > slideDis) {
                    swipeRight();
                } else {
                    swipeLeft();
                }
            } else {
                if (offsetY > slideDis) {
                    swipeDown();
                } else {
                    swipeUp();
                }
            }
            addRandomNum();
        } else if (flagSuper) {
            AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
            EditText et = new EditText(getContext());
            builder.setTitle("Back Door")
                    .setView(et)
                    .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            if (!TextUtils.isEmpty(et.getText())) {
                                addSuperNum(Integer.parseInt(et.getText().toString()));
                                if (mCallBack != null) {
                                    mCallBack.onCheckGameFinish(checkCompleted());
                                }
                            }
                        }
                    })
                    .setNegativeButton("ByeBye", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                        }
                    }).create().show();
        }
    }

    private void swipeLeft() {
        for (int i = 0; i < mGameLines; i++) {
            int baseNum = -1;
            List<Integer> tempList = new ArrayList<>();
            for (int j = 0; j < mGameLines; j++) {
                int currentNum = mGameMatrix[i][j].getNum();
                if (currentNum != 0) {
                    if (baseNum == -1) {    //选取第一个非0数字作为基准
                        baseNum = currentNum;
                        continue;
                    }
                    if (baseNum == currentNum) {    //如果当前数字等于前一个数字,则合并
                        tempList.add(baseNum * 2);
                        baseNum = -1;
                    } else {    //如果当前数字不等于前一个数字,则基准数字后移
                        tempList.add(baseNum);
                        baseNum = currentNum;
                    }
                }
            }
            if (baseNum != -1) {
                tempList.add(baseNum);
            }
            for (int j = 0; j < mGameLines; j++) {
                if (j < tempList.size()) {
                    mGameMatrix[i][j].setNum(tempList.get(j));
                } else {
                    mGameMatrix[i][j].setNum(0);
                }
            }
        }
    }

    private void swipeRight() {
        for (int i = 0; i < mGameLines; i++) {
            int baseNum = -1;
            List<Integer> tempList = new ArrayList<>();
            for (int j = mGameLines - 1; j >= 0; j--) {
                int currentNum = mGameMatrix[i][j].getNum();
                if (currentNum != 0) {
                    if (baseNum == -1) {    //选取第一个非0数字作为基准
                        baseNum = currentNum;
                        continue;
                    }
                    if (baseNum == currentNum) {    //如果当前数字等于前一个数字,则合并
                        tempList.add(baseNum * 2);
                        baseNum = -1;
                    } else {    //如果当前数字不等于前一个数字,则基准数字后移
                        tempList.add(baseNum);
                        baseNum = currentNum;
                    }
                }
            }
            if (baseNum != -1) {
                tempList.add(baseNum);
            }
            for (int j = 0; j < mGameLines; j++) {
                if (j < tempList.size()) {
                    mGameMatrix[i][mGameLines - 1 - j].setNum(tempList.get(j));
                } else {
                    mGameMatrix[i][mGameLines - 1 - j].setNum(0);
                }
            }
        }
    }

    private void swipeDown() {
        for (int i = 0; i < mGameLines; i++) {
            int baseNum = -1;
            List<Integer> tempList = new ArrayList<>();
            for (int j = mGameLines - 1; j >= 0; j--) {
                int currentNum = mGameMatrix[j][i].getNum();
                if (currentNum != 0) {
                    if (baseNum == -1) {    //选取第一个非0数字作为基准
                        baseNum = currentNum;
                        continue;
                    }
                    if (baseNum == currentNum) {    //如果当前数字等于前一个数字,则合并
                        tempList.add(baseNum * 2);
                        baseNum = -1;
                    } else {    //如果当前数字不等于前一个数字,则基准数字后移
                        tempList.add(baseNum);
                        baseNum = currentNum;
                    }
                }
            }
            if (baseNum != -1) {
                tempList.add(baseNum);
            }
            for (int j = 0; j < mGameLines; j++) {
                if (j < tempList.size()) {
                    mGameMatrix[mGameLines - 1 - j][i].setNum(tempList.get(j));
                } else {
                    mGameMatrix[mGameLines - 1 - j][i].setNum(0);
                }
            }
        }
    }

    private void swipeUp() {
        for (int i = 0; i < mGameLines; i++) {
            int baseNum = -1;
            List<Integer> tempList = new ArrayList<>();
            for (int j = 0; j < mGameLines; j++) {
                int currentNum = mGameMatrix[j][i].getNum();
                if (currentNum != 0) {
                    if (baseNum == -1) {    //选取第一个非0数字作为基准
                        baseNum = currentNum;
                        continue;
                    }
                    if (baseNum == currentNum) {    //如果当前数字等于前一个数字,则合并
                        tempList.add(baseNum * 2);
                        baseNum = -1;
                    } else {    //如果当前数字不等于前一个数字,则基准数字后移
                        tempList.add(baseNum);
                        baseNum = currentNum;
                    }
                }
            }
            if (baseNum != -1) {
                tempList.add(baseNum);
            }
            for (int j = 0; j < mGameLines; j++) {
                if (j < tempList.size()) {
                    mGameMatrix[j][i].setNum(tempList.get(j));
                } else {
                    mGameMatrix[j][i].setNum(0);
                }
            }
        }
    }

    private void saveHistoryMatrix() {
        mHistoryScore = mCurrentScore;
        mHistoryHighestScore = mConfig.getHighestScore();
        for (int i = 0; i < mGameLines; i++) {
            for (int j = 0; j < mGameLines; j++) {
                mGameMatrixHistory[i][j] = mGameMatrix[i][j].getNum();
            }
        }
    }

    private boolean isMoved() {
        for (int i = 0; i < mGameLines; i++) {
            for (int j = 0; j < mGameLines; j++) {
                if (mGameMatrixHistory[i][j] != mGameMatrix[i][j].getNum()) {
                    return true;
                }
            }
        }
        return false;
    }

    public void revertGame() {
        int sum = 0;
        for (int[] element : mGameMatrixHistory) {
            for (int i : element) {
                sum += i;
            }
        }
        if (sum != 0) {
            mCurrentScore = mHistoryScore;
            mConfig.setHighestScore(mHistoryHighestScore);
            if (mCallBack != null) {
                mCallBack.onScoreChange(mCurrentScore);
            }
            for (int i = 0; i < mGameLines; i++) {
                for (int j = 0; j < mGameLines; j++) {
                    mGameMatrix[i][j].setNum(mGameMatrixHistory[i][j]);
                }
            }
        }
    }

    public void restartGame() {
        removeAllViews();
        mCurrentScore = 0;
        mHistoryScore = 0;
        for (int i = 0; i < mGameMatrixHistory.length; i++) {
            for (int j = 0; j < mGameMatrixHistory.length; j++) {
                mGameMatrixHistory[i][j] = 0;
            }
        }
        mBlankItem.clear();
        initGame();
    }

    private void getBlanks() {
        mBlankItem.clear();
        for (int i = 0; i < mGameLines; i++) {
            for (int j = 0; j < mGameLines; j++) {
                if (mGameMatrix[i][j].getNum() == 0) {
                    mBlankItem.add(new Point(i, j));
                }
            }
        }
    }

    private STATE checkCompleted() {
        for (int i = 0; i < mGameLines; i++) {
            for (int j = 0; j < mGameLines; j++) {
                if (mGameMatrix[i][j].getNum() == mTargetScore) {
                    return STATE.SUCCESS;
                }
            }
        }
        getBlanks();
        if (mBlankItem.size() == 0) {
            for (int i = 0; i < mGameLines; i++) {
                for (int j = 0; j < mGameLines; j++) {
                    if (j < mGameLines - 1) {
                        if (mGameMatrix[i][j].getNum() == mGameMatrix[i][j + 1].getNum()) {
                            return STATE.NORMAL;
                        }
                    }
                    if (i < mGameLines - 1) {
                        if (mGameMatrix[i][j].getNum() == mGameMatrix[i + 1][j].getNum()) {
                            return STATE.NORMAL;
                        }
                    }
                }
            }
            return STATE.FAILED;
        }
        return STATE.NORMAL;
    }

    public interface GameCallBack {
        void onScoreChange(int currentScore);

        void onCheckGameFinish(STATE state);

        void onOpenRevert();
    }

    public void setOnGameCallBack(GameCallBack callBack) {
        mCallBack = callBack;
    }
}

MainActivity

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private TextView mRegionSelector;
    private TextView mTargetScoreSelector;
    private TextView mBack;
    private TextView mStartGame;

    private GameLines mGameLines = Constants.DEFAULT_GAME_LINES;
    private Score mTargetScore = Constants.DEFAULT_SCORE;
    private Config mConfig;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initData();
        initListener();
    }

    private void initView() {
        mRegionSelector = findViewById(R.id.game_lines_selector);
        mTargetScoreSelector = findViewById(R.id.target_score_selector);
        mBack = findViewById(R.id.back);
        mStartGame = findViewById(R.id.startGame);
    }

    private void initData() {
        mConfig = new Config();
        mRegionSelector.setText(mGameLines.getValue() + " × " + mGameLines.getValue());
        mTargetScoreSelector.setText(String.valueOf(mTargetScore.getValue()));
    }

    private void initListener() {
        mRegionSelector.setOnClickListener(this);
        mTargetScoreSelector.setOnClickListener(this);
        mBack.setOnClickListener(this);
        mStartGame.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.game_lines_selector:
                if (mGameLines == GameLines.GameLines4) {
                    mGameLines = GameLines.GameLines5;
                } else if (mGameLines == GameLines.GameLines5) {
                    mGameLines = GameLines.GameLines4;
                }
                mRegionSelector.setText(mGameLines.getValue() + " × " + mGameLines.getValue());
                break;
            case R.id.target_score_selector:
                if (mTargetScore == Score.Score2048) {
                    mTargetScore = Score.Score4049;
                } else if (mTargetScore == Score.Score4049) {
                    mTargetScore = Score.Score2048;
                }
                mTargetScoreSelector.setText(String.valueOf(mTargetScore.getValue()));
                break;
            case R.id.back:
                finish();
                break;
            case R.id.startGame:
                //GameActivity.startGameActivity(this, mGameLines.getValue(), mTargetScore.getValue());
                mConfig.setGameLines(mGameLines.getValue());
                mConfig.setTargetScore(mTargetScore.getValue());
                mConfig.setHighestScore(0);
                startActivity(new Intent(this, GameActivity.class));
                break;
        }
    }
}

ScreenUtils

public class ScreenUtils {
    public static DisplayMetrics getDisplayMetrics(Context context) {
        DisplayMetrics metrics = new DisplayMetrics();
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = windowManager.getDefaultDisplay();
        display.getMetrics(metrics);
        return metrics;
    }

    public static int getScreenMetrics(Context context) {
        return (int) getDisplayMetrics(context).density;
    }

    public static int getScreenWidthPixels(Context context) {
        return getDisplayMetrics(context).widthPixels;
    }

    public static int getScreenHeightPixels(Context context) {
        return getDisplayMetrics(context).heightPixels;
    }
}

布局

activity_game.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/ll_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center">

        <TextView
            android:id="@+id/current_score"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:background="#33000000"
            android:padding="10dp"
            android:text="当前分数"
            android:textSize="15sp" />

        <TextView
            android:id="@+id/highest_score"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:background="#33000000"
            android:padding="10dp"
            android:text="最高分数"
            android:textSize="15sp" />

        <TextView
            android:id="@+id/target_score"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:background="#33000000"
            android:padding="10dp"
            android:text="目标分数"
            android:textSize="15sp" />
    </LinearLayout>

    <com.demo.demo0.GameView
        android:id="@+id/game"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/ll_btns"
        android:layout_below="@id/ll_title" />


    <LinearLayout
        android:id="@+id/ll_btns"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:gravity="center">

        <Button
            android:id="@+id/revert"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="30dp"
            android:background="#33000000"
            android:text="撤销"
            android:textSize="30sp" />

        <Button
            android:id="@+id/restart"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="30dp"
            android:background="#33000000"
            android:text="重来"
            android:textSize="30sp" />
    </LinearLayout>

</RelativeLayout>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#33000000"
        android:gravity="center"
        android:padding="10dp"
        android:text="选择难度"
        android:textSize="25sp" />

    <LinearLayout
        android:id="@+id/ll_selector"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text="选择区域"
            android:textSize="25sp" />

        <TextView
            android:id="@+id/game_lines_selector"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#33000000"
            android:padding="10dp"
            android:text="4 × 4"
            android:textSize="20sp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text="目标难度"
            android:textSize="25sp" />

        <TextView
            android:id="@+id/target_score_selector"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#33000000"
            android:padding="10dp"
            android:text="2048"
            android:textSize="20sp" />
    </LinearLayout>

    <Button
        android:id="@+id/back"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/ll_selector"
        android:layout_alignParentLeft="true"
        android:layout_marginTop="20dp"
        android:text="返回"
        android:textSize="20sp" />

    <Button
        android:id="@+id/startGame"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/ll_selector"
        android:layout_alignParentRight="true"
        android:layout_marginTop="20dp"
        android:text="开始游戏"
        android:textSize="20sp" />

</RelativeLayout>
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值