第一代版本 v1.0
放个项目链接
各个类的功能
- Ball:小球的基本参数,draw,move方法
- 监听器:监听鼠标按下的动作。new一个小球,new一个线程并启动。
- BallThread:每个线程是一个小球,一个线程既要move又要draw。
一些值得注意的问题
- 所有小球共用一个画笔,就会出现上面这种线程不安全问题。解决方法见监听器中的注释。
- 小球move和draw的衔接问题。见BallThread中的注释。
v2.0版本
v1的问题
每个小球一个线程这种方法是有问题的。小球只有draw和move两个操作。运算量很小,却占用了一个线程,这事不合理的。
小球少的话,只是浪费资源,小球多的话,就会开始卡顿。
v2做出了以下修改
- 新建DrawThread和MoveThread两个线程,分别用来控制画小球和移动小球。
- 修改监听器,new并star以上的两个线程,以实现v1中的功能。
- 修改Ball中的move方法,实现小球反弹。具体见注释。
- 监听器重修了mouseDragger方法,实现了跟踪鼠标拖动的轨迹画小球。
v2版本的问题
- 储存小球用的list是不支持线程安全的,具体见注释。
- drag ball时,各个球颜色不同,后续可根据需求修改。详见bragger注释。
- 当小球多的时候,放在一个线程中绘制,工作量太大。可以考虑一个线程绘制200个小球,满了就开下一个线程。
v3.0
v3的改动
- 注释掉了监听器中的mousePressed,避免碍眼。
- 实现了一个鼠标拖动的小球。
- 新增了两个类,MainBall,以及它的线程。
解决的技术问题
- 绘制新的小球时,老的小球轨迹依旧存在。解决办法:绘制个白板,遮盖住之前绘制的小球。
- 小球由于内存问题会频闪。是用BufferedImage解决,在缓存器上画背景和小球,然后在窗体中将缓存器画出来。详见MainBallThread。
V 4.0 planewar
一个飞机大战的小游戏,双方飞机自动射击,自动生成敌方飞机,己方飞机可以用子弹击毁敌方飞机,可以撞毁敌方飞机。敌方飞机不能击毁己方飞机(自己给自己开挂)。
详见项目中的planewar,项目架构如下:
一些值得注意的问题
- 一个小技巧:弄一个Main,负责数据(plane,enemies,planeBullets,enemyBullets,ui和监听器)的集中调度。项目中所有的变量实际上都是main中的变量,其他类使用引用变量进行get,set操作。
- planeBullet和enemyBullets的架构有些不同。planeBullet直接放在了Plane中,而enemyBullets则是在Main中。因为enemyBullets逻辑更复杂,放在Main中方便其他类使用。
- Plane.fire()只是在new bullet,并将其加入planeBullets。
- 在AutoCreatThread中,每一个enemy均有一个GunThread,但是处于业务需要,所有的bullets只需要存在一个thread中即可,并不需要为每个enemy去创建一个list来存放子弹。
- Main.init():使用creatPlane()创建了plane,并启动了plane.fire()。另外就是初始化了ui和监听器。
- 当一个enemy消失之后,他的GunTheard并不会停止,还会继续开火。所以需要给Enemy一个HP属性,当检测到碰撞时,HP=0。在GunThread.run()中,则是当if(HP==0)break;