之前一直心心念想做小游戏,这次终于花了一个下午写了一个推箱子,本来想做有GUI的,但是找了半个小时图之后就放弃了。
其实推箱子思路很简单,逻辑也很清晰,主要是想看一下自己能不能用类的思想来实现,我也不知道自己这样写有哪些问题,还希望路过的大神指点一下。
文末贴一个我遇到的问题及参考的博客
package SokoMan;
import java.util.Scanner;
public class Main {
/*
* 使用手册:命令行推箱子小游戏
*
* 符号含义:
* .:空地
* M:墙
* O:箱子
* Y:人(当前处于空地)
* T:(Target)目的地
* f:(find)箱子到达目的地
* $:人站在目的地上面
*
* 移动:
* w-上
* s-下
* a-左
* d-右
*
* 操作说明:
* 每次运行游戏就会弹出地图,每次移动会更新地图(输入上下左右后回车,每次只能有一个命令),当所有目标归位时显示“You Win”,同时游戏结束,程序退出
*
* 测试说明:
* 所有测试用数据都在最前面。
* x,y代表初始时人的位置
* tot代表目的地的总数
* ROW和COL代表地图的行和列
* 更改地图时注意同时更改以上数据即可。
*
* 后编:
* 以下代码中
* x,y都代表当前的人物的位置
* x_,y_都代表当前的人物在当前方向的下一个位置
* newX,newY都代表当前的人物在当前方向的下下一个位置
*
*/
/*
* 0为空地
* 1为墙
* 2为箱子
* 3为没有箱子的目的地
* 4为有箱子的目的地
* 5为人在空地
* 6为人在目标
*/
//如果判定出来是有目标的箱子,优先进入目标
int x, y;
int x_, y_;
int newX, newY;
static int num = 0;
final static int tot = 3;
static int ROW = 6;
static int COL = 10;
int[][] maze = {
{1,1,1,1,1,1,1,1,1,1},
{1,0,0,0,0,0,0,0,0,1},
{1,5,2,3,0,2,3,0,0,1},
{1,0,0,0,2,3,0,0,0,1},
{1,0,0,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1},
};
Print print = new Print();
Change change = new Change();
//人的下一个位置是箱子,仅处理 箱子-(?) 的情况
class Box{
Wall wall = new Wall();
public void Check(String dir){
newX=change.changeX(dir,x_);
newY=change.changeY(dir,y_);
if(maze[newX][newY] == 1){ //箱子-墙
print.print(dir,false);
}else if(maze[newX][newY] == 2){ //箱子-箱子
print.print(dir,false);
}else if(maze[newX][newY] == 0){ //箱子-空地
print.print(dir,true);
}else if(maze[newX][newY] == 3){ //箱子-没有箱子的目的地
//num++;
print.print(dir,true);
}else if(maze[newX][newY] == 4){ //箱子-有箱子的目的地
print.print(dir,false);
}
}
}
//人的下一个位置是墙,仅处理 墙-(?) 的情况
class Wall{
public void Check(String dir){
print.print(dir, false);
}
}
//人的下一个位置是目标,仅处理 目标-(?) 的情况
class Target{
public void Check(String dir){
if(maze[x_][y_] == 4){ //人-有箱子的目的地
newX = change.changeX(dir,x_);
newY = change.changeY(dir,y_);
if(maze[newX][newY] == 0){ //人-有箱子的目的地-空地
print.print(dir,true);
}else if(maze[newX][newY] == 1){ //人-有箱子的目的地-墙
print.print(dir, false);
}else if(maze[newX][newY] == 2){ //人-有箱子的目的地-箱子
print.print(dir, false);
}else if(maze[newX][newY] == 3){ //人-有箱子的目的地-没有箱子的目的地
print.print(dir, true);
}else if(maze[newX][newY] == 4){ //人-有箱子的目的地-有箱子的目的地
print.print(dir, false);
}
}else if(maze[x_][y_] == 3){
print.print(dir, true);
}
}
}
//初始图片并且每次找到人在对应方向的下一个物品,调用该类处理
//每次行走结束判断是否胜利
class Person{
Box box = new Box();
Wall wall = new Wall();
Target target = new Target();
Person(){
x = 2; y = 1;
print.print("a", false);
}
public void run(){
Scanner scan = new Scanner(System.in);
while(scan.hasNext()){
String dir = scan.next();
System.out.println(dir);
if(dir.equals("a")==false && dir.equals("s")==false
&& dir.equals("d")==false && dir.equals("w")==false) continue;
x_=change.changeX(dir,x);
y_=change.changeY(dir,y);
if(maze[x_][y_] == 0){
print.print(dir, true);
}else if(maze[x_][y_] == 1){
print.print(dir, false);
}else if(maze[x_][y_] == 2){
box.Check(dir);
}else if(maze[x_][y_] == 3 || maze[x_][y_] == 4){
target.Check(dir);
}
if(num == tot){
System.out.println("You Win!");
break;
}
}
}
}
//更新图片并同时更新箱子到达目标的箱子数num
class Print{
public void print(String dir,boolean flag){
//说明这是移动后的坐标
if(flag == true){
if(maze[x][y] == 5 || maze[x][y] == 6){
if(maze[x][y] ==5) maze[x][y] = 0;
else maze[x][y] = 3;
if(maze[x_][y_] == 0){ //人-空地
x = x_; y = y_;
maze[x_][y_] = 5;
}else if(maze[x_][y_] == 2){
if(maze[newX][newY] == 0){ //人-箱子-空地
x = x_; y = y_;
maze[x_][y_] = 5;
maze[newX][newY] = 2;
}else if(maze[newX][newY] == 3){ //人-箱子-没箱子的目的地
num++;
x = x_; y = y_;
maze[x_][y_] =5;
maze[newX][newY] = 4;
}
}else if(maze[x_][y_] == 3){ //人-没有箱子的目的地
x = x_; y = y_;
maze[x_][y_] = 6;
}else if(maze[x_][y_] == 4){ //人-有箱子的目的地
if(maze[newX][newY] == 0){ //人-有箱子的目的地-空地
num--;
x = x_; y = y_;
maze[x_][y_] = 6;
maze[newX][newY] = 2;
}else if(maze[newX][newY] == 3){ //人-有箱子的目的地-没有箱子的目的地
x = x_; y = y_;
maze[x_][y_] = 6;
maze[newX][newY] = 4;
}
}
}
}
for(int i=0;i<ROW;i++){
for(int j=0;j<COL;j++){
if(maze[i][j] == 0){
System.out.print(".");
}else if(maze[i][j] == 1){
System.out.print("M");
}else if(maze[i][j] == 2){
System.out.print("O");
}else if(maze[i][j] == 3){
System.out.print("T");
}else if(maze[i][j] == 4){
System.out.print("f");
}else if(maze[i][j] == 5){
System.out.print("Y");
}else if(maze[i][j] == 6){
System.out.print("$");
}
}
System.out.println();
}
}
}
//找到当前x,y的下一个位置
class Change{
public int changeX(String dir,int _x){
if(dir.equals("w")){
_x--;
}else if(dir.equals("s")){
_x++;
}
return _x;
}
public int changeY(String dir,int _y){
if(dir.equals("a")){
_y--;
}else if(dir.equals("d")){
_y++;
}
return _y;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
/*
* 注释掉的语句会报错,因为内部类是依赖于外部类的 如果要创建成员内部类的对象,前提是必须存在一个外部类对象
*/
//Person person = new Person();
Person person = new Main().new Person();
person.run();
}
}
Java内部类
Java内部类一般包括四种:成员内部类,局部内部类,匿名内部类和静态内部类。
上面代码就有成员内部类。1.成员内部类可以无条件访问外部类中的所有成员属性和成员方法(包括private成员和静态成员),但是当内部类和外部类有相同的成员变量或方法时,会发生隐藏现象,默认访问的是内部类成员(外部类.this.成员变量)。2.外部类访问成员内部类必须创建一个成员内部类的对象,再通过只想这个对象的引用来访问
//方法一
Main main_=new Main();
Main.Person person2 = main_.new Person();
//方法二
Main.Person person1 = new Main().new Person();
其他的内部类种类还没遇到过,没有很好的理解,先贴出海 子的博客。