day04-应用线程03

JavaGUI-坦克大战04

7.线程的应用03

7.3坦克大战4.0版

7.3.4功能3:敌方坦克自由移动

功能3:让敌人的坦克也可以自由随机地上下左右移动

思路:

  1. 因为要求敌人的坦克自由移动,因此需要将敌人坦克当做线程使用,EnemyTank类实现Runnable接口
  2. 线程的run方法的具体操作为:根据当前的方向继续移动敌坦,然后改变敌坦移动方向,再继续移动,如此不断循环。break的条件是当前的敌人坦克被击中,即enemy.isLive == false。
  3. 在MyPanel类中,每创建一个敌人坦克对象就启动一个线程。

EnemyTank:

package li.TankGame.version04;

import java.util.Vector;

public class EnemyTank extends Tank implements Runnable {

    //在敌人坦克类使用Vector保存多个Shot
    Vector<Shot> shots = new Vector<>();
    boolean isLive = true;

    public EnemyTank(int x, int y) {
        super(x, y);
    }

    @Override
    public void run() {
        while (true) {
            //根据坦克的方法来继续移动
            switch (getDirect()) {
                case 0://上
                    //让坦克保持一个方向走30步
                    for (int i = 0; i < 100; i++) {
                        moveUp();
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                case 1://右
                    //让坦克保持一个方向走30步
                    for (int i = 0; i < 100; i++) {
                        moveRight();//走一步
                        try {
                            Thread.sleep(50);//每走一步就休眠50毫秒
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                case 2://下
                    for (int i = 0; i < 100; i++) {
                        moveDown();
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                case 3://左
                    for (int i = 0; i < 100; i++) {
                        moveLeft();
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
            }
            //随机地改变坦克的方向 0-3
            setDirect((int) (Math.random() * 4));//[0,4)的取整
            //如果被击中了,就退出线程
            if (!isLive) {
                break;//退出线程
            }
        }
    }
}

MyPanel:line 46-47

image-20220907172539933
image-20220907173956306

7.3.5功能4: 控制坦克移动范围

控制坦克的移动范围

如图,坦克的绘图以图案的左上方坐标为参考。
在向上时,坦克的纵坐标限制为y>0,向下时,y+60<面板高度;向左时,x>0,向右时,x+60<面板宽度

EnemyTank:控制敌人的坦克不出界

package li.TankGame.version04;

import java.util.Vector;

public class EnemyTank extends Tank implements Runnable {

    //在敌人坦克类使用Vector保存多个Shot
    Vector<Shot> shots = new Vector<>();
    boolean isLive = true;

    public EnemyTank(int x, int y) {
        super(x, y);
    }

    @Override
    public void run() {
        while (true) {
            //根据坦克的方法来继续移动
            switch (getDirect()) {
                case 0://上
                    //让坦克保持一个方向走30步
                    for (int i = 0; i < 100; i++) {
                        if (getY() > 0) {
                            moveUp();
                        }
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                case 1://右
                    //让坦克保持一个方向走30步
                    for (int i = 0; i < 100; i++) {
                        if (getX() + 60 < 700) {//700为面板宽度
                            moveRight();//走一步
                        }
                        try {
                            Thread.sleep(50);//每走一步就休眠50毫秒
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                case 2://下
                    for (int i = 0; i < 100; i++) {
                        if (getY() + 60 < 550) {//550为面板宽度
                            moveDown();
                        }
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                case 3://左
                    for (int i = 0; i < 100; i++) {
                        if (getX() > 0) {
                            moveLeft();
                        }
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
            }
            //随机地改变坦克的方向 0-3
            setDirect((int) (Math.random() * 4));//[0,4)的取整
            //如果被击中了,就退出线程
            if (!isLive) {
                break;//退出线程
            }
        }
    }
}

修改MyPanel类中的keyPressed方法,使我方坦克也不能走出边界:

//控制方向--处理 WSAD 键按下的情况
@Override
public void keyPressed(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_W) {//按下W键-向上
        //改变坦克的方向
        hero.setDirect(0);
        //修改坦克的坐标
        if (hero.getY() > 0) {//向上
            hero.moveUp();
        }
    } else if (e.getKeyCode() == KeyEvent.VK_D) {//按下D键-向右
        hero.setDirect(1);
        if (hero.getX() + 60 < 750) {//向右
            hero.moveRight();
        }
    } else if (e.getKeyCode() == KeyEvent.VK_S) {//按下S键-向下
        hero.setDirect(2);
        if (hero.getY() + 60 < 550) {//向下
            hero.moveDown();
        }
    } else if (e.getKeyCode() == KeyEvent.VK_A) {//按下A键-向左
        hero.setDirect(3);
        if (hero.getX() > 0) {//向左
            hero.moveLeft();
        }
    }
    //如果用户按下j键,hero就发射子弹
    if (e.getKeyCode() == KeyEvent.VK_J) {
        hero.shotEnemyTank();
    }

    //让面板重绘
    this.repaint();
}

image-20220907190237174

hmoban主题是根据ripro二开的主题,极致后台体验,无插件,集成会员系统
自学咖网 » day04-应用线程03