Android期末项目2048小游戏

Android期末项目2048小游戏。

简介

2048属于益智类小游戏,它做到了娱乐性、趣味性、教育性相统一。益智类的游戏即是需要去开动大脑去思考从而获得游戏的胜利。简单的益智类游戏可以使玩家在娱乐中不断的开发大脑。这样一来就实现了在娱乐中学习。每次可以选择上下左右其中一个方向去滑动,每滑动一次,所有的数字方块都会往滑动的方向靠拢,系统也会在空白的地方随机出现一个数字方块,相同数字的方块在靠拢、相撞时会相加。不断的叠加最终拼凑出2048这个数字就算成功。

设计思想

完成2048基本功能,加入动画效果,加入声音效果,能够记录并显示最高分,能够自动保存游戏进度。

程序功能

1.基本的2048游戏功能
2.记录最高分功能
3.记录完成2048次数功能
4.声音设置功能
5.自动保存游戏进度功能
6.结束游戏时判定是否是新纪录

程序截图

Android期末项目2048小游戏_第1张图片

Android期末项目2048小游戏_第2张图片

Android期末项目2048小游戏_第3张图片
Android期末项目2048小游戏_第4张图片
Android期末项目2048小游戏_第5张图片

部分功能实现

1.初始化面板

// An highlighted block
public void initView() {
        removeAllViews();
        canSwipe = true;
        getGoal=false;
        gridColumnCount=4;
        cells = new Cell[gridColumnCount][gridColumnCount];
        // 设置界面大小
        setColumnCount(gridColumnCount);
        // 获取格子的宽
        int cellWidth = getCellSize();
        // 获取格子的高
        int cellHeight = getCellSize();
        addCell(cellWidth, cellHeight);
        startGame();
        setOnTouchListener((v, event) -> {
            // 通知父控件不要拦截此控件的onTouch事件
            v.getParent().requestDisallowInterceptTouchEvent(true);
            if (canSwipe) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        setX = event.getX();
                        setY = event.getY();
                        break;
                    case MotionEvent.ACTION_UP:
                        offsetX = event.getX() - setX;
                        offsetY = event.getY() - setY;
                        // 判断滑动方向
                        int orientation = getOrientation(offsetX, offsetY);
                        switch (orientation) {
                            case 0:
                                // 向右滑动
                                swipeRight();
                                break;
                            case 1:
                                // 向左滑动
                                swipeLeft();
                                break;
                            case 2:
                                // 向下滑动
                                swipeDown();
                                break;
                            case 3:
                                // 向上滑动
                                swipeUp();
                                break;
                            default:
                                break;
                        }
                    default:
                        break;
                }
            }
            return true;
        });
    }
 

2.Cell类实现,Cell表示游戏中移动的数字快,块的字体、颜色、等属性都在对象中进行设置,Cell类如下:

package com.example.game2048.view;

import android.content.Context;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import android.graphics.Typeface;
import android.view.Gravity;
import android.widget.FrameLayout;
import android.widget.TextView;
import com.example.game2048.R;

public class Cell extends FrameLayout {

    private TextView cellShowText;
    private int digital;

    public Cell(Context context) {
        super(context);
    }
    public Cell(@NonNull Context context, int leftMargin, int topMargin, int bottomMargin) {
        super(context);
        init(context, leftMargin, topMargin, bottomMargin);
    }


    private void init(@NonNull Context context, int leftMargin, int topMargin, int bottomMargin) {
        cellShowText = new TextView(context);
        cellShowText.setTextSize(40);
        cellShowText.setGravity(Gravity.CENTER);
        // 抗锯齿
        cellShowText.getPaint().setAntiAlias(true);
        // 粗体
        cellShowText.getPaint().setFakeBoldText(true);
        // 字体
        cellShowText.setTypeface(Typeface.MONOSPACE);
        // 颜色
        cellShowText.setTextColor(ContextCompat.getColor(context, R.color.colorTextDark));
        // 填充整个父容器
        LayoutParams params = new LayoutParams(-1, -1);
        params.setMargins(leftMargin, topMargin, 0, bottomMargin);
        addView(cellShowText, params);
        setDigital(0);
    }

    //获取卡片
    public TextView getItemCell() {
        return cellShowText;
    }

    //获取数字
    public int getDigital() {
        return digital;
    }

    //设置数字
    public void setDigital(int digital) {
        this.digital = digital;
        cellShowText.setBackgroundResource(getBackgroundResource(digital));
        if (digital <= 0) {
            cellShowText.setText("");
        } else {
            cellShowText.setText(String.valueOf(digital));
        }
    }

   //设置数字背景
    private int getBackgroundResource(int number) {
        switch (number) {
            case 0:
                return R.drawable.bg_cell_0;
            case 2:
                return R.drawable.bg_cell_2;
            case 4:
                return R.drawable.bg_cell_4;
            case 8:
                return R.drawable.bg_cell_8;
            case 16:
                return R.drawable.bg_cell_16;
            case 32:
                return R.drawable.bg_cell_32;
            case 64:
                return R.drawable.bg_cell_64;
            case 128:
                return R.drawable.bg_cell_128;
            case 256:
                return R.drawable.bg_cell_256;
            case 512:
                return R.drawable.bg_cell_512;
            case 1024:
                return R.drawable.bg_cell_1024;
            case 2048:
                return R.drawable.bg_cell_2048;
            default:
                return R.drawable.bg_cell_default;
        }
    }

}

3、在空白处随机添加数字

public void addDigital() {
        getEmptyCell();
        if (emptyCellPoint.size() > 0) {
            // 随机取出一个空格子的坐标位置
            Point point = emptyCellPoint.get((int) (Math.random() * emptyCellPoint.size()));
            cells[point.x][point.y].setDigital(Math.random() > 0.4 ? 2 : 4);

            // 设置动画
            setAppearAnim(cells[point.x][point.y]);
        }
    }

4、向面板中加入数字块

private void addCell(int cellWidth, int cellHeight) {
        Cell cell;
        for (int i = 0; i < gridColumnCount; i++) {
            for (int j = 0; j < gridColumnCount; j++) {
                if (i == gridColumnCount - 1) {
                    // 为最底下的格子加上bottomMargin
                    cell = new Cell(getContext(), 16, 16, 16);
                } else {
                    cell = new Cell(getContext(), 16, 16, 0);
                }
                cell.setDigital(0);
                addView(cell, cellWidth, cellHeight);
                cells[i][j] = cell;
            }
        }
    }

5、滑动逻辑实现,滑动时,判断每一行(列)的数据,0代表空格子,将非0数字存在一个list中,然后判断若当前数字与前一个数字相同,合并,并将此list作为这行(列)的新数据,再按滑动的方向向这行(列)中存放list中的数字,以上滑为例:

private void swipeUp() {
        // 判断是否需要添加数字
        boolean needAddDigital = false;
        for (int i = 0; i < gridColumnCount; i++) {
            for (int j = 0; j < gridColumnCount; j++) {
                // 获取当前位置数字
                int currentDigital = cells[j][i].getDigital();
                someData.add(currentDigital);
                if (currentDigital != 0) {
                    // 记录数字
                    if (recordPreviousDigital == -1) {
                        recordPreviousDigital = currentDigital;
                    } else {
                        // 记录的之前的数字和当前数字不同
                        if (recordPreviousDigital != currentDigital) {
                            // 加入记录的数字
                            dataAfterSwipe.add(recordPreviousDigital);
                            recordPreviousDigital = currentDigital;
                        } else {// 记录的之前的数字和当前的数字相同
                            // 加入*2
                            dataAfterSwipe.add(recordPreviousDigital * 2);
                            // 记录得分
                            recordScore(recordPreviousDigital * 2);
                            // 重置记录数字
                            recordPreviousDigital = -1;
                        }
                    }
                }
            }

            if (recordPreviousDigital != -1) {
                dataAfterSwipe.add(recordPreviousDigital);
            }

            // 补0
            for (int p = dataAfterSwipe.size(); p < gridColumnCount; p++) {
                dataAfterSwipe.add(0);
            }
            // 若原始数据和移动后的数据不同,视为界面发生改变
            if (!someData.equals(dataAfterSwipe)) {
                needAddDigital = true;
            }
            someData.clear();

            // 重新设置格子数据
            for (int k = 0; k < dataAfterSwipe.size(); k++) {
                cells[k][i].setDigital(dataAfterSwipe.get(k));
            }
            // 重置数据
            recordPreviousDigital = -1;
            dataAfterSwipe.clear();
        }
        if (needAddDigital) {
            // 添加一个随机数字(2或4)
            addDigital();
            playSound();
        }
        judgeOverOrAccomplish();
    }

总结

基本完成了2048游戏的所有功能,但界面比较简陋,没有做出块滑动、碰撞的动画。在此过程中也学到了许多新东西,如SharedPreferences, GestureOverlayView, BoradcastReceiver等等。
此项目有待改进的地方:
1.加入数字快滑动和碰撞的动画效果。
2.增加选择阶数功能。即总方块数可由用户自定义4x4或5x5、6x6等。
3.增加一些游戏工具,如消除指定数字块,指定方块换位等,工具可通过完成指定分数获得。

项目源码:链接:https://pan.baidu.com/s/1TwBOzI5MDBPx6LtgzZxYmg 提取码:9pn6

你可能感兴趣的:(android,java)