在此之前,先修复以往的一个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);
}
}
pushbox(4),布布扣,bubuko.com