当我们做好俄罗斯方块的第一版,如果要加一个模块,比如用线性代数做坐标修改。工程要做成两个:项目工程,模块调试工程。
源码下载:
链接: https://pan.baidu.com/s/1q11tAE7-csita6FjDugW3Q 提取码: uytz
项目结构如下:
1. 俄罗斯方块的项目工程。2.线性代数的调试工程。
而且,模块调试工程,尽量和界面无关,用纯数据做调试。当模块调试工程做好以后,再整合进项目工程。
整合的方法,可以是粘贴代码,或者导出一个jar包。
四个小方块的x,y, 用8个整数组成数组。用矩阵乘法、加法,旋转方块。公式推导,有三角函数和图形学的帖子,大家可以查推导过程。
对于一个点(x,y), 矩阵处理的代码如下:
public class MatrixTool {
// cos90,sin90
// -sin90, cos90
public static int[][] rotatem = new int[][] {
{ 0, 1 },
{ -1, 0 } };
// (x,y) + (3,0)
public static int[] moveoff_m = new int[] { 3, 0 };
// (a1,a2,... an) 乘以 m(n行n列)
public static void rotatef(int[] old, int[][] m) {
if (old.length != m.length || m.length != m[0].length) {
System.out.println("matrix error");
return;
}
// 结果
int[] result = new int[old.length];
// result[0] = old[0] * m[0][0] + old[1] * m[1][0];
// result[1] = old[0] * m[0][1] + old[1] * m[1][1];
for (int col = 0; col < old.length; col++) {
result[col] = 0;
for (int m_num = 0; m_num < old.length; m_num++) {
result[col] += old[m_num] * m[m_num][col];
}
}
// System.out.println("c:"+result[0]+","+ result[1]);
// old=result.clone(); 可以赋值。但是这种写法的问题:
// 函数结束后,在调用点的old不会变化。
// 因为old是形参传入的指针,要传出数据,只能修改内容。
// 要用System.arraycopy,修改old的数组内容
System.arraycopy(result, 0, old, 0, old.length);
// System.out.println("bug:"+old[0]+","+ old[1]);
}
public static void movef(int[] old, int[] moveoff) {
old[0] += moveoff[0];
old[1] += moveoff[1];
}
}
先用纯数据,测试这个模块是否正确。然后整合到游戏中:
public class BlockData {
// 7种形状
// line
// L
// 左L
// z
// 右z
// square
// T
public int[][] shapes = new int[][] {
{ 0, 1, 1, 1, 2, 1, 3, 1 },
{ 1, 0, 1, 1, 1, 2, 2, 2 },
{ 2, 0, 2, 1, 2, 2, 1, 2 },
{ 0, 1, 1, 1, 1, 2, 2, 2 },
{ 1, 2, 2, 2, 2, 1, 3, 1 },
{ 1, 1, 2, 1, 1, 2, 2, 2 },
{ 0, 2, 1, 2, 1, 1, 2, 2 } };
public int[] ar = new int[8];
public BlockData() {
ar = shapes[1];
for (int t : ar)
System.out.print(t + ",");
System.out.println();
System.out.println("-------------");
int[] newShape = new int[8];
int i = 0;
for (i = 0; i < 8; i += 2) {
int[] p1 = new int[] { ar[i], ar[i + 1] };
MatrixTool.rotatef(p1, MatrixTool.rotatem);
//System.out.println("put " + p1[0] + "," + p1[1]);
MatrixTool.movef( p1, MatrixTool.moveoff_m);
newShape[i] = p1[0];
newShape[i + 1] = p1[1];
}
for (int t : newShape)
System.out.print(t + ",");
}
}
整合后,游戏正确。
线性代数有大量应用,所以做一个举例。
对于多数人,基本的学习目标是,用设计模式等通用的架构设计,做出不同的游戏,比如俄罗斯方块,贪吃蛇。
用通用的类的架构,解决复杂问题,使项目容易扩展维护,这是java学习的重要内容。