先介绍作者做该项目的历程,本人有c语言、python基础,技术仅为入门级别,初学java,仅仅看了一节cs61b的课程,完成该项目用了3-4h。所以没有java基础的小白完全不用担心,该项目主要考察你一些游戏的逻辑,编程只是展示你逻辑的手段。做之前可以先玩玩2048,边玩边思考这款游戏的运行逻辑。
游戏网址:2048
游戏的spec去官方网站去看,这里主要说一下做项目的经验和容易出现的坑,仅供参考。
首先,你未必要一口气读完proj里的所有代码,建议的路径是从目标函数本身出发阅读,遇到不懂的地方再进行扩展,去相关的代码部分查看。这里的底层逻辑是扩散学习而非线性学习,以问题驱动。
前三个函数没什么难度,这里略过。
第四个tilt函数,是开放度最大的函数,简而言之就是游戏中展现玩家不同按键后界面产生相应变化的底层逻辑。作者的思路比较暴力,就是把每一列作为独立单元处理,每个单元有n=4种情况,即以每一列有n个存在的方块进行分类,对每类的运行逻辑逐一处理。
代码如下:
public boolean tilt(Side side) {
boolean changed;
changed = false;
board.setViewingPerspective(side);
changed = isChanged(changed);//函数返回changed变量的真值
board.setViewingPerspective(Side.NORTH);
checkGameOver();
if (changed) {
setChanged();
}
return changed;
}
private boolean isChanged(boolean changed) {
ArrayList<Integer>[] valids = new ArrayList[4]; // 使用ArrayList数组来动态存储行数
// 初始化valids数组
for (int i = 0; i < valids.length; i++) {
valids[i] = new ArrayList<>();
}
//遍历board,如果(col,row)存在方块,则将row存入valids[col][]中
for(int col=0;col<board.size();col++){
for(int row= board.size()-1; row>=0;row--){
if(board.tile(col,row)!=null)valids[col].add(row);
}
}
//遍历每一列
for(int i=0;i<4;i++){
//如果某一列均为空,跳过
if(valids[i].isEmpty())continue;
//注意坐标表示,board左下角为(0,0),右上角为(3,3)
if(valids[i].size()==1){
Tile t = board.tile(i,valids[i].get(0));
if(t.row()!=3) changed =true;
board.move(i, 3,t);
} else if (valids[i].size()==2) {
Tile t = board.tile(i,valids[i].get(0));
Tile tile1 = board.tile(i,valids[i].get(1));
if(t.row()!=3) changed =true;
board.move(i, 3,t);
if(tile1.value()==t.value()) {
changed =true;
board.move(i,3,tile1);
score+=board.tile(i,3).value();
}
else {
if(tile1.row()!=2) changed =true;
board.move(i,2,tile1);
}
} else if (valids[i].size()==3) {
Tile t = board.tile(i,valids[i].get(0));
if(t.row()!=3) changed =true;
board.move(i, 3,t);
Tile tile1 = board.tile(i,valids[i].get(1));
Tile tile2 = board.tile(i,valids[i].get(2));
if(tile1.value()==t.value()){
changed =true;
board.move(i,3,tile1);
score+=board.tile(i,3).value();
board.move(i, 2,tile2);
}else {
if(tile1.row()!=2) changed =true;
board.move(i,2,tile1);
if(tile2.value()==tile1.value()){
changed =true;
board.move(i,2, tile2);
score+=board.tile(i,2).value();
}
else {
if(tile2.row()!=1) changed =true;
board.move(i,1,tile2);
}
}
} else if (valids[i].size()==4) {
Tile t = board.tile(i,valids[i].get(0));
if(t.row()!=3) changed =true;
board.move(i, 3,t);
Tile tile1 = board.tile(i,valids[i].get(1));
Tile tile2 = board.tile(i,valids[i].get(2));
Tile tile3 = board.tile(i,valids[i].get(3));
if(tile1.value()==t.value()){
changed =true;
board.move(i,3,tile1);
score+=board.tile(i,3).value();
board.move(i, 2,tile2);
if(tile2.value()==tile3.value()){
board.move(i, 2, tile3);
score+=board.tile(i,2).value();
}else {
board.move(i,1,tile3);
}
}else{
if(tile1.row()!=2) changed =true;
board.move(i,2,tile1);
if(tile1.value()==tile2.value()){
changed =true;
board.move(i,2,tile2);
score+= board.tile(i,2).value();
board.move(i,1,tile3);
}
else{
if(tile2.row()!=1) changed =true;
board.move(i,1,tile2);
if(tile2.value()==tile3.value()){
changed =true;
board.move(i,1,tile3);
score+=board.tile(i,1).value();
}
}
}
}
}
return changed;
}
最后遇到了一个问题:所有测试均通过,但按键后游戏无响应。解决方法如下: