这学期开了专业课《JAVA语言程序设计》,前面有一段时间跟着韩顺平老师的视频学习,顺着也把坦克大战的代码敲了出来。今天,应老汪的任务布置,在博客园上开了个人博客,主要目的在于学习交流,分享自己的点滴经验。这也是我在博客园上的第一篇随笔,罗嗦下~~~~
TankeGame1_3.java
/**
* 功能:坦克大战
* 1.画出坦克
* 2.通过上下左右键控制坦克的移动
* 3.增加四辆敌人的坦克
* 4.画出了自己坦克的子弹,并能向敌人开火,子弹飞出去
* 5.子弹可以连发
* 6.子弹可以打死敌人的坦克,即子弹击中敌人坦克则敌人坦克消失
* 7.敌人的坦克击中我的坦克,则我的坦克消失
* 8.敌人的坦克运动时不能重叠在一起
* 9.游戏可以分关
* 9.1做一个分关panel,起提示作用
* 10.玩家在玩游戏时可以暂停
* 11.玩家结束游戏时可以保存游戏
*/
import java.awt.*;
import java.util.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.io.*;
//定义MyHelpPanel,提示帮助信息
class MyHelpPanel extends JPanel
{
public void paint(Graphics g)
{
g.fill3DRect(0, 0, 570, 430, false);
g.setColor(Color.blue);
Font myfont = new Font("方正喵呜体",Font.BOLD,30);
g.setFont(myfont);
g.drawString("游戏帮助:", 30, 50);
Font myfont1 = new Font("方正喵呜体",Font.BOLD,20);
g.setFont(myfont1);
g.drawString("1.↑,↓,←,→分别控制坦克的上下左右移动。", 38, 100);
g.drawString("2.按下空格键可以发射子弹。", 38, 150);
g.drawString("3.结束游戏可点击菜单栏的退出选项。", 38, 200);
g.drawString("---稻草人工作室", 260, 260);
}
}
//定义一个panel,提示首页信息
class MyStartPanel extends JPanel implements Runnable
{
int times = 0;
public void paint(Graphics g)
{
g.fill3DRect(0, 0, 570, 430, false);
//信息提示
if(times%2==0)
{
g.setColor(Color.blue);
Font myfont = new Font("方正喵呜体",Font.BOLD,40);
g.setFont(myfont);
g.drawString("坦克大战游戏", 140, 150);
Font myfont1 = new Font("方正喵呜体",Font.BOLD,25);
g.setFont(myfont1);
g.drawString("——稻草人工作室", 200, 200);
}
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true)
{
//休眠一秒
try {
Thread.sleep(1000);
times++;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
//重画
this.repaint();
}
}
}
//定义我的面板
class MyPanel extends JPanel implements KeyListener, Runnable {
int x = 10, y = 10;
// 定义一个我的坦克
Hero hero = null;
// 定义敌人的坦克组
Vector<Enemy> en = new Vector<Enemy>();
Vector<Node> nodes = new Vector<Node>();
// 定义敌人的坦克数量
int encount = 3;
// 定义炸弹向量集合
Vector<Bomb> bomb = new Vector<Bomb>();
// 构造函数
public MyPanel(String flag) {
//恢复数据
Record.getRecord();
// 初始化我的坦克
hero = new Hero(80, 80);
if(flag.equals("newgame"))
{
System.out.println("新游戏");
// 初始化敌人的坦克
for (int i = 0; i < encount; i++)
{
// 创建一辆坦克的对象
Enemy e = new Enemy((i + 1) * 50, 4);
e.setColor(3);// 给定敌人的坦克颜色
e.setDirect(1);// 给定方向
// 启动敌人的坦克
Thread t = new Thread(e);
t.start();
// 给敌人添加一颗子弹
Bullet b = new Bullet(e.x + 8, e.y + 35, 1);
// 给敌人坦克加入子弹
e.bb.add(b);
// 启动敌人子弹启动线程
Thread t2 = new Thread(b);
t2.start();
en.add(e);// 加入
// 将panel里的敌人坦克向量交给敌人的坦克
e.setEn(en);
}
}else if(flag.equals("con"))
{
nodes = new Record().getNodes();
System.out.println(nodes.size()+"旧游戏");
// 初始化敌人的坦克
for (int i = 0; i < nodes.size(); i++)
{
//取出节点中的一辆坦克(即是上次幸存下来的敌人坦克)
Node node = nodes.get(i);
// 创建一辆坦克的对象
Enemy e = new Enemy(node.x, node.y);
e.setColor(3);// 给定敌人的坦克颜色
e.setDirect(node.direct);// 给定方向
//将MyPanel的敌人坦克向量交给该敌人坦克
e.setEn(en);
// 启动敌人的坦克
Thread t = new Thread(e);
t.start();
// 给敌人添加一颗子弹
Bullet b = new Bullet(e.x + 8, e.y + 35, 1);
// 给敌人坦克加入子弹
e.bb.add(b);
// 启动敌人子弹启动线程
Thread t2 = new Thread(b);
t2.start();
en.add(e);// 加入
}
}
// try{
// image1 = ImageIO.read(new File("bomb_1.gif"));
// image2 = ImageIO.read(new File("bomb_2.gif"));
// image3 = ImageIO.read(new File("bomb_3.gif"));
// }catch(Exception e){
// e.printStackTrace();
// }
//播放开战声音
AePlayWave apw = new AePlayWave("E:/TDDOWNLOAD/tankedazhan.wav");
apw.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"));
}
// 定义三张坦克爆炸的图片
Image image1 = null;
Image image2 = null;
Image image3 = null;
//画出提示信息的函数
public void ShowInfo(Graphics g)
{
//画出提示信息,用于显示坦克的数量
//画出当前敌人坦克数量
this.drawTanke(20, 306, g, 2, 0);
g.setColor(Color.black);
Font myfont = new Font("方正喵呜体",Font.BOLD,20);
g.setFont(myfont);
g.drawString(Record.getEnNum()+"辆", 60, 325);
//画出当前我的坦克数量
this.drawTanke(125, 306, g, 2, 2);
g.drawString(Record.getMyLife()+"辆", 165, 325);
//画出玩家的总成绩
g.setColor(Color.black);
g.drawString("你的总成绩为:", 405, 30);
this.drawTanke(420, 45, g, 0, 0);
g.drawString(Record.getAllNum()+"×100="+Record.getAllNum()*100, 445, 70);
this.drawTanke(420, 105, g, 0, 1);
g.drawString(Record.getAllNum()+"×100="+Record.getAllNum()*200, 445, 130);
this.drawTanke(420, 165, g, 0, 2);
g.drawString(Record.getAllNum()+"×100="+Record.getAllNum()*300, 445, 190);
this.drawTanke(420, 225, g, 0, 3);
g.drawString(Record.getAllNum()+"×100="+Record.getAllNum()*400, 445, 250);
}
// 重新paint
public void paint(Graphics g) {
super.paint(g);
g.fillRect(0, 0, 400, 300);// 整个画面填充成黑色
//画出提示信息
this.ShowInfo(g);
// 画出自己的坦克
if(hero.isLive)
{
this.drawTanke(hero.getX(), hero.getY(), g, this.hero.direct, 3);
}else{
//this.remove(hero);
}
// 画自己坦克的子弹:从bb中取出每颗子弹,并画出来
for (int i = 0; i < hero.bb.size(); i++) {
Bullet mybullet = hero.bb.get(i);
// 画出子弹
if (mybullet != null && mybullet.isLive == true) {
g.draw3DRect(mybullet.x, mybullet.y, 2, 2, false);
}
// 如果子弹死亡就把子弹从bb中删除
if (mybullet.isLive == false) {
hero.bb.remove(mybullet);
}
}
// 画出炸弹
for (int i = 0; i < bomb.size(); i++) {
Bomb bo = bomb.get(i);
if (bo.Life > 6) {
g.drawImage(image1, bo.x, bo.y, 30, 30, this);
} else if (bo.Life > 3) {
g.drawImage(image2, bo.x, bo.y, 30, 30, this);
} else {
g.drawImage(image3, bo.x, bo.y, 30, 30, this);
}
// 生命值减减
bo.lifeDown();
if (bo.Life == 0) {
bomb.remove(bo);
}
}
// 画出敌人的坦克
for (int i = 0; i < en.size(); i++) {
Enemy enemy = en.get(i);
if (enemy.isLive) {
this.drawTanke(enemy.getX(), enemy.getY(), g, enemy.getDirect(), 1);
// 从bb中取出每颗子弹,并画出来
for (int j = 0; j < enemy.bb.size(); j++) {
Bullet enemybullet = enemy.bb.get(j);
// 画出子弹
if (enemybullet.isLive) {
g.draw3DRect(enemybullet.x, enemybullet.y, 2, 2, false);
} else// 如果这样就把子弹从bb中删除
{
enemy.bb.remove(enemybullet);
}
}
}
}
}
// 判断我的子弹是否击中敌人的坦克的函数
public void ShootEnemies() {
for (int i = 0; i < hero.bb.size(); i++) {
// 取出子弹
Bullet bullet1 = hero.bb.get(i);
// 判断子弹是否击中敌人
if (bullet1.isLive) {
// 取出每个坦克与子弹判断是否击中
for (int j = 0; j < en.size(); j++) {
// 取出坦克
Enemy enemy1 = en.get(j);
if (enemy1.isLive) {
if(this.ShootTanke(bullet1, enemy1))
{
Record.ReduceenNum();
Record.DeadNum();
}
}
}
}
}
}
// 判断敌人的子弹是否击中我的坦克的函数
public void ShootHero()
{
for(int i=0;i<this.en.size();i++)
{
//取出敌人坦克
Enemy e = en.get(i);
//取出每颗子弹判断是否击中我的坦克
if(e.isLive)
{
for(int j=0;j<e.bb.size();j++)
{
//取出子弹
Bullet bullet = e.bb.get(j);
if(hero.isLive)
{
if(this.ShootTanke(bullet, hero))
{
Record.HeroNum();
}
}
}
}
}
}
// 写一个专门函数判断子弹是否击中坦克
public boolean ShootTanke(Bullet b, Tanke ens) {
boolean boo = false;
// 判断坦克的方向
switch (ens.direct) {
// 如果敌人的坦克是向上或者向下
case 0:
case 1:
if (b.x > ens.x && b.x < ens.x + 20 && b.y > ens.y
&& b.y < ens.y + 30) {
// 击中,子弹死亡
b.isLive = false;
// 敌人坦克死亡
ens.isLive = false;
// Record.ReduceenNum();
// Record.DeadNum();
boo = true;
// 创建炸弹爆炸
Bomb bo = new Bomb(ens.x, ens.y);
// 放入炸弹的向量里
bomb.add(bo);
}
break;
case 2:
case 3:
if (b.x > ens.x && b.x < ens.x + 30 && b.y > ens.y
&& b.y < ens.y + 20) {
// 击中,子弹死亡
b.isLive = false;
// 敌人坦克死亡
ens.isLive = false;
boo = true;
// 创建炸弹爆炸
Bomb bo = new Bomb(ens.x, ens.y);
bomb.add(bo);
}
break;
}
return boo;
}
// 画坦克的函数(扩展)
public void drawTanke(int x, int y, Graphics g, int direct, int type) {
// 判断什么类型的坦克
switch (type) {
case 0:
g.setColor(Color.gray);
break;
case 1:
g.setColor(Color.green);
break;
case 2:
g.setColor(Color.blue);
break;
case 3:
g.setColor(Color.red);
break;
}
// 判断方向
switch (direct) {
// 坦克向上移动
case 0:
// 1.画左边的矩形框
g.fill3DRect(x, y, 5, 30, false);
// 2.画右边的矩形框
g.fill3DRect(x + 15, y, 5, 30, false);
// 画出中间矩形
g.fill3DRect(x + 5, y + 5, 10, 20, false);
// 画圆
g.fillOval(x + 4, y + 10, 10, 10);
// 画线(炮筒向上)
g.drawLine(x + 9, y + 10, x + 9, y - 7);
g.drawLine(x + 10, y + 10, x + 10, y - 7);
// 画左链条
g.drawLine(x, y + 5, x + 4, y + 5);
g.drawLine(x, y + 10, x + 4, y + 10);
g.drawLine(x, y + 15, x + 4, y + 15);
g.drawLine(x, y + 20, x + 4, y + 20);
g.drawLine(x, y + 25, x + 4, y + 25);
// 画右边的链条
g.drawLine(x + 15, y + 5, x + 19, y + 5);
g.drawLine(x + 15, y + 10, x + 19, y + 10);
g.drawLine(x + 15, y + 15, x + 19, y + 15);
g.drawLine(x + 15, y + 20, x + 19, y + 20);
g.drawLine(x + 15, y + 25, x + 19, y + 25);
break;
// 坦克向下移动
case 1:
// 1.画左边的矩形框
g.fill3DRect(x, y, 5, 30, false);
// 2.画右边的矩形框
g.fill3DRect(x + 15, y, 5, 30, false);
// 画出中间矩形
g.fill3DRect(x + 5, y + 5, 10, 20, false);
// 画圆
g.fillOval(x + 4, y + 10, 10, 10);
// 画线(炮筒向下)
g.drawLine(x + 9, y + 10, x + 9, y + 37);
g.drawLine(x + 10, y + 10, x + 10, y + 37);
// 画左链条
g.drawLine(x, y + 5, x + 4, y + 5);
g.drawLine(x, y + 10, x + 4, y + 10);
g.drawLine(x, y + 15, x + 4, y + 15);
g.drawLine(x, y + 20, x + 4, y + 20);
g.drawLine(x, y + 25, x + 4, y + 25);
// 画右边的链条
g.drawLine(x + 15, y + 5, x + 19, y + 5);
g.drawLine(x + 15, y + 10, x + 19, y + 10);
g.drawLine(x + 15, y + 15, x + 19, y + 15);
g.drawLine(x + 15, y + 20, x + 19, y + 20);
g.drawLine(x + 15, y + 25, x + 19, y + 25);
break;
// 坦克向左移动
case 2:
// 1.画上边的矩形框
g.fill3DRect(x, y, 30, 5, false);
// 2.画下边的矩形框
g.fill3DRect(x, y + 15, 30, 5, false);
// 画出中间矩形
g.fill3DRect(x + 5, y + 5, 20, 10, false);
// 画圆
g.fillOval(x + 10, y + 4, 10, 10);
// 画线(炮筒向左)
g.drawLine(x + 15, y + 9, x - 7, y + 9);
g.drawLine(x + 15, y + 10, x - 7, y + 10);
// 画上边的链条
g.drawLine(x + 5, y, x + 5, y + 4);
g.drawLine(x + 10, y, x + 10, y + 4);
g.drawLine(x + 15, y, x + 15, y + 4);
g.drawLine(x + 20, y, x + 20, y + 4);
g.drawLine(x + 25, y, x + 25, y + 4);
// 画下边的链条
g.drawLine(x + 5, y + 15, x + 5, y + 19);
g.drawLine(x + 10, y + 15, x + 10, y + 19);
g.drawLine(x + 15, y + 15, x + 15, y + 19);
g.drawLine(x + 20, y + 15, x + 20, y + 19);
g.drawLine(x + 25, y + 15, x + 25, y + 19);
break;
// 坦克向右移动
case 3:
// 1.画上边的矩形框
g.fill3DRect(x, y, 30, 5, false);
// 2.画下边的矩形框
g.fill3DRect(x, y + 15, 30, 5, false);
// 画出中间矩形
g.fill3DRect(x + 5, y + 5, 20, 10, false);
// 画圆
g.fillOval(x + 10, y + 4, 10, 10);
// 画线(炮筒向右)
g.drawLine(x + 15, y + 9, x + 35, y + 9);
g.drawLine(x + 15, y + 10, x + 35, y + 10);
// 画上边的链条
g.drawLine(x + 5, y, x + 5, y + 4);
g.drawLine(x + 10, y, x + 10, y + 4);
g.drawLine(x + 15, y, x + 15, y + 4);
g.drawLine(x + 20, y, x + 20, y + 4);
g.drawLine(x + 25, y, x + 25, y + 4);
// 画下边的链条
g.drawLine(x + 5, y + 15, x + 5, y + 19);
g.drawLine(x + 10, y + 15, x + 10, y + 19);
g.drawLine(x + 15, y + 15, x + 15, y + 19);
g.drawLine(x + 20, y + 15, x + 20, y + 19);
g.drawLine(x + 25, y + 15, x + 25, y + 19);
break;
}
}
// 按下某一个键
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_UP)// 上移
{
this.hero.setDirect(0);
this.hero.moveUp();
// 调用repaint()函数来重绘界面
this.repaint();
} else if (e.getKeyCode() == KeyEvent.VK_RIGHT)// 右移
{
this.hero.setDirect(3);
this.hero.moveRight();
// 调用repaint()函数来重绘界面
this.repaint();
} else if (e.getKeyCode() == KeyEvent.VK_LEFT)// 左移
{
this.hero.setDirect(2);
this.hero.moveLeft();
// 调用repaint()函数来重绘界面
this.repaint();
} else if (e.getKeyCode() == KeyEvent.VK_DOWN)// 下移
{
this.hero.setDirect(1);
this.hero.moveDown();
// 调用repaint()函数来重绘界面
this.repaint();
}
// 判断玩家是否按下空格键,是否发出子弹
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
// 此时玩家按下空格键,则开火
if (this.hero.bb.size() < 5) {
this.hero.Fire();
}
}
// 必须重新绘制Panel
this.repaint();
}
// 松开某一个键
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
// 键的值被输出
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
try {
Thread.sleep(100);// 每隔100毫秒重绘
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//我打敌人
this.ShootEnemies();
//敌人打我
this.ShootHero();
// 重绘
this.repaint();
}
}
}
public class TankeGame1_4 extends JFrame implements ActionListener{
//定义游戏面板
MyPanel mp = null;
//定义一个开始面板
MyStartPanel msp = null;
MyHelpPanel mhp = null;
//定义菜单和菜单选项
JMenuBar jmb = null;
JMenu jm1 = null,jm2 = null,jm3 = null;
JMenuItem jmi1 = null, jmi2 = null,jmi3 = null, jmi4 = null,
jmi5 = null,jmi6 = null,jmi7 = null;
// 构造函数
public TankeGame1_4() {
//创建菜单及菜单选项
jmb = new JMenuBar();
jm1 = new JMenu("游戏(G)");
jm2 = new JMenu("暂停/继续(Q)");
jm3 = new JMenu("帮助(H)");
jm1.setFont(new Font("方正喵呜体",Font.BOLD,15));//设置菜单显示的字体
jm1.setMnemonic('G');//设置快捷方式
jm2.setFont(new Font("方正喵呜体",Font.BOLD,15));//设置菜单显示的字体
jm2.setMnemonic('Q');//设置快捷方式
jm3.setFont(new Font("方正喵呜体",Font.BOLD,15));//设置菜单显示的字体
jm3.setMnemonic('H');//设置快捷方式
jmi1 = new JMenuItem("开始新游戏(N)");
jmi2 = new JMenuItem("继续旧游戏(J)");
jmi3 = new JMenuItem("保存游戏(B)");
jmi4 = new JMenuItem("退出(E)");
jmi5 = new JMenuItem("暂停(S)");
jmi6 = new JMenuItem("继续(C)");
jmi7 = new JMenuItem("游戏制作");
jmi1.setFont(new Font("方正喵呜体", Font.BOLD, 15));
jmi2.setFont(new Font("方正喵呜体", Font.BOLD, 15));
jmi3.setFont(new Font("方正喵呜体", Font.BOLD, 15));
jmi4.setFont(new Font("方正喵呜体", Font.BOLD, 15));
jmi5.setFont(new Font("方正喵呜体", Font.BOLD, 15));
jmi6.setFont(new Font("方正喵呜体", Font.BOLD, 15));
jmi7.setFont(new Font("方正喵呜体", Font.BOLD, 15));
jmi1.setMnemonic('N');//设置快捷键
jmi2.setMnemonic('J');//设置快捷键
jmi3.setMnemonic('B');//设置快捷键
jmi4.setMnemonic('E');//设置快捷键
jmi5.setMnemonic('S');//设置快捷键
jmi6.setMnemonic('C');//设置快捷键
jm1.add(jmi1);
jm1.add(jmi2);
jm1.add(jmi3);
jm1.add(jmi4);
jm2.add(jmi5);
jm2.add(jmi6);
jm3.add(jmi7);
jmb.add(jm1);
jmb.add(jm2);
jmb.add(jm3);
//注册菜单项的监听
jmi1.addActionListener(this);
jmi1.setActionCommand("newgame");
jmi2.addActionListener(this);
jmi2.setActionCommand("jixu");
jmi3.addActionListener(this);
jmi3.setActionCommand("save");
jmi4.addActionListener(this);
jmi4.setActionCommand("exit");
jmi7.addActionListener(this);
jmi7.setActionCommand("help");
msp = new MyStartPanel();
// 启动mp线程
Thread t = new Thread(msp);
t.start();
this.setJMenuBar(jmb);//菜单Bar放到JFrame上
this.add(msp);
this.setTitle("坦克大战");
this.setSize(570, 430);
this.setLocation(300, 100);//设置游戏框在屏幕上出现的位置
this.setResizable(false);//游戏框不能修改大小
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args) {
TankeGame1_4 tankegame1_1 = new TankeGame1_4();
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
//对监听到的用户的动作作出反应
if(e.getActionCommand().equals("newgame"))
{
//创建真正游戏面板
mp = new MyPanel("newgame");
Thread tt = new Thread(mp);
tt.start();
this.remove(msp);//移除旧的MyStartPanel面板
this.add(mp);//添加游戏面板MyPanel
// 注册监听
this.addKeyListener(mp);
//显示一下新添加的面板,这样才能看到新面板。
this.setVisible(true);
}
else if(e.getActionCommand().equals("save"))
{
//保存当前游戏状态
System.out.println("保存");
Record record = new Record();
record.setEn(mp.en);
record.keepEnemyRecord();
}
else if(e.getActionCommand().endsWith("jixu"))
{
//创建真正游戏面板
mp = new MyPanel("con");
Thread tt = new Thread(mp);
tt.start();
this.remove(msp);//移除旧的MyStartPanel面板
this.add(mp);//添加游戏面板MyPanel
// 注册监听
this.addKeyListener(mp);
//显示一下新添加的面板,这样才能看到新面板。
this.setVisible(true);
}
else if(e.getActionCommand().equals("exit"))
{
//退出前先保存游戏
Record record = new Record();
record.setEn(mp.en);
record.keepEnemyRecord();
System.exit(0);
}
else if(e.getActionCommand().equals("help"))
{
mhp = new MyHelpPanel();
this.remove(msp);
this.add(mhp);
this.setVisible(true);
}
}
}
Material.java
import java.util.Vector;
import java.io.*;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
//播放声音的类
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();
}
}
}
class Node
{
int x;
int y;
int direct;
public Node(int x,int y,int direct)
{
this.x = x;
this.y = y;
this.direct = direct;
}
}
//记录类,记录玩家的各种信息和设置
class Record
{
//从文件中读取记录点
static Vector<Node> nodes = new Vector<Node>();
//记录每关有多少敌人
private static int enNum = 20;
//我的生命值
private static int myLife = 3;
private static int allNum = 0;
private static FileWriter fw = null;
private static BufferedWriter bw = null;
private static FileReader fr = null;
private static BufferedReader br = null;
private static Vector<Enemy> en = new Vector<Enemy>();
public Vector<Enemy> getEn() {
return en;
}
public void setEn(Vector<Enemy> en1) {
this.en = en1;
}
//写一个函数读取文件里的信息(敌人坦克数量、坐标、方向)
public Vector<Node> getNodes()
{
try {
fr = new FileReader("d:\\mykeepRecord.txt");
br = new BufferedReader(fr);
String str = "";
str = br.readLine();
allNum = Integer.parseInt(str);
while((str = br.readLine())!=null)
{
String string[] = str.split(" ");
Node node = new Node(Integer.parseInt(string[0]), Integer.parseInt(string[1]),Integer.parseInt(string[2]));
nodes.add(node);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
try {
br.close();
fr.close();
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
return nodes;
}
//退出保存我消灭的敌人坦克数量的记录
public static void keepRecord()
{
try {
//创建txt文件
fw = new FileWriter("d:\\mykeepRecord.txt");
bw = new BufferedWriter(fw);
bw.write(allNum+"\r\n");
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
try {
//关闭流,谁先开就后关,后开先关
bw.close();
fw.close();
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
}
public void keepEnemyRecord()
{
try {
//创建txt文件,保存被消灭的敌人坦克数
fw = new FileWriter("d:\\mykeepRecord.txt");
bw = new BufferedWriter(fw);
bw.write(allNum+"\r\n");
//记录敌人活着的坦克的坐标、方向,为恢复游戏做准备。
for(int i = 0; i<en.size();i++)
{
//取出一辆坦克
Enemy e = en.get(i);
if(e.isLive)//坦克还活着
{
String enemyrecord = e.x+" "+e.y+" "+e.direct;
//写入
bw.write(enemyrecord+"\r\n");
}
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
try {
//关闭流,谁先开就后关,后开先关
bw.close();
fw.close();
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
}
//读取击毁的敌人坦克数量记录
public static void getRecord()
{
try {
fr = new FileReader("d:\\mykeepRecord.txt");
br = new BufferedReader(fr);
String str = br.readLine();
allNum = Integer.parseInt(str);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
try {
br.close();
fr.close();
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
}
public static int getAllNum() {
return allNum;
}
public static void setAllNum(int allNum) {
Record.allNum = allNum;
}
public static int getEnNum() {
return enNum;
}
public static void setEnNum(int enNum) {
Record.enNum = enNum;
}
public static int getMyLife() {
return myLife;
}
public static void setMyLife(int myLife) {
Record.myLife = myLife;
}
//减少敌人数量
public static void ReduceenNum()
{
enNum--;
}
//被消灭的敌人的坦克
public static void DeadNum()
{
allNum++;
}
//若我被击中,我的坦克数量减少
public static void HeroNum()
{
myLife--;
}
}
//炸弹类
class Bomb
{
int x, y;
int Life = 9;
boolean isLive = true;
public Bomb(int x,int y)
{
this.x = x;
this.y = y;
}
//减少生命值
public void lifeDown()
{
if(Life > 0)
{
Life--;
}else{
this.isLive = false;
}
}
}
//子弹类
class Bullet implements Runnable
{
int x, y,direct=0;
boolean isLive = true;
int speed = 3;//子弹的速度
public Bullet(int x, int y,int direct)
{
this.x = x;
this.y = y;
this.direct = direct;
}
public void run()
{
while(isLive){
//子弹先休息50毫秒
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
switch(direct)
{
//子弹向上飞
case 0:
y-=speed;
break;
//子弹向下飞
case 1:
y+=speed;
break;
//子弹向左飞
case 2:
x-=speed;
break;
//子弹向右飞
case 3:
x+=speed;
break;
}
//子弹何时死亡,判断子弹是否到达边缘
if(x < -2 || x > 400 || y < -2 || y > 296)
{
this.isLive = false;
break;
}
}
}
}
//坦克类
class Tanke{
int x = 0;//横坐标
int y = 0;//纵坐标
boolean isLive = true;
int direct = 0; //0表示向上,1表示向下,2表示向左,3表示向右
int speed = 3;//定义速度
int type = 0;//坦克类型:0表示灰色,打一次就死;1表示绿色,打两次才死;2表示蓝色,打三次才死;3表示红色,打四次才死。
int color;//坦克颜色
public int getColor() {
return color;
}
public void setEn(Vector<Enemy> vv) {
// TODO Auto-generated method stub
}
public void setColor(int color) {
this.color = color;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
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 Tanke(int x, int y){
this.x = x;
this.y = y;
}
}
//我的坦克
class Hero extends Tanke{
//子弹
//子弹向量组
Vector<Bullet> bb = new Vector<Bullet>();
Bullet b = null;
//坦克
public Hero(int x,int y){
super(x,y);
}
//开火
public void Fire()
{
switch(this.direct)
{
//子弹向上
case 0:
//创建一颗子弹
b = new Bullet(x+8, y-8,0);
//把子弹加入到向量中
bb.add(b);
break;
//子弹向下
case 1:
//创建一颗子弹
b = new Bullet(x+8, y+35,1);
//把子弹加入到向量中
bb.add(b);
break;
//子弹向左
case 2:
b = new Bullet(x-8,y+9,2);
bb.add(b);
break;
//子弹向右
case 3:
b = new Bullet(x+35, y+9,3);
bb.add(b);
break;
}
//启动子弹线程
Thread t = new Thread(b);
t.start();
}
//我的坦克向上移动
public void moveUp(){
if(y>0){
y-=speed;
}
}
//我的坦克向下移动
public void moveDown(){
if(y<228){
y+=speed;
}
}
//我的坦克向左移动
public void moveLeft(){
if(x>0){
x-=speed;
}
}
//我的坦克向右移动
public void moveRight(){
if(x<350){
x+=speed;
}
}
public void MyType(){
}
}
//敌人的坦克
class Enemy extends Tanke implements Runnable{
//定义敌人的坦克组,定义向量,可以访问到panel里敌人的坦克
Vector<Enemy> en = new Vector<Enemy>();
//定义敌人的子弹向量组
Vector<Bullet> bb = new Vector<Bullet>();
public Enemy(int x,int y)
{
super(x,y);
}
//得到panel里的敌人坦克向量
public void setEn(Vector<Enemy> vv)
{
this.en = vv;
}
//判断是否碰到了别的坦克
public boolean isTouchOtherEnemy()
{
boolean b = false;
switch(this.direct)
{
case 0:
//坦克向上,取出所有的敌人坦克
for(int i=0;i<en.size();i++)
{
//取出每一辆坦克
Enemy e = en.get(i);
//如果不是自己的坦克
if(e!=this)
{
//如果敌人的坦克向上或者向下
if(e.direct==0||e.direct==1)
{
if(this.x>=e.x&&this.x<=e.x+20&&this.y>=e.y&&this.y<=e.y+30)
{
return true;
}
if(this.x+20>=e.x&&this.x+20<=e.x+20&&this.y>=e.y&&this.y<=e.y+30)
{
return true;
}
}
//如果敌人的坦克向左或者向右
if(e.direct==2||e.direct==3)
{
if(this.x>=e.x&&this.x<=e.x+30&&this.y>=e.y&&this.y<=e.y+20)
{
return true;
}
if(this.x+20>=e.x&&this.x+20<=e.x+30&&this.y>=e.y&&this.y<=e.y+20)
{
return true;
}
}
}
}
break;
case 1:
//坦克向下,取出所有的敌人坦克
for(int i=0;i<en.size();i++)
{
//取出每一辆坦克
Enemy e = en.get(i);
//如果不是自己的坦克
if(e!=this)
{
//如果敌人的坦克向上或者向下
if(e.direct==0||e.direct==1)
{
if(this.x>=e.x&&this.x<=e.x+20&&this.y+30>=e.y&&this.y+30<=e.y+30)
{
return true;
}
if(this.x+20>=e.x&&this.x+20<=e.x+20&&this.y+30>=e.y&&this.y+30<=e.y+30)
{
return true;
}
}
//如果敌人的坦克向左或者向右
if(e.direct==2||e.direct==3)
{
if(this.x>=e.x&&this.x<=e.x+30&&this.y+30>=e.y&&this.y+30<=e.y+20)
{
return true;
}
if(this.x+20>=e.x&&this.x+20<=e.x+30&&this.y+30>=e.y&&this.y+30<=e.y+20)
{
return true;
}
}
}
}
break;
case 2:
//坦克向左,取出所有的敌人坦克
for(int i=0;i<en.size();i++)
{
//取出每一辆坦克
Enemy e = en.get(i);
//如果不是自己的坦克
if(e!=this)
{
//如果敌人的坦克向上或者向下
if(e.direct==0||e.direct==1)
{
if(this.x>=e.x&&this.x<=e.x+20&&this.y>=e.y&&this.y<=e.y+30)
{
return true;
}
if(this.x>=e.x&&this.x<=e.x+20&&this.y+20>=e.y&&this.y+20<=e.y+30)
{
return true;
}
}
//如果敌人的坦克向左或者向右
if(e.direct==2||e.direct==3)
{
if(this.x>=e.x&&this.x<=e.x+30&&this.y>=e.y&&this.y<=e.y+20)
{
return true;
}
if(this.x>=e.x&&this.x<=e.x+30&&this.y+20>=e.y&&this.y+20<=e.y+20)
{
return true;
}
}
}
}
break;
case 3:
//坦克向上,取出所有的敌人坦克
for(int i=0;i<en.size();i++)
{
//取出每一辆坦克
Enemy e = en.get(i);
//如果不是自己的坦克
if(e!=this)
{
//如果敌人的坦克向上或者向下
if(e.direct==0||e.direct==1)
{
if(this.x+30>=e.x&&this.x+30<=e.x+20&&this.y>=e.y&&this.y<=e.y+30)
{
return true;
}
if(this.x+30>=e.x&&this.x+30<=e.x+20&&this.y+20>=e.y&&this.y+20<=e.y+30)
{
return true;
}
}
//如果敌人的坦克向左或者向右
if(e.direct==2||e.direct==3)
{
if(this.x+30>=e.x&&this.x+30<=e.x+30&&this.y>=e.y&&this.y<=e.y+20)
{
return true;
}
if(this.x+30>=e.x&&this.x+30<=e.x+30&&this.y+20>=e.y&&this.y+20<=e.y+20)
{
return true;
}
}
}
}
break;
}
return b;
}
public void run() {
// TODO Auto-generated method stub
while(true)
{
//坦克休息80毫秒
try {
Thread.sleep(80);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
switch(this.direct)
{
//坦克向上
case 0:
for(int i=10;i>0;i--){
try {
Thread.sleep(40);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(y>0&&!this.isTouchOtherEnemy()){
y-=speed;
}
}
break;
//下
case 1:
for(int i=10;i>0;i--){
try {
Thread.sleep(80);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(y<228&&!this.isTouchOtherEnemy()){
y+=speed;
}
}
break;
//左
case 2:
for(int i=10;i>0;i--){
try {
Thread.sleep(80);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(x>0&&!this.isTouchOtherEnemy()){
x-=speed;
}
}
break;
//右
case 3:
for(int i=10;i>0;i--){
try {
Thread.sleep(80);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(x<333&&!this.isTouchOtherEnemy()){
x+=speed;
}
}
break;
}
//为敌人的坦克添加子弹连发
if(isLive)
{
if(bb.size()<3)
{
Bullet b = null;
//没有子弹 ,则添加子弹
switch(this.direct)
{
//子弹向上
case 0:
//创建一颗子弹
b = new Bullet(x+8, y-8,0);
//把子弹加入到向量中
bb.add(b);
break;
//子弹向下
case 1:
//创建一颗子弹
b = new Bullet(x+8, y+35,1);
//把子弹加入到向量中
bb.add(b);
break;
//子弹向左
case 2:
b = new Bullet(x-8,y+9,2);
bb.add(b);
break;
//子弹向右
case 3:
b = new Bullet(x+35, y+9,3);
bb.add(b);
break;
}
//启动子弹线程
Thread t = new Thread(b);
t.start();
}
}
//让坦克随机产生一个数,来确定坦克的方向
this.direct =(int)(Math.random()*4);
//判断坦克是否死亡
if(this.isLive == false){
break;
}
}
}
}
运行截图: