坦克大戰1.0:
1.首先建立我的面板Mypanel,繼承JPanel ,引用 import javax.swing;
2.主函數要顯示面板,使用Demo1類需要extends JFrame
3.繪圖 Graphics 需要引用 import java.awt.*;
4.初始化不要忘了初始化 x y
5.整個Myframe 作為坦克的圖形,設計好面板最終放入到框架中JFrame
6.Myframe中的畫筆畫出所有的圖形,而JFrame只是設定一個顯示框架
7.g.fillRect是為了將背景顏色進行修改
8.編寫drawTank函數用g來畫出坦克的形狀,每調用一個drawTank只能畫一個坦克
初步顯示靜止圖形代碼:

package demo1; import javax.swing.*; import java.awt.*; /** * 設計坦克形狀 * * @author 王志 */ public class Demo1 extends JFrame { Myframe mp = null; public static void main(String[] args) { Demo1 demo = new Demo1(); } public Demo1() { mp = new Myframe(); this.add(mp); this.setSize(400, 300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } } // 定義我的面板,最終的顯示窗口,整個面板作為坦克的形狀 class Myframe extends JPanel { Hero hero; public void paint(Graphics g) {// JPanel的畫圖功能 g.fillRect(0, 0, 400, 300); this.drawTank(hero.getX(), hero.getY(), g, 0, 1); } public Myframe() { hero = new Hero(200, 100);// 設定位置 } // 畫出坦克函數 type表示坦克類型,坦克的形狀與type1有關 敵人0與自己1 public void drawTank(int x, int y, Graphics g, int direct, int type) { // 為坦克上色 switch (type) { case 0:// 敵人的坦克 g.setColor(Color.CYAN); case 1:// 我的坦克 g.setColor(Color.YELLOW); } // 判斷方向 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.drawLine(x + 10, y, x + 10, y + 15); break; case 1: case 2: case 3: } } }
怎么樣讓坦克動起來?
事件監聽:
import java.awt.event.KeyEvent; import java.awt.event.KeyListener;
1.想要坦克動起來,首先需要設置KeyListener,在Myframe中定義接口,自動生成接口函數
2.在Hero中設置move函數 實現上下左右移動
3.為什么坦克還沒有動?主函數加入加入 this.addKeyListener(mp),但是還沒有動,還需要在 keyPressed函數中加入this.repeat()函數將面板重畫
4.坦克的方向還未改變,switch(direct) 編寫完整
可以移動的坦克代碼:

package demo1; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; /** * 設計坦克形狀 * * @author 王志 */ public class Demo1 extends JFrame { Myframe mp = null; public static void main(String[] args) { Demo1 demo = new Demo1(); } public Demo1() { mp = new Myframe(); this.add(mp); this.addKeyListener(mp); this.setSize(400, 300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } } // 定義我的面板,最終的顯示窗口,整個面板作為坦克的形狀 class Myframe extends JPanel implements KeyListener { Hero hero; public void paint(Graphics g) {// JPanel的畫圖功能 g.fillRect(0, 0, 400, 300); this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1); } public Myframe() { hero = new Hero(200, 100);// 設定位置 } // 畫出坦克函數 type表示坦克類型,坦克的形狀與type1有關 敵人0與自己1 public void drawTank(int x, int y, Graphics g, int direct, int type) { // 為坦克上色 switch (type) { case 0:// 敵人的坦克 g.setColor(Color.CYAN); case 1:// 我的坦克 g.setColor(Color.YELLOW); } // 判斷方向 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.drawLine(x + 10, y, x + 10, y + 15); 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 + 5, 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, y + 10, x + 15, y + 10); break; } } @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub if (e.getKeyCode() == KeyEvent.VK_W) { // W 表示上 this.hero.setDirect(0); this.hero.moveup(); } else if (e.getKeyCode() == KeyEvent.VK_D) { // D 表示右 this.hero.setDirect(1); this.hero.moveright(); } else if (e.getKeyCode() == KeyEvent.VK_S) { // S 表示下 this.hero.setDirect(2); this.hero.movedown(); } else if (e.getKeyCode() == KeyEvent.VK_A) { // A 表示左 this.hero.setDirect(3); this.hero.moveleft(); } this.repaint(); } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } }
坦克大戰2.0版本:(線程機制,編寫敵方動態坦克)

package demo1; //橫着x 豎着y import java.awt.*; import javax.swing.*; import java.awt.Event.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.*; public class Demo2 extends JFrame { Myframe mp; public static void main(String[] args) { Demo2 demo = new Demo2(); } public Demo2() { mp = new Myframe(); // 啟動mp線程 Thread t = new Thread(mp); t.start(); this.add(mp); this.setSize(400, 300); this.addKeyListener(mp); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } } // Myframe定義的面板用於繪圖 class Myframe extends JPanel implements KeyListener, Runnable { // 定義我的坦克 Hero hero; // 定義敵人的坦克 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.getDirect(), 1);// 可以實現坦克的類型0 // 畫出自己的子彈 if (hero.p != null && hero.p.islive == true) { g.draw3DRect(hero.p.x, hero.p.y, 3, 3, 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 Myframe() { hero = new Hero(100, 50);// 初始化坦克 // 初始化敵人的坦克 for (int i = 0; i < ensize; i++) { // 生產坦克 EnemyTank et = new EnemyTank((i + 1) * 50, 0); et.setColor(0); et.setDirect(2); ets.add(et); } } // 畫出坦克的函數 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: // 左邊的矩形 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.drawLine(x + 10, y, x + 10, y + 15); 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 + 5, 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 + 0, y + 10, x + 15, y + 10); break; } } @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub 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) { // 判斷玩家是否按下 this.hero.shote(); } // 重新繪制panel this.repaint(); } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } @Override public void run() { // 每100毫秒進行重繪制 while (true) { try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } this.repaint(); } } } class Tank { int x; int y; int direct = 0;// 0 表示上 1表示右 2表示下 3表示左 int speed = 5; int color = 0; public int getColor() { return color; } public void setColor(int color) { this.color = color; } 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 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 Hero extends Tank { shot p = null; public Hero(int x, int y) { super(x, y); } // 開火 public void shote() { switch (this.direct) { case 0: p = new shot(x + 10, y, 0); break; case 1: p = new shot(x + 30, y + 10, 1); break; case 2: p = new shot(x + 10, y + 30, 2); break; case 3: p = new shot(x, y + 10, 3); break; } Thread s = new Thread(p); s.start(); } public void moveup() { y -= speed; } public void moveright() { x += speed; } public void movedown() { y += speed; } public void moveleft() { x -= speed; } } class shot implements Runnable { int x, y; int direct, speed = 3; boolean islive = true; public shot(int x, int y, int direct) { this.x = x; this.y = y; this.direct = direct; // this.speed=speed; } @Override public void run() { while (true) { try { Thread.sleep(50); } catch (Exception e) { // TODO: handle exception } switch (direct) { case 0: y -= speed; break; case 1: x += speed; break; case 2: y += speed; break; case 3: x -= speed; } // 子彈坐標 System.out.println("子彈坐標x= " + x + "y=" + y); // 判斷該子彈是否碰到邊緣 if (x < 0 || x > 400 || y < 0 || y > 300) { this.islive = false; break; } } } }
首先增加敵方坦克
1.面板中定義敵方坦克容器
2.構造函數對敵方坦克進行初始化
3.繪圖g畫出坦克模型,

package demo1; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.*; /** * 設計坦克形狀 * * @author 王志 */ public class Demo1 extends JFrame { Myframe mp = null; public static void main(String[] args) { Demo1 demo = new Demo1(); } public Demo1() { mp = new Myframe(); this.add(mp); this.addKeyListener(mp); this.setSize(400, 300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } } // 定義我的面板,最終的顯示窗口,整個面板作為坦克的形狀 class Myframe extends JPanel implements KeyListener { Hero hero; // 初始化我的敵人 Vector<EnemyTank> ets = new Vector<EnemyTank>(); int ensize = 3; public void paint(Graphics g) {// JPanel的畫圖功能 g.fillRect(0, 0, 400, 300); this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1); // 畫出子彈 if (hero.s != null) { g.draw3DRect(hero.x, hero.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 Myframe() { hero = new Hero(200, 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);// 放入容器 } } // 畫出坦克函數 type表示坦克類型,坦克的形狀與type1有關 敵人0與自己1 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:// 向上 // 左邊的矩形 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.drawLine(x + 10, y, x + 10, y + 15); 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 + 5, 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, y + 10, x + 15, y + 10); break; } } @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub if (e.getKeyCode() == KeyEvent.VK_W) { // W 表示上 this.hero.setDirect(0); this.hero.moveup(); } else if (e.getKeyCode() == KeyEvent.VK_D) { // D 表示右 this.hero.setDirect(1); this.hero.moveright(); } else if (e.getKeyCode() == KeyEvent.VK_S) { // S 表示下 this.hero.setDirect(2); this.hero.movedown(); } else if (e.getKeyCode() == KeyEvent.VK_A) { // A 表示左 this.hero.setDirect(3); this.hero.moveleft(); } // 判斷玩家是否發射了炮彈J if (e.getKeyCode() == KeyEvent.VK_J) { // 開火 this.hero.shot(); } this.repaint(); } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } }
標准代碼;
主函數Demo1:

package demo1; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; /** * 設計坦克形狀 * * @author 王志 */ public class Demo1 extends JFrame { Myframe mp = null; public static void main(String[] args) { Demo1 demo = new Demo1(); } public Demo1() { mp = new Myframe(); Thread t = new Thread(mp); t.start(); this.add(mp); this.addKeyListener(mp); this.setSize(400, 300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } } // 定義我的面板,最終的顯示窗口,整個面板作為坦克的形狀 class Myframe extends JPanel implements KeyListener, Runnable { Hero hero; public void paint(Graphics g) {// JPanel的畫圖功能 g.fillRect(0, 0, 400, 300); this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1); // 畫出自己的子彈 if (hero.p != null && hero.p.islive == true) { g.draw3DRect(hero.p.x, hero.p.y, 3, 3, false); } } public Myframe() { hero = new Hero(200, 100);// 設定位置 } // 畫出坦克函數 type表示坦克類型,坦克的形狀與type1有關 敵人0與自己1 public void drawTank(int x, int y, Graphics g, int direct, int type) { // 為坦克上色 switch (type) { case 0:// 敵人的坦克 g.setColor(Color.CYAN); case 1:// 我的坦克 g.setColor(Color.YELLOW); } // 判斷方向 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.drawLine(x + 10, y, x + 10, y + 15); 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 + 5, 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, y + 10, x + 15, y + 10); break; } } @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub if (e.getKeyCode() == KeyEvent.VK_W) { // W 表示上 this.hero.setDirect(0); this.hero.moveup(); } else if (e.getKeyCode() == KeyEvent.VK_D) { // D 表示右 this.hero.setDirect(1); this.hero.moveright(); } else if (e.getKeyCode() == KeyEvent.VK_S) { // S 表示下 this.hero.setDirect(2); this.hero.movedown(); } else if (e.getKeyCode() == KeyEvent.VK_A) { // A 表示左 this.hero.setDirect(3); this.hero.moveleft(); } if (e.getKeyCode() == KeyEvent.VK_J) { // 判斷玩家是否按下 this.hero.shote(); } this.repaint(); } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } @Override public void run() {// 重繪 // TODO Auto-generated method stub // 每100毫秒進行重繪制 while (true) { try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } this.repaint(); } } }
Tank:

package demo1; public class Tank { int x; int y; int direct = 0;// 0 表示上 1表示右 2表示下 3表示左 int speed = 5; int color = 0; Shot p=null; //開火 public void shote() { switch (this.direct) { case 0: p = new Shot(x + 10, y, 0); break; case 1: p = new Shot(x + 30, y + 10, 1); break; case 2: p = new Shot(x + 10, y + 30, 2); break; case 3: p = new Shot(x, y + 10, 3); break; } Thread s = new Thread(p); s.start(); } public int getColor() { return color; } public void setColor(int color) { this.color = color; } 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 Tank(int x, int y) { this.x = x; this.y = y; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public void moveup() { y -= speed; } public void moveright() { x += speed; } public void movedown() { y += speed; } public void moveleft() { x -= speed; } } class Hero extends Tank { public Hero(int x, int y) { super(x, y); } }
炮彈Shot

package demo1; class Shot implements Runnable { int x, y; int direct, speed = 3; boolean islive = true; public Shot(int x, int y, int direct) { this.x = x; this.y = y; this.direct = direct; // this.speed=speed; } @Override public void run() { while (true) { try { Thread.sleep(50); } catch (Exception e) { // TODO: handle exception } switch (direct) { case 0: y -= speed; break; case 1: x += speed; break; case 2: y += speed; break; case 3: x -= speed; } // 子彈坐標 System.out.println("子彈坐標x= " + x + "y=" + y); // 判斷該子彈是否碰到邊緣 if (x < 0 || x > 400 || y < 0 || y > 300) { this.islive = false; break; } } } }
怎么實現連發?
子彈是坦克的屬性,設計彈夾,然后繪制
可以連發后最多連發五顆子彈?
連發五顆后就沒子彈了,怎么上子彈? 從彈夾中刪除彈殼

package demo1; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.*; /** * 設計坦克形狀 * * @author 王志 */ public class Demo1 extends JFrame { Myframe mp = null; public static void main(String[] args) { Demo1 demo = new Demo1(); } public Demo1() { mp = new Myframe(); Thread t = new Thread(mp); t.start(); this.add(mp); this.addKeyListener(mp); this.setSize(400, 300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } } // 定義我的面板,最終的顯示窗口,整個面板作為坦克的形狀 class Myframe extends JPanel implements KeyListener, Runnable { Hero hero; // 加入敵人的坦克(數量不確定用容器) Vector<Enemy> enemy = new Vector<Enemy>(); int ensize = 3; public void paint(Graphics g) {// JPanel的畫圖功能 g.fillRect(0, 0, 400, 300); this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1); // 畫出敵方的坦克 for (int i = 0; i < ensize; i++) { this.drawTank(enemy.get(i).getX(), enemy.get(i).getY(), g, enemy.get(i).getDirect(), 0); } // 從彈夾中取出每一顆子彈 for (int i = 0; i < this.hero.m.size(); i++) { Shot myshot = hero.m.get(i); // 畫出自己的子彈 (一顆) if (myshot != null && myshot.islive == true) { // g.setColor(Color.red); g.draw3DRect(myshot.x, myshot.y, 3, 3, false); } else { // 從m中刪除子彈 hero.m.remove(myshot);// 為什么不用i } } } public Myframe() { hero = new Hero(200, 100);// 設定位置 // 初始化敵方坦克 // 初始化敵人的坦克 for (int i = 0; i < ensize; i++) { // 生產坦克 Enemy et = new Enemy((i + 1) * 50, 0); // et.set enemy.add(et); } } // 畫出坦克函數 type表示坦克類型,坦克的形狀與type1有關 敵人0與自己1 public void drawTank(int x, int y, Graphics g, int direct, int type) { // 為坦克上色 switch (type) { case 0:// 敵人的坦克 g.setColor(Color.cyan); break;// 注意break case 1:// 我的坦克 g.setColor(Color.yellow); 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.drawLine(x + 10, y, x + 10, y + 15); 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 + 5, 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, y + 10, x + 15, y + 10); break; } } @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub if (e.getKeyCode() == KeyEvent.VK_W) { // W 表示上 this.hero.setDirect(0); this.hero.moveup(); } else if (e.getKeyCode() == KeyEvent.VK_D) { // D 表示右 this.hero.setDirect(1); this.hero.moveright(); } else if (e.getKeyCode() == KeyEvent.VK_S) { // S 表示下 this.hero.setDirect(2); this.hero.movedown(); } else if (e.getKeyCode() == KeyEvent.VK_A) { // A 表示左 this.hero.setDirect(3); this.hero.moveleft(); } if (e.getKeyCode() == KeyEvent.VK_J) { if (this.hero.m.size() <= 5) { // 判斷玩家是否按下 this.hero.shote(); } } this.repaint(); } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } @Override public void run() {// 重繪 // TODO Auto-generated method stub // 每100毫秒進行重繪制 while (true) { try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } this.repaint(); } } }
打中坦克后消失,怎么判斷打中坦克?
1.選中一個函數判斷是否打中,位置在Mypanel中
s.islive=false;
et.islive=false;
在什么地方調用判斷函數,隨時判斷run函數
定義完成后,修改Mypanel的畫坦克函數

package demo1; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.*; /** * 設計坦克形狀 * * @author 王志 */ public class Demo1 extends JFrame { Myframe mp = null; public static void main(String[] args) { Demo1 demo = new Demo1(); } public Demo1() { mp = new Myframe(); Thread t = new Thread(mp); t.start(); this.add(mp); this.addKeyListener(mp); this.setSize(400, 300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } } // 定義我的面板,最終的顯示窗口,整個面板作為坦克的形狀 class Myframe extends JPanel implements KeyListener, Runnable { Hero hero; // 加入敵人的坦克(數量不確定用容器) Vector<Enemy> enemy = new Vector<Enemy>(); int ensize = 3; public void paint(Graphics g) {// JPanel的畫圖功能 g.fillRect(0, 0, 400, 300); this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1); // 畫出敵方的坦克 for (int i = 0; i < ensize; i++) { Enemy et = enemy.get(i); if (et.islive) { // 這里用et代替 this.drawTank(enemy.get(i).getX(), enemy.get(i).getY(), g, enemy.get(i).getDirect(), 0); } } // 從彈夾中取出每一顆子彈 for (int i = 0; i < this.hero.m.size(); i++) { Shot myshot = hero.m.get(i); // 畫出自己的子彈 (一顆) if (myshot != null && myshot.islive == true) { // g.setColor(Color.red); g.draw3DRect(myshot.x, myshot.y, 3, 3, false); } else { // 從m中刪除子彈 hero.m.remove(myshot);// 為什么不用i } } } public Myframe() { hero = new Hero(200, 100);// 設定位置 // 初始化敵方坦克 // 初始化敵人的坦克 for (int i = 0; i < ensize; i++) { // 生產坦克 Enemy et = new Enemy((i + 1) * 50, 0); // et.set enemy.add(et); } } // 寫出一個函數判斷是否打中坦克 對象:子彈 敵方坦克 public void hitTank(Shot s, Enemy 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; } break; 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; } break; } } // 畫出坦克函數 type表示坦克類型,坦克的形狀與type1有關 敵人0與自己1 public void drawTank(int x, int y, Graphics g, int direct, int type) { // 為坦克上色 switch (type) { case 0:// 敵人的坦克 g.setColor(Color.cyan); break;// 注意break case 1:// 我的坦克 g.setColor(Color.yellow); 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.drawLine(x + 10, y, x + 10, y + 15); 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 + 5, 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, y + 10, x + 15, y + 10); break; } } @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub if (e.getKeyCode() == KeyEvent.VK_W) { // W 表示上 this.hero.setDirect(0); this.hero.moveup(); } else if (e.getKeyCode() == KeyEvent.VK_D) { // D 表示右 this.hero.setDirect(1); this.hero.moveright(); } else if (e.getKeyCode() == KeyEvent.VK_S) { // S 表示下 this.hero.setDirect(2); this.hero.movedown(); } else if (e.getKeyCode() == KeyEvent.VK_A) { // A 表示左 this.hero.setDirect(3); this.hero.moveleft(); } if (e.getKeyCode() == KeyEvent.VK_J) { if (this.hero.m.size() <= 5) { // 判斷玩家是否按下 this.hero.shote(); } } this.repaint(); } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } @Override public void run() {// 重繪 // TODO Auto-generated method stub // 每100毫秒進行重繪制 while (true) { try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } // 判斷是否擊中 for (int i = 0; i < hero.m.size(); i++) { // 取出子彈 Shot myshot = hero.m.get(i); // 判斷子彈是否有效 if (myshot.islive) { // 取出每一個坦克與他判斷 for (int j = 0; j < enemy.size(); j++) { // 取出坦克 Enemy et = enemy.get(j); if (et.islive) { this.hitTank(myshot, et); } } } } this.repaint(); } } }
怎么產生爆炸效果?
炸彈好多可能都會爆炸,
1.准備三張照片
2.定義bom類
3.在擊中敵人坦克時把炸彈放入
4.繪制

package demo1; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.*; /** * 設計坦克形狀 * * @author 王志 */ public class Demo1 extends JFrame { Myframe mp = null; public static void main(String[] args) { Demo1 demo = new Demo1(); } public Demo1() { mp = new Myframe(); Thread t = new Thread(mp); t.start(); this.add(mp); this.addKeyListener(mp); this.setSize(400, 300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } } // 定義我的面板,最終的顯示窗口,整個面板作為坦克的形狀 class Myframe extends JPanel implements KeyListener, Runnable { Hero hero; // 加入敵人的坦克(數量不確定用容器) Vector<Enemy> enemy = new Vector<Enemy>(); // 定義炸彈集合 Vector<Bom> bom = new Vector<Bom>(); int ensize = 3; // 定義三張圖片,才能組成一炸彈 Image img1, img2, img3; public void paint(Graphics g) {// JPanel的畫圖功能 g.fillRect(0, 0, 400, 300); this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1); // 畫出敵方的坦克 for (int i = 0; i < ensize; i++) { Enemy et = enemy.get(i); if (et.islive) { this.drawTank(enemy.get(i).getX(), enemy.get(i).getY(), g, enemy.get(i).getDirect(), 0); } } // 畫出炸彈 for (int i = 0; i < bom.size(); i++) { System.out.println("你媽個比比比" + bom.size()); // 取出炸彈 Bom b = bom.get(i); if (b.life > 6) { g.drawImage(img1, b.x, b.y, 30, 30, this); } else if (b.life > 4) { g.drawImage(img2, b.x, b.y, 30, 30, this); } else { g.drawImage(img3, b.x, b.y, 30, 30, this); } b.lifeDown(); if (b.life == 0) { bom.remove(b); } } // 從彈夾中取出每一顆子彈 for (int i = 0; i < this.hero.m.size(); i++) { Shot myshot = hero.m.get(i); // 畫出自己的子彈 (一顆) if (myshot != null && myshot.islive == true) { // g.setColor(Color.red); g.draw3DRect(myshot.x, myshot.y, 3, 3, false); } else { // 從m中刪除子彈 hero.m.remove(myshot);// 為什么不用i } } } public Myframe() { hero = new Hero(200, 100);// 設定位置 // 初始化敵方坦克 // 初始化敵人的坦克 for (int i = 0; i < ensize; i++) { // 生產坦克 Enemy et = new Enemy((i + 1) * 50, 0); // et.set enemy.add(et); } // 初始化圖片 img1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg")); img2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg")); img3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg")); } // 寫出一個函數判斷是否打中坦克 對象:子彈 敵方坦克 public void hitTank(Shot s, Enemy 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; // 創建一顆炸彈, Bom b = new Bom(et.x, et.y); // 放入到vector bom.add(b); } break; 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; // 創建一顆炸彈 Bom b = new Bom(et.x, et.y); // 放入到vector bom.add(b); } break; } } // 畫出坦克函數 type表示坦克類型,坦克的形狀與type1有關 敵人0與自己1 public void drawTank(int x, int y, Graphics g, int direct, int type) { // 為坦克上色 switch (type) { case 0:// 敵人的坦克 g.setColor(Color.cyan); break;// 注意break case 1:// 我的坦克 g.setColor(Color.yellow); 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.drawLine(x + 10, y, x + 10, y + 15); 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 + 5, 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, y + 10, x + 15, y + 10); break; } } @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub if (e.getKeyCode() == KeyEvent.VK_W) { // W 表示上 this.hero.setDirect(0); this.hero.moveup(); } else if (e.getKeyCode() == KeyEvent.VK_D) { // D 表示右 this.hero.setDirect(1); this.hero.moveright(); } else if (e.getKeyCode() == KeyEvent.VK_S) { // S 表示下 this.hero.setDirect(2); this.hero.movedown(); } else if (e.getKeyCode() == KeyEvent.VK_A) { // A 表示左 this.hero.setDirect(3); this.hero.moveleft(); } if (e.getKeyCode() == KeyEvent.VK_J) { if (this.hero.m.size() <= 5) { // 判斷玩家是否按下 this.hero.shote(); } } this.repaint(); } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } @Override public void run() {// 重繪 // TODO Auto-generated method stub // 每100毫秒進行重繪制 while (true) { try { Thread.sleep(1000); } catch (Exception e) { // TODO: handle exception } // 判斷是否擊中 for (int i = 0; i < hero.m.size(); i++) { // 取出子彈 Shot myshot = hero.m.get(i); // 判斷子彈是否有效 if (myshot.islive) { // 取出每一個坦克與他判斷 for (int j = 0; j < enemy.size(); j++) { // 取出坦克 Enemy et = enemy.get(j); if (et.islive) { this.hitTank(myshot, et); } } } } this.repaint(); } } }
讓敵人的坦克也可以自由的移動:

package demo1; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.*; /** * 設計坦克形狀 * * @author 王志 */ public class Demo1 extends JFrame { Myframe mp = null; public static void main(String[] args) { Demo1 demo = new Demo1(); } public Demo1() { mp = new Myframe(); Thread t = new Thread(mp); t.start(); this.add(mp); this.addKeyListener(mp); this.setSize(400, 300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } } // 定義我的面板,最終的顯示窗口,整個面板作為坦克的形狀 class Myframe extends JPanel implements KeyListener, Runnable { Hero hero; // 加入敵人的坦克(數量不確定用容器) Vector<Enemy> enemy = new Vector<Enemy>(); // 定義炸彈集合 Vector<Bom> bom = new Vector<Bom>(); int ensize = 3; // 定義三張圖片,才能組成一炸彈 Image img1, img2, img3; public void paint(Graphics g) {// JPanel的畫圖功能 g.fillRect(0, 0, 400, 300); this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1); // 畫出敵方的坦克 for (int i = 0; i < ensize; i++) { Enemy et = enemy.get(i); if (et.islive) { this.drawTank(enemy.get(i).getX(), enemy.get(i).getY(), g, enemy.get(i).getDirect(), 0); } } // 畫出炸彈 for (int i = 0; i < bom.size(); i++) { System.out.println("你媽個比比比" + bom.size()); // 取出炸彈 Bom b = bom.get(i); if (b.life > 6) { g.drawImage(img1, b.x, b.y, 30, 30, this); } else if (b.life > 4) { g.drawImage(img2, b.x, b.y, 30, 30, this); } else { g.drawImage(img3, b.x, b.y, 30, 30, this); } b.lifeDown(); if (b.life == 0) { bom.remove(b); } } // 從彈夾中取出每一顆子彈 for (int i = 0; i < this.hero.m.size(); i++) { Shot myshot = hero.m.get(i); // 畫出自己的子彈 (一顆) if (myshot != null && myshot.islive == true) { // g.setColor(Color.red); g.draw3DRect(myshot.x, myshot.y, 3, 3, false); } else { // 從m中刪除子彈 hero.m.remove(myshot);// 為什么不用i } } } public Myframe() { hero = new Hero(200, 100);// 設定位置 // 初始化敵方坦克 // 初始化敵人的坦克 for (int i = 0; i < ensize; i++) { // 生產坦克 Enemy et = new Enemy((i + 1) * 50, 0); // 啟動敵人的坦克 Thread t = new Thread(et); t.start(); enemy.add(et); } // 初始化圖片 img1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg")); img2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg")); img3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg")); } // 寫出一個函數判斷是否打中坦克 對象:子彈 敵方坦克 public void hitTank(Shot s, Enemy 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; // 創建一顆炸彈, Bom b = new Bom(et.x, et.y); // 放入到vector bom.add(b); } break; 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; // 創建一顆炸彈 Bom b = new Bom(et.x, et.y); // 放入到vector bom.add(b); } break; } } // 畫出坦克函數 type表示坦克類型,坦克的形狀與type1有關 敵人0與自己1 public void drawTank(int x, int y, Graphics g, int direct, int type) { // 為坦克上色 switch (type) { case 0:// 敵人的坦克 g.setColor(Color.cyan); break;// 注意break case 1:// 我的坦克 g.setColor(Color.yellow); 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.drawLine(x + 10, y, x + 10, y + 15); 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 + 5, 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, y + 10, x + 15, y + 10); break; } } @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub if (e.getKeyCode() == KeyEvent.VK_W) { // W 表示上 this.hero.setDirect(0); this.hero.moveup(); } else if (e.getKeyCode() == KeyEvent.VK_D) { // D 表示右 this.hero.setDirect(1); this.hero.moveright(); } else if (e.getKeyCode() == KeyEvent.VK_S) { // S 表示下 this.hero.setDirect(2); this.hero.movedown(); } else if (e.getKeyCode() == KeyEvent.VK_A) { // A 表示左 this.hero.setDirect(3); this.hero.moveleft(); } if (e.getKeyCode() == KeyEvent.VK_J) { if (this.hero.m.size() <= 5) { // 判斷玩家是否按下 this.hero.shote(); } } this.repaint(); } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } @Override public void run() {// 重繪 // TODO Auto-generated method stub // 每100毫秒進行重繪制 while (true) { try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } // 判斷是否擊中 for (int i = 0; i < hero.m.size(); i++) { // 取出子彈 Shot myshot = hero.m.get(i); // 判斷子彈是否有效 if (myshot.islive) { // 取出每一個坦克與他判斷 for (int j = 0; j < enemy.size(); j++) { // 取出坦克 Enemy et = enemy.get(j); if (et.islive) { this.hitTank(myshot, et); } } } } this.repaint(); } } }
怎么樣平緩的移動?坦克在范圍內移動

package demo1; import java.util.*; public class Tank { int x; int y; int direct = 0;// 0 表示上 1表示右 2表示下 3表示左 int speed = 5; int color = 0; boolean islive=true; //Shot p=null; 關鍵點是建立容器 Vector<Shot> m=new Vector<Shot>(); Shot p; //開火 public void shote() { switch (this.direct) { //創建子彈加入彈夾 case 0: p = new Shot(x + 10, y, 0); m.add(p); break; case 1: p = new Shot(x + 30, y + 10, 1); m.add(p); break; case 2: p = new Shot(x + 10, y + 30, 2); m.add(p); break; case 3: p = new Shot(x, y + 10, 3); m.add(p); break; } Thread s = new Thread(p); s.start(); } public int getColor() { return color; } public void setColor(int color) { this.color = color; } 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 Tank(int x, int y) { this.x = x; this.y = y; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public void moveup() { y -= speed; } public void moveright() { x += speed; } public void movedown() { y += speed; } public void moveleft() { x -= speed; } } class Hero extends Tank { public Hero(int x, int y) { super(x, y); } } class Enemy extends Tank implements Runnable{ public Enemy(int x, int y) { super(x, y); // this.ensize=ensize; } @Override public void run() { // TODO Auto-generated method stub while(true){ try { Thread.sleep(50); } catch (Exception e) { // TODO: handle exception } // Math.random(); switch(this.direct){ case 0://向上走 for(int i=0;i<20;i++){ if(y>0){ y-=speed;} try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } } break; case 1://向右走 for(int i=0;i<20;i++){ if(x<400){ x+=2*speed;} try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } } break; case 2: for(int i=0;i<20;i++){ if(y<200){ y+=speed;} try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } } break; case 3: for(int i=0;i<20;i++){ if(x>0){ x-=speed;} try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } } break; } //讓坦克產生一個隨機的方向 this.direct=(int) (Math.random()*4); //判斷敵人坦克是否死亡 if(this.islive==false){ //讓坦克死亡后退出 break; } } } }
讓敵人的坦克也可以發射子彈:

package demo1; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.*; /** * 設計坦克形狀 * * @author 王志 */ public class Demo1 extends JFrame { Myframe mp = null; public static void main(String[] args) { Demo1 demo = new Demo1(); } public Demo1() { mp = new Myframe(); Thread t = new Thread(mp); t.start(); this.add(mp); this.addKeyListener(mp); this.setSize(400, 300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } } // 定義我的面板,最終的顯示窗口,整個面板作為坦克的形狀 class Myframe extends JPanel implements KeyListener, Runnable { Hero hero; // 加入敵人的坦克(數量不確定用容器) Vector<Enemy> enemy = new Vector<Enemy>(); // 定義炸彈集合 Vector<Bom> bom = new Vector<Bom>(); int ensize = 3; // 定義三張圖片,才能組成一炸彈 Image img1, img2, img3; public void paint(Graphics g) {// JPanel的畫圖功能 g.fillRect(0, 0, 400, 300); this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1); // 畫出敵方的坦克 for (int i = 0; i < ensize; i++) { Enemy et = enemy.get(i); if (et.islive) { this.drawTank(enemy.get(i).getX(), enemy.get(i).getY(), g, enemy.get(i).getDirect(), 0); for(int j=0;j<et.m.size();j++){ //取出子彈 Shot xx=et.m.get(j); if(xx.islive){ g.draw3DRect(xx.x, xx.y, 3, 3, false); } } } } // 畫出炸彈 for (int i = 0; i < bom.size(); i++) { System.out.println("你媽個比比比" + bom.size()); // 取出炸彈 Bom b = bom.get(i); if (b.life > 6) { g.drawImage(img1, b.x, b.y, 30, 30, this); } else if (b.life > 4) { g.drawImage(img2, b.x, b.y, 30, 30, this); } else { g.drawImage(img3, b.x, b.y, 30, 30, this); } b.lifeDown(); if (b.life == 0) { bom.remove(b); } } // 從彈夾中取出每一顆子彈 for (int i = 0; i < this.hero.m.size(); i++) { Shot myshot = hero.m.get(i); // 畫出自己的子彈 (一顆) if (myshot != null && myshot.islive == true) { // g.setColor(Color.red); g.draw3DRect(myshot.x, myshot.y, 3, 3, false); } else { // 從m中刪除子彈 hero.m.remove(myshot);// 為什么不用i } } } public Myframe() { hero = new Hero(200, 100);// 設定位置 // 初始化敵方坦克 // 初始化敵人的坦克 for (int i = 0; i < ensize; i++) { // 生產坦克 Enemy et = new Enemy((i + 1) * 50, 0); // 啟動敵人的坦克 Thread t = new Thread(et); t.start(); //給敵人的坦克加子彈 Shot s=new Shot(et.x+10,et.y+30,2); et.m.add(s); Thread t2=new Thread(s); t2.start(); enemy.add(et); } // 初始化圖片 img1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg")); img2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg")); img3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg")); } // 寫出一個函數判斷是否打中坦克 對象:子彈 敵方坦克 public void hitTank(Shot s, Enemy 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; // 創建一顆炸彈, Bom b = new Bom(et.x, et.y); // 放入到vector bom.add(b); } break; 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; // 創建一顆炸彈 Bom b = new Bom(et.x, et.y); // 放入到vector bom.add(b); } break; } } // 畫出坦克函數 type表示坦克類型,坦克的形狀與type1有關 敵人0與自己1 public void drawTank(int x, int y, Graphics g, int direct, int type) { // 為坦克上色 switch (type) { case 0:// 敵人的坦克 g.setColor(Color.cyan); break;// 注意break case 1:// 我的坦克 g.setColor(Color.yellow); 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.drawLine(x + 10, y, x + 10, y + 15); 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 + 5, 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, y + 10, x + 15, y + 10); break; } } @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub if (e.getKeyCode() == KeyEvent.VK_W) { // W 表示上 this.hero.setDirect(0); this.hero.moveup(); } else if (e.getKeyCode() == KeyEvent.VK_D) { // D 表示右 this.hero.setDirect(1); this.hero.moveright(); } else if (e.getKeyCode() == KeyEvent.VK_S) { // S 表示下 this.hero.setDirect(2); this.hero.movedown(); } else if (e.getKeyCode() == KeyEvent.VK_A) { // A 表示左 this.hero.setDirect(3); this.hero.moveleft(); } if (e.getKeyCode() == KeyEvent.VK_J) { if (this.hero.m.size() <= 5) { // 判斷玩家是否按下 this.hero.shote(); } } this.repaint(); } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } @Override public void run() {// 重繪 // TODO Auto-generated method stub // 每100毫秒進行重繪制 while (true) { try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } // 判斷是否擊中 for (int i = 0; i < hero.m.size(); i++) { // 取出子彈 Shot myshot = hero.m.get(i); // 判斷子彈是否有效 if (myshot.islive) { // 取出每一個坦克與他判斷 for (int j = 0; j < enemy.size(); j++) { // 取出坦克 Enemy et = enemy.get(j); if (et.islive) { this.hitTank(myshot, et); } } } } this.repaint(); } } }
修改后能敵人隨便打子彈: