坦克大战0.3_多线程_面向对象

 

需求:坦克发射子弹思路

我的思路:

1、坦克发射子弹需子弹对象、射击的动作、且按下某个键射出子弹

2、射击出来的子弹需要绘画在画板上,从坦克炮口射出,射出后撞到边界消失

3、这个子弹需启一个线程

老师的思路

代码:

package tankegame3;
//坦克类
public class Tank {
    private int x;//坦克的横坐标
    private int y;//坦克的纵坐标
    private int direct; //增加坦克方向 0 1 2 3 按顺时顺序

    private int speed =1 ;

    // 上、右、下、左移动方法
    public void moveUp() {
        y -= speed;
    }
    public void moveRight() {
        x += speed;
    }

    public void moveDown() {
        y += speed;
    }
    public void moveLeft() {
        x -= speed;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    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 int getDirect() {
        return direct;
    }

    public void setDirect(int direct) {
        this.direct = direct;
    }
}
package tankegame3;
//我方坦克类
public class Hero extends Tank {

    Shot shot = null;

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

    public void shoutEnemyTank() {//子弹从炮管射出的位置
        //创建Shot对象,根据当前Hero方向来创建Shot
        switch (getDirect()) { //获取坦克Hero的方向
            case 0://向上  根据方向确定子弹射出的位置
                shot = new Shot(getX() + 20, getY(), 0);
                break;
            case 1://向右
                shot = new Shot(getX() + 60, getY() + 20, 1);
                break;

            case 2://向下
                shot = new Shot(getX() + 20, getY() + 60, 2);
                break;

            case 3://向左
                shot = new Shot(getX(), getY(), 3);
                break;
        }

        //启动Shot线程
        new Thread(shot).start();

    }

}
package tankegame3;
//敌方坦克类
public class Enemy_Tank extends Tank {
    public Enemy_Tank(int x, int y) {
        super(x, y);
    }

}
package tankegame3;

//射击方法
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;

//坦克的绘图区
//为了监听 键盘事件,实现KeyListener
//为了让Panel 不停重新绘制子弹,需要将Mypanel 当做一个线程使用
public class Mypanel extends JPanel implements KeyListener, Runnable {
    //定义我的坦克
    Hero hero = null;
    //定义敌人坦克数组
    Vector<Enemy_Tank> enemyTanks = new Vector<>();
    int enemyTankSize = 3;//定义敌人坦克数量为3

    public Mypanel() {
        hero = new Hero(200, 200);//初始化自己坦克
        hero.setSpeed(10);

        //初始化敌人坦克3个
        for (int i = 0; i < enemyTankSize; i++) {
            Enemy_Tank enemyTank = new Enemy_Tank(100 * (i + 1), 0);//创建敌人坦克
            enemyTank.setDirect(2);//设置敌人坦克方向向下
            enemyTanks.add(enemyTank);//将坦克加入到数组内
        }
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.fillRect(0, 0, 1000, 750);//填充矩形黑色

        //画出坦克 -- 封装方法
        drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 0);//自己的坦克

        //画出坦克子弹
        if (hero.shot != null && hero.shot.isLive == true) {
            System.out.println("子弹发射");
            g.fill3DRect(hero.shot.x, hero.shot.y, 1, 1, false);
        }


        for (int i = 0; i < enemyTanks.size(); i++) {//绘制敌人的坦克, 遍历Vector
            Enemy_Tank enemyTank = enemyTanks.get(i);
            drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 1);
        }


        //   drawTank(hero.getX() + 60,hero.getY(),g,0,0);//坦克1

    }

    //编写方法画出坦克 考虑坦克的属性
    /*
     * x 为坦克左上角的x坐标
     * y 为坦克左上角y坐标
     * g 为画笔
     * direct 坦克上下左右方向
     * type 坦克类型
     *
     * */
    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) { //(0表示向上,1表示向右,2表示向下,3表示向左)
            case 0://坦克向上
                g.fill3DRect(x, y, 10, 60, false);//画出坦克左边的轮子
                g.fill3DRect(x + 30, y, 10, 60, false);//画出坦克右边的轮子
                g.fill3DRect(x + 10, y + 10, 20, 40, false);//画出坦克盖子
                g.fillOval(x + 10, y + 20, 20, 20);//画出圆形盖子
                g.drawLine(x + 20, y + 30, x + 20, y);//画出炮筒
                break;

            case 1://坦克向右边
                g.fill3DRect(x, y, 60, 10, false);//画出坦克左边的轮子
                g.fill3DRect(x, y + 30, 60, 10, false);//画出坦克右边的轮子
                g.fill3DRect(x + 10, y + 10, 40, 20, false);//画出坦克盖子
                g.fillOval(x + 20, y + 10, 20, 20);//画出圆形盖子
                g.drawLine(x + 30, y + 20, x + 60, y + 20);//画出炮筒
                break;

            case 2://坦克向下
                g.fill3DRect(x, y, 10, 60, false);//画出坦克左边的轮子
                g.fill3DRect(x + 30, y, 10, 60, false);//画出坦克右边的轮子
                g.fill3DRect(x + 10, y + 10, 20, 40, false);//画出坦克盖子
                g.fillOval(x + 10, y + 20, 20, 20);//画出圆形盖子
                g.drawLine(x + 20, y + 30, x + 20, y + 60);//画出炮筒
                break;

            case 3://坦克向左
                g.fill3DRect(x, y, 60, 10, false);//画出坦克左边的轮子
                g.fill3DRect(x, y + 30, 60, 10, false);//画出坦克右边的轮子
                g.fill3DRect(x + 10, y + 10, 40, 20, false);//画出坦克盖子
                g.fillOval(x + 20, y + 10, 20, 20);//画出圆形盖子
                g.drawLine(x + 30, y + 20, x, y + 20);//画出炮筒
                break;

            default:
                System.out.println("暂时不处理");
        }
    }


    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {//处理 w\d\s\a按下的情况
        if (e.getKeyCode() == KeyEvent.VK_W) {//
            //改变坦克方式为上
            hero.setDirect(0);
            hero.moveUp();
        } else if (e.getKeyCode() == KeyEvent.VK_D) {
            //改变坦克方式为右
            hero.setDirect(1);
            hero.moveRight();
        } else if (e.getKeyCode() == KeyEvent.VK_S) {
            //改变坦克方式为下
            hero.setDirect(2);
            hero.moveDown();
        } else if (e.getKeyCode() == KeyEvent.VK_A) {
            //改变坦克方式为左
            hero.setDirect(3);
            hero.moveLeft();
        }


        //如果用户按下J,就发射子弹,射击敌人子弹
        if (e.getKeyCode() == KeyEvent.VK_J) {
            hero.shoutEnemyTank();

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

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void run() { //每隔一定100ms时间自己重绘区域,子弹就会移动起来了

        while (true) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            this.repaint();
        }
    }
}
package tankegame3;
//坦克的画板

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;

//坦克的绘图区
//为了监听 键盘事件,实现KeyListener
//为了让Panel 不停重新绘制子弹,需要将Mypanel 当做一个线程使用
public class Mypanel extends JPanel implements KeyListener, Runnable {
    //定义我的坦克
    Hero hero = null;
    //定义敌人坦克数组
    Vector<Enemy_Tank> enemyTanks = new Vector<>();
    int enemyTankSize = 3;//定义敌人坦克数量为3

    public Mypanel() {
        hero = new Hero(200, 200);//初始化自己坦克
        hero.setSpeed(10);

        //初始化敌人坦克3个
        for (int i = 0; i < enemyTankSize; i++) {
            Enemy_Tank enemyTank = new Enemy_Tank(100 * (i + 1), 0);//创建敌人坦克
            enemyTank.setDirect(2);//设置敌人坦克方向向下
            enemyTanks.add(enemyTank);//将坦克加入到数组内
        }
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.fillRect(0, 0, 1000, 750);//填充矩形黑色

        //画出坦克 -- 封装方法
        drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 0);//自己的坦克

        //画出坦克子弹
        if (hero.shot != null && hero.shot.isLive == true) {
            System.out.println("子弹发射");
            g.fill3DRect(hero.shot.x, hero.shot.y, 1, 1, false);
        }


        for (int i = 0; i < enemyTanks.size(); i++) {//绘制敌人的坦克, 遍历Vector
            Enemy_Tank enemyTank = enemyTanks.get(i);
            drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 1);
        }


        //   drawTank(hero.getX() + 60,hero.getY(),g,0,0);//坦克1

    }

    //编写方法画出坦克 考虑坦克的属性
    /*
     * x 为坦克左上角的x坐标
     * y 为坦克左上角y坐标
     * g 为画笔
     * direct 坦克上下左右方向
     * type 坦克类型
     *
     * */
    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) { //(0表示向上,1表示向右,2表示向下,3表示向左)
            case 0://坦克向上
                g.fill3DRect(x, y, 10, 60, false);//画出坦克左边的轮子
                g.fill3DRect(x + 30, y, 10, 60, false);//画出坦克右边的轮子
                g.fill3DRect(x + 10, y + 10, 20, 40, false);//画出坦克盖子
                g.fillOval(x + 10, y + 20, 20, 20);//画出圆形盖子
                g.drawLine(x + 20, y + 30, x + 20, y);//画出炮筒
                break;

            case 1://坦克向右边
                g.fill3DRect(x, y, 60, 10, false);//画出坦克左边的轮子
                g.fill3DRect(x, y + 30, 60, 10, false);//画出坦克右边的轮子
                g.fill3DRect(x + 10, y + 10, 40, 20, false);//画出坦克盖子
                g.fillOval(x + 20, y + 10, 20, 20);//画出圆形盖子
                g.drawLine(x + 30, y + 20, x + 60, y + 20);//画出炮筒
                break;

            case 2://坦克向下
                g.fill3DRect(x, y, 10, 60, false);//画出坦克左边的轮子
                g.fill3DRect(x + 30, y, 10, 60, false);//画出坦克右边的轮子
                g.fill3DRect(x + 10, y + 10, 20, 40, false);//画出坦克盖子
                g.fillOval(x + 10, y + 20, 20, 20);//画出圆形盖子
                g.drawLine(x + 20, y + 30, x + 20, y + 60);//画出炮筒
                break;

            case 3://坦克向左
                g.fill3DRect(x, y, 60, 10, false);//画出坦克左边的轮子
                g.fill3DRect(x, y + 30, 60, 10, false);//画出坦克右边的轮子
                g.fill3DRect(x + 10, y + 10, 40, 20, false);//画出坦克盖子
                g.fillOval(x + 20, y + 10, 20, 20);//画出圆形盖子
                g.drawLine(x + 30, y + 20, x, y + 20);//画出炮筒
                break;

            default:
                System.out.println("暂时不处理");

        }


    }


    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {//处理 w\d\s\a按下的情况
        if (e.getKeyCode() == KeyEvent.VK_W) {//
            //改变坦克方式为上
            hero.setDirect(0);
            hero.moveUp();
        } else if (e.getKeyCode() == KeyEvent.VK_D) {
            //改变坦克方式为右
            hero.setDirect(1);
            hero.moveRight();
        } else if (e.getKeyCode() == KeyEvent.VK_S) {
            //改变坦克方式为下
            hero.setDirect(2);
            hero.moveDown();
        } else if (e.getKeyCode() == KeyEvent.VK_A) {
            //改变坦克方式为左
            hero.setDirect(3);
            hero.moveLeft();
        }


        //如果用户按下J,就发射子弹,射击敌人子弹
        if (e.getKeyCode() == KeyEvent.VK_J) {
            hero.shoutEnemyTank();

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

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void run() { //每隔一定100ms时间自己重绘区域,子弹就会移动起来了

        while (true) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            this.repaint();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值