package mytankgame;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Vector;
public class MyTankGame implements ActionListener{
JFrame jf=null;
StartPanel sp=null;
JMenuBar jmb=null;
//菜单
JMenu jm=null;
//菜单选项
JMenuItem ji1=null;
JMenuItem ji2=null;
JMenuItem ji3=null;
//构造函数初始化程序的界面
MyTankGame()
{
jf=new JFrame("坦克大战");
sp=new StartPanel();
jf.setBounds(300, 200, 800, 700);
//菜单条
jmb=new JMenuBar();
//菜单
jm=new JMenu("游戏");
//开始游戏菜单选项
ji1=new JMenuItem("开始游戏");
ji1.setActionCommand("newgame");
ji1.addActionListener(this);
//存盘退出
ji2=new JMenuItem("存盘退出");
ji2.setActionCommand("saveexit");
ji2.addActionListener(this);
jf.setJMenuBar(jmb);
jmb.add(jm);
jm.add(ji1);
jm.add(ji2);
jm.add(ji3);
jf.add(sp);
new Thread(sp).start();
jf.setVisible(true);
}
//主函数
public static void main(String[] args) {
MyTankGame mtg=new MyTankGame();
}
@Override
//事件监听方法
public void actionPerformed(ActionEvent e) {
//当点击新游戏的时候的方法
if(e.getActionCommand().equals("newgame"))
{
MyPanel mp=new MyPanel();
jf.remove(sp);
jf.add(mp);
new Thread(mp).start();
jf.addKeyListener(mp);
jf.setVisible(true);
}else if(e.getActionCommand().equals("saveexit"))//点击存盘退出时的方法
{
Recorder.saveExit();
System.exit(0);
}
}
}
//设置一个开始时的面板,并且实现字体闪动效果
class StartPanel extends JPanel implements Runnable
{
int times=0;
public void paint(Graphics g)
{
super.paint(g);
g.fillRect(0, 0, 500, 400);
//让面板实现闪动效果
if(times%2==0)
{
g.setColor(Color.lightGray);
Font myfont=new Font("华文新魏", Font.BOLD, 100);
g.setFont(myfont);
g.drawString("STAGE :1", 30, 150);
}
}
@Override
public void run() {
while(true)
{
try {
Thread.sleep(500);
} catch (Exception e) {
// TODO: handle exception
}
times++;
this.repaint();
}
}
}
//游戏主界面
class MyPanel extends JPanel implements KeyListener,Runnable
{
//定义爆炸时候的图片
Image i1=null;
Image i2=null;
Image i3=null;
Image i4=null;
Image i5=null;
Image i6=null;
Image i7=null;
Image i8=null;
//存放爆炸类的集合
Vector vboom=new Vector();
HeroTank hero=null;
//存放敌方坦克的集合
Vector v=new Vector();
MyPanel()
{
//将敌方坦克的集合传入
Recorder.setV(v);
//初始化我的坦克
hero=new HeroTank(10,10);
//初始化敌方坦克
for (int x=0;x<3;x++)
{
enemyTank enemy=new enemyTank((x+1)*100,0);
//将面板上的所有坦克传入,来判断是否碰撞
enemy.setEt(v);
enemy.setDirect(2);
new Thread(enemy).start();
Bullet bullet=new Bullet(enemy.x+23,enemy.y+25,enemy.direct);
enemy.enemyV.add(bullet);
new Thread(bullet).start();
v.add(enemy);
}
i1=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/blast1.gif"));
i2=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/blast2.gif"));
i3=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/blast3.gif"));
i4=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/blast4.gif"));
i5=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/blast5.gif"));
i6=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/blast6.gif"));
i7=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/blast7.gif"));
i8=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/blast8.gif"));
}
public void paint(Graphics g)
{
super.paint(g);
g.fillRect(0, 0, 500, 400);
//画出记录坦克总数的方法
showInfo(g);
//画自己的坦克
if(hero.isLive)
{
drawTank(hero.getX(),hero.getY(),g,1,hero.getDirect());
}
//画出敌方坦克和子弹
for (int x=0;xif(et.isLive==true)
{
drawTank(et.getX(),et.getY(),g,0,et.direct);
for(int i=0;iif(b.isLive)
{
g.drawOval(b.x,b.y, 2, 2);
}else
{
et.enemyV.remove(b);
}
}
}
}
//画出自己的子弹
for(int i=0;iif(mybullet!=null&&mybullet.isLive==true)
{
g.drawOval(mybullet.x, mybullet.y, 2, 2);
}
if(mybullet.isLive==false)
{
hero.vb.remove(i);
}
}
//画出爆炸的效果
for(int j=0;j//System.out.println(b.x+":"+b.y);
if(b.live>42)
{
g.drawImage(i1, b.x, b.y, 60, 60,this);
}else if(b.live>36)
{
g.drawImage(i2, b.x, b.y, 60, 60, this);
}else if(b.live>30)
{
g.drawImage(i3, b.x, b.y, 60, 60, this);
}else if(b.live>24)
{
g.drawImage(i4,b.x, b.y, 60, 60, this);
}else if(b.live>18)
{
g.drawImage(i5, b.x, b.y, 60, 60, this);
}else if(b.live>12)
{
g.drawImage(i6, b.x, b.y, 60, 60, this);
}else if(b.live>6)
{
g.drawImage(i7, b.x, b.y, 60, 60, this);
}else
{
g.drawImage(i8, b.x, b.y, 60, 60, this);
}
b.lifeDown();
if(b.live==0)
{
vboom.remove(b);
}
}
}
//画出记录坦克数量的函数
public void showInfo(Graphics g)
{
this.drawTank(50,450,g,0,0);
g.setColor(Color.BLACK);
Font myfont=new Font("华文新魏", Font.BOLD, 30);
g.setFont(myfont);
g.drawString(Recorder.getEnemynum()+"", 100, 480);
this.drawTank(150,450,g,1,0);
g.drawString(Recorder.getMenum()+"", 200, 480);
g.setColor(Color.black);
g.drawString("您的总成绩", 530, 50);
this.drawTank(530, 90, g, 0, 0);
g.setColor(Color.black);
g.drawString(Recorder.getAllen()+"", 600, 120);
}
//画坦克的函数
public void drawTank(int x,int y,Graphics g,int type,int direct)
{
//根据类型画出不同颜色的坦克来区分
switch(type)
{
case 0:
g.setColor(Color.CYAN);
break;
case 1:
g.setColor(Color.ORANGE);
break;
}
//判断方向画出不同方向的坦克
switch(direct)
{
case 0:
g.fill3DRect(x, y, 10, 50,false);
g.fill3DRect(x+5, y+5,25,40,false);
g.fill3DRect(x+30, y, 10, 50,false);;
g.fillOval(x+9, y+13, 20, 20);
g.drawLine(x+20, y+18, x+20, y-15);
break;
case 1:
g.fill3DRect(x, y, 50, 10, false);
g.fill3DRect(x+5, y+5, 40, 25, false);
g.fill3DRect(x, y+30, 50, 10, false);
g.fillOval(x+13, y+9, 20, 20);
g.drawLine(x+13, y+18, x+65, y+18);
break;
case 2:
g.fill3DRect(x, y, 10, 50,false);
g.fill3DRect(x+5, y+5,25,40,false);
g.fill3DRect(x+30, y, 10, 50,false);;
g.fillOval(x+9, y+13, 20, 20);
g.drawLine(x+20, y+18, x+20, y+63);
break;
case 3:
g.fill3DRect(x, y, 50, 10, false);
g.fill3DRect(x+5, y+5, 40, 25, false);
g.fill3DRect(x, y+30, 50, 10, false);
g.fillOval(x+13, y+9, 20, 20);
g.drawLine(x+20, y+18,x-15 , y+18);
break;
}
this.repaint();
}
//判断是否击中,子弹的坐标是否在坦克的范围内
public void hitTank(Tank et,Bullet b)
{
switch(et.direct)
{
case 0:
case 2:
if(b.x>et.x&&b.x45&&b.y>et.y&&b.y50)
{
et.isLive=false;
b.isLive=false;
if(et instanceof enemyTank)
{
Recorder.enemydown();
Recorder.allUp();
}else
{
Recorder.medown();
}
Boom bm=new Boom(et.x,et.y);
vboom.add(bm);
}
break;
case 1:
case 3:
if(b.x>et.x&&b.x50&&b.y>et.y&&b.y45)
{
et.isLive=false;
b.isLive=false;
if(et instanceof enemyTank)
{
Recorder.enemydown();
Recorder.allUp();
}else
{
Recorder.medown();
}
Boom bm=new Boom(et.x,et.y);
vboom.add(bm);
}
break;
}
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
//控制方向
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_W)
{
//方向向上
this.hero.setDirect(0);
this.hero.moveUp();
}else if(e.getKeyCode()==KeyEvent.VK_D)
{
this.hero.setDirect(1);
this.hero.moveRight();
}else if(e.getKeyCode()==KeyEvent.VK_S)
{
this.hero.setDirect(2);
this.hero.moveDown();
}else if(e.getKeyCode()==KeyEvent.VK_A)
{
this.hero.setDirect(3);
this.hero.moveLeft();
}
if(e.getKeyCode()==KeyEvent.VK_J)
{
if(hero.isLive)
{
if(hero.vb.size()<5)
{
hero.shot();
}
}
}
if(e.getKeyCode()==KeyEvent.VK_SPACE)
{
hero.speed=0;
hero.bullet.speed=0;
hero.setDirect(hero.direct);
for(int i=0;i0;
v.get(i).setDirect(v.get(i).direct);
for(int j=0;j0;
}
}
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void run() {
while(true)
{
try{
Thread.sleep(100);
}catch (Exception e) {
// TODO: handle exception
}
//判断敌人坦克是否被子弹击中
for (int i=0;iif(b.isLive)
{
for (int j=0;jif(et.isLive)
{
hitTank(et,b);
}
}
}
}
//判断自己坦克有没有被坦克击中
for(int i=0;ifor(int j=0;jif(hero.isLive)
{
hitTank(hero,b);
}
}
}
this.repaint();
}
}
}
//记录类
class Recorder
{
//敌人坦克的数量
private static int enemynum=20;
//自己坦克的生命
private static int menum=3;
//杀死坦克的数量
private static int allen=0;
private static BufferedReader br=null;
private static BufferedWriter bw=null;
private static Vector v=new Vector();
public static Vector getV() {
return v;
}
public static void setV(Vector v) {
Recorder.v = v;
}
public static int getAllen() {
return allen;
}
public static void setAllen(int allen) {
Recorder.allen = allen;
}
public static int getEnemynum() {
return enemynum;
}
public void setEnemynum(int enemynum) {
this.enemynum = enemynum;
}
public static int getMenum() {
return menum;
}
public void setMenum(int menum) {
this.menum = menum;
}
public static void enemydown()
{
enemynum--;
}
public static void medown()
{
menum--;
}
public static void allUp()
{
allen++;
}
public static void saveExit()
{
//将传进来的敌方坦克的集合里的坦克的坐标方向都存在文件里
try
{
bw=new BufferedWriter(new FileWriter("myRecorder.txt"));
for(int i=0;iif(v.get(i).isLive)
{
bw.write(allen+""+"\r\n");
String recorder=v.get(i).x+" "+v.get(i).y+" "+v.get(i).direct+"\r\n";
bw.write(recorder);
}
}
}catch (Exception e) {
// TODO: handle exception
}finally
{
try
{
bw.close();
}catch (Exception e) {
// TODO: handle exception
}
}
}
}
//爆炸类
class Boom
{
//定义爆炸的坐标
int x;
int y;
//爆炸随着时间的不同来显示不同的图片,来造成爆炸的视觉效果,定义一个时间
int live=48;
boolean isLive=true;
public Boom(int x,int y)
{
this.x=x;
this.y=y;
}
public void lifeDown()
{
if(live>0)
{
live--;
}else
{
isLive=false;
}
}
}
//坦克类
class Tank
{
//坦克的横纵坐标
int x=0;
int y=0;
//坦克的方向
int direct=0;
int speed=1;
boolean isLive=true;
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;
}
Tank(int x,int y)
{
this.x=x;
this.y=y;
}
}
//敌方坦克
class enemyTank extends Tank implements Runnable
{
int times=0;
//存放子弹的集合,为每个坦克自带的属性
Vector enemyV=new Vector();
//取出所有panel里面的坦克的集合,来判断是否有碰撞
Vector vv=new Vector();
Bullet bullet=null;
enemyTank(int x,int y)
{
super(x,y);
}
//将所有面板上的坦克传进的方法
public void setEt(Vector v)
{
this.vv=v;
}
//判断是否碰撞的方法
public boolean isTouch()
{
boolean flag=false;
switch(this.direct)
{
case 0:
for(int i=0;i//判断取出的坦克是不是自己
if(et!=this)
{
//敌方坦克向上或者向下
if(et.direct==0||et.direct==2)
{
//判断最前面的两个点即可
if(this.x>=et.x&&this.x45&&this.y>=et.y&&this.y<=et.y+50)
{
return true;
}
if(this.x+45>=et.x&&this.x+45<=et.x+45&&this.y>=et.y&&this.y<=et.y+50)
{
return true;
}
}
//敌方坦克向左或者向右
if(et.direct==1||et.direct==3)
{
if(this.x>=et.x&&this.x<=et.x+50&&this.y>=et.y&&this.y<=et.y+45)
{
return true;
}
if(this.x+45>=et.x&&this.x+45<=et.x+50&&this.y>=et.y&&this.y<=et.y+45)
{
return true;
}
}
}
}
break;
case 1:
for(int i=0;i//判断取出的坦克是不是自己
if(et!=this)
{
//敌方坦克向上或者向下
if(et.direct==0||et.direct==2)
{
//判断最前面的两个点即可
if(this.x+50>=et.x&&this.x+5045&&this.y>=et.y&&this.y<=et.y+50)
{
return true;
}
if(this.x+50>=et.x&&this.x+50<=et.x+45&&this.y+45>=et.y&&this.y+45<=et.y+50)
{
return true;
}
}
//敌方坦克向左或者向右
if(et.direct==1||et.direct==3)
{
if(this.x+50>=et.x&&this.x+50<=et.x+50&&this.y>=et.y&&this.y<=et.y+45)
{
return true;
}
if(this.x+50>=et.x&&this.x+50<=et.x+50&&this.y+45>=et.y&&this.y+45<=et.y+45)
{
return true;
}
}
}
}
break;
case 2:
for(int i=0;i//判断取出的坦克是不是自己
if(et!=this)
{
//敌方坦克向上或者向下
if(et.direct==0||et.direct==2)
{
//判断最前面的两个点即可
if(this.x>=et.x&&this.x45&&this.y+50>=et.y&&this.y+50<=et.y+50)
{
return true;
}
if(this.x+45>=et.x&&this.x+45<=et.x+45&&this.y+50>=et.y&&this.y+50<=et.y+50)
{
return true;
}
}
//敌方坦克向左或者向右
if(et.direct==1||et.direct==3)
{
if(this.x>=et.x&&this.x<=et.x+50&&this.y+50>=et.y&&this.y+50<=et.y+45)
{
return true;
}
if(this.x+45>=et.x&&this.x+45<=et.x+50&&this.y+50>=et.y&&this.y+50<=et.y+45)
{
return true;
}
}
}
}
break;
case 3:
for(int i=0;i//判断取出的坦克是不是自己
if(et!=this)
{
//敌方坦克向上或者向下
if(et.direct==0||et.direct==2)
{
//判断最前面的两个点即可
if(this.x>=et.x&&this.x45&&this.y>=et.y&&this.y<=et.y+50)
{
return true;
}
if(this.x>=et.x&&this.x<=et.x+45&&this.y+45>=et.y&&this.y+45<=et.y+50)
{
return true;
}
}
//敌方坦克向左或者向右
if(et.direct==1||et.direct==3)
{
if(this.x>=et.x&&this.x<=et.x+50&&this.y>=et.y&&this.y<=et.y+45)
{
return true;
}
if(this.x>=et.x&&this.x<=et.x+50&&this.y+45>=et.y&&this.y+45<=et.y+45)
{
return true;
}
}
}
}
break;
}
return flag;
}
@Override
public void run() {
while(true)
{
//判断方向,然后让坦克向一定方向走一段时间,再转换方向
switch(direct)
{
case 0:
for(int i=0;i<30;i++)
{
if(y>0&&!isTouch())
{
y-=speed;
try {
Thread.sleep(50);
} catch (Exception e) {
}
}
}
break;
case 1:
for(int i=0;i<30;i++)
{
if(x<500&&!isTouch())
{
x+=speed;
try {
Thread.sleep(50);
} catch (Exception e) {
}
}
}
break;
case 2:
for(int i=0;i<30;i++)
{
if(y<400&&!isTouch())
{
y+=speed;
try {
Thread.sleep(50);
} catch (Exception e) {
}
}
}
break;
case 3:
for(int i=0;i<30;i++)
{
if(x>0&&!isTouch())
{
x-=speed;
try {
Thread.sleep(50);
} catch (Exception e) {
}
}
}
break;
}
times++;
if(times%2==0)
{
if(isLive)
{
Bullet bullet=null;
if(enemyV.size()<5)
{
switch(direct)
{
case 0:
bullet=new Bullet(x+20,y-15,0);
enemyV.add(bullet);
break;
case 1:
bullet=new Bullet(x+65,y+18,1);
enemyV.add(bullet);
break;
case 2:
bullet=new Bullet(x+20,y+63,2);
enemyV.add(bullet);
break;
case 3:
bullet=new Bullet(x-15,y+18,3);
enemyV.add(bullet);
break;
}
new Thread(bullet).start();
}
}
}
//随机产生方向
direct=(int)(Math.random()*4);
if(isLive==false)
{
break;
}
}
}
}
//我方坦克
class HeroTank extends Tank
{
int speed=1;
Bullet bullet=null;
Vector vb=new Vector();
HeroTank(int x,int y)
{
super(x,y);
}
public void shot()
{
switch(direct)
{
case 0:
bullet=new Bullet(x+20,y-15,0);
vb.add(bullet);
break;
case 1:
bullet=new Bullet(x+65,y+18,1);
vb.add(bullet);
break;
case 2:
bullet=new Bullet(x+20,y+63,2);
vb.add(bullet);
break;
case 3:
bullet=new Bullet(x-15,y+18,3);
vb.add(bullet);
break;
}
new Thread(bullet).start();
}
public void moveUp()
{
y-=speed;
}
public void moveRight()
{
x+=speed;
}
public void moveDown()
{
y+=speed;
}
public void moveLeft()
{
x-=speed;
}
}
//子弹
class Bullet implements Runnable
{
int x;
int y;
int direct;
int speed=1;
boolean isLive=true;
Bullet(int x,int y,int direct)
{
this.x=x;
this.y=y;
this.direct=direct;
}
@Override
public void run()
{
while(true)
{
//每发射一颗子弹都停50ms
try{
Thread.sleep(50);
}catch(InterruptedException e)
{
}
//判断子弹的方向,然后移动
switch(direct)
{
case 0:
y-=speed;
break;
case 1:
x+=speed;
break;
case 2:
y+=speed;
break;
case 3:
x-=speed;
break;
}
//如果子弹超出了panel的大小就视为死亡
if(x<0||x>500||y<0||y>400)
{
isLive=false;
break;
}
}
}
}
跟着教程做了简易版的坦克大战,才知道自己要学习的东西还有很多很多。挺艰难的,很多东西也都还没有实现。以后的路还有很远很远。与君共勉。