主要是利用JAVA的swing和多线程做一个简易飞机大战的小游戏,功能比较简单。完整代码已经上传到 https://download.csdn.net/download/weixin_42368748/12137255 ,可免费下载。
文章目录
游戏规则
通过鼠标控制己方飞机的左右移动,移动到不同地方按下空格键切换不同的状态(颜色),它发射出来的子弹要打到相同颜色的敌机才能使其击毁。击毁一架敌机加一分,敌机越界则己方扣一滴血,到0则游戏结束。
基本框架
简单讲述一下设计思路,首先打开UI布局,然后启动飞行物管理线程;从而生成己方飞机,并且开启管理子弹的线程和管理敌机的线程;这两个线程生成子弹和敌机。
可以看看这个粗略的UML图,大致理解各个类的关系:
GameUI:游戏布局类。用JFrame和JPanel实现游戏布局;创建FlyCtrl对象,同时启动后者这一线程。
FlyCtrl:飞行物管理类,同时也是一个管理整个游戏的线程。包括创建Plane对象、ScoreBoard对象;启动BulletThread线程和ShipThread线程;存储上述两个线程产生的Bullet对象和Ship对象,并进行管理。
Plane:己方飞机类。存储己方飞机的位置、大小、状态等信息;受监听器MListener控制;提供位置信息给BulletThread;包含对自身的绘制。
ScoreBoard:得分和血量显示类。存储当前游戏得分、己方飞机血量;包含加分、扣血等方法;回馈信息给FlyCtrl;作为难度参考提供信息给ShipThread。
BulletThread:管理子弹生成的线程。根据Plane的位置和状态定时生成Bullet对象,加入到FlyCtrl的子弹列表中。
ShipThread:管理敌机生成的线程。根据ScoreBoard提供的当前分数,按不同难度随机生成Ship对象,加入到FlyCtrl的敌机列表中。
Bullet类和Ship类实现FlyObject接口,分别表示一个子弹和一个敌机,包含位置、大小、状态等自身信息,以及移动、绘制自身、得到自身信息的方法。
重要代码展示
挑几个重点的讲一下吧!
(1) UI布局
- 创建JFrame。
- 创建中间面板,加进frame中。
- 创建底部面板,添加标签插入图片,加进frame中。
- 设置frame可见。
- 创建FlyCtrl对象,传入中间面板。
- 创建新线程,传入上述对象(任务)。
- 线程start,设置标志位。
重点就是启动管理线程:
FlyCtrl实现Runnable接口,所以创建了它的对象后,赋值给一个新的线程,并且start即可。另外,设置标志位是为了方便该线程的控制。
JPanel mainPanel= new JPanel(); //中间区域 游戏主要的区域
mainPanel.setPreferredSize(new Dimension(600,700));
jf.add(mainPanel, BorderLayout.CENTER);
jf.setVisible(true);
FlyCtrl ctrl= new FlyCtrl(mainPanel); //飞行控制线程,控制所有飞行物
Thread ctrlThread = new Thread(ctrl);
ctrlThread.start();
ctrl.setFlag(true);
(2) 总控线程 FlyCtrl
飞行物管理类,同时也是一个管理整个游戏的线程。结构如下:
- 获取画板。
- 创建Plane对象(设置监听器)、ScoreBoard对象。
- 创建对象并启动BulletThread线程和ShipThread线程。
- 创建两个列表分别存储待生成的Bullet对象和Ship对象。
- 绘制全部物品:
- 创建缓冲图像。
- 绘制己方飞机。
- 对子弹进行处理:
- 移动;
- 检测是否出界,若出界则删除该子弹;
- 检测碰撞,若与不同颜色敌机碰撞则删除子弹,同颜色则摧毁处理(删除、音效)。
- 绘制现有所有子弹。
- 对敌机进行处理:
- 移动;
- 检测是否出界,若出界说明越界,己方飞机扣血;
- 绘制现有所有敌机。
- 绘制得分血量牌。
- 以上均是绘制到缓冲图像上,现在再把缓冲图像绘制到容器的画板上。
- 线程循环运行。
结合注释看看代码吧:
public class FlyCtrl implements Runnable{
Plane myPlane;
MListener listener;
ScoreBoard scoreBoard;
List<FlyObject> bulletList;
List<FlyObject> enemyList;
AudioClip boomSound;
AudioClip debloodSound;
Graphics2D g;
boolean flag; //线程运行的标志
//初始化
public void init(){
//创建己方飞机对象
Plane myPlane = new Plane();
listener.myplane= myPlane;
this.myPlane= myPlane;
//创建得分、血量显示牌
scoreBoard = new ScoreBoard();
//存储子弹和敌机的列表
bulletList = new ArrayList<FlyObject>();
enemyList = new ArrayList<FlyObject>();
//启动子弹管理线程
BulletThread bulletThread = new BulletThread(myPlane,bulletList);
bulletThread.start();
//启动敌机管理线程
ShipThread shipThread = new ShipThread(enemyList,scoreBoard);
shipThread.start();
}
//构造方法
public FlyCtrl(JPanel mainPanel){
//获取画板
g = (Graphics2D)mainPanel.getGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints