上文中, 我们学习到了 坦克大战系列二:从零编写【坦克大战】
接下来我们学习让坦克移动起来
1.防止敌人坦克重叠运动
- 八种情况
防止敌人坦克重叠代码
public boolean isTouchEnemyTank() {
//判断当前敌人坦克(this)方向
switch (this.direct) {
case 0://上
//让当前敌人坦克和其它所有的敌人坦克比较
for (int i = 0; i < enemyTanks.size(); i++) {
//从Vector 集合中拿到一个坦克
EnemyTank enemyTank = enemyTanks.get(i);
//不和自己比较
if (enemyTank != this) {
//如果敌人坦克是 上/下 方向
//思路分析
// 1.如果敌人坦克是上/下 x的范围 [enemyTank.x, enemyTank.x + 40]
// y的范围 [enemyTank.y, enemyTank.y + 60]
if (enemyTank.direct == 0 || enemyTank.direct == 2) {
// 2.当前坦克 左上角的坐标 [this.x, this.y]
if (this.x >= enemyTank.x
&& this.x <= enemyTank.x + 40
&& this.y >= enemyTank.y
&& this.y <= enemyTank.y + 60) {
return true;
}
// 3.当前坦克 右上角的坐标 [this.x + 40, this.y]
if (this.x + 40 >= enemyTank.x
&& this.x + 40 <= enemyTank.x + 40
&& this.y >= enemyTank.y
&& this.y <= enemyTank.y + 60) {
return true;
}
}
//如果敌人坦克是 右/左 方向
//思路分析
// 1.如果敌人坦克是右/左 x的范围 [enemyTank.x, enemyTank.x + 60]
// y的范围 [enemyTank.y, enemyTank.y + 40]
if (enemyTank.direct == 1 || enemyTank.direct == 3) {
// 2.当前坦克 左上角的坐标 [this.x, this.y]
if (this.x >= enemyTank.x
&& this.x <= enemyTank.x + 60
&& this.y >= enemyTank.y
&& this.y <= enemyTank.y + 40) {
return true;
}
// 3.当前坦克 右上角的坐标 [this.x + 40, this.y]
if (this.x + 40 >= enemyTank.x
&& this.x + 40 <= enemyTank.x + 60
&& this.y >= enemyTank.y
&& this.y <= enemyTank.y + 40) {
return true;
}
}
}
}
break;
case 1://右
//让当前敌人坦克和其它所有的敌人坦克比较
for (int i = 0; i < enemyTanks.size(); i++) {
//从Vector 集合中拿到一个坦克
EnemyTank enemyTank = enemyTanks.get(i);
//不和自己比较
if (enemyTank != this) {
//如果敌人坦克是 上/下 方向
//思路分析
// 1.如果敌人坦克是上/下 x的范围 [enemyTank.x, enemyTank.x + 40]
// y的范围 [enemyTank.y, enemyTank.y + 60]
if (enemyTank.direct == 0 || enemyTank.direct == 2) {
// 2.当前坦克 右上角的坐标 [this.x + 60, this.y]
if (this.x + 60 >= enemyTank.x
&& this.x + 60 <= enemyTank.x + 40
&& this.y >= enemyTank.y
&& this.y <= enemyTank.y + 60) {
return true;
}
// 3.当前坦克 右下角的坐标 [this.x + 60, this.y + 40]
if (this.x + 60 >= enemyTank.x
&& this.x + 60 <= enemyTank.x + 40
&& this.y + 40 >= enemyTank.y
&& this.y + 40 <= enemyTank.y + 60) {
return true;
}
}
//如果敌人坦克是 右/左 方向
//思路分析
// 1.如果敌人坦克是右/左 x的范围 [enemyTank.x, enemyTank.x + 60]
// y的范围 [enemyTank.y, enemyTank.y + 40]
if (enemyTank.direct == 1 || enemyTank.direct == 3) {
// 2.当前坦克 右上角的坐标 [this.x + 60, this.y]
if (this.x + 60 >= enemyTank.x
&& this.x + 60 <= enemyTank.x + 60
&& this.y >= enemyTank.y
&& this.y <= enemyTank.y + 40) {
return true;
}
// 3.当前坦克 右下角的坐标 [this.x + 60, this.y + 40]
if (this.x + 60 >= enemyTank.x
&& this.x + 60 <= enemyTank.x + 60
&& this.y + 40 >= enemyTank.y
&& this.y + 40 <= enemyTank.y + 40) {
return true;
}
}
}
}
break;
case 2://下
//让当前敌人坦克和其它所有的敌人坦克比较
for (int i = 0; i < enemyTanks.size(); i++) {
//从Vector 集合中拿到一个坦克
EnemyTank enemyTank = enemyTanks.get(i);
//不和自己比较
if (enemyTank != this) {
//如果敌人坦克是 上/下 方向
//思路分析
// 1.如果敌人坦克是上/下 x的范围 [enemyTank.x, enemyTank.x + 40]
// y的范围 [enemyTank.y, enemyTank.y + 60]
if (enemyTank.direct == 0 || enemyTank.direct == 2) {
// 2.当前坦克 左下角的坐标 [this.x, this.y + 60]
if (this.x >= enemyTank.x
&& this.x <= enemyTank.x + 40
&& this.y + 60 >= enemyTank.y
&& this.y + 60 <= enemyTank.y + 60) {
return true;
}
// 3.当前坦克 右下角的坐标 [this.x + 40, this.y + 60]
if (this.x + 40 >= enemyTank.x
&& this.x + 40 <= enemyTank.x + 40
&& this.y + 60 >= enemyTank.y
&& this.y + 60 <= enemyTank.y + 60) {
return true;
}
}
//如果敌人坦克是 右/左 方向
//思路分析
// 1.如果敌人坦克是右/左 x的范围 [enemyTank.x, enemyTank.x + 60]
// y的范围 [enemyTank.y, enemyTank.y + 40]
if (enemyTank.direct == 1 || enemyTank.direct == 3) {
// 2.当前坦克 左下角的坐标 [this.x, this.y + 60]
if (this.x >= enemyTank.x
&& this.x <= enemyTank.x + 60
&& this.y + 60 >= enemyTank.y
&& this.y + 60 <= enemyTank.y + 40) {
return true;
}
// 3.当前坦克 右下角的坐标 [this.x + 40, this.y + 60]
if (this.x + 40 >= enemyTank.x
&& this.x + 40 <= enemyTank.x + 60
&& this.y + 60 >= enemyTank.y
&& this.y + 60 <= enemyTank.y + 40) {
return true;
}
}
}
}
break;
case 3://左
//让当前敌人坦克和其它所有的敌人坦克比较
for (int i = 0; i < enemyTanks.size(); i++) {
//从Vector 集合中拿到一个坦克
EnemyTank enemyTank = enemyTanks.get(i);
//不和自己比较
if (enemyTank != this) {
//如果敌人坦克是 上/下 方向
//思路分析
// 1.如果敌人坦克是上/下 x的范围 [enemyTank.x, enemyTank.x + 40]
// y的范围 [enemyTank.y, enemyTank.y + 60]
if (enemyTank.direct == 0 || enemyTank.direct == 2) {
// 2.当前坦克 左上角的坐标 [this.x, this.y]
if (this.x >= enemyTank.x
&& this.x <= enemyTank.x + 40
&& this.y >= enemyTank.y
&& this.y <= enemyTank.y + 60) {
return true;
}
// 3.当前坦克 左下角的坐标 [this.x, this.y + 40]
if (this.x >= enemyTank.x
&& this.x <= enemyTank.x + 40
&& this.y + 40 >= enemyTank.y
&& this.y + 40 <= enemyTank.y + 60) {
return true;
}
}
//如果敌人坦克是 右/左 方向
//思路分析
// 1.如果敌人坦克是右/左 x的范围 [enemyTank.x, enemyTank.x + 60]
// y的范围 [enemyTank.y, enemyTank.y + 40]
if (enemyTank.direct == 1 || enemyTank.direct == 3) {
// 2.当前坦克 左上角的坐标 [this.x, this.y]
if (this.x >= enemyTank.x
&& this.x <= enemyTank.x + 60
&& this.y >= enemyTank.y
&& this.y <= enemyTank.y + 40) {
return true;
}
// 3.当前坦克 左下角的坐标 [this.x, this.y + 40]
if (this.x >= enemyTank.x
&& this.x <= enemyTank.x + 60
&& this.y + 40 >= enemyTank.y
&& this.y + 40 <= enemyTank.y + 40) {
return true;
}
}
}
}
break;
}
return false;
}
这辆敌方坦克和任何其它敌方坦克都不发生碰撞时且不超边界时才可以移动
2.记录玩家成绩
绘制版面信息
paint()方法中如果没有super.paint(g),那么绘制的敌方坦克数会出现重叠情况
调用方法
在Recorder类中定义一个方法
write(int c) 指的是一个字符,并不能存入一个int类型的数字
给JFrame添加监听事件
3. 记录敌方坦克坐标和方向
定义Vector,指向 MyPanel对象的 敌人坦克Vector
让Recorder中的enemyTanks也指向同一个地址
修改keepRecorder()方法
4. 继续上一把游戏
public static Vector<Node> getNodesAndEnemyTankSum() {
try {
bufferedReader = new BufferedReader(new FileReader(recordFile));
allEnemyTankNum = new Integer(bufferedReader.readLine());
String line = "";
while ((line = bufferedReader.readLine()) != null) {
String[] xyd = line.split(" ");
Node node = new Node(new Integer(xyd[0]), new Integer(xyd[1]),
new Integer(xyd[2]));
nodes.add(node);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bufferedReader != null) {
bufferedReader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return nodes;
}
}
在主类的构造器里,程序还未启动时,加入选项
在MyPanel类中定义保存Node节点的集合
将MyPanel构造器变为有参构造器,加入switch分支,1表示新游戏
2表示继续上一局
5. 播放音乐
将AePlayWave类资源放入包中,将音乐资源放入src目录下,在MyPanel构造器的最后一行调用即可;
- 修正文件存储位置
5.1 处理文件相关异常
或者
至此,坦克大战已全部完成