今天想將自己去年自己編寫的坦克大戰的代碼與大家分享一下,主要面向學習過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學習視頻,跟著教程做程序,效果很明顯!(●ˇ∀ˇ●)