我正在参加「兔了个兔」创意投稿大赛,详情请看:「兔了个兔」创意投稿大赛
创作缘由
活动一月五号就开始了,一直勾的我心痒痒,想参加活动搞点花里胡哨的震惊四座,奈何自己前端水平实在有限,CSS样式我看着就头疼,不知道怎么调出来炫酷的花样,只会纯HTML拼接。左思右想,看到评论区里运营同学说 “鸡兔同笼” 都算在里面,再加上这几天看着不少套着兔子外壳的技术文,终于想出来了一些头绪。 炫酷吊炸天的特效效果我做不出来,但是借着兔子的外壳搞点别的我还是很会的。于是想到了大一时候做过的消消乐游戏,用《三体》中的话来说,我这就是增援未来。 可惜那时的源码已经找不到了,不过凭借我的智慧迅速做出来一套简易的模型还是很容易的。
创作思路
三消类游戏的底层简单的来说就是一个二维数组,里面放了不同类型的元素,如果有接连几分相同的元素就计数或者记分增加结果,主体结构大纲确定下来后,剩下的就是逐步细分,一步步填坑就结束了。
填坑之路
初始化
初始化比较简单,搞个随机数先把棋盘遍历填充好,先不考虑去重的事情。如果这个时候就有满足条件的三连区域,就当给用户送福利积分了。
public static int[][] init(int x, int y) {
int[][] arr = new int[x][y];
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
arr[i][j] = getRabbit();
}
}
return arr;
}
public static int getRabbit() {
return (int) (Math.random() * n);
}
打印棋盘
棋盘初始化后,要展示出来,这样才能有交互。用一个map记录来转换
public static void printBoard() {
Map<Integer, String> desc = descMap();
System.out.println("~~~~~~兔了个兔~~~~~~");
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[0].length; j++) {
System.out.print(desc.get(arr[i][j]) + " ");
}
System.out.println();
}
System.out.println("~~~~~~兔了个兔~~~~~~");
}
public static void printScore() {
System.out.println("当前兔分:" + score);
}
public static Map<Integer, String> descMap() {
Map<Integer, String> descMap = new HashMap<>();
descMap.put(0, "红兔");
descMap.put(1, "橙兔");
descMap.put(2, "黄兔");
descMap.put(3, "绿兔");
descMap.put(4, "蓝兔");
descMap.put(5, "靛兔");
descMap.put(6, "紫兔");
descMap.put(7, "黑兔");
descMap.put(8, "白兔");
descMap.put(9, "青兔");
descMap.put(10, "褐兔");
return descMap;
}
交换计数
这一步是最复杂的一步,因为第一步成功之后,后续还会可能产生消除的效果,怎么解决连续撞击是个问题。
public static int count(int x, int y) {
exchange(x, y, x - 1, y);
int c1 = scan();
if (c1 > 0) {
return c1;
} else {
exchange(x, y, x - 1, y);
}
exchange(x, y, x + 1, y);
int c2 = scan();
if (c2 > 0) {
return c2;
} else {
exchange(x, y, x + 1, y);
}
exchange(x, y, x, y + 1);
int c3 = scan();
if (c3 > 0) {
return c3;
} else {
exchange(x, y, x, y + 1);
}
exchange(x, y, x, y - 1);
int c4 = scan();
if (c4 > 0) {
return c4;
} else {
exchange(x, y, x, y - 1);
}
return 0;
}
public static void exchange(int x1, int y1, int x2, int y2) {
int temp = arr[x1][y1];
arr[x1][y1] = arr[x2][y2];
arr[x2][y2] = temp;
}
public static int scan() {
int s = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[0].length; j++) {
s += test(i, j);
if (s > 0) {
return s;
}
}
}
return 0;
}
public static int test(int x, int y) {
int r = 0, l = 0, u = 0, d = 0;
for (int i = x - 1; i >= 0; i--) {
if (arr[i][y] == arr[x][y]) {
l++;
arr[i][y] = getRabbit();
} else {
break;
}
}
for (int i = x + 1; i < arr.length; i++) {
if (arr[i][y] == arr[x][y]) {
r++;
arr[i][y] = getRabbit();
} else {
break;
}
}
for (int i = y - 1; i >= 0; i--) {
if (arr[x][i] == arr[x][y]) {
u++;
arr[x][i] = getRabbit();
} else {
break;
}
}
for (int i = y + 1; i < arr.length; i++) {
if (arr[i][y] == arr[x][y]) {
d++;
arr[i][y] = getRabbit();
} else {
break;
}
}
int h = (r + l) >= 3 ? (r + l) : 0;
int v = (u + d) >= 3 ? (u + d) : 0;
return h + v;
}
拼接碎片
各个步骤需要的碎片都好了,下面就是拼接到一起了。
public static void main(String[] args) {
arr = init(10, 10);
Scanner sc = new Scanner(System.in);
while (true) {
printBoard();
printScore();
int cnt = scan();
while (cnt != 0) {
printBoard();
printScore();
score += cnt;
cnt = scan();
}
System.out.println("输入可以消除的横坐标:");
int x = sc.nextInt();
System.out.println("输入可以消除的纵坐标:");
int y = sc.nextInt();
int cnt_score = count(x, y);
if (cnt_score > 0) {
score += cnt_score;
}
}
}
成果
这是最后做出来的成果,欢迎大家来玩。