java初学者对于马士兵坦克大战的个人学习笔记及代码问题总结(第一阶段),
1、系统自动初始化了Graphics g参数
2、设计原则:高内聚,低耦合;
一个模块中的各元素之间的紧密程度越高,内聚性越高;
每个模块之间相互联系的紧密程度越低,耦合性越低。
对修改关闭,对扩展开放;
3、局部内部类:可以用,但是看起来不方便,内部类可以非常方便的访问包装类的局部变量
4、添加键盘监听时,如果使用implements KeyListener,则需要重写这个不需要的方法:
@Override
public void keyTyped(KeyEvent e) {
}
5、面向对象设计思想:
抽象出名词:类,属性
抽象出动词:方法
6、相对于int类型,用enum代表方向便于检查代码,编译期间就能知道错误,代码不易被修改
7、碰撞检测如何处理:
rectangle得到坦克和子弹的矩形,使用rect.intersects(tank.rect)判断两个矩形是否相交
8、坦克移动时一顿一顿的?
原因:把move方法放在了键盘监听的press方法和release方法里了,应该放在paint方法里
9、方块移动太快?
原因:paint方法的延时使用了以下方法(50微秒),使用MILLISECONDS(毫秒级)或者Thread.sleep正常
while(true){
try {
TimeUnit.MICROSECONDS.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
tf.repaint(); //repaint方法调用update方法,update方法调用paint方法
}
10、图像、声音资源只在程序打开时load一次,使用时调用即可
11、消除闪烁现象,先把图像数据加载到显存里的虚拟窗口,加载完成后再显示到窗口
12、NullPointerException 变量未初始化的异常
13、一个对象持有另一个对象的引用,把参数和方法传递给另一个对象
14、画不出敌方坦克?
原因是:if (this.group == Group.BAD) 的判断放在 if (this.group == Group.GOOD)的语句里了
15、简单处理,把碰撞检测看作判断坦克和子弹两个方块是否相撞,其他不规则物体判断相撞一般有封装的类库。可以直接引用
16、代码的重构:在不改变系统功能的前提下改善程序的结构,提高代码的质量
17、坦克可以出界?原因是用了以下程序
if (x>TankFrame.GAME_X+TankFrame.GAME_WIDTH-TANK_WIDTH-2){
x=TankFrame.GAME_X+TankFrame.GAME_WIDTH-TANK_WIDTH-2;
}
正确为:
if (x<0 || y<30 || x>TankFrame.GAME_WIDTH-TANK_WIDTH || y>TankFrame.GAME_HEIGHT-TANK_HEIGHT)
this.back();
}
18、坦克死了之后没有重画,但是可以发射子弹?
for (int i=0;i<tanks.size();i++) {
for (int j = 0; j < bullets.size(); j++) {
bullets.get(j).collidesWithTank(tanks.get(i));
}
}
此处for外循环的大括号没加,且子弹碰撞时的坐标写成了以下错误this.x应为this.y
int bY=this.x+TANK_HEIGHT/2-Bullet.BULLET_HEIGHT/2;
19、打死一个坦克后,再打另一个坦克出现错误
IllegalThreadStateException 非法的线程状态异常
原因是在TankFrame里Thread tr=new Thread(()->new Audio(“audio/explode.wav”).play());
然后在explode构造方法里调用tr.start方法,应该直接在构造方法里写new Thread(()->new Audio(“audio/explode.wav”).play()).start();
同一个线程不能多次执行start()方法
20、Class类:在硬盘上的class文件,虚拟机要用该文件时,会load进内存,便成为了Class类的对象