首页 > 代码库 > pushbox(4)

pushbox(4)

在此之前,先修复以往的一个bug,因为前面的MapList是通过static方法得到二维数组的,因此不论调用

 public static int[][] getMap(int grade)该方法多少此,都将得到同一块二维数组的引用,如果一个改变,则应一个也会改变。而判断某一关是否过关比较的way[][]和may[][]的目标位置是否都变成了箱子,因此就会有一个bug.
解决办法,修改MapList,从三维数组重新拷贝出一个二维数组。
MapList.java
package edu.pushbox;

public class MapList {
    /**
     * 0 nothing 
     * 1 wall 
     * 2 goal 
     * 3 road 
     * 4 box 
     * 5 box at goal 
     * 6 worker
     * */
    
    public static int[][][] map =
        {
            { 
                    { 0, 0, 1, 1, 1, 0, 0, 0 },
                    { 0, 0, 1, 2, 1, 0, 0, 0 },
                    { 0, 0, 1, 3, 1, 1, 1, 1 },
                    { 1, 1, 1, 4, 3, 4, 2, 1 },
                    { 1, 2, 3, 4, 6, 1, 1, 1 },
                    { 1, 1, 1, 1, 4, 1, 0, 0 },
                    { 0, 0, 0, 1, 2, 1, 0, 0 }, 
                    { 0, 0, 0, 1, 1, 1, 0, 0 } 
            },
            {     
                    { 1, 1, 1, 1, 1, 0, 0, 0, 0 },
                    { 1, 6, 3, 3, 1, 0, 0, 0, 0 },
                    { 1, 3, 4, 4, 1, 0, 1, 1, 1 },
                    { 1, 3, 4, 3, 1, 0, 1, 2, 1 },
                    { 1, 1, 1, 3, 1, 1, 1, 2, 1 },
                    { 0, 1, 1, 3, 3, 3, 3, 2, 1 },
                    { 0, 1, 3, 3, 3, 1, 3, 3, 1 },
                    { 0, 1, 3, 3, 3, 1, 1, 1, 1 },
                    { 0, 1, 1, 1, 1, 1, 0, 0, 0 } 
            }
        };

    public static int count = map.length;

    public static int getCount() {
        return count;
    }
    /*
     * 判断是否到最后一关
     */
    public static boolean isEnd(int grade) {
        if(grade==count){
            return true;
        }else{
            return false;
        }
    }

/*
 * 从MapList分离出int map[][]
 */
    public static int[][] getMap(int grade) {
        int row = map[grade].length;
        int col = map[grade][0].length;

        int[][] result = new int[row][col];
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                result[i][j] = map[grade][i][j];
            }
        }
        return result;
    }

    /*
     * CopyMap return int[][]
     */
    public static int[][] copyMap(int[][] src) {
        int row = src.length;
        int col = src[0].length;

        int[][] result = new int[row][col];
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                result[i][j] = src[i][j];
            }
        }
        return result;
    }
}
本节:
当某一步走错是需要有一个back返回功能,这就要记录下上一次的map存起来,当用户需要返回时,再取回。这就要求每一次推之前就要先记录当前map[][]然后再更新。特别添加map助手类。

CurrentMap.java(把map[][]包装,以便存入mapUtil中)

package edu.pushbox.util;

public class CurrentMap {
    private int[][] currentMap;

    public int[][] getCurrentMap() {
        int row = currentMap.length;
        int col = currentMap[0].length;
        int[][] result = new int[row][col];
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                result[i][j] = currentMap[i][j];
            }
        }
        return result;
    }

    public void setCurrentMap(int[][] currentMap) {
        this.currentMap = currentMap;
    }

    public CurrentMap(int[][] currentMap) {
        int row = currentMap.length;
        int col = currentMap[0].length;
        int[][] result = new int[row][col];
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                result[i][j] = currentMap[i][j];
            }
        }
        this.currentMap = result;
    }
}

MapUtils.java 

package edu.pushbox.util;

import java.util.ArrayList;

public class MapUtils {
    private ArrayList<CurrentMap> list;
    private int size=10;

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    private static MapUtils mapUtils = new MapUtils();

    private MapUtils() {
        list = new ArrayList<CurrentMap>();
    }

    public static MapUtils getSingleton() {
        return mapUtils;
    }

    /*
     * 判断是否能回
     */
    public boolean canBack() {
        boolean flag = false;
        if (list.size() > 0) {
            flag = true;
        }
        return flag;
    }

    /*
     * 储存一步
     */

    public void storeOneMap(CurrentMap currentMap) {
        list.add(currentMap);
        if (list.size() > size) {
            list.remove(0);
        }
    }

    /*
     * 退回一步
     */

    public CurrentMap returnBack() {
        CurrentMap currentMap = list.get(list.size() - 1);
        list.remove(list.size() - 1);
        return currentMap;
    }

    /*
     * 清空路
     */
    public void clear() {
        list.clear();
    }
}
GameView.java
package edu.pushbox;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;
import edu.phshbox.R;
import edu.pushbox.service.PreferencesService;
import edu.pushbox.util.CurrentMap;
import edu.pushbox.util.MapUtils;
import edu.pushbox.util.Point;
import edu.pushbox.util.Position;

public class GameView extends View {
    private int count = 0;// count
    private long beginTime = 0;// time
    private long currentTime = 0;// time
    int width = 0;
    int oxOff = 15;
    int oyOff = 30;
    GameMain gameMain = null;

    public final int WALL = 1;//
    public final int GOAL = 2;// 目标
    public final int ROAD = 3;//
    public final int BOX = 4;// 锟斤拷锟斤拷
    public final int BOX_AT_GOAL = 5;// 锟斤拷锟接碉拷目锟斤拷位锟斤拷
    public final int WORKER = 6;//

    public final int BACK = 7;
    public final int UP = 8;
    public final int DOWN = 9;
    public final int LEFT = 10;
    public final int RIGHT = 11;
    public final int EXIT = 12;
    public final int SETTING = 13;
    private MapUtils mapUtils = MapUtils.getSingleton();;
    private Point workPoint;
    int wrow, wcolumn;
    public static int picSize = 30;
    private int map[][] = null;// 路锟斤拷位锟斤拷
    private int way[][] = null;// 原始路锟斤拷位锟斤拷
    private int row = 0;
    private int col = 0;
    private static int grade = 0;
    private String[] arrayGrade = null;
    private static final int GRADE = 2;
    private Bitmap picture[] = null;
    private PreferencesService preferencesService = null;
    private int selectedGradeIndex = 0;
    public GameView(Context context, AttributeSet attrs) {
        super(context, attrs);
        gameMain = (GameMain) context;
        preferencesService = new PreferencesService(context);
        WindowManager win = gameMain.getWindowManager();
        width = win.getDefaultDisplay().getWidth();
        grade = Integer.parseInt(preferencesService.getPreferences("grade"));
        Log.d("GRADE", grade + "");
        init();
    }

    public void init() {
        initMap();
        initWay();
        initMapUtils();
        initWorkerPosition();
        initTimeAndCount();
        reset();
        initPicture();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
            moveDown();
        } else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
            moveUp();
        } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
            moveLeft();
        } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
            moveRight();
        } else if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
            if (mapUtils.canBack()) {
                count--;
                returnBack();
            } else {
                Toast.makeText(this.getContext(), "Can‘t return more",
                        Toast.LENGTH_LONG).show();
            }
        }
        if (Position.isSuccess(map, way, GOAL)) {

            Dialog alterDialog = new AlertDialog.Builder(getContext())
                    .setTitle(R.string.tip)
                    .setMessage(R.string.continue_next)
                    .setIcon(getResources().getDrawable(R.drawable.tip))
                    .setPositiveButton(R.string.yes,
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog,
                                        int which) {
                                    GameView.grade = GameView.grade + 1;
                                    preferencesService.save("grade", grade);
                                    // Log.d("Grade",grade+"");
                                    if (MapList.isEnd(grade)) {
                                        resetGrade();
                                    }
                                    Log.d("Grade", grade + "");
                                    init();
                                    initMapUtils();
                                }
                            })
                    .setNegativeButton(R.string.no,
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog,
                                        int which) {

                                }
                            }).create();
            alterDialog.show();
        }
        invalidate();
        currentTime = System.currentTimeMillis();
        invalidate();
        return super.onKeyDown(keyCode, event);
    }

    private void returnBack() {
        map = mapUtils.returnBack().getCurrentMap();
        initWay();
        initWorkerPosition();
    }

    /*
     * 重置关数
     */
    private void resetGrade() {
        grade = 0;
    }
  /**
   *移动之前先保存当前路径
   */
private void moveDown() { if (map[wrow + 1][wcolumn] == ROAD || map[wrow + 1][wcolumn] == GOAL) { count++; mapUtils.storeOneMap(new CurrentMap(map)); map[wrow + 1][wcolumn] = WORKER; map[wrow][wcolumn] = roadOrGoal(); wrow++; return; } else if (map[wrow + 1][wcolumn] == BOX || map[wrow + 1][wcolumn] == BOX_AT_GOAL) { if (map[wrow + 2][wcolumn] == ROAD || map[wrow + 2][wcolumn] == GOAL) { count++; mapUtils.storeOneMap(new CurrentMap(map)); map[wrow + 2][wcolumn] = map[wrow + 2][wcolumn] == GOAL ? BOX_AT_GOAL : BOX; map[wrow + 1][wcolumn] = WORKER; map[wrow][wcolumn] = roadOrGoal(); wrow++; return; } } } private void moveUp() { if (map[wrow - 1][wcolumn] == ROAD || map[wrow - 1][wcolumn] == GOAL) { count++; mapUtils.storeOneMap(new CurrentMap(map)); map[wrow - 1][wcolumn] = WORKER; map[wrow][wcolumn] = roadOrGoal(); wrow--; return; } else if (map[wrow - 1][wcolumn] == BOX || map[wrow - 1][wcolumn] == BOX_AT_GOAL) { if (map[wrow - 2][wcolumn] == ROAD || map[wrow - 2][wcolumn] == GOAL) { count++; mapUtils.storeOneMap(new CurrentMap(map)); map[wrow - 2][wcolumn] = map[wrow - 2][wcolumn] == GOAL ? BOX_AT_GOAL : BOX; map[wrow - 1][wcolumn] = WORKER; map[wrow][wcolumn] = roadOrGoal(); wrow--; return; } } } private void moveLeft() { if (map[wrow][wcolumn - 1] == ROAD || map[wrow][wcolumn - 1] == GOAL) { count++; mapUtils.storeOneMap(new CurrentMap(map)); map[wrow][wcolumn - 1] = WORKER; map[wrow][wcolumn] = roadOrGoal(); wcolumn--; return; } else if (map[wrow][wcolumn - 1] == BOX || map[wrow][wcolumn - 1] == BOX_AT_GOAL) { if (map[wrow][wcolumn - 2] == ROAD || map[wrow][wcolumn - 2] == GOAL) { count++; mapUtils.storeOneMap(new CurrentMap(map)); map[wrow][wcolumn - 2] = map[wrow][wcolumn - 2] == GOAL ? BOX_AT_GOAL : BOX; map[wrow][wcolumn - 1] = WORKER; map[wrow][wcolumn] = roadOrGoal(); wcolumn--; return; } } } private void moveRight() { if (map[wrow][wcolumn + 1] == ROAD || map[wrow][wcolumn + 1] == GOAL) { count++; mapUtils.storeOneMap(new CurrentMap(map)); map[wrow][wcolumn + 1] = WORKER; map[wrow][wcolumn] = roadOrGoal(); wcolumn++; return; } else if (map[wrow][wcolumn + 1] == BOX || map[wrow][wcolumn + 1] == BOX_AT_GOAL) { if (map[wrow][wcolumn + 2] == ROAD || map[wrow][wcolumn + 2] == GOAL) { count++; mapUtils.storeOneMap(new CurrentMap(map)); map[wrow][wcolumn + 2] = map[wrow][wcolumn + 2] == GOAL ? BOX_AT_GOAL : BOX; map[wrow][wcolumn + 1] = WORKER; map[wrow][wcolumn] = roadOrGoal(); wcolumn++; return; } } } private int roadOrGoal() { int result = ROAD; if (way[wrow][wcolumn] == GOAL) result = GOAL; return result; } public void reset() { row = map.length; col = map[0].length; picSize = (int) Math.floor((width - oxOff - oyOff) / col); } private void initMap() { map = MapList.getMap(grade); } // private void initTimeAndCount() { beginTime = System.currentTimeMillis(); currentTime = System.currentTimeMillis(); count = 0; } /* * copy map to way */ private void initWay() { way = MapList.copyMap(map); } /* * getWorkPosition */ private void initWorkerPosition() { workPoint = Position.getPosition(map, WORKER);// 找到人的位置 wrow = workPoint.row; wcolumn = workPoint.column; } /* * initMapUtils */ private void initMapUtils() { mapUtils.clear(); } private void initPicture() { picture = new Bitmap[14]; loadPicture(WALL, R.drawable.wall); loadPicture(GOAL, R.drawable.goal); loadPicture(ROAD, R.drawable.road); loadPicture(BOX, R.drawable.box); loadPicture(BOX_AT_GOAL, R.drawable.box_at_goal); loadPicture(WORKER, R.drawable.worker); loadPicture(BACK, R.drawable.back); loadPicture(UP, R.drawable.up); loadPicture(DOWN, R.drawable.down); loadPicture(LEFT, R.drawable.left); loadPicture(RIGHT, R.drawable.right); loadPicture(EXIT, R.drawable.exit); loadPicture(SETTING, R.drawable.setting); } private void loadPicture(int key, int pictureId) { Drawable drawable = getResources().getDrawable(pictureId); Bitmap bitMap = Bitmap.createBitmap(picSize, picSize, Bitmap.Config.ARGB_8888); drawable.setBounds(0, 0, picSize, picSize); Canvas canvas = new Canvas(bitMap); drawable.draw(canvas); picture[key] = bitMap; } @SuppressLint("DrawAllocation") @Override protected void onDraw(Canvas canvas) { Paint paint = new Paint(); paint.setColor(Color.RED); paint.setTextSize(14); for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { if (map[i][j] > 0) canvas.drawBitmap(picture[map[i][j]], oxOff + picSize * j, oyOff + picSize * i, paint); } } canvas.drawText(getContext().getString(R.string.time) + "" + (currentTime - beginTime) / 1000, 6, 16, paint); canvas.drawText(getContext().getString(R.string.count) + "" + count, 190, 16, paint); canvas.drawBitmap(picture[BACK], oxOff, oyOff + row * picSize + 20, paint); canvas.drawBitmap(picture[UP], oxOff + picSize, oyOff + row * picSize + 20, paint); canvas.drawBitmap(picture[DOWN], oxOff + 2 * picSize, oyOff + row * picSize + 20, paint); canvas.drawBitmap(picture[LEFT], oxOff + 3 * picSize, oyOff + row * picSize + 20, paint); canvas.drawBitmap(picture[RIGHT], oxOff + 4 * picSize, oyOff + row * picSize + 20, paint); canvas.drawBitmap(picture[EXIT], oxOff + 5 * picSize + 10, oyOff + row * picSize + 20, paint); canvas.drawBitmap(picture[SETTING], oxOff + 7 * picSize, oyOff + row * picSize + 20, paint); super.onDraw(canvas); } }