坦克大戰編程


坦克大戰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:
        }
    }
}
View Code

 怎么樣讓坦克動起來?

事件監聽:

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

    }
}
View Code

 

坦克大戰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;
            }
        }
    }
}
View Code

 

首先增加敵方坦克

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

    }
}
View Code

 

標准代碼;

主函數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();
        }
    }
}
View Code

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);

    }
}

    
View Code

炮彈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;
            }
        }
    }
}
View Code

 

怎么實現連發?

 子彈是坦克的屬性,設計彈夾,然后繪制

可以連發后最多連發五顆子彈?

連發五顆后就沒子彈了,怎么上子彈? 從彈夾中刪除彈殼

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();
        }
    }
}
View Code

 打中坦克后消失,怎么判斷打中坦克?

 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();
        }
    }
}
View Code

 

怎么產生爆炸效果?

炸彈好多可能都會爆炸,

 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();
        }
    }
}
View Code

 

讓敵人的坦克也可以自由的移動:

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();
        }
    }
}
View Code

怎么樣平緩的移動?坦克在范圍內移動

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;
            }
            
        }
    }
}

    
View Code

 讓敵人的坦克也可以發射子彈:

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();
        }
    }
}
View Code

修改后能敵人隨便打子彈:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM