今天想將自己去年自己編寫的坦克大戰的代碼與大家分享一下,主要面向學習過java但對java運用並不是很熟悉的同學,該編程代碼基本上涉及了java基礎知識的各個方面,大家可以通過練習該程序對自己的java進行一下實戰。
每個程序版本代碼中,都附有相關注釋,看完注釋大家就可以對本程序設計有個很明顯的思路。真的很有趣,想對java重新溫習的同學完全不必再對厚厚的java基礎書籍進行閱讀了,在跟著本次代碼練習並分析後,大家一定會對java各方面基礎知識 尤其是線程的知識有更深一步的了解!!!
本次坦克大戰系列的各個版本都是在一步步的升級改進,難度逐漸加大,功能愈加完善;話不多說,先給大家分享一下代碼(●ˇ∀ˇ●)
Tank大戰 version1.0
實現功能:
1.繪制出我方Tank;
2.可以通過鍵盤上下左右鍵 控制移動;
package com.test; import java.awt.Color; import java.awt.Graphics; import java.awt.event.*; import javax.swing.*; public class MyTankGame extends JFrame { Mypanel mp=null; public static void main(String[] args) { // TODO 自動生成的方法存根 MyTankGame mtg=new MyTankGame(); } //構造函數 public MyTankGame() { mp=new Mypanel(); this.add(mp); this.setSize(800,600); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } //坦克類 class Tank { //表示坦克橫坐標 int x=0; 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; } //表示坦克縱坐標 int y=0; public Tank(int x,int y) { this.x=x; this.y=y; } } //我的Tank class Hero extends Tank { public Hero(int x, int y) { super(x, y); // TODO 自動生成的構造函數存根 } } //我的面板 class Mypanel extends JPanel { //定義一個我的坦克 Hero hero=null; //構造函數 public Mypanel() { hero=new Hero(100,100); } public void paint(Graphics g) { super.paint(g); //設置面板背景色,全部填充即可,默認為黑色 g.fillRect(0, 0, 800, 600); //畫出我的tank,放到paint函數中 this.DrawTank(hero.getX(), hero.getY(), g,0,0);//hero.getX(), hero.getY()就將x,y傳過去了 } //畫出tank public void DrawTank(int x,int y,Graphics g,int direct,int type) { //判斷是什麼類型坦克 switch(type) { case 0://我的tank g.setColor(Color.cyan); break; case 1://敵人的tank g.setColor(Color.orange); break; } //判斷坦克的方向 switch(direct) { //向上 case 0: //畫出左邊矩形 g.fill3DRect(x, y, 5, 30, false); //畫出右邊矩形 g.fill3DRect(x+15, y, 5, 30, false); //畫出中間矩形 g.fill3DRect(x+5, y+5, 10, 20, false); //畫出中間圓形 g.fillOval(x+5, y+10, 10, 10); //畫出中間直線 g.fillRect(x+9, y, 2, 10); break; } } } /* 畫出左邊矩形 g.fill3DRect(hero.getX(), hero.getY(), 5, 30, false); //畫出右邊矩形 g.fill3DRect(hero.getX()+15, hero.getY(), 5, 30, false); //畫出中間矩形 g.fill3DRect(hero.getX()+5, hero.getY()+5, 10, 20, false); //畫出中間圓形 g.fillOval(hero.getX()+5, hero.getY()+10, 10, 10); //畫出中間直線 g.drawLine(hero.getX()+10, hero.getY()+15, 10, 20); break; */
Tank大戰 version2.0
java練習---->坦克大戰2.0------>引入多線程
實現功能:
1.有敵方tank與我方tank;
2.我方tank可以控制移動;
3.我方tank可以發射炮彈;
4.敵方tank未作處理;
package TankGame2; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.*; import javax.swing.*; public class MyTankGame2 extends JFrame { MyPanel mp=null; public static void main(String[] args) { MyTankGame2 mytankgame1=new MyTankGame2(); } public MyTankGame2() { mp=new MyPanel(); //啟動mp線程 Thread t=new Thread(mp); t.start(); this.add(mp); this.addKeyListener(mp); this.setSize(400,300); this.setVisible(true); this.setDefaultCloseOperation(EXIT_ON_CLOSE); } } class MyPanel extends JPanel implements KeyListener,Runnable { //定義我的坦克,成員變量 Hero hero=null; //定義敵人的坦克組 Vector<EnemyTank> ets=new Vector<EnemyTank>(); int enSize=3; public void paint (Graphics g) { super.paint(g); g.fillRect(0,0,400,300); //畫出自己的坦克 this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1); //畫出子彈 if (hero.s!=null&&hero.s.isLive==true) { g.draw3DRect(hero.s.x, hero.s.y, 1, 1, false); } //畫出敵人的坦克 for(int i=0;i<ets.size();i++) { this.drawTank(ets.get(i).getX(),ets.get(i).getY(), g,ets.get(i).getDirect(), 0); } } //畫出坦克函數(擴展) public void drawTank(int x,int y,Graphics g,int direct,int type) { //判斷類型 switch (type) { case 0: g.setColor(Color.cyan);break; case 1: g.setColor(Color.yellow);break; } //判斷方向 switch(direct) { //向上 case 0: //畫出我的坦克(到時候再封裝成一個函數) //1.畫出左面的矩形 //g.drawRect(hero.getX(), hero.getY(), 5, 30); g.fill3DRect(x,y,5,30,false); //2.畫出右邊的矩形 g.fill3DRect(x+15,y,5,30,false); //3.畫出坦克的中間矩形 g.fill3DRect(x+5, y+5, 10, 20,false); //畫出中間的圓 g.fillOval(x+4, y+10,10,10); //畫出線 g.drawLine(x+9, y+15, x+9, y); break; case 1: //炮筒向右 //畫出上面的矩形 g.fill3DRect(x,y,30, 5, false); g.fill3DRect(x, y+15, 30, 5, false); g.fill3DRect(x+5, y+5, 20, 10, false); g.fillOval(x+10, y+5, 10, 10); g.drawLine(x+15, y+10, x+30, y+10); break; case 2: //向下 g.fill3DRect(x,y,5,30,false); 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+10, y+15, x+10, y+30); break; case 3: //向左 g.fill3DRect(x,y,30, 5, false); g.fill3DRect(x, y+15, 30, 5, false); g.fill3DRect(x+5, y+5, 20, 10, false); g.fillOval(x+10, y+5, 10, 10); g.drawLine(x+15, y+10, x, y+10); break; } } public MyPanel() { hero=new Hero(100,100); //初始化敵人的坦克 for(int i=0;i<enSize;i++) { //創建敵人的坦克對象 EnemyTank et=new EnemyTank((i+1)*50,0); et.setColor(0); et.setDirect(2); ets.add(et); } } //鍵按下處理a表示左,s表示向下,w表示向上,d表示向右 public void keyPressed(KeyEvent e) { if(e.getKeyCode()==KeyEvent.VK_UP) { // 設置我的坦克的方向 this.hero.setDirect(0); this.hero.moveUp(); } else if (e.getKeyCode()==KeyEvent.VK_DOWN) { this.hero.setDirect(2); this.hero.moveDown(); } else if (e.getKeyCode()==KeyEvent.VK_RIGHT) { this.hero.setDirect(1); this.hero.moveRight(); } else if (e.getKeyCode()==KeyEvent.VK_LEFT) { this.hero.setDirect(3); this.hero.moveLeft(); } if (e.getKeyCode()==KeyEvent.VK_SPACE) { this.hero.shotEnemy(); } //必須重新繪制Panel this.repaint(); } public void keyReleased(KeyEvent e) //有什麼用?!!!!!!!!!!! { } public void keyTyped(KeyEvent e) { } public void run() { //每個一百毫秒去重畫子彈 while(true) { try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } this.repaint(); } } } class Tank { //設置坦克的速度 int speed=1; public int getSpeed() { return speed; } public void setSpeed(int speed) { this.speed = speed; } //表示坦克的橫坐標 int x=0; //坦克的縱坐標 int y=0; int direct=0; int color; //坦克方向,0表示上,1表示右,2表示下,3表示左 public int getColor() { return color; } public void setColor(int color) { this.color = color; } public int getDirect() { return direct; } public void setDirect(int direct) { this.direct = direct; } 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; } } class EnemyTank extends Tank { public EnemyTank(int x,int y) { super(x,y); //super的用法??? } } //我的坦克 class Hero extends Tank { //子彈 Shot s=null; public Hero(int x, int y) { super(x,y); } //坦克向上移動 //坦克的開火的能力和動作 public void shotEnemy() { switch(this.direct) { case 0: s=new Shot(x+9,y-1,0); break; case 1: s=new Shot(x+30,y+10,1); break; case 2: s=new Shot(x+9,y+30,2); break; case 3: s=new Shot(x-1,y+9,3); break; } Thread t=new Thread(s); t.start(); } public void moveUp() { this.y-=speed; } public void moveRight() { this.x+=speed; } public void moveDown() { this.y+=speed; } public void moveLeft() { this.x-=speed; } } class Shot implements Runnable //runnable的用法???? { int x; int y; int direct; int speed=1; //是否活著 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) { e.printStackTrace(); } switch(direct) { case 0: //向上 y-=speed;break; case 1: x+=speed;break; case 2: y+=speed;break; case 3: x-=speed;break; } //判斷該子彈是否碰到邊緣 if(x<0||x>400||y<0||y>300) { this.isLive=false; break; } } } }
Tank大戰 version3.0
java練習---->坦克大戰3.0
實現功能:
1.有敵方tank與我方tank;
2.我方tank可以控制移動,可以發射炮彈;
3.寫一個函數專門判斷子彈是否擊中敵人坦克;
4.判斷tank是否活著;
(注:本版本中,Tank是不可以發射炮彈的······)
package TankGame3; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.*; import javax.swing.*; import java.util.Vector; public class MyTankGame4 extends JFrame { MyPanel mp=null; public static void main(String[] args) { MyTankGame4 mytankgame1=new MyTankGame4(); } public MyTankGame4() { mp=new MyPanel(); //啟動mp線程 Thread t=new Thread(mp); t.start(); this.add(mp); this.addKeyListener(mp); this.setSize(400,300); this.setVisible(true); this.setDefaultCloseOperation(EXIT_ON_CLOSE); } } class MyPanel extends JPanel implements KeyListener,Runnable { //定義我的坦克,成員變量 Hero hero=null; //定義敵人的坦克組 Vector<EnemyTank> ets=new Vector<EnemyTank>(); int enSize=3; public void paint (Graphics g) { super.paint(g); g.fillRect(0,0,400,300); //畫出自己的坦克 this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1); //從Vector ss中取出每一顆子彈,並畫出 for(int i=0;i<this.hero.ss.size();i++) { Shot myShot=hero.ss.get(i); //畫出子彈,只畫一顆子彈 if (myShot!=null&&myShot.isLive==true) { g.draw3DRect(myShot.x, myShot.y, 1, 1, false); } if (myShot.isLive==false) { //從ss中刪除該子彈 hero.ss.remove(myShot); } } //畫出敵人的坦克 for(int i=0;i<ets.size();i++) { EnemyTank et=ets.get(i); if(et.isLive) { this.drawTank(ets.get(i).getX(),ets.get(i).getY(), g,ets.get(i).getDirect(), 0); } } } //寫一個函數專門判斷子彈是否擊中敵人坦克 public void hitTank(Shot s,EnemyTank et) { //判斷該坦克的方向 switch(et.direct) { //如果敵人的方向是上或者是下 case 0: case 2: if (s.x>et.x&&s.x<(et.x+20)&&s.y>et.y&&s.y<(et.y+30)) { //擊中了 //子彈死亡 s.isLive=false; //敵人坦克也要死亡 et.isLive=false; } case 1: case 3: if (s.x>et.x&&s.x<(et.x+30)&&s.y>et.y&&s.y<(et.y+20)) { //擊中了 //子彈死亡 s.isLive=false; //敵人坦克也要死亡 et.isLive=false; } } } //畫出坦克函數(擴展) public void drawTank(int x,int y,Graphics g,int direct,int type) { //判斷類型 switch (type) { case 0: g.setColor(Color.cyan);break; case 1: g.setColor(Color.yellow);break; } //判斷方向 switch(direct) { //向上 case 0: //畫出我的坦克(到時候再封裝成一個函數) //1.畫出左面的矩形 //g.drawRect(hero.getX(), hero.getY(), 5, 30); g.fill3DRect(x,y,5,30,false); //2.畫出右邊的矩形 g.fill3DRect(x+15,y,5,30,false); //3.畫出坦克的中間矩形 g.fill3DRect(x+5, y+5, 10, 20,false); //畫出中間的圓 g.fillOval(x+4, y+10,10,10); //畫出線 g.drawLine(x+9, y+15, x+9, y); break; case 1: //炮筒向右 //畫出上面的矩形 g.fill3DRect(x,y,30, 5, false); g.fill3DRect(x, y+15, 30, 5, false); g.fill3DRect(x+5, y+5, 20, 10, false); g.fillOval(x+10, y+5, 10, 10); g.drawLine(x+15, y+10, x+30, y+10); break; case 2: //向下 g.fill3DRect(x,y,5,30,false); 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+10, y+15, x+10, y+30); break; case 3: //向左 g.fill3DRect(x,y,30, 5, false); g.fill3DRect(x, y+15, 30, 5, false); g.fill3DRect(x+5, y+5, 20, 10, false); g.fillOval(x+10, y+5, 10, 10); g.drawLine(x+15, y+10, x, y+10); break; } } public MyPanel() { hero=new Hero(100,100); //初始化敵人的坦克 for(int i=0;i<enSize;i++) { //創建敵人的坦克對象 EnemyTank et=new EnemyTank((i+1)*50,0); et.setColor(0); et.setDirect(2); ets.add(et); } } //鍵按下處理a表示左,s表示向下,w表示向上,d表示向右 public void keyPressed(KeyEvent e) { if(e.getKeyCode()==KeyEvent.VK_W) { // 設置我的坦克的方向 this.hero.setDirect(0); this.hero.moveUp(); } else if (e.getKeyCode()==KeyEvent.VK_S) { this.hero.setDirect(2); this.hero.moveDown(); } else if (e.getKeyCode()==KeyEvent.VK_D) { this.hero.setDirect(1); this.hero.moveRight(); } else if (e.getKeyCode()==KeyEvent.VK_A) { this.hero.setDirect(3); this.hero.moveLeft(); } if (e.getKeyCode()==KeyEvent.VK_J) { this.hero.shotEnemy(); } //必須重新繪制Panel this.repaint(); } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { } public void run() { //每個一百毫秒去重畫子彈 while(true) { try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } for(int i=0;i<hero.ss.size();i++) { Shot myShot=hero.ss.get(i); //判斷子彈是否有效 if(myShot.isLive) { //取出每個坦克,與它判斷 for(int j=0;j<ets.size();j++) { //取出坦克 EnemyTank et=ets.get(j); if(et.isLive) { this.hitTank(myShot,et); } } } } this.repaint(); } } } //package MyTankGame4; //import java.util.Vector; //import MyTankGame4.Shot; //import MyTankGame4.Tank; class Tank { //設置坦克的速度 int speed=1; public int getSpeed() { return speed; } public void setSpeed(int speed) { this.speed = speed; } //表示坦克的橫坐標 int x=0; //坦克的縱坐標 int y=0; int direct=0; int color; //坦克方向,0表示上,1表示右,2表示下,3表示左 public int getColor() { return color; } public void setColor(int color) { this.color = color; } public int getDirect() { return direct; } public void setDirect(int direct) { this.direct = direct; } 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; } } class EnemyTank extends Tank { boolean isLive=true; public EnemyTank(int x,int y) { super(x,y); } } //我的坦克 class Hero extends Tank { //子彈 //Shot s=null; Vector<Shot> ss=new Vector<Shot>(); Shot s=null; public Hero(int x, int y) { super(x,y); } //坦克向上移動 //坦克的開火的能力和動作 public void shotEnemy() { switch(this.direct) { case 0: s=new Shot(x+9,y-1,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+9,y+30,2); ss.add(s); break; case 3: s=new Shot(x-1,y+9,3); ss.add(s); ss.add(s); break; } Thread t=new Thread(s); t.start(); } public void moveUp() { this.y-=speed; } public void moveRight() { this.x+=speed; } public void moveDown() { this.y+=speed; } public void moveLeft() { this.x-=speed; } } class Shot implements Runnable { int x; int y; int direct; int speed=1; //是否活著 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) { e.printStackTrace(); } switch(direct) { case 0: //向上 y-=speed;break; case 1: x+=speed;break; case 2: y+=speed;break; case 3: x-=speed;break; } //判斷該子彈是否碰到邊緣 if(x<0||x>400||y<0||y>300) { this.isLive=false; break; } } } }
Tank大戰 version4.0
java練習---->坦克大戰4.0
實現功能:
1.有敵方tank與我方tank;
2.雙方都可以控制移動,可以發射炮彈;
3.敵方坦克可以被擊中消失
4.有爆炸效果;
5.可以計算生命值和炸彈生命;
package TankGame4; //package MyTankGame4; import java.util.Vector; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.*; import javax.swing.*; public class MyTankGame4 extends JFrame { MyPanel mp=null; public static void main(String[] args) { MyTankGame4 mytankgame1=new MyTankGame4(); } public MyTankGame4() { mp=new MyPanel(); //啟動mp線程 Thread t=new Thread(mp); t.start(); this.add(mp); this.addKeyListener(mp); this.setSize(400,300); this.setVisible(true); this.setDefaultCloseOperation(EXIT_ON_CLOSE); } } class MyPanel extends JPanel implements KeyListener,Runnable { //定義我的坦克,成員變量 Hero hero=null; //定義敵人的坦克組 Vector<EnemyTank> ets=new Vector<EnemyTank>(); int enSize=5; //定義炸彈集合 Vector<Bomb> bombs=new Vector<Bomb>(); public void run() { //每個一百毫秒去重畫子彈 while(true) { try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } for(int i=0;i<hero.ss.size();i++) { Shot myShot=hero.ss.get(i); //判斷子彈是否有效 if(myShot.isLive) { //取出每個坦克,與它判斷 for(int j=0;j<ets.size();j++) { //取出坦克 EnemyTank et=ets.get(j); if(et.isLive) { this.hitTank(myShot,et); } } } } this.repaint(); //判斷是否需要給坦克加入新的子彈 for(int i=0;i<ets.size();i++) { EnemyTank et=ets.get(i); if(et.isLive) { if (et.ss.size()<5&&(int)(100*Math.random())>75) { //每輛坦克的子彈少於5發的話 //添加 Shot s=null; switch(et.direct) { case 0: s=new Shot(et.x+9,et.y-1,0); et.ss.add(s); break; case 1: s=new Shot(et.x+30,et.y+10,1); et.ss.add(s); break; case 2: s=new Shot(et.x+9,et.y+30,2); et.ss.add(s); break; case 3: s=new Shot(et.x-1,et.y+9,3); et.ss.add(s); break; } //啟動子彈線程 Thread t=new Thread(s); t.start(); } } } } } public void paint (Graphics g) { super.paint(g); g.fillRect(0,0,400,300); //畫出自己的坦克 this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1); //從Vector ss中取出每一顆子彈,並畫出 for(int i=0;i<this.hero.ss.size();i++) { Shot myShot=hero.ss.get(i); //畫出子彈,只畫一顆子彈 if (myShot!=null&&myShot.isLive==true) { g.draw3DRect(myShot.x, myShot.y, 1, 1, false); } if (myShot.isLive==false) { //從ss中刪除該子彈 hero.ss.remove(myShot); } } //畫出炸彈 for(int i=0;i<bombs.size();i++) { // 取出炸彈 Bomb b=bombs.get(i); if(b.life>6) { 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的生命值減小 b.lifeDown(); //如果炸彈的生命值為0,我們就剔除 if(b.life==0) bombs.remove(b); } //畫出敵人的坦克 for(int i=0;i<ets.size();i++) { EnemyTank et=ets.get(i); if(et.isLive) { this.drawTank(ets.get(i).getX(),ets.get(i).getY(), g,ets.get(i).getDirect(), 0); //畫出敵人的子彈 for(int j=0;j<et.ss.size();j++) { //取出子彈 Shot enemyShot=et.ss.get(j); if(enemyShot.isLive) { g.draw3DRect(enemyShot.x, enemyShot.y, 1, 1, false); } else { //如果敵人的坦克死亡就從Vector去掉 et.ss.remove(enemyShot); } } } } } //寫一個函數專門判斷子彈是否擊中敵人坦克 public void hitTank(Shot s,EnemyTank et) { //判斷該坦克的方向 switch(et.direct) { //如果敵人的方向是上或者是下 case 0: case 2: if (s.x>et.x&&s.x<(et.x+20)&&s.y>et.y&&s.y<(et.y+30)) { //擊中了 //子彈死亡 s.isLive=false; //敵人坦克也要死亡 et.isLive=false; //創建一個炸彈,放入Vector Bomb b=new Bomb(et.x,et.y); //放入Vector bombs.add(b); } case 1: case 3: if (s.x>et.x&&s.x<(et.x+30)&&s.y>et.y&&s.y<(et.y+20)) { //擊中了 //子彈死亡 s.isLive=false; //敵人坦克也要死亡 et.isLive=false; //創建一個炸彈,放入Vector Bomb b=new Bomb(et.x,et.y); //放入Vector bombs.add(b); } } } //畫出坦克函數(擴展) public void drawTank(int x,int y,Graphics g,int direct,int type) { //判斷類型 switch (type) { case 0: g.setColor(Color.cyan);break; case 1: g.setColor(Color.yellow);break; } //判斷方向 switch(direct) { //向上 case 0: //畫出我的坦克(到時候再封裝成一個函數) //1.畫出左面的矩形 //g.drawRect(hero.getX(), hero.getY(), 5, 30); g.fill3DRect(x,y,5,30,false); //2.畫出右邊的矩形 g.fill3DRect(x+15,y,5,30,false); //3.畫出坦克的中間矩形 g.fill3DRect(x+5, y+5, 10, 20,false); //畫出中間的圓 g.fillOval(x+4, y+10,10,10); //畫出線 g.drawLine(x+9, y+15, x+9, y); break; case 1: //炮筒向右 //畫出上面的矩形 g.fill3DRect(x,y,30, 5, false); g.fill3DRect(x, y+15, 30, 5, false); g.fill3DRect(x+5, y+5, 20, 10, false); g.fillOval(x+10, y+5, 10, 10); g.drawLine(x+15, y+10, x+30, y+10); break; case 2: //向下 g.fill3DRect(x,y,5,30,false); 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+10, y+15, x+10, y+30); break; case 3: //向左 g.fill3DRect(x,y,30, 5, false); g.fill3DRect(x, y+15, 30, 5, false); g.fill3DRect(x+5, y+5, 20, 10, false); g.fillOval(x+10, y+5, 10, 10); g.drawLine(x+15, y+10, x, y+10); break; } } //定義三張圖片,三張圖片切換組成一顆炸彈 Image image1=null; Image image2=null; Image image3=null; //構造函數 public MyPanel() { hero=new Hero(100,100); //初始化敵人的坦克 for(int i=0;i<enSize;i++) { //創建敵人的坦克對象 EnemyTank et=new EnemyTank((i+1)*50,0); et.setColor(0); et.setDirect(2); //啟動敵人的坦克 Thread t=new Thread(et); t.start(); //給敵人坦克添加一顆子彈 Shot s=new Shot(et.x+10,et.y+30,2); et.ss.add(s); Thread t2=new Thread(s); t2.start(); //加入 ets.add(et); } image1=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/33.jpg")); image2=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/22.jpg")); image3=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/11.jpg")); } //鍵按下處理向左,向下,向上,向右 public void keyPressed(KeyEvent e) { if(e.getKeyCode()==KeyEvent.VK_UP) { // 設置我的坦克的方向 this.hero.setDirect(0); this.hero.moveUp(); } else if (e.getKeyCode()==KeyEvent.VK_DOWN) { this.hero.setDirect(2); this.hero.moveDown(); } else if (e.getKeyCode()==KeyEvent.VK_RIGHT) { this.hero.setDirect(1); this.hero.moveRight(); } else if (e.getKeyCode()==KeyEvent.VK_LEFT) { this.hero.setDirect(3); this.hero.moveLeft(); } if (e.getKeyCode()==KeyEvent.VK_J) { this.hero.shotEnemy(); } //必須重新繪制Panel this.repaint(); } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { } } class Tank { //設置坦克的速度 int speed=3; public int getSpeed() { return speed; } public void setSpeed(int speed) { this.speed = speed; } //表示坦克的橫坐標 int x=0; //坦克的縱坐標 int y=0; int direct=0; int color; //坦克方向,0表示上,1表示右,2表示下,3表示左 public int getColor() { return color; } public void setColor(int color) { this.color = color; } public int getDirect() { return direct; } public void setDirect(int direct) { this.direct = direct; } 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; } } class EnemyTank extends Tank implements Runnable { boolean isLive=true; //定義一個向量,可以存放敵人的子彈 Vector<Shot> ss=new Vector<Shot>(); //敵人添加子彈應該在剛剛創建坦克和坦克子彈死亡之後 public EnemyTank(int x,int y) { super(x,y); } public void run() { while(true) { //移動前進 switch(this.direct) { case 0: for(int i=0;i<(int)(100*Math.random());i++) { try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); } if(y>=speed) { y-=speed; } } break; case 1: for(int i=0;i<(int)(100*Math.random());i++) { try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); } if(x<=400-(speed+30)) { x+=speed; } } break; case 2: for(int i=0;i<(int)(100*Math.random());i++) { try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); } if(y<=300-(speed+30)) { y+=speed; } } break; case 3: for(int i=0;i<(int)(100*Math.random());i++) { try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); } if(x>=speed) { x-=speed; } } break; } //讓坦克隨機產生一個新的方向 if(Math.random()>0.50) this.direct=(int)(Math.random()*4); //判斷敵人坦克是否死亡 if(this.isLive==false) { //讓坦克死亡後,退出線程 break; } } } } //我的坦克 class Hero extends Tank { //子彈 //Shot s=null; Vector<Shot> ss=new Vector<Shot>(); Shot s=null; public Hero(int x, int y) { super(x,y); } //坦克向上移動 //坦克的開火的能力和動作 public void shotEnemy() { switch(this.direct) { case 0: s=new Shot(x+9,y-1,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+9,y+30,2); ss.add(s); break; case 3: s=new Shot(x-1,y+9,3); ss.add(s); ss.add(s); break; } Thread t=new Thread(s); t.start(); } public void moveUp() { this.y-=speed; } public void moveRight() { this.x+=speed; } public void moveDown() { this.y+=speed; } public void moveLeft() { this.x-=speed; } } class Shot implements Runnable { int x; int y; int direct; int speed=1; //是否活著 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) { e.printStackTrace(); } switch(direct) { case 0: //向上 y-=speed;break; case 1: x+=speed;break; case 2: y+=speed;break; case 3: x-=speed;break; } //子彈何時死亡? //判斷該子彈是否碰到邊緣 if(x<0||x>400||y<0||y>300) { this.isLive=false; break; } } } } 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;} } }
Tank大戰 version5.0
java練習---->坦克大戰5.0
實現功能:
1.在原有基礎啊上進行優化和功能完善;
2.增加闖關功能等;
3.完結版!!!!!
package TankGame5; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.*; import java.io.*; import java.util.Vector; import javax.imageio.ImageIO; import javax.swing.*; public class MyTankGame5 extends JFrame implements ActionListener { //聲明一個標志 int flag=0; // 聲明一個運行面板 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) { MyTankGame5 mytankgame1=new MyTankGame5(); mytankgame1.setLocationRelativeTo(null);//將JFrame設置在中間 // mytankgame1.setLocation(210,140);//設置JFrame的位置 } public MyTankGame5() //構造 {//初始化菜單欄 jmb=new JMenuBar(); jm1=new JMenu("游戲(G)"); //設置快捷方式 jm1.setMnemonic('G'); jmi1=new JMenuItem("開始新游戲(N)"); jmi2=new JMenuItem("退出游戲(E)"); jmi3=new JMenuItem("存盤退出(C)"); jmi4=new JMenuItem("繼續上次游戲(L)"); jmi1.setMnemonic('N'); jmi2.setMnemonic('E'); jmi3.setMnemonic('C'); jmi4.setMnemonic('L'); //對jmi1響應,注冊監聽,標記消息源 jmi1.addActionListener(this); jmi1.setActionCommand("new game"); jmi2.addActionListener(this); jmi2.setActionCommand("exit"); jmi3.addActionListener(this); jmi3.setActionCommand("save and exit"); jmi4.addActionListener(this); jmi4.setActionCommand("continue game"); jm1.add(jmi1); jm1.add(jmi2); jm1.add(jmi3); jm1.add(jmi4); jmb.add(jm1); // 聲明初始化面板 msp=new MyStartPanel(); Thread t=new Thread(msp); t.start(); // 初始化窗口,構造函數的重點 this.setJMenuBar(jmb);//千萬注意啊!!!! this.add(msp); this.setSize(400,300); this.setVisible(true); this.setDefaultCloseOperation(EXIT_ON_CLOSE); } public void actionPerformed(ActionEvent e) { //對用戶不同的點擊做出不同的處理 // 首先得到command字符串,判斷消息源 if(e.getActionCommand().equals("new game")) { this.setSize(600,500); mp=new MyPanel(flag); //啟動mp線程 Thread t1=new Thread(mp); t1.start(); //先刪除舊的面板 this.remove(msp); this.add(mp); //注冊監聽 this.addKeyListener(mp); //顯示 this.setVisible(true); } else if(e.getActionCommand().equals("exit")) { //用戶退出 //保存擊毀敵人數量 Recorder.keepRecording(); System.exit(0); } else if(e.getActionCommand().equals("save and exit")) { Recorder.keepRecAndEnemyTank(mp.ets); if(this.mp.hero.isLive==true) { Recorder.keepRecAndMyTank(this.mp.hero); } System.exit(0); } else if(e.getActionCommand().equals("continue game")) { this.setSize(600,500); flag=1; mp=new MyPanel(flag); //啟動mp線程 Thread t1=new Thread(mp); t1.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); //開關信息的字體 try{ Font myFont=new Font("華文新魏",Font.BOLD,30); g.setFont(myFont); } catch(Exception e){e.printStackTrace();} g.drawString("stage:1", 150, 150); } } public void run() { while(true) { try { Thread.sleep(500); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } this.repaint(); times++; if(times==1000) times=0; } } } class MyPanel extends JPanel implements KeyListener,Runnable { //定義我的坦克,成員變量 Hero hero=null; //判斷是續上局還是新的游戲 String flag="newGame"; //定義敵人的坦克組 Vector<EnemyTank> ets=new Vector<EnemyTank>(); // 全局變量,聲明,敵人坦克數量 static int enSize=5; public static int getEnSize() { return enSize; } //定義炸彈集合 Vector<Bomb> bombs=new Vector<Bomb>(); // paint 方法被面板適時自動調用 public void paint (Graphics g) { super.paint(g); g.fillRect(0,0,400,300); //畫出提示信息 this.showInfo(g); //畫出自己的坦克 if(hero.isLive==true) { this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1); } //從Vector ss中取出每一顆子彈,並畫出,如果有子彈 for(int i=0;i<this.hero.ss.size();i++) { Shot myShot=hero.ss.get(i); //畫出子彈,只畫一顆子彈 if (myShot!=null&&myShot.isLive==true) { g.draw3DRect(myShot.x, myShot.y, 1, 1, false); } if (myShot.isLive==false) { //從ss中刪除該子彈 hero.ss.remove(myShot); } } //畫出炸彈 for(int i=0;i<bombs.size();i++) { // 取出炸彈 Bomb b=bombs.get(i); if(b.life>6) { g.drawOval(b.x, b.y, 30, 30); // g.drawImage(image1, b.x, b.y, 30,30,this); } else if(b.life>3) { g.drawOval(b.x, b.y, 20, 20); // g.drawImage(image2, b.x, b.y, 30,30,this); } else { g.drawOval(b.x, b.y, 10, 10); // g.drawImage(image3, b.x, b.y, 30,30,this); } //讓b的生命值減小 b.lifeDown(); //如果炸彈的生命值為0,我們就剔除 if(b.life==0) bombs.remove(b); } //畫出敵人的坦克 for(int i=0;i<ets.size();i++) { EnemyTank et=ets.get(i); if(et.isLive) { this.drawTank(ets.get(i).getX(),ets.get(i).getY(), g,ets.get(i).getDirect(), 0); //畫出敵人的子彈 for(int j=0;j<et.ss.size();j++) { //取出子彈 Shot enemyShot=et.ss.get(j); if(enemyShot.isLive) { g.draw3DRect(enemyShot.x, enemyShot.y, 1, 1, false); } else { //如果敵人的坦克死亡就從Vector去掉 et.ss.remove(enemyShot); } } } } } //判斷我是否被擊中了 public void hitMe() { //取出敵人的每一顆子彈 for(int i=0;i<this.ets.size();i++) { //取出坦克 EnemyTank et=ets.get(i); //取出每一顆子彈 for (int j=0;j<et.ss.size();j++) { //取出子彈 Shot enemyShot=et.ss.get(j); if(hero.isLive)//&&Recorder.getMyLife()>=1 { this.hitTank(enemyShot, hero); //Recorder.setMyLife(Recorder.getMyLife()-1); } } } } //判斷我的子彈是否擊中敵人的坦克 public void hitEnemyTank() { for(int i=0;i<hero.ss.size();i++) { Shot myShot=hero.ss.get(i); //判斷子彈是否有效 if(myShot.isLive) { //取出每個坦克,與它判斷 for(int j=0;j<ets.size();j++) { //取出坦克 EnemyTank et=ets.get(j); if(et.isLive) { this.hitTank(myShot,et); } } } } } //寫一個函數專門判斷子彈是否擊中敵人坦克 public void hitTank(Shot s,Tank et) { //判斷該坦克的方向 switch(et.direct) { //如果敵人的方向是上或者是下 case 0: case 2: if (s.x>et.x&&s.x<(et.x+20)&&s.y>et.y&&s.y<(et.y+30)) { //擊中了 //子彈死亡 s.isLive=false; //敵人坦克也要死亡 et.isLive=false; //減少敵人數量 if (et.getClass()==EnemyTank.class)//反射機制 { Recorder.reduceEnNum(); //增加我的記錄 Recorder.addEnNumRec(); } if (et.getClass()==Hero.class)//反射機制 { } //創建一個炸彈,放入Vector Bomb b=new Bomb(et.x,et.y); //放入Vector bombs.add(b); } case 1: case 3: if (s.x>et.x&&s.x<(et.x+30)&&s.y>et.y&&s.y<(et.y+20)) { //擊中了 //子彈死亡 s.isLive=false; //敵人坦克也要死亡 et.isLive=false; //減少敵人數量 if (et.getClass()==EnemyTank.class)//反射機制 { Recorder.reduceEnNum(); //增加我的記錄 Recorder.addEnNumRec(); } if (et.getClass()==Hero.class)//反射機制 { Recorder.setMyLife(Recorder.getMyLife() - 1); } //創建一個炸彈,放入Vector Bomb b=new Bomb(et.x,et.y); //放入Vector bombs.add(b); } } } //畫出坦克函數(擴展) public void drawTank(int x,int y,Graphics g,int direct,int type) { //判斷類型 switch (type) { case 0: g.setColor(Color.cyan);break; case 1: g.setColor(Color.yellow);break; } //判斷方向 switch(direct) { //向上 case 0: //畫出我的坦克(到時候再封裝成一個函數) //1.畫出左面的矩形 //g.drawRect(hero.getX(), hero.getY(), 5, 30); g.fill3DRect(x,y,5,30,false); //2.畫出右邊的矩形 g.fill3DRect(x+15,y,5,30,false); //3.畫出坦克的中間矩形 g.fill3DRect(x+5, y+5, 10, 20,false); //畫出中間的圓 g.fillOval(x+4, y+10,10,10); //畫出線 g.drawLine(x+9, y+15, x+9, y); break; case 1: //炮筒向右 //畫出上面的矩形 g.fill3DRect(x,y,30, 5, false); g.fill3DRect(x, y+15, 30, 5, false); g.fill3DRect(x+5, y+5, 20, 10, false); g.fillOval(x+10, y+5, 10, 10); g.drawLine(x+15, y+10, x+30, y+10); break; case 2: //向下 g.fill3DRect(x,y,5,30,false); 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+10, y+15, x+10, y+30); break; case 3: //向左 g.fill3DRect(x,y,30, 5, false); g.fill3DRect(x, y+15, 30, 5, false); g.fill3DRect(x+5, y+5, 20, 10, false); g.fillOval(x+10, y+5, 10, 10); g.drawLine(x+15, y+10, x, y+10); break; } } public void run() { //每個一百毫秒去重畫子彈 while(true) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } this.hitEnemyTank(); //函數,判斷敵人的子彈是否擊中我了 this.hitMe(); this.repaint(); //判斷是否需要給坦克加入新的子彈 for(int i=0;i<ets.size();i++) { EnemyTank et=ets.get(i); if(et.isLive) { if (et.ss.size()<3) { //沒有子彈了 //添加 Shot s=null; switch(et.direct) { case 0: s=new Shot(et.x+9,et.y-1,0); et.ss.add(s); break; case 1: s=new Shot(et.x+30,et.y+10,1); et.ss.add(s); break; case 2: s=new Shot(et.x+9,et.y+30,2); et.ss.add(s); break; case 3: s=new Shot(et.x-1,et.y+9,3); et.ss.add(s); break; } //啟動子彈線程 Thread t=new Thread(s); t.start(); } } } } } //定義三張圖片,三張圖片切換組成一顆炸彈 Image image1=null; Image image2=null; Image image3=null; int flagOfContinue; //構造函數 public MyPanel(int flag) { this.flagOfContinue=flag; //恢復記錄 Recorder.getRecording(); if(this.flagOfContinue==0) { //如果不是繼續上次就直接建一個 hero=new Hero(100,100); //初始化敵人的坦克 for(int i=0;i<enSize;i++) { //創建敵人的坦克對象 EnemyTank et=new EnemyTank((i+1)*60,0); et.setColor(0); et.setDirect(2); //將MyPanel的敵人坦克向量交給該敵人坦克 et.setEts(ets); //啟動敵人的坦克 Thread t=new Thread(et); t.start(); //給敵人坦克添加一顆子彈 Shot s=new Shot(et.x+10,et.y+30,2); et.ss.add(s); Thread t2=new Thread(s); t2.start(); //加入 ets.add(et); } } else if(this.flagOfContinue==1) { //如果是繼續上次的就讀取坐標 Vector<Node> nodes1=new Vector<Node>(); nodes1=Recorder.getNodes(); //初始化敵人的坦克 for(int i=0;i<nodes1.size();i++) { if(nodes1.get(i).type==0) { //創建敵人的坦克對象 EnemyTank et=new EnemyTank(nodes1.get(i).x,nodes1.get(i).y); et.setColor(0); et.setDirect(nodes1.get(i).direct); //將MyPanel的敵人坦克向量交給該敵人坦克 et.setEts(ets); //啟動敵人的坦克 Thread t=new Thread(et); t.start(); //給敵人坦克添加一顆子彈 Shot s=new Shot(et.x+10,et.y+30,2); et.ss.add(s); Thread t2=new Thread(s); t2.start(); //加入 ets.add(et); } else if(nodes1.get(i).type==1) { //如果保存有我上次的坦克的信息,就按照信息保存 hero=new Hero(nodes1.get(i).x,nodes1.get(i).y); hero.setDirect(nodes1.get(i).direct); } } } // image1=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/33.jpg"));//文件應該放在src文件夾裡面 // image2=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/22.jpg")); // image3=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/11.jpg")); //關於圖像我們使用好一點的方法,引入java.io.File;和java.io.IOException; try { image1=ImageIO.read(new File("33.jpg"));//此時文件應該放在工程的根目錄裡面 image2=ImageIO.read(new File("22.jpg")); image3=ImageIO.read(new File("11.jpg")); } catch (IOException e) { e.printStackTrace(); } } //畫出提示信息 public void showInfo(Graphics g) { //畫出提示信息的坦克 ,該坦克不參加戰斗 this.drawTank(80,330,g,0,0); g.setColor(Color.black); g.drawString(Recorder.getEnNum()+"",110,350); this.drawTank(150,330,g,0,1); g.setColor(Color.black); g.drawString(Recorder.getMyLife()+"",180,350); //畫出玩家的總成績 g.setColor(Color.black); try{ Font f=new Font("宋體",Font.BOLD,20); g.setFont(f); }catch(Exception e){ e.printStackTrace();} g.drawString("您的總成績:",420,40); this.drawTank(420, 60, g, 0, 0); g.setColor(Color.BLACK); g.drawString(Recorder.getAllEnemy()+"",460,80); } //鍵按下處理a表示左,s表示向下,w表示向上,d表示向右 public void keyPressed(KeyEvent e) { if(hero.isLive) { if(e.getKeyCode()==KeyEvent.VK_UP&&hero.getY()>0) { // 設置我的坦克的方向 this.hero.setDirect(0); this.hero.moveUp(); } else if (e.getKeyCode()==KeyEvent.VK_DOWN&&hero.getY()<270) { this.hero.setDirect(2); this.hero.moveDown(); } else if (e.getKeyCode()==KeyEvent.VK_RIGHT&&hero.getX()<370) { this.hero.setDirect(1); this.hero.moveRight(); } else if (e.getKeyCode()==KeyEvent.VK_LEFT&&hero.getX()>0) { this.hero.setDirect(3); this.hero.moveLeft(); } if (e.getKeyCode()==KeyEvent.VK_SPACE) { this.hero.shotEnemy(); } //必須重新繪制Panel this.repaint(); } } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { } } //---------------------------------------------------- class Node { int x; int y; int direct; int type; public Node(int x,int y,int direct,int type) { this.x=x; this.y=y; this.direct=direct; this.type=type; } } //記錄類 class Recorder { public static int getEnNum() { return enNum; } public static void setEnNum(int enNum) { Recorder.enNum = enNum; } public static int getMyLife() { return myLife; } public static void setMyLife(int myLife) { Recorder.myLife = myLife; } //記錄每關多少敵人 private static int enNum=MyPanel.getEnSize(); //設置我有多少可以用的人 public static int myLife=3; //記錄總共消滅了多少敵人 private static int allEnNum=0; //從文件中恢復記錄點 static Vector<Node> nodes=new Vector<Node>(); private static FileWriter fw=null; private static BufferedWriter bw=null; private static FileReader fr=null; private static BufferedReader br=null; public static Vector<Node> getNodes() { 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]),Integer.parseInt(xyz[3])); nodes.add(node); } } catch (Exception e) { e.printStackTrace(); } finally { try { br.close(); fr.close(); } catch (Exception e) { e.printStackTrace(); } } return nodes; } public static void keepRecAndEnemyTank(Vector<EnemyTank> ets) { try { //創建 fw=new FileWriter("d:\\myRecording.txt"); bw=new BufferedWriter(fw); bw.write(allEnNum+"\r\n"); //保存當前還活著的敵人坐標和方向 for(int i=0;i<ets.size();i++) { //取出第一個坦克 EnemyTank et=ets.get(i); if(et.isLive) { //活著的保存 String record=et.x+" "+et.y+" "+et.direct+" "+0; //寫入 bw.write(record+"\r\n"); } } } catch (Exception e) { e.printStackTrace(); } finally { //關閉流 try { //誰先開誰後關 bw.close(); fw.close(); } catch (Exception e2) { } } } public static void keepRecAndMyTank(Hero hero) { try { //創建 fw=new FileWriter("d:\\myRecording.txt",true);//追加 bw=new BufferedWriter(fw); //保存當前我的坐標和方向 String record=hero.x+" "+hero.y+" "+hero.direct+" "+1; //寫入 bw.write(record+"\r\n"); } catch (Exception e) { e.printStackTrace(); } finally { //關閉流 try { //誰先開誰後關 bw.close(); fw.close(); } catch (Exception e2) { e2.printStackTrace(); } } } //從文件中讀取記錄 public static void getRecording() { try { fr=new FileReader("d:\\myRecording.txt"); br=new BufferedReader(fr); String n=br.readLine(); allEnNum=Integer.parseInt(n); } catch (Exception e) { e.printStackTrace(); } finally { try { br.close(); fr.close(); } catch (Exception e) { e.printStackTrace(); } } } //把玩家擊毀敵人的坦克數量保存到文件中 public static void keepRecording() { try { //創建 fw=new FileWriter("d:\\myRecording.txt"); bw=new BufferedWriter(fw); bw.write(allEnNum+"\r\n"); } catch (Exception e) { e.printStackTrace(); } finally { //關閉流 try { //誰先開誰後關 bw.close(); fw.close(); } catch (Exception e2) { } } } public static int getAllEnemy() { return allEnNum; } public static void reduceEnNum() { enNum--; } //消滅敵人 public static void addEnNumRec() { allEnNum++; } } 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 Tank { //設置坦克的速度 int speed=3; public int getSpeed() { return speed; } public void setSpeed(int speed) { this.speed = speed; } //表示坦克的橫坐標 int x=0; //坦克的縱坐標 int y=0; int direct=0; int color; boolean isLive=true; //坦克方向,0表示上,1表示右,2表示下,3表示左 public int getColor() { return color; } public void setColor(int color) { this.color = color; } public int getDirect() { return direct; } public void setDirect(int direct) { this.direct = direct; } 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; } } class EnemyTank extends Tank implements Runnable { //定義一個向量,可以訪問到MyPanel上所有敵人的坦克 Vector<EnemyTank> ets=new Vector<EnemyTank>(); //定義一個向量,可以存放敵人的子彈 Vector<Shot> ss=new Vector<Shot>(); //敵人添加子彈應該在剛剛創建坦克和坦克子彈死亡之後 public EnemyTank(int x,int y) { super(x,y); } //得到MyPanel的敵人坦克向量 public void setEts(Vector<EnemyTank> vv) { this.ets=vv; } //判斷是否碰到了別人的坦克 public boolean isTouchOtherEnemy() { boolean b=false; switch(this.direct) { case 0: //我的坦克向上 //取出所有的敵人坦克 for(int i=0;i<ets.size();i++) { //取出第一個坦克 EnemyTank et=ets.get(i); //如果不是自己 if(et!=this) { //如果敵人的方向向上或者是向下 if(et.direct==0||et.direct==2) { if(this.x>=et.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<=et.x+20&&this.y>=et.y&&this.y<=et.y+30) { return true; } } if(et.direct==1||et.direct==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.x+30&&this.y>=et.y&&this.y<=et.y+30) { return true; } } } } break; case 1: //坦克向右 //取出所有的敵人坦克 for(int i=0;i<ets.size();i++) { //取出第一個坦克 EnemyTank et=ets.get(i); //如果不是自己 if(et!=this) { //如果敵人的方向向上或者是向下 if(et.direct==0||et.direct==2) { if(this.x+30>=et.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.x+20&&this.y+20>=et.y&&this.y+20<=et.y+30) { return true; } } if(et.direct==1||et.direct==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.x+30&&this.y+20>=et.y&&this.y+20<=et.y+20) { return true; } } } } case 2: //坦克向下 //取出所有的敵人坦克 for(int i=0;i<ets.size();i++) { //取出第一個坦克 EnemyTank et=ets.get(i); //如果不是自己 if(et!=this) { //如果敵人的方向向上或者是向下 if(et.direct==0||et.direct==2) { if(this.x>=et.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<=et.x+20&&this.y+30>=et.y&&this.y+30<=et.y+30) { return true; } } if(et.direct==1||et.direct==3) { if(this.x+20>=et.x&&this.x+20<=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.x+30&&this.y+30>=et.y&&this.y+30<=et.y+30) { return true; } } } } break; case 3 : //坦克向左 //取出所有的敵人坦克 for(int i=0;i<ets.size();i++) { //取出第一個坦克 EnemyTank et=ets.get(i); //如果不是自己 if(et!=this) { //如果敵人的方向向上或者是向下 if(et.direct==0||et.direct==2) { if(this.x>=et.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.x+20&&this.y>=et.y&&this.y<=et.y+30) { return true; } } if(et.direct==1||et.direct==3) { if(this.x>=et.x&&this.x<=et.x+30&&this.y+20>=et.y&&this.y+20<=et.y+20) { return true; } if(this.x>=et.x && this.x<=et.x+30&&this.y+20>=et.y&&this.y+20<=et.y+20) { return true; } } } } } return b; } public void run() { while(true) { switch(this.direct) { case 0: for(int i=0;i<(int)(100*Math.random());i++) { try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); } if(y>=speed && !this.isTouchOtherEnemy()) { y-=speed; } } break; case 1: for(int i=0;i<(int)(100*Math.random());i++) { try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); } if(x<=(400-(speed+30))&& !this.isTouchOtherEnemy()) { x+=speed; } } break; case 2: for(int i=0;i<(int)(100*Math.random());i++) { try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); } if(y<=(300-(speed+30))&& !this.isTouchOtherEnemy()) { y+=speed; } } break; case 3: for(int i=0;i<(int)(100*Math.random());i++) { try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); } if(x>=speed && !this.isTouchOtherEnemy()) { x-=speed; } } break; } //讓坦克隨機產生一個新的方向 this.direct=(int)(Math.random()*4); //判斷敵人坦克是否死亡 if(this.isLive==false) { //讓坦克死亡後,退出線程 break; } } } } //我的坦克 class Hero extends Tank { //子彈 //Shot s=null; Vector<Shot> ss=new Vector<Shot>(); Shot s=null; public Hero(int x, int y) { super(x,y); } //坦克向上移動 //坦克的開火的能力和動作 public void shotEnemy() { switch(this.direct) { case 0: s=new Shot(x+9,y-1,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+9,y+30,2); ss.add(s); break; case 3: s=new Shot(x-1,y+9,3); ss.add(s); ss.add(s); break; } Thread t=new Thread(s); t.start(); } public void moveUp() { this.y-=speed; } public void moveRight() { this.x+=speed; } public void moveDown() { this.y+=speed; } public void moveLeft() { this.x-=speed; } } 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) { e.printStackTrace(); } switch(direct) { case 0: //向上 y-=speed;break; case 1: x+=speed;break; case 2: y+=speed;break; case 3: x-=speed;break; } //子彈何時死亡? //判斷該子彈是否碰到邊緣 if(x<0||x>400||y<0||y>300) { this.isLive=false; break; } } } }
注:如果大家很多java基礎內容不是很清楚,可以觀看韓順平的java學習視頻,跟著教程做程序,效果很明顯!(●ˇ∀ˇ●)