快捷键 I
while + iterator的快捷键itit,ctrl + j调出快捷键列表 ,遍历完一次后想重置iterator iterator = 名字.iterator
JAVA API 在线文档 www.matools.com
1990 sun公司启动绿色计划,1992年创建java语言,1994gosling参加硅谷大会演示java功能震惊世界,1995年sun公司发布java第一个版本,2009年甲骨文公司宣布收购sun公司。2014发布java8,广泛应用的版本。
JAVA SE:JAVA标准版,支持面向桌面级应用的平台,提供了完整的JAVA核心API,此版本之前称为J2SE
JAVA EE:JAVA企业版,为开发企业环境下的应用程序提供一套解决方案。主要针对Web应用程序开发,此版本之前称为J2EE
JAVA ME:JAVA小型版,支持java程序运行在移动终端上的平台,对java api有所精简,加入了针对移动终端的支持,此版本之前称为J2ME
跨平台的核心:JVM(JAVA虚拟机)
JDK与JRE,JVM
关于环境变量的配置
这里需要注意的是换行和回车的区别,换行是将光标移动到下一行,而回车是将光标移动到当前行的开始第一个字符
单行注释://
多行注释:/*
…
*/
多行注释内部不允许嵌套多行注释
文档注释:注释内容可以被JDK提供的工具javadoc解析,生成一套以网页文件形式体现的该程序的说明文档,一般写在类
基本格式:/**
*
*
*/
如何生成对应的文档注释:javadoc -d 文件夹 -xx -yy 需要生成的java文件名字
其中xx和yy是javadoc标签
与C或C++不同,不可以用0或非0的数代替false或者true;
数组的每个元素是一个数组
动态初始化,列数不确定,每个一维数组的长度不一样
关于%取模运算符,它的运算公式为 a % b = a − ( i n t ) a / b ∗ b a \%b = a - (int)a / b * b a%b=a−(int)a/b∗b,经过证明,取模的结果的符号与 a a a的符号相同。
++的魔鬼细节
“+” 的使用(连接符)
对于短路与 & & \&\& &&而言,如果第一个为假,后面的条件不会执行也不会判断,逻辑与 & \& &则都要判断执行;
同样的对于短路或 ∣ ∣ || ∣∣,如果第一个为真,后面的条件不会执行和判断,逻辑 ∣ | ∣则都要判断执行;
switch细节
经典问题掌握猴子吃桃,斐波那契数列,汉诺塔问题,八皇后问题,走迷宫问题。
可变参数的形参访问与数组类似,通过形参名[下标]访问.
会发现打印的name和age仍然是默认值
哪个对象调用,this就指向哪个对象
继承的本质
会被该类的所有实例对象所共享
当涉及到继承的时候
可以对代码进行规范的管理调用
一方面相对于C++的多继承机制,或许JAVA中的接口实现是对单继承的补充
Override作语法校验
单列集合,存放单值
双列集合,存放键值对
无参构造的源码
有参构造的源码
自己dubug下CRUD的源码
hashset加入节点时,只要增加一个元素不管是在数组上还是挂载在链表上,size都要自增
扩容机制是乘以2倍再加1
interru一般用于中断线程休眠
mkdirs创建多级目录
发送方通常要设置一个结束标记,socket.shutdownOutput().
netstat -anb 可以查看端口被哪个程序占用,cmd需要管理员权限
int.class和Integer.TYPE是同一个对象
将set方法写入构造器可以控制外部通过构造器对属性的修改。
Sqlyog注释的快捷键,shift + ctrl +c,取消为 shift + ctrl + r
自连接
把一个查询结果当做另一个查询的条件
把子查询当做临时表解决查询问题
多列子查询
自我复制
如何对一张表去重
查询合并
外连接
DESC 表名 查看表的结构
查看隔离级别 select @@tx_isolation
设置隔离级别 set session transaction isolation level 后跟隔离级别
视图可以在创建视图
用反射机制时,底层有个静态代码块完成了对驱动的注册,这是用的比较多的
将url,user ,password等写入配置文件,让连接更灵活
resultSet结果集,返回类似一张表的查询记录,是一个对象
参数列表中的1是赋值给sql中的?,是个可变参数,可以多个赋值
当.?*等出现在中括号中时,不用转义
matches方法用于整体匹配是否成功不保存匹配结果,只返回匹配成功与否,且不需要限定符。
面向过程版本简单模拟微信零钱通功能
SmallChangeSystem.java
package smallchange;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
/**
* ClassName: SmallChangeSystem
* Description:
* date: 2023/3/30 14:11
*
* @author Mr.Shen
* @since JDK 8
*/
@SuppressWarnings({"all"})
public class SmallChangeSystem {
//先显示菜单
public static void main(String[] args) {
//控制变量
boolean loop = true;
//接受输入
Scanner scanner = new Scanner(System.in);
String choice = "";
//用字符串存零钱通明细
String details = "---------------零钱通明细---------------" +
"\n操作\t\t金额\t\t时间\t\t\t\t\t\t余额";
//余额
double balance = 0;
//消费金额
double money = 0;
//时间
Date date = null;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm::ss");
//保存消费操作
String operation = "";
do {
System.out.println("\n===============零钱通菜单===============");
System.out.println("\t\t\t1 零钱通明细");
System.out.println("\t\t\t2 收益入账");
System.out.println("\t\t\t3 消\t费");
System.out.println("\t\t\t4 退\t出");
System.out.println("请选择(1-4):");
choice = scanner.next();
switch (choice) {
case "1":
System.out.println(details);
break;
case "2":
System.out.println("收入金额:");
money = scanner.nextDouble();
if (money > 0) {
balance += money;
date = new Date();
details += "\n收益入账\t+" + money + "\t" + simpleDateFormat.format(date) + "\t" + balance;
} else {
System.out.println("收入金额不能小于等于零,请重新输入");
}
break;
case "3":
System.out.println("输入消费金额:");
money = scanner.nextDouble();
System.out.println("消费说明:");
operation = scanner.next();
if (money > 0 && money <= balance) {
balance -= money;
date = new Date();
if (operation.length() <= 2)
details += "\n" + operation + "\t\t-" + money + "\t" + simpleDateFormat.format(date) + "\t" + balance;
else
details += "\n" + operation + "\t-" + money + "\t" + simpleDateFormat.format(date) + "\t" + balance;
}else {
System.out.println("消费金额应该在0-"+balance);
}
break;
case "4":
//定义退出标志
String exit = "";
while (true) {
System.out.println("是否确认退出系统(y/n):");
exit = scanner.next();
if ("y".equalsIgnoreCase(exit) || "n".equalsIgnoreCase(exit))
break;
}
if ("y".equalsIgnoreCase(exit))
loop = false;
break;
default:
System.out.println("输入有误,请重新选择");
}
} while (loop);
System.out.println("零钱通项目退出");
}
}
进行封装后的面对对象版本
SmallChangeSystemOOP.java
package smallchange;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
/**
* ClassName: SmallChangeSystemOOP
* Description:
* date: 2023/3/30 15:11
*
* @author Mr.Shen
* @since JDK 8
*/
@SuppressWarnings({"all"})
public class SmallChangeSystemOOP {
//控制变量
boolean loop = true;
//接受输入
Scanner scanner = new Scanner(System.in);
String choice = "";
//用字符串存零钱通明细
String details = "---------------零钱通明细---------------" +
"\n操作\t\t金额\t\t时间\t\t\t\t\t\t余额";
//余额
double balance = 0;
//消费金额
double money = 0;
//时间
Date date = null;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm::ss");
//保存消费操作
String operation = "";
public void MainMenu(){
do {
System.out.println("\n===============零钱通菜单===============");
System.out.println("\t\t\t1 零钱通明细");
System.out.println("\t\t\t2 收益入账");
System.out.println("\t\t\t3 消\t费");
System.out.println("\t\t\t4 退\t出");
System.out.println("请选择(1-4):");
choice = scanner.next();
switch (choice) {
case "1":
this.detail();
break;
case "2":
this.income();
break;
case "3":
this.pay();
break;
case "4":
this.exit();
break;
default:
System.out.println("输入有误,请重新选择");
}
} while (loop);
}
public void detail(){
System.out.println(details);
}
public void income(){
System.out.println("收入金额:");
money = scanner.nextDouble();
if (money > 0) {
balance += money;
date = new Date();
details += "\n收益入账\t+" + money + "\t" + simpleDateFormat.format(date) + "\t" + balance;
} else {
System.out.println("收入金额不能小于等于零,请重新输入");
}
}
public void pay(){
System.out.println("输入消费金额:");
money = scanner.nextDouble();
System.out.println("消费说明:");
operation = scanner.next();
if (money > 0 && money <= balance) {
balance -= money;
date = new Date();
if (operation.length() <= 2)
details += "\n" + operation + "\t\t-" + money + "\t" + simpleDateFormat.format(date) + "\t" + balance;
else
details += "\n" + operation + "\t-" + money + "\t" + simpleDateFormat.format(date) + "\t" + balance;
}else {
System.out.println("消费金额应该在0-"+balance);
}
}
public void exit(){
//定义退出标志
String exit = "";
while (true) {
System.out.println("是否确认退出系统(y/n):");
exit = scanner.next();
if ("y".equalsIgnoreCase(exit) || "n".equalsIgnoreCase(exit))
break;
}
if ("y".equalsIgnoreCase(exit))
this.loop = false;
}
}
SmallChangeSystemApp.java进行调用
package smallchange;
/**
* ClassName: SmallChangeSystemApp
* Description:
* date: 2023/3/30 15:11
*
* @author Mr.Shen
* @since JDK 8
*/
public class SmallChangeSystemApp {
public static void main(String[] args) {
SmallChangeSystemOOP smallChangeSystemOOP = new SmallChangeSystemOOP();
smallChangeSystemOOP.MainMenu();
}
}
HouseRentApp.java
package houserent;
import houserent.view.HouseView;
/**
* ClassName: HouseRentApp
* Description:
* date: 2023/3/30 17:58
*
* @author Mr.Shen
* @since JDK 8
*/
public class HouseRentApp {
public static void main(String[] args) {
//程序的入口
HouseView houseView = new HouseView();
houseView.mainMenu();
System.out.println("退出了房屋出租系统");
}
}
House.java
package houserent.domain;
/**
* ClassName: House
* Description: House的一个对象表示一个房屋信息
* date: 2023/3/30 18:04
*
* @author Mr.Shen
* @since JDK 8
*/
public class House {
private int id;
private String name;
private String phone;
private String address;
private int rent;
private String state;
public House(int id, String name, String phone, String address, int rent, String state) {
this.id = id;
this.name = name;
this.phone = phone;
this.address = address;
this.rent = rent;
this.state = state;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getRent() {
return rent;
}
public void setRent(int rent) {
this.rent = rent;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
@Override
public String toString() {
return id +
"\t\t" + name +
"\t" + phone +
"\t\t" + address +
"\t" + rent +
"\t" + state ;
}
}
HouseView.java
package houserent.view;
import houserent.domain.House;
import houserent.service.HouseService;
import houserent.utils.Utility;
import java.util.Scanner;
/**
* ClassName: HouseView
* Description: 1. 显示界面
* 2.接收用户输入
* 3.调用HouseService完成对房屋信息的操作
* date: 2023/3/30 18:10
*
* @author Mr.Shen
* @since JDK 8
*/
@SuppressWarnings({"all"})
public class HouseView {
//菜单显示控制变量
private boolean loop = true;
//用户输入
private char key = ' ';
//初始的House数组大小
private HouseService houseService = new HouseService(2);
public void mainMenu() {
do {
System.out.println("===============房屋出租系统菜单===============");
System.out.println("\t\t\t1 新 增 房 源");
System.out.println("\t\t\t2 查 找 房 屋");
System.out.println("\t\t\t3 删 除 房 屋 信 息");
System.out.println("\t\t\t4 修 改 房 屋 信 息");
System.out.println("\t\t\t5 房 屋 列 表");
System.out.println("\t\t\t6 退 出");
System.out.println("请输入你的选择:");
key = Utility.readChar();
switch (key) {
case '1':
addHouse();
break;
case '2':
findHouse();
break;
case '3':
deleteHouse();
break;
case '4':
updateHouse();
break;
case '5':
listHouses();
break;
case '6':
exit();
break;
}
} while (loop);
}
//显示房屋列表
public void listHouses() {
System.out.println("===============房屋列表===============");
System.out.println("编号\t\t房主\t\t电话\t\t地址\t\t月租\t\t状态(未出租/已出租)");
House[] list = houseService.list();
for (House house : list) {
if (house != null)
System.out.println(house);
}
System.out.println("=============房屋列表显示完毕=============");
}
public void addHouse() {
System.out.println("===============添加房屋===============");
System.out.println("姓名:");
String name = Utility.readString(8);
System.out.println("电话:");
String phone = Utility.readString(12);
System.out.println("地址:");
String address = Utility.readString(16);
System.out.println("月租:");
int rent = Utility.readInt();
System.out.println("状态:");
String state = Utility.readString(3);
//创建一个house对象,id自增长
House house = new House(0, name, phone, address, rent, state);
if (houseService.add(house))
System.out.println("===============添加房屋成功===============");
else
System.out.println("===============添加房屋失败===============");
}
public void deleteHouse() {
System.out.println("===============删除房屋信息===============");
System.out.println("请输入待删除房屋的编号(-1退出):");
int deleteId = Utility.readInt();
if (deleteId == -1) {
System.out.println("放弃删除房屋信息");
return;
}
char choice = Utility.readConfirmSelection();
if (choice == 'Y') {
if (houseService.delete(deleteId)) {
System.out.println("===============删除房屋成功===============");
} else {
System.out.println("===============删除房屋失败,编号不存在===============");
}
} else {
System.out.println("===============放弃删除房屋===============");
}
}
public void exit() {
char c = Utility.readConfirmSelection();
if (c == 'Y') loop = false;
}
public void findHouse() {
System.out.println("请输入你要查找的房屋ID:");
int findId = Utility.readInt();
House house = houseService.findById(findId);
if (house != null) {
System.out.println(house);
} else {
System.out.println("===============查找的房屋ID不存在===============");
}
}
public void updateHouse() {
System.out.println("请输入你要修改的房屋ID(-1退出):");
int updId = Utility.readInt();
if (updId == -1) {
System.out.println("===============放弃修改房屋信息===============");
return;
}
House house = houseService.findById(updId);
if (house == null) {
System.out.println("===============修改房屋ID不存在===============");
return;
}
System.out.println("姓名(" + house.getName() + "):");
String name = Utility.readString(8, "");
if (!name.equals("")) {
house.setName(name);
}
System.out.println("电话(" + house.getPhone() + "):");
String phone = Utility.readString(12, "");
if (!phone.equals("")) {
house.setPhone(phone);
}
System.out.println("地址(" + house.getAddress() + "):");
String address = Utility.readString(16, "");
if (!address.equals("")) {
house.setAddress(address);
}
System.out.println("租金(" + house.getRent() + "):");
int rent = Utility.readInt(-1);
if (rent != -1) {
house.setRent(rent);
}
System.out.println("状态("+house.getState()+"):");
String state = Utility.readString(3, "");
if(!state.equals("")){
house.setState(state);
}
System.out.println("===============修改房屋信息成功===============");
}
}
HouseService.java
package houserent.service;
import houserent.domain.House;
/**
* ClassName: HouseService
* Description: 响应HouseView的调用
* 完成对房屋信息的crud
* date: 2023/3/30 18:35
*
* @author Mr.Shen
* @since JDK 8
*/
@SuppressWarnings({"all"})
public class HouseService {
private House[] houses;
private int housenum = 1; //记录有多少房屋
private int idcounter = 1;//记录id增长
//通过size指定生成的House[]数组大小
public HouseService(int size) {
houses = new House[size];
houses[0] = new House(1, "jack", "154611", "徐州", 1500, "未出租");
}
public House[] list() {
return houses;
}
//房屋信息添加
public boolean add(House house) {
if (housenum == houses.length) {
int newSize = (int) (housenum * 1.5);
House[] temp = new House[newSize];
for (int i = 0; i < housenum; i++) {
temp[i] = houses[i];
}
houses = temp;
System.out.println("已经扩容");
}
houses[housenum++] = house;//加house数组
//同时更新刚加入的房屋id
house.setId(++idcounter);
return true;
}
//房屋信息删除
public boolean delete(int delId) {
int index = -1;//记录delId对应的下标
for (int i = 0; i < housenum; i++){
if(houses[i].getId() == delId){
index = i;
}
}
if(index == -1)
return false;
for(int i =index;i<housenum-1;i++){
houses[i]=houses[i+1];
}
houses[--housenum] = null;//当前有存在的房屋信息最后一个置为null
return true;
}
public House findById(int findId){
for(int i=0;i<housenum;i++){
if(findId == houses[i].getId())
return houses[i];
}
return null;
}
}
Utility.java
package houserent.utils;
/**
工具类的作用:
处理各种情况的用户输入,并且能够按照程序员的需求,得到用户的控制台输入。
*/
import java.util.*;
/**
*/
public class Utility {
//静态属性。。。
private static Scanner scanner = new Scanner(System.in);
/**
* 功能:读取键盘输入的一个菜单选项,值:1——5的范围
* @return 1——5
*/
public static char readMenuSelection() {
char c;
for (; ; ) {
String str = readKeyBoard(1, false);//包含一个字符的字符串
c = str.charAt(0);//将字符串转换成字符char类型
if (c != '1' && c != '2' &&
c != '3' && c != '4' && c != '5') {
System.out.print("选择错误,请重新输入:");
} else break;
}
return c;
}
/**
* 功能:读取键盘输入的一个字符
* @return 一个字符
*/
public static char readChar() {
String str = readKeyBoard(1, false);//就是一个字符
return str.charAt(0);
}
/**
* 功能:读取键盘输入的一个字符,如果直接按回车,则返回指定的默认值;否则返回输入的那个字符
* @param defaultValue 指定的默认值
* @return 默认值或输入的字符
*/
public static char readChar(char defaultValue) {
String str = readKeyBoard(1, true);//要么是空字符串,要么是一个字符
return (str.length() == 0) ? defaultValue : str.charAt(0);
}
/**
* 功能:读取键盘输入的整型,长度小于2位
* @return 整数
*/
public static int readInt() {
int n;
for (; ; ) {
String str = readKeyBoard(10, false);//一个整数,长度<=2位
try {
n = Integer.parseInt(str);//将字符串转换成整数
break;
} catch (NumberFormatException e) {
System.out.print("数字输入错误,请重新输入:");
}
}
return n;
}
/**
* 功能:读取键盘输入的 整数或默认值,如果直接回车,则返回默认值,否则返回输入的整数
* @param defaultValue 指定的默认值
* @return 整数或默认值
*/
public static int readInt(int defaultValue) {
int n;
for (; ; ) {
String str = readKeyBoard(10, true);
if (str.equals("")) {
return defaultValue;
}
//异常处理...
try {
n = Integer.parseInt(str);
break;
} catch (NumberFormatException e) {
System.out.print("数字输入错误,请重新输入:");
}
}
return n;
}
/**
* 功能:读取键盘输入的指定长度的字符串
* @param limit 限制的长度
* @return 指定长度的字符串
*/
public static String readString(int limit) {
return readKeyBoard(limit, false);
}
/**
* 功能:读取键盘输入的指定长度的字符串或默认值,如果直接回车,返回默认值,否则返回字符串
* @param limit 限制的长度
* @param defaultValue 指定的默认值
* @return 指定长度的字符串
*/
public static String readString(int limit, String defaultValue) {
String str = readKeyBoard(limit, true);
return str.equals("")? defaultValue : str;
}
/**
* 功能:读取键盘输入的确认选项,Y或N
* 将小的功能,封装到一个方法中.
* @return Y或N
*/
public static char readConfirmSelection() {
System.out.println("请输入你的选择(Y/N)");
char c;
for (; ; ) {//无限循环
//在这里,将接受到字符,转成了大写字母
//y => Y n=>N
String str = readKeyBoard(1, false).toUpperCase();
c = str.charAt(0);
if (c == 'Y' || c == 'N') {
break;
} else {
System.out.print("选择错误,请重新输入:");
}
}
return c;
}
/**
* 功能: 读取一个字符串
* @param limit 读取的长度
* @param blankReturn 如果为true ,表示 可以读空字符串。
* 如果为false表示 不能读空字符串。
*
* 如果输入为空,或者输入大于limit的长度,就会提示重新输入。
* @return
*/
private static String readKeyBoard(int limit, boolean blankReturn) {
//定义了字符串
String line = "";
//scanner.hasNextLine() 判断有没有下一行
while (scanner.hasNextLine()) {
line = scanner.nextLine();//读取这一行
//如果line.length=0, 即用户没有输入任何内容,直接回车
if (line.length() == 0) {
if (blankReturn) return line;//如果blankReturn=true,可以返回空串
else continue; //如果blankReturn=false,不接受空串,必须输入内容
}
//如果用户输入的内容大于了 limit,就提示重写输入
//如果用户如的内容 >0 <= limit ,我就接受
if (line.length() < 1 || line.length() > limit) {
System.out.print("输入长度(不能大于" + limit + ")错误,请重新输入:");
continue;
}
break;
}
return line;
}
}
其中涉及到爆炸的三张图片,以及音效文件,网上素材应该很多,有需要的私信我或下方评论我给你发。
MyTankGame.java 启动游戏
package tankgame;
import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Scanner;
/**
* ClassName: MyTankGame
* Description:
* date: 2023/4/2 5:54
*
* @author Mr.Shen
* @since JDK 8
*/
@SuppressWarnings({"all"})
public class MyTankGame extends JFrame {
MyPanel myPanel = null;
Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
MyTankGame myTankGame = new MyTankGame();
}
public MyTankGame(){
System.out.println("请输入你的选择1:新游戏 2:继续上局游戏");
String key = scanner.next();
myPanel = new MyPanel(key);
new Thread(myPanel).start();
this.add(myPanel);//把面板放入
this.setSize(1300,950);
this.addKeyListener(myPanel);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
//增加相应关闭窗口的监听器
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
Recorder.keepRecord();
System.exit(0);
}
});
}
}
Tank.java 坦克父类
package tankgame;
/**
* ClassName: Tank
* Description: tank父类
* date: 2023/4/2 5:49
*
* @author Mr.Shen
* @since JDK 8
*/
@SuppressWarnings({"all"})
public class Tank {
private int x;//坦克横坐标
private int y;//坦克纵坐标
private int direct;//坦克方向
private int speed;//坦克速度
private boolean isLive = true;//坦克存活
public boolean isLive() {
return isLive;
}
public void setLive(boolean live) {
isLive = live;
}
public void moveUp() {
y -= speed;
}
public void moveRight() {
x += speed;
}
public void moveDown() {
y += speed;
}
public void moveLeft() {
x -= speed;
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
public int getDirect() {
return direct;
}
public void setDirect(int direct) {
this.direct = direct;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public Tank(int x, int y) {
this.x = x;
this.y = y;
}
}
MyTank.java 玩家操控的tank对象
package tankgame;
import java.util.Vector;
/**
* ClassName: MyTank
* Description:
* date: 2023/4/2 5:50
*
* @author Mr.Shen
* @since JDK 8
*/
@SuppressWarnings({"all"})
public class MyTank extends Tank{
//定义一个shot对象,对应射击行为
Shot shot = null;
//发射多颗子弹,用Vector存储
Vector<Shot> shots = new Vector<>();
public MyTank(int x, int y) {
super(x, y);
}
public void shotEnemy(){
if(shots.size() == 10){
return;
}
//子弹方向要和当前MyTank对象一致
switch (getDirect()){
case 0:
shot = new Shot(getX()+20,getY(),0);
break;
case 1:
shot = new Shot(getX()+60,getY()+20,1);
break;
case 2:
shot = new Shot(getX()+20,getY()+60,2);
break;
case 3:
shot = new Shot(getX(),getY()+20,3);
break;
}
shots.add(shot);
new Thread(shot).start();
}
}
EnemyTank.java 敌人tank
package tankgame;
import java.util.Vector;
/**
* ClassName: EnemyTank
* Description: 敌人的坦克
* date: 2023/4/3 11:55
*
* @author Mr.Shen
* @since JDK 8
*/
@SuppressWarnings({"all"})
public class EnemyTank extends Tank implements Runnable {
//敌人坦克的子弹集合
Vector<Shot> shots = new Vector<>();
//存储所有敌方坦克的Vector
Vector<EnemyTank> enemyTanks = new Vector<>();
public EnemyTank(int x, int y) {
super(x, y);
}
public void setEnemyTanks(Vector<EnemyTank> enemyTanks) {
this.enemyTanks = enemyTanks;
}
//判断当前的敌人坦克是否和其他敌人坦克碰撞
public boolean isTouchEnemyTank() {
//判断当前敌人坦克方向
switch (getDirect()) {
case 0:
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
if (this != enemyTank) {
//如果敌人是上下方向
//1.敌人坦克范围x[enemyTank.getX(),enemyTank.getX()+40]
//2.敌人坦克范围y[enemyTank.getY(),enemyTank.getY()+60]
//当前坦克坐标左上角[this.getX(),this.getY()]
//当前坦克坐标右上角[this.getX()+40,this.getY()]
if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 40
&& this.getY() >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 60) {
return true;
}
if (this.getX() + 40 >= enemyTank.getX()
&& this.getX() + 40 <= enemyTank.getX() + 40
&& this.getY() >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 60) {
return true;
}
}
//如果敌人是左右方向
//1.敌人坦克范围x[enemyTank.getX(),enemyTank.getX()+60]
//2.敌人坦克范围y[enemyTank.getY(),enemyTank.getY()+40]
if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 60
&& this.getY() >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 40) {
return true;
}
if (this.getX() + 40 >= enemyTank.getX()
&& this.getX() + 40 <= enemyTank.getX() + 60
&& this.getY() >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 40) {
return true;
}
}
}
}
break;
case 1:
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
if (this != enemyTank) {
//如果敌人是上下方向
//1.敌人坦克范围x[enemyTank.getX(),enemyTank.getX()+40]
//2.敌人坦克范围y[enemyTank.getY(),enemyTank.getY()+60]
//当前坦克坐标右上角[this.getX()+60,this.getY()]
//当前坦克坐标右下角[this.getX()+60,this.getY()+40]
if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {
if (this.getX() + 60 >= enemyTank.getX()
&& this.getX() + 60 <= enemyTank.getX() + 40
&& this.getY() >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 60) {
return true;
}
if (this.getX() + 60 >= enemyTank.getX()
&& this.getX() + 60 <= enemyTank.getX() + 40
&& this.getY() + 40 >= enemyTank.getY()
&& this.getY() + 40 <= enemyTank.getY() + 60) {
return true;
}
}
//如果敌人是左右方向
//1.敌人坦克范围x[enemyTank.getX(),enemyTank.getX()+60]
//2.敌人坦克范围y[enemyTank.getY(),enemyTank.getY()+40]
if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
if (this.getX() + 60 >= enemyTank.getX()
&& this.getX() + 60 <= enemyTank.getX() + 60
&& this.getY() >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 40) {
return true;
}
if (this.getX() + 60 >= enemyTank.getX()
&& this.getX() + 60 <= enemyTank.getX() + 60
&& this.getY() + 40 >= enemyTank.getY()
&& this.getY() + 40 <= enemyTank.getY() + 40) {
return true;
}
}
}
}
break;
case 2:
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
if (this != enemyTank) {
//如果敌人是上下方向
//1.敌人坦克范围x[enemyTank.getX(),enemyTank.getX()+40]
//2.敌人坦克范围y[enemyTank.getY(),enemyTank.getY()+60]
//当前坦克坐标左下角[this.getX(),this.getY()+60]
//当前坦克坐标右下角[this.getX()+40,this.getY()+60]
if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 40
&& this.getY() + 60 >= enemyTank.getY()
&& this.getY() + 60 <= enemyTank.getY() + 60) {
return true;
}
if (this.getX() + 40 >= enemyTank.getX()
&& this.getX() + 40 <= enemyTank.getX() + 40
&& this.getY() + 60 >= enemyTank.getY()
&& this.getY() + 60 <= enemyTank.getY() + 60) {
return true;
}
}
//如果敌人是左右方向
//1.敌人坦克范围x[enemyTank.getX(),enemyTank.getX()+60]
//2.敌人坦克范围y[enemyTank.getY(),enemyTank.getY()+40]
if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 60
&& this.getY() + 60 >= enemyTank.getY()
&& this.getY() + 60 <= enemyTank.getY() + 40) {
return true;
}
if (this.getX() + 40 >= enemyTank.getX()
&& this.getX() + 40 <= enemyTank.getX() + 60
&& this.getY() + 60 >= enemyTank.getY()
&& this.getY() + 60 <= enemyTank.getY() + 40) {
return true;
}
}
}
}
break;
case 3:
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
if (this != enemyTank) {
//如果敌人是上下方向
//1.敌人坦克范围x[enemyTank.getX(),enemyTank.getX()+40]
//2.敌人坦克范围y[enemyTank.getY(),enemyTank.getY()+60]
//当前坦克坐标左上角[this.getX(),this.getY()]
//当前坦克坐标左下角[this.getX(),this.getY()+40]
if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 40
&& this.getY() >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 60) {
return true;
}
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 40
&& this.getY() + 40 >= enemyTank.getY()
&& this.getY() + 40 <= enemyTank.getY() + 60) {
return true;
}
}
//如果敌人是左右方向
//1.敌人坦克范围x[enemyTank.getX(),enemyTank.getX()+60]
//2.敌人坦克范围y[enemyTank.getY(),enemyTank.getY()+40]
if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 60
&& this.getY() >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 40) {
return true;
}
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 60
&& this.getY() + 40 >= enemyTank.getY()
&& this.getY() + 40 <= enemyTank.getY() + 40) {
return true;
}
}
}
}
break;
}
return false;
}
@Override
public void run() {
while (true) {
//发射多颗子弹
if (shots.size() <= 5 && isLive()) {
//子弹方向要和当前MyTank对象一致
Shot shot = null;
switch (getDirect()) {
case 0:
shot = new Shot(getX() + 20, getY(), 0);
break;
case 1:
shot = new Shot(getX() + 60, getY() + 20, 1);
break;
case 2:
shot = new Shot(getX() + 20, getY() + 60, 2);
break;
case 3:
shot = new Shot(getX(), getY() + 20, 3);
break;
}
shots.add(shot);
new Thread(shot).start();
}
//进行随机移动且避免碰撞
switch (getDirect()) {
case 0:
for (int i = 0; i < 20; i++) {
if (getY() > 0 && !isTouchEnemyTank()) {
moveUp();
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 1:
for (int i = 0; i < 20; i++) {
if (getX() + 60 < 1000 && !isTouchEnemyTank()) {
moveRight();
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 2:
for (int i = 0; i < 20; i++) {
if (getY() + 60 < 750 && !isTouchEnemyTank()) {
moveDown();
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 3:
for (int i = 0; i < 20; i++) {
if (getX() > 0 && !isTouchEnemyTank()) {
moveLeft();
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
}
setDirect((int) (Math.random() * 4));
if (!isLive()) {
break;
}
}
}
}
Shot.java 描述子弹的类
package tankgame;
/**
* ClassName: Shot
* Description: 子弹类
* date: 2023/4/3 13:58
*
* @author Mr.Shen
* @since JDK 8
*/
@SuppressWarnings({"all"})
public class Shot implements Runnable{
private int x;
private int y;
private int direct;
private int speed = 2;
private boolean isLive = true;
public Shot(int x, int y, int direct) {
this.x = x;
this.y = y;
this.direct = direct;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getDirect() {
return direct;
}
public void setDirect(int direct) {
this.direct = direct;
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
public boolean isLive() {
return isLive;
}
public void setLive(boolean live) {
isLive = live;
}
@Override
public void run() {
while (true){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
switch (direct){
case 0:
y-=speed;
break;
case 1:
x+=speed;
break;
case 2:
y+=speed;
break;
case 3:
x-=speed;
break;
}
if(!(x >= 0 && x<= 1000 && y>=0 && y<=750 && isLive)){
isLive = false;
break;
}
}
}
}
MyPanel.java 主要界面
package tankgame;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.util.Vector;
/**
* ClassName: MyPanel
* Description: 主要界面
* date: 2023/4/2 5:51
*
* @author Mr.Shen
* @since JDK 8
*/
@SuppressWarnings({"all"})
public class MyPanel extends JPanel implements KeyListener, Runnable {
//定义我的坦克
MyTank myTank = null;
Vector<EnemyTank> enemyTanks = new Vector<>();
Vector<Node> nodes = new Vector<>();
int enemyTankSize = 5;
Vector<Bomb> bombs = new Vector<>();
Image image1 = null;
Image image2 = null;
Image image3 = null;
public MyPanel(String key) {
File file = new File(Recorder.getRecordFile());
if(file.exists()) {
nodes = Recorder.getNodesAndEnemyTankRecord();
}else{
System.out.println("上局游戏不存在,开始新游戏");
key = "1";
}
Recorder.setEnemyTanks(enemyTanks);
myTank = new MyTank(400, 300);//初始化位置
myTank.setSpeed(10);
switch (key){
case "1":
for (int i = 0; i < enemyTankSize; i++) {
EnemyTank enemyTank = new EnemyTank(100 * (i + 1), 0);
enemyTank.setDirect(2);
enemyTank.setSpeed(3);
enemyTank.setEnemyTanks(enemyTanks);
enemyTanks.add(enemyTank);
new Thread(enemyTank).start();
Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
enemyTank.shots.add(shot);
new Thread(shot).start();
}
break;
case "2":
for (int i = 0; i < nodes.size(); i++) {
Node node = nodes.get(i);
EnemyTank enemyTank = new EnemyTank(node.getX(), node.getY());
enemyTank.setDirect(node.getDirect());
enemyTank.setSpeed(3);
enemyTank.setEnemyTanks(enemyTanks);
enemyTanks.add(enemyTank);
new Thread(enemyTank).start();
Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
enemyTank.shots.add(shot);
new Thread(shot).start();
}
}
for (int i = 0; i < enemyTankSize; i++) {
EnemyTank enemyTank = new EnemyTank(100 * (i + 1), 0);
enemyTank.setDirect(2);
enemyTank.setSpeed(3);
enemyTank.setEnemyTanks(enemyTanks);
enemyTanks.add(enemyTank);
new Thread(enemyTank).start();
Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
enemyTank.shots.add(shot);
new Thread(shot).start();
}
image1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_1.gif"));
image2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_2.gif"));
image3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_3.gif"));
new AePlayWave("src\\111.wav").start();
}
//编写方法,提示击毁坦克的信息
public void showInfo(Graphics g){
g.setColor(Color.BLACK);
Font font = new Font("宋体", Font.BOLD, 25);
g.setFont(font);
g.drawString("您累积击毁敌方坦克",1020,30);
drawTank(1020,60,g,0,1);
g.setColor(Color.BLACK);
g.drawString(Recorder.getAllEnemyTankNum()+"",1080,100);
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.fillRect(0, 0, 1000, 750);//填充矩形
showInfo(g);
if(myTank.isLive() && myTank !=null) {
drawTank(myTank.getX(), myTank.getY(), g, myTank.getDirect(), 0);
}
for (int i = 0; i < myTank.shots.size(); i++) {
Shot shot = myTank.shots.get(i);
if (shot != null && shot.isLive()) {
g.draw3DRect(shot.getX(), shot.getY(), 1, 1, false);
} else {
myTank.shots.remove(shot);
}
}
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
if (enemyTank.isLive() && enemyTank != null) {
drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 1);
for (int j = 0; j < enemyTank.shots.size(); j++) {
Shot shot = enemyTank.shots.get(j);
if (shot.isLive() && shot != null) {
g.draw3DRect(shot.getX(), shot.getY(), 1, 1, false);
} else {
enemyTank.shots.remove(shot);
}
}
} else {
enemyTanks.remove(enemyTank);
}
}
for (int i = 0; i < bombs.size(); i++) {
Bomb bomb = bombs.get(i);
if (bomb.getLife() > 6) {
g.drawImage(image1, bomb.getX(), bomb.getY(), 60, 60, this);
} else if (bomb.getLife() > 3) {
g.drawImage(image2, bomb.getX(), bomb.getY(), 60, 60, this);
} else {
g.drawImage(image3, bomb.getX(), bomb.getY(), 60, 60, this);
}
bomb.lifeDown();
if (bomb.getLife() == 0) {
bombs.remove(bomb);
}
}
}
//编写方法,画出坦克
/**
* @param x 坦克左上角的x坐标
* @param y 坦克左上角的y坐标
* @param g 画笔
* @param direct 坦克朝向
* @param type 坦克类型
*/
public void drawTank(int x, int y, Graphics g, int direct, int type) {
switch (type) {
case 0://自己的坦克
g.setColor(Color.cyan);
break;
case 1://敌人的坦克
g.setColor(Color.yellow);
break;
}
//根据方向来绘制坦克
switch (direct) {
case 0://上
g.fill3DRect(x, y, 10, 60, false);//坦克左边的轮子
g.fill3DRect(x + 30, y, 10, 60, false);//坦克右边的轮子
g.fill3DRect(x + 10, y + 10, 20, 40, false);//坦克中间的矩形
g.fillOval(x + 10, y + 20, 20, 20);//坦克的盖子
g.drawLine(x + 20, y + 30, x + 20, y);//坦克的炮筒
break;
case 1://右
g.fill3DRect(x, y, 60, 10, false);//坦克上边的轮子
g.fill3DRect(x, y + 30, 60, 10, false);//坦克下边的轮子
g.fill3DRect(x + 10, y + 10, 40, 20, false);//坦克中间的矩形
g.fillOval(x + 20, y + 10, 20, 20);//坦克的盖子
g.drawLine(x + 30, y + 20, x + 60, y + 20);//坦克的炮筒、
break;
case 2://下
g.fill3DRect(x, y, 10, 60, false);//坦克左边的轮子
g.fill3DRect(x + 30, y, 10, 60, false);//坦克右边的轮子
g.fill3DRect(x + 10, y + 10, 20, 40, false);//坦克中间的矩形
g.fillOval(x + 10, y + 20, 20, 20);//坦克的盖子
g.drawLine(x + 20, y + 30, x + 20, y + 60);//坦克的炮筒
break;
case 3://左
g.fill3DRect(x, y, 60, 10, false);//坦克上边的轮子
g.fill3DRect(x, y + 30, 60, 10, false);//坦克下边的轮子
g.fill3DRect(x + 10, y + 10, 40, 20, false);//坦克中间的矩形
g.fillOval(x + 20, y + 10, 20, 20);//坦克的盖子
g.drawLine(x + 30, y + 20, x, y + 20);//坦克的炮筒
break;
}
}
public void hitTank(Shot shot, Tank tank) {
switch (tank.getDirect()) {
case 0:
case 2:
if (shot.getX() >= tank.getX() && shot.getX() <=
tank.getX() + 40 && shot.getY() >= tank.getY()
&& shot.getY() <= tank.getY() + 60) {
shot.setLive(false);
tank.setLive(false);
Bomb bomb = new Bomb(tank.getX(), tank.getY());
bombs.add(bomb);
if(tank instanceof EnemyTank){
enemyTanks.remove(tank);
Recorder.addAllEnemyTankNum();
}
}
break;
case 1:
case 3:
if (shot.getX() >= tank.getX() && shot.getX() <=
tank.getX() + 60 && shot.getY() >= tank.getY()
&& shot.getY() <= tank.getY() + 40) {
shot.setLive(false);
tank.setLive(false);
Bomb bomb = new Bomb(tank.getX(), tank.getY());
bombs.add(bomb);
if(tank instanceof EnemyTank){
enemyTanks.remove(tank);
Recorder.addAllEnemyTankNum();;
}
}
break;
}
}
public void hitEnemyTank(){
for (int i = 0; i < myTank.shots.size(); i++) {
Shot shot = myTank.shots.get(i);
if (shot != null && shot.isLive()) {
for (int j = 0;j<enemyTanks.size();j++) {
EnemyTank enemyTank = enemyTanks.get(j);
hitTank(shot, enemyTank);
}
}
}
}
public void hitMyTank(){
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
for (int j = 0; j < enemyTank.shots.size(); j++) {
Shot shot = enemyTank.shots.get(j);
if (shot.isLive() && myTank.isLive()){
hitTank(shot,myTank);
}
}
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_W) {//按下W键
System.out.println((char) e.getKeyCode());
myTank.setDirect(0);
if (myTank.getY() > 0) {
myTank.moveUp();
}
} else if (e.getKeyCode() == KeyEvent.VK_D) {
System.out.println((char) e.getKeyCode());
myTank.setDirect(1);
if (myTank.getX() + 60 < 1000) {
myTank.moveRight();
}
} else if (e.getKeyCode() == KeyEvent.VK_S) {
System.out.println((char) e.getKeyCode());
myTank.setDirect(2);
if (myTank.getY() + 60 < 750) {
myTank.moveDown();
}
} else if (e.getKeyCode() == KeyEvent.VK_A) {
System.out.println((char) e.getKeyCode());
myTank.setDirect(3);
if (myTank.getX() > 0) {
myTank.moveLeft();
}
}
if (e.getKeyCode() == KeyEvent.VK_J) {
/**发射一颗子弹的情况
* if(myTank.shot == null || !myTank.shot.isLive()) {
* myTank.shotEnemy();
* }
*/
myTank.shotEnemy();
}
this.repaint();
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
hitMyTank();
hitEnemyTank();
this.repaint();
}
}
}
Node.java 存储敌人位置方向,用于恢复实现继续上局游戏
package tankgame;
/**
* ClassName: Node
* Description: 一个node对象表示一个敌人坦克的信息
* date: 2023/4/6 0:10
*
* @author Mr.Shen
* @since JDK 8
*/
public class Node {
private int x;
private int y;
private int direct;
public Node(int x, int y, int direct) {
this.x = x;
this.y = y;
this.direct = direct;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getDirect() {
return direct;
}
public void setDirect(int direct) {
this.direct = direct;
}
}
Recorder.java 与文件进行交互,记录相关信息
package tankgame;
import java.io.*;
import java.util.Vector;
/**
* ClassName: Recoder
* Description: 该类用于记录相关信息和文件进行交互
* date: 2023/4/5 18:26
*
* @author Mr.Shen
* @since JDK 8
*/
@SuppressWarnings({"all"})
public class Recorder {
private static int allEnemyTankNum = 0;
private static BufferedReader bufferedReader = null;
private static BufferedWriter bufferedWriter = null;
private static String recordFile = "src\\myRecord.txt";
private static Vector<EnemyTank> enemyTanks = null;
private static Vector<Node> nodes = new Vector<>();
public static void setEnemyTanks(Vector<EnemyTank> enemyTanks) {
Recorder.enemyTanks = enemyTanks;
}
public static int getAllEnemyTankNum() {
return allEnemyTankNum;
}
public static void setAllEnemyTankNum(int allEnemyTankNum) {
Recorder.allEnemyTankNum = allEnemyTankNum;
}
public static void addAllEnemyTankNum() {
Recorder.allEnemyTankNum++;
}
public static String getRecordFile() {
return recordFile;
}
public static void keepRecord() {
try {
bufferedWriter = new BufferedWriter(new FileWriter(recordFile));
bufferedWriter.write(Recorder.getAllEnemyTankNum() + "\r\n");
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
if (enemyTank.isLive()) {
String record = enemyTank.getX() + " " + enemyTank.getY() + " " + enemyTank.getDirect();
bufferedWriter.write(record + "\r\n");
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bufferedWriter != null) {
try {
bufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//增加一个信息用于读取recordFile,恢复相关信息
public static Vector<Node> getNodesAndEnemyTankRecord(){
try {
bufferedReader = new BufferedReader(new FileReader(recordFile));
allEnemyTankNum = Integer.parseInt(bufferedReader.readLine());
String line = "";
while ((line = bufferedReader.readLine()) != null){
String[] s = line.split(" ");
Node node = new Node(Integer.parseInt(s[0]),
Integer.parseInt(s[1]),
Integer.parseInt(s[2]));
nodes.add(node);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if(bufferedReader != null){
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return nodes;
}
}
韩老师的音屏处理类
package tankgame;
import javax.sound.sampled.*;
import java.io.File;
import java.io.IOException;
/**
* @author 韩顺平
* @version 1.0
*/
public class AePlayWave extends Thread {
private String filename;
public AePlayWave(String wavfile) {
filename = wavfile;
}
public void run() {
File soundFile = new File(filename);
AudioInputStream audioInputStream = null;
try {
audioInputStream = AudioSystem.getAudioInputStream(soundFile);
} catch (Exception e1) {
e1.printStackTrace();
return;
}
AudioFormat format = audioInputStream.getFormat();
SourceDataLine auline = null;
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
try {
auline = (SourceDataLine) AudioSystem.getLine(info);
auline.open(format);
} catch (Exception e) {
e.printStackTrace();
return;
}
auline.start();
int nBytesRead = 0;
//这是缓冲
byte[] abData = new byte[512];
try {
while (nBytesRead != -1) {
nBytesRead = audioInputStream.read(abData, 0, abData.length);
if (nBytesRead >= 0)
auline.write(abData, 0, nBytesRead);
}
} catch (IOException e) {
e.printStackTrace();
return;
} finally {
auline.drain();
auline.close();
}
}
}
将重复代码提取到共同的父类,并声明为抽象类,子类继承并实现不同的方法