/*
*
* 功能:坦克大战4.0.版
* 画出坦克
* 可以上下左右移动
* 坦克可以连发子弹
* 实现坦克爆炸的效果
* 防止敌人坦克重叠
* 1,决定把这段代码放在EnemyTank中
* 可以分关
* 1、专门写一个Panel,他说一个空的
* 2、让字体闪烁
* 可以在玩游戏的时候暂停和继续
*
* 1、当用户点击暂停时,把子弹和坦克的速度都设置为0,
* 并让坦克的方向不要变化
* 可以记录玩家的成绩
* 1、用文件流
* 2、单写一个类,来记录这些信息
* 3、先完成保存共击毁多少辆敌人坦克
* 4、存盘退出,可以记录未消灭坦克的状态,并可以恢复
* 5、
* java如何操作声音文件
*
*/
package com.hiatao.tank6;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.Reader;
import java.util.*;
public class MyTankGame6 extends JFrame implements ActionListener{
MyPanel mp=null;
//定义一个开始面板
MystartPanel msp=null;
//做出我的菜单
JMenuBar jmb=null;
//开始游戏
JMenu jm1=null;
JMenuItem jmi1=null;
JMenuItem jmi2=null;
JMenuItem jmi3=null;
JMenuItem jmi4=null;
public static void main(String[] args) {
MyTankGame6 mt=new MyTankGame6();
}
//构造函数
public MyTankGame6()
{
// mp=new MyPanel();
//启动mp线程
// Thread t=new Thread(mp);
// t.start();
// this.add(mp);
//注册监听
// this.addKeyListener(mp);
//创建菜单及菜单选项
jmb=new JMenuBar();
jm1=new JMenu("游戏(G)");
//设置快捷方式
jm1.setMnemonic('G');
jmi1=new JMenuItem("开始新游戏(N)");
jmi1.setMnemonic('N');
//对jmi1响应
jmi1.addActionListener(this);
jmi1.setActionCommand("newGame");
jmi2=new JMenuItem("退出游戏(E)");
jmi2.setMnemonic('E');
//对jmi2响应
jmi2.addActionListener(this);
jmi2.setActionCommand("exit");
jmi3=new JMenuItem("存盘退出(C)");
jmi3.setMnemonic('C');
//对jmi3进行注册监听
jmi3.addActionListener(this);
jmi3.setActionCommand("saveExit");
jmi4=new JMenuItem("继续上局(S)");
//注册监听
jmi4.addActionListener(this);
jmi4.setActionCommand("conGame");
jm1.add(jmi1);
jm1.add(jmi2);
jm1.add(jmi3);
jm1.add(jmi4);
jmb.add(jm1);
msp=new MystartPanel();
this.add(msp);
Thread t=new Thread(msp);
t.start();
this.setJMenuBar(jmb);
this.setTitle("坦克大战");
this.setSize(400,500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
//对用户不同的点击做出不同的处理
if(arg0.getActionCommand().equals("newGame"))
{
//创建战场面板
mp=new MyPanel("newGame");
//启动mp线程
Thread t=new Thread(mp);
t.start();
//先删除旧的面板
this.remove(msp);
this.add(mp);
//注册监听
this.addKeyListener(mp);
//显示,刷新
this.setVisible(true);
}
else if(arg0.getActionCommand().equals("exit"))
{
//用户点击了退出系统的菜单
//保存击毁敌人数量
Recorder.keepRecording();
System.exit(0);
}
else if(arg0.getActionCommand().equals("saveExit"))
{
//工作
Recorder er=new Recorder();
er.setEts(mp.ets);
//保存击毁敌人的数量和敌人的坐标
er.keepRecAndEnemyTank();
//退出
System.exit(0);
}
else if(arg0.getActionCommand().equals("conGame"))
{
//恢复
//创建战场面板
mp=new MyPanel("con");
//启动mp线程
Thread t=new Thread(mp);
t.start();
//先删除旧的面板
this.remove(msp);
this.add(mp);
//注册监听
this.addKeyListener(mp);
//显示,刷新
this.setVisible(true);
}
}
}
//就是一个提示作用
class MystartPanel extends JPanel implements Runnable
{
int times=0;
public void paint(Graphics g)
{
super.paint(g);
g.fillRect(0, 0, 400, 300);
//提示信息
if(times%2==0)
{
g.setColor(Color.YELLOW);
//开关信息的字体
Font myFont=new Font("华文新魏",Font.BOLD,30 );
g.setFont(myFont);
g.drawString("start", 150, 150);
}
}
public void run() {
// TODO Auto-generated method stub
while(true)
{
//休眠一秒
try {
Thread.sleep(400);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
times++;
//重画
this.repaint();
}
}
}
//我的面板
class MyPanel extends JPanel implements KeyListener,Runnable
{
//初始化一个我的坦克
Hero hero=null;
//判断是续上局还是新游戏
//定义敌人的坦克
Vector ets=new Vector();
Vector nodes=new Vector();
//定义一个炸弹集合
Vector bombs=new Vector();
int enSize=5;
//定义三张图片,三张图片才能组成一颗炸弹
Image image1=null;
Image image2=null;
Image image3=null;
//构造函数
public MyPanel(String flag)
{
//恢复记录
Recorder.getRecording();
hero=new Hero (170,260);
if(flag.equals("newGame"))
{
//初始化敌人的坦克
for(int i=0;i6)
{
g.drawImage(image1, b.x, b.y, 30, 30, this);
}
else if(b.life>3)
{
g.drawImage(image2, b.x, b.y, 30, 30, this);
}
else
{
g.drawImage(image3, b.x, b.y, 30, 30, this);
}
//让生命值减小
b.lifeDown();
//如果炸弹生命值为0,就让该炸弹从bombs向量中去掉
if(b.life==0)
{
bombs.remove(b);
}
}
//画出敌人的坦克
for(int i=0;iet.x&&s.x<(et.x+20)&&et.yet.x&&s.xet.y&&s.y
package com.hiatao.tank6;
import java.awt.Color;
import java.io.*;
import java.util.*;
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 Recorder
{
//记录每关有多少人
private static int enNum=20;
//设置我有多少人
private static int myLife=3;
//记录总共消灭了多少敌人
private static int allEnNum=0;
//从文件中恢复记录点
private static Vector nodes=new Vector();
private static FileWriter fw=null;
private static BufferedWriter bw=null;
private static FileReader fr=null;
private static BufferedReader br=null;
private Vector ets=new Vector();
//完成读取任务
public Vector getNodesAndEnNums()
{
try {
fr=new FileReader("d:\\myRecording.txt");
br=new BufferedReader(fr);
String n="";
//先读取第一行
n=br.readLine();
allEnNum=Integer.parseInt(n);
while((n=br.readLine())!=null)
{
String []xyz=n.split(" ");
Node node=new Node(Integer.parseInt(xyz[0]),Integer.parseInt(xyz[1]),Integer.parseInt(xyz[2]));
nodes.add(node);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
try {
br.close();
fr.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return nodes;
}
//保存击毁敌人的数量和地热坦克坐标和方向
public void keepRecAndEnemyTank()
{
//创建文件流
try {
fw=new FileWriter("d:\\myRecording.txt");
bw=new BufferedWriter(fw);
bw.write(allEnNum+"\r\n");
//保存当前还活着的坦克的坐标和方向
for(int i=0;i getEts() {
return ets;
}
public void setEts(Vector ets) {
this.ets = ets;
// System.out.println("ok");
}
}
//炸弹类
class Bomb
{
//定义炸弹的坐标
int x;
int 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 Shot implements Runnable
{
int x;
int y;
int direct;
int speed=2;
boolean islive=true;
public Shot(int x,int y,int direct)
{
this.x=x;
this.y=y;
this.direct=direct;
}
public void run() {
while(true)
{
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
switch(direct)
{
case 0:
//上
y-=speed;
break;
case 1:
x+=speed;
break;
case 2:
y+=speed;
break;
case 3:
x-=speed;
break;
}
// System.out.println("子弹坐标x="+x+"y="+y);
//判断该子弹是否碰到边缘
if(x<0||x>400||y<0||y>300)
{
this.islive=false;
break;
}
}
}
}
//定义一个坦克类
class Tank
{
//表示坦克的横坐标
int x=0;
//表示坦克纵坐标
int y=0;
//坦克方向,0表示上,1表示右,2表示下,3表示左
int dircet=0;
boolean islive=true;
//设置坦克的速度
int speed=2;
//定义坦克的颜色
int color;
public Tank(int x,int y)
{
this.x=x;
this.y=y;
}
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 int getDircet() {
return dircet;
}
public void setDircet(int dircet) {
this.dircet = dircet;
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
}
//敌人的坦克
class EnemyTank extends Tank implements Runnable
{
int times=0;
//定义一个向量,可以访问到MyPanel上所有敌人的坦克
Vector ets=new Vector();
//定义一个向量,可以存放敌人的坦克
Vector ss=new Vector();
//敌人添加子弹,应当在刚刚创建坦克和敌人的坦克子弹死亡后
public EnemyTank(int x, int y) {
super(x, y);
}
//得到MyPanel的敌人坦克向量
public void setEts(Vector vv)
{
this.ets=vv;
}
//判断是否碰到了别人坦克
public boolean isTouchotherEnemy()
{
boolean b=false;
switch(this.dircet)
{
case 0:
//我的坦克向上
//取出所有的敌人坦克
for(int i=0;iet.x&&this.x<=et.x+20&&this.y>=et.y&&this.y<=et.y+30)
{
return true;
}
//右一点
if(this.x+20>=et.x&&this.x+20=et.y&&this.y<=et.y+30)
{
return true;
}
}
if(et.dircet==1||et.dircet==3)
{
if(this.x>et.x&&this.x<=et.x+30&&this.y>=et.y&&this.y<=et.y+20)
{
return true;
}
if(this.x+20>=et.x&&this.x+20=et.y&&this.y<=et.y+20)
{
return true;
}
}
}
}
break;
case 1:
//坦克向右方向
//取出所有的敌人坦克
for(int i=0;iet.x&&this.x+30<=et.x+20&&this.y>=et.y&&this.y<=et.y+30)
{
return true;
}
//下一点
if(this.x+30>=et.x&&this.x+30=et.y&&this.y+20<=et.y+30)
{
return true;
}
}
if(et.dircet==1||et.dircet==3)
{
if(this.x+30>et.x&&this.x+30<=et.x+30&&this.y>=et.y&&this.y<=et.y+20)
{
return true;
}
if(this.x+30>=et.x&&this.x+30=et.y&&this.y+20<=et.y+20)
{
return true;
}
}
}
}
break;
case 2:
//坦克向下
//取出所有的敌人坦克
for(int i=0;iet.x&&this.x<=et.x+20&&this.y+30>=et.y&&this.y+30<=et.y+30)
{
return true;
}
//我右一点
if(this.x+20>=et.x&&this.x+20=et.y&&this.y+30<=et.y+30)
{
return true;
}
}
if(et.dircet==1||et.dircet==3)
{
if(this.x>et.x&&this.x<=et.x+30&&this.y+30>=et.y&&this.y+30<=et.y+20)
{
return true;
}
if(this.x+20>=et.x&&this.x+20=et.y&&this.y+30<=et.y+20)
{
return true;
}
}
}
}
break;
case 3:
//坦克方向向左
//取出所有的敌人坦克
for(int i=0;iet.x&&this.x<=et.x+20&&this.y>=et.y&&this.y<=et.y+30)
{
return true;
}
//我的下一点
if(this.x>=et.x&&this.x=et.y&&this.y+20<=et.y+30)
{
return true;
}
}
if(et.dircet==1||et.dircet==3)
{
//上一点
if(this.x>et.x&&this.x<=et.x+30&&this.y>=et.y&&this.y+20<=et.y+20)
{
return true;
}
if(this.x>=et.x&&this.x=et.y&&this.y+20<=et.y+20)
{
return true;
}
}
}
}
break;
}
return b;
}
public void run() {
// TODO Auto-generated method stub
while(true)
{
{
switch(this.dircet)
{
case 0:
//说明坦克正在向上移动
for(int i=0;i<30;i++)
{
//保证坦克不出边界
if(y>0&&!this.isTouchotherEnemy())
{
y-=speed;
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
break;
//向右
case 1:
for(int i=0;i<30;i++)
{
if(x<350&&!this.isTouchotherEnemy())
{
x+=speed;
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
break;
//向下
case 2:
for(int i=0;i<30;i++)
{
if(y<250&&!this.isTouchotherEnemy())
{
y+=speed;
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
break;
//向左
case 3:
for(int i=0;i<30;i++)
{
if(x>0&&!this.isTouchotherEnemy())
{
x-=speed;
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
break;
}
this.times++;
if(times%2==0)
{
if(islive)
{
if(ss.size()<5)
{
Shot s=null;
//添加子弹
//添加
switch(dircet)
{
case 0:
//创建一颗子弹
s=new Shot(x+10,y,0);
//把子弹加入到向量
ss.add(s);
break;
case 1:
s=new Shot(x+30,y+10,1);
ss.add(s);
break;
case 2:
s=new Shot(x+10,y+30,2);
ss.add(s);
break;
case 3:
s=new Shot(x,y+10,3);
ss.add(s);
break;
}
//启动子弹线程
Thread t=new Thread(s);
t.start();
}
}
}
//让坦克随机产生一个新的方向
this.dircet=(int)(Math.random()*4);
//判断敌人坦克是否死亡
if(this.islive==false)
{
//让坦克死亡后退出线程
break;
}
}
}
}
}
//定义我的坦克
class Hero extends Tank
{
//子弹
// Shot s=null;
Vector ss=new Vector();
Shot s=null;
public Hero(int x, int y) {
super(x, y);
}
//开火
public void ShotEnemy()
{
switch(this.dircet)
{
case 0:
//创建一颗子弹
s=new Shot(x+10,y,0);
//把子弹加入到向量
ss.add(s);
break;
case 1:
s=new Shot(x+30,y+10,1);
ss.add(s);
break;
case 2:
s=new Shot(x+10,y+30,2);
ss.add(s);
break;
case 3:
s=new Shot(x,y+10,3);
ss.add(s);
break;
}
//启动子弹线程
Thread t=new Thread(s);
t.start();
}
//坦克向上移动
public void moveUp()
{
if(y>0)
{
this.y-=speed;
}
}
//坦克向右移动4
public void moveRight()
{
if(x<350)
{
this.x+=speed;
}
}
//坦克向下移动
public void moveDown()
{
if(y<250)
{
this.y+=speed;
}
}
//坦克向左移动
public void moveLeft()
{
if(x>0)
{
this.x-=speed;
}
}
}