前言
本项目实现一个简单的坦克游戏程序1。游戏开始时,用户通过键盘操纵坦克移动和射击,与敌人坦克交战,最终记录被击毁次数和击毁敌方坦克数量。
程序功能设计要求
- 菜单界面。初始界面显示文字“stage 1”,单击菜单中的“开始”进入游戏界面。
- 我方坦克。绘制我方坦克,颜色为红色,我方坦克根据方向键上、下、左、右、移动,当按下空格键时,我方坦克发射红色子弹,当我方坦克子弹击中敌方坦克时,出现爆炸效果,敌方坦克消失,短暂时间后,在初始位置重新生成。
- 敌方坦克。绘制10个敌方坦克,颜色为蓝色,敌方坦克随机移动,敌方坦克根据自己的运动方向发射蓝色子弹,当敌方坦克子弹打中我方坦克,出现爆炸效果,我方坦克消失,短暂时间后,在初始位置重新生成。
项目解析
这个小游戏是用IntelliJ IDEA编写的,共有6个java文件:
* TankGameJFrame.java # 提供进入程序的main()方法,继承JFrame类,实现GUI框架
* Tank.java # 存储我方坦克相关数据的类
* eTank.java # 存储敌方坦克相关数据,实现Runnable接口,用线程实现坦克移动和发射子弹
* Shot.java # 存储子弹相关数据,实现Runnable接口,用线程实现子弹的发射
* Bomb.java # 存储爆炸图片,当坦克被击中时调用
* MyJPanel.java # 游戏场景界面,内有paint()方法,绘制敌我坦克交战的画面
菜单界面开发
程序主界面分为上下两部分,North是菜单,Center是卡片布局,叠放两个JPanel,一个初始面板,显示标签“stage 1”,一个对战面板,为一个MyJPanel的对象。
具体实现代码如下:
jPanelCenter = new JPanel();
cardLayout = new CardLayout();
jPanelCenter.setLayout(cardLayout);
getContentPane().add(jPanelCenter, BorderLayout.CENTER);
jPanelFirst = new JPanel();
jPanelFirst.setLayout(null);
jPanelFirst.setPreferredSize(new Dimension(800, 600));
jPanelFirst.setBackground(new Color(120, 100, 156));
label = new Label("Stage: 1");
label.setBounds(100, 50, 120, 30);
label.setFont(new Font("stfangsong", 1, 20));
label.setForeground(new Color(255, 255, 255));
jPanelFirst.add(label);
jPanelCenter.add("first", jPanelFirst);
cardLayout.show(jPanelCenter, "first");
jMenuBar1 = new JMenuBar();
setJMenuBar(jMenuBar1);
jMenuGame = new JMenu();
jMenuBar1.add(jMenuGame);
jMenuGame.setText("游戏(G)");
jMenuItemStart = new JMenuItem();
jMenuGame.add(jMenuItemStart);
jMenuItemStart.setText("开始");
jSeparator1 = new JSeparator();
jMenuGame.add(jSeparator1);
jMenuItemStart.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
tankPanel = new MyJPanel();
jPanelCenter.add("game", tankPanel);
cardLayout.show(jPanelCenter, "game");
Thread t = new Thread(tankPanel);
t.start();
addKeyListener(tankPanel);
}
});
jMenuItemSave = new JMenuItem();
jMenuGame.add(jMenuItemSave);
jMenuItemSave.setText("保存");
jSeparator2 = new JSeparator();
jMenuGame.add(jSeparator2);
jMenuItemExit = new JMenuItem();
jMenuGame.add(jMenuItemExit);
jMenuItemExit.setText("退出");
jMenuItemExit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
System.exit( 0 );
}
});
jMenuSet = new JMenu();
jMenuBar1.add(jMenuSet);
jMenuSet.setText("设置(T)");
jMenuHelp = new JMenu();
jMenuBar1.add(jMenuHelp);
jMenuHelp.setText("帮助(P)");
在JMenuItem“开始”事件响应子程序中,建立了MyJPanel类的对象,然后卡片布局切换到该对象面板,开启线程是因为要每隔100毫秒刷新对战面板中的场景,最后为对战面板添加了键盘输入监听器。
坦克的绘制
坦克的外形分为左边矩形框、中间矩形框、右边矩形框、圆形和直线,如图:
具体的参数如下:
g.fill3DRect(t.x, t.y, 5, 30, false); // 左边矩形框
g.fill3DRect(t.x + 5, t.y + 5, 10, 20, false); // 中间矩形框
g.fill3DRect(t.x + 15, t.y, 5, 30, false); // 右边矩形框
g.drawOval(t.x + 8, t.y + 11, 4, 4); // 圆形
g.drawLine(t.x + 10, t.y + 15, t.x + 10, t.y + 30); // 直线
这样画出来是朝上的坦克,朝右、朝下、朝左的坦克绘制原理是一样的,只需要调整相应参数的值,具体请看完整源代码。
实现我方坦克运动
让MyJPanel实现KeyListener接口,然后添加如下代码:
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_UP) {
TankGameJFrame.lYTank1.moveUp();
} else if(e.getKeyCode() == KeyEvent.VK_RIGHT) {
TankGameJFrame.lYTank1.moveRight();
} else if(e.getKeyCode() == KeyEvent.VK_DOWN) {
TankGameJFrame.lYTank1.moveDown();
} else if(e.getKeyCode() == KeyEvent.VK_LEFT) {
TankGameJFrame.lYTank1.moveLeft();
} else if(e.getKeyCode() == KeyEvent.VK_SPACE) {
TankGameJFrame.lYTank1.showShot();
}
this.repaint();
}
实现子弹飞翔
让Shot.java类实现Runnable接口,添加run()函数:
@Override
public void run() {
while(isLive) {
try {
Thread.sleep(20); // 休眠20毫秒
} catch(InterruptedException e) {}
if(direction == 0) { // 0 - 方向向上
this.setY(y - speed);
if(this.getY() < 0) {
this.isLive = false;
break;
}
}
if(direction == 1) { // 1 - 方向向右
this.setX(x + speed);
if(this.getX() > 800) {
this.isLive = false;
break;
}
}
if(direction == 2) { // 2 - 方向向下
this.setY(y + speed);
if(this.getY() > 600) {
this.isLive = false;
break;
}
}
if(direction == 3) { // 3 - 方向向左
this.setX(x - speed);
if(this.getX() < 0) {
this.isLive = false;
break;
}
}
}
}
源代码
完整的源代码请在GitCode中下载查看:下唐人 / tank_game · GitCode
运行
该项目已经编译好可执行JAR包,可直接运行。方法是打开终端,然后输入:
java -jar tank_game.jar
运行结果展示
Java程序设计实战教程——基于成果导向. 北京理工大学出版社. 2022.2 ↩︎