Day12-进程与线程补充

例题1

package com.lsq.study.锁;

import java.util.Scanner;

public class Demo03 {
   public static void main(String[] args) {
       PrintInteger_ printInteger = new PrintInteger_();
       new Thread(printInteger).start();
       InputApl inputApl = new InputApl(printInteger);
       inputApl.start();
  }
}

class PrintInteger_ implements Runnable{
   private boolean flag=true;

   public void setFlag(boolean flag) {
       this.flag = flag;
  }

   public void printRandom(){
       while (flag) {
           try {
               Thread.sleep(2000);
          } catch (InterruptedException e) {
               throw new RuntimeException(e);
          }
           synchronized (this) {
               System.out.println(Thread.currentThread().getName()+"当前整数为:" + (int) (Math.random() * 100 + 1));

          }
      }
  }

   @Override
   public void run() {
       printRandom();
  }
}

class InputApl extends Thread{
   private PrintInteger_ printInteger;
   private Scanner scanner=new Scanner(System.in);

   public InputApl(PrintInteger_ printInteger) {
       this.printInteger = printInteger;
  }

   @Override
   public void run() {
       while(true){
           System.out.println("请输入你的指令(Q)表示退出:"+Thread.currentThread().getName());
           char c = scanner.next().toUpperCase().charAt(0);
           if (c=='Q'){
               printInteger.setFlag(false);
               break;
          }
      }
  }
}
使用键盘监听的方式(只用了一个线程)
package com.lsq.study.锁;

import javafx.scene.input.KeyCode;
import jdk.nashorn.internal.runtime.regexp.JoniRegExp;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.security.Key;

public class Demo02 extends JFrame{
   KeyPress keyPress=null;
   static PrintInteger printInteger=null;
   public static void main(String[] args) {
       printInteger=new PrintInteger();
       new Thread(printInteger).start();
       Demo02 demo02 = new Demo02();
  }

   public Demo02(){
       keyPress=new KeyPress(printInteger);
       this.add(keyPress);
       this.addKeyListener(keyPress);
       this.setSize(400,400);
       this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       this.setVisible(true);
  }
}

class PrintInteger implements Runnable{
   private boolean flag=true;

   public void setFlag(boolean flag) {
       this.flag = flag;
  }

   public void printRandom(){
       while (flag) {
           try {
               Thread.sleep(1000);
          } catch (InterruptedException e) {
               throw new RuntimeException(e);
          }
           synchronized (this) {
               System.out.println(Thread.currentThread().getName()+"当前整数为:" + (int) (Math.random() * 100 + 1));

          }
      }
  }

   @Override
   public void run() {
       printRandom();
  }
}

class KeyPress extends JPanel implements KeyListener{
   PrintInteger printInteger;

   public KeyPress(PrintInteger printInteger) {
       this.printInteger = printInteger;
  }

   @Override
   public void paint(Graphics g) {
       super.paint(g);
       g.fillRect(0,0,700,500);
  }

   @Override
   public void keyTyped(KeyEvent e) {

  }

   @Override
   public void keyPressed(KeyEvent e) {
       if (e.getKeyCode()==KeyEvent.VK_Q){
           System.out.println(Thread.currentThread().getName()+"从键盘读取了Q命令");
           printInteger.setFlag(false);
      }
  }

   @Override
   public void keyReleased(KeyEvent e) {

  }
}

例题2

package com.lsq.study.锁;

import java.util.Currency;

public class Demo04 {
   public static void main(String[] args) {
       GetCardmoney getCardmoney = new GetCardmoney();
       Thread thread = new Thread(getCardmoney);
       thread.setName("用户1");
       thread.start();
       Thread thread1 = new Thread(getCardmoney);
       thread1.setName("用户2");
       thread1.start();
  }
}

class GetCardmoney implements Runnable{
   private int money=10000;
   private boolean loop=true;

   public void getMoney(){
       synchronized (this) {
           if (money < 1000) {
               System.out.println("余额不足,取款失败");
               loop = false;
               return;
          }
           money -= 1000;
           System.out.println(Thread.currentThread().getName() + "取出1000元,当前账户剩余" + money);
      }
       try {
           Thread.sleep(1000);
      } catch (InterruptedException e) {
           throw new RuntimeException(e);
      }
  }

   @Override
   public void run() {
       while (loop){
           getMoney();
      }
  }
}

例题3

坦克大战3.0

在坦克2.0的基础上增加了Shot(子弹类),除EnemyTanke、Tanke类,其余类全部做了修改

package com.lsq.study.坦克;

public class Shot implements Runnable{
  int x;
  int y;
  int direct=0;
  int speed = 2;

  boolean isLive=true; //子弹是否还存活

  public Shot(int x, int y, int direct) {
      this.x = x;
      this.y = y;
      this.direct = direct;
  }

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

  @Override
  public void run() {
      while (true) {
          try {
              Thread.sleep(50);
          } catch (InterruptedException e) {
              throw new RuntimeException(e);
          }
          switch (direct) {
              //子弹向上
              case 0:
                  y-=speed;
                  break;
              //子弹向右
              case 1:
                  x+=speed;
                  break;
              //子弹向下
              case 2:
                  y+=speed;
                  break;
              //子弹向左
              case 3:
                  x-=speed;
                  break;
          }
          System.out.println("x="+x+",y="+y);
          if (!(x>=0&&x<=1000&&y>=0&&y<=750)){
              isLive=false;
              break;
          }
      }
  }
}
package com.lsq.study.坦克;

//要画的坦克
public class Wenji extends Tanke{
  Shot shot=null;
  public Wenji(int x, int y) {
      super(x, y);
  }

//新增部分
  public void shotEnemyTank(){
      switch (getDrect()){
          //坦克向上
          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()+20, 3);
              break;
      }
      new Thread(shot).start();
  }
}
package com.lsq.study.坦克;

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

//绘图区(面板)
public class Panel extends JPanel implements KeyListener,Runnable{

  Wenji wenji = null;
  Vector<EnemyTanke> enemyTankes=new Vector<>();
  int enemyTankeSize=3;
  public Panel() {
      wenji = new Wenji(100, 100);
      wenji.setSpeed(5);
      for (int i = 0; i < enemyTankeSize; i++) {
          EnemyTanke enemyTanke = new EnemyTanke(100 * (i + 1), 0);
          enemyTanke.setDrect(2);
          enemyTankes.add(enemyTanke);
      }
  }

  @Override
  public void paint(Graphics g) {
      super.paint(g);
      g.fillRect(0, 0, 1000, 750);//填充矩形,默认黑色
      //画出自己的坦克
      drawTanke(wenji.getX(),wenji.getY(),g,wenji.getDrect(),1);
       
      //画出自己的子弹(新增部分)
      if (wenji.shot!=null&&wenji.shot.isLive==true) {
          g.fillOval(wenji.shot.x, wenji.shot.y, 2, 2);
      }

      //画出敌人坦克
      for (int i = 0; i < enemyTankeSize; i++) {
          EnemyTanke enemyTanke = enemyTankes.get(i);
          drawTanke(enemyTanke.getX(),enemyTanke.getY(),g,enemyTanke.getDrect(),0);
      }
  }

  //单独写一个画坦克的方法
  public void drawTanke(int x,int y,Graphics g,int drect,int type){
      switch (type){
          case 0://我方坦克
              g.setColor(Color.cyan);
              break;
          case 1://敌方坦克
              g.setColor(Color.orange);
              break;
      }

      //设置坦克的方向(0:向上,1:向右,2:向下,3:向左)
      switch (drect){
          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("暂时不做处理");
              break;
      }
  }

  @Override
  public void keyTyped(KeyEvent e) {
  }

  @Override
  public void keyPressed(KeyEvent e) {
      if (e.getKeyCode()==KeyEvent.VK_W){
          wenji.setDrect(0);
          wenji.moveUp();
      }else if (e.getKeyCode()==KeyEvent.VK_D){
          wenji.setDrect(1);
          wenji.moveRight();
      }else if (e.getKeyCode()==KeyEvent.VK_S){
          wenji.setDrect(2);
          wenji.moveDown();
      }else if (e.getKeyCode()==KeyEvent.VK_A){
          wenji.setDrect(3);
          wenji.moveLeft();
      }

      //新增部分
      if (e.getKeyCode()==KeyEvent.VK_J){
          wenji.shotEnemyTank();
      }
      this.repaint();
  }
   

  @Override
  public void keyReleased(KeyEvent e) {

  }

  //新增部分
  @Override
  public void run() {
      while (true) {
          try {
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              throw new RuntimeException(e);
          }
          this.repaint();
      }
  }
}
package com.lsq.study.坦克;

import javax.swing.*;

//窗口
public class TankeGame03 extends JFrame {
  Panel panel=null;
  public static void main(String[] args) {

      TankeGame03 tankeGame = new TankeGame03();
  }

  public TankeGame03(){
      panel=new Panel();
      new Thread(panel).start(); //新增部分
      this.add(panel);//把游戏的绘图区添加到到窗口
      this.addKeyListener(panel);
      this.setSize(1000,750);
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      this.setVisible(true);
  }
}

例题4

坦克大战4.0

除TankeGame04类,其余类全部变化

package com.lsq.study.坦克42;

public class Bomb {
  int x;
  int y;
  int life=9; //炸弹的生命周期,用于计算是否已消亡
  boolean isLive=true;

  public Bomb(int x, int y) {
      this.x = x;
      this.y = y;
  }

  //减少生命值
  public void lifeDown(){
      if (life>0){
          life--;
      }else {
          isLive=false;
      }
  }
}
package com.lsq.study.坦克42;

import sun.net.www.protocol.http.HttpURLConnection;

import java.util.Map;
import java.util.Vector;

public class EnemyTanke extends Tanke implements Runnable {

  Vector<Shot> shots = new Vector<>();
  boolean isLive = true;

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

  @Override
  public void run() {
      while (true) {
          //根据坦克的方向来随机移动
          switch (getDrect()) {
              case 0://向上
                  for (int i = 0; i < 70; i++) {
                      if (getY()>0) {
                          moveUp();
                      }
                  }
                  break;
              case 1://向右
                  for (int i = 0; i <70; i++) {
                      if (getX()+60<1000) {
                          moveRight();
                      }
                  }
                  break;
              case 2://向下
                  for (int i = 0; i < 70; i++) {
                      if (getY()+60<750) {
                          moveDown();
                      }
                  }
                  break;
              case 3://向左
                  for (int i = 0; i < 70; i++) {
                      if (getX()>0)
                      moveLeft();
                  }
                  break;
          }
          try {
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              throw new RuntimeException(e);
          }

          //然后随机改变坦克的方向
          setDrect((int)(Math.random()*4));
          if (!isLive){
              break;//退出线程
          }
      }
  }
}
package com.lsq.study.坦克42;

import javax.swing.*;
import javax.xml.stream.events.StartDocument;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;

//绘图区(面板)
public class Panel extends JPanel implements KeyListener,Runnable{

  Wenji wenji = null;
  Vector<EnemyTanke> enemyTankes=new Vector<>();
  //当子弹击中坦克是,加入一个Bomb对象到bombs
  Vector<Bomb> bombs=new Vector<>();
  int enemyTankeSize=3;

  //定义3张炸弹图片,用于显示爆炸效果
  Image image1=null;
  Image image2=null;
  Image image3=null;
  public Panel() {
      //初始化我方坦克
      wenji = new Wenji(100, 100);
      wenji.setSpeed(2);

      //初始化敌方坦克
      for (int i = 0; i < enemyTankeSize; i++) {
          EnemyTanke enemyTanke = new EnemyTanke(100 * (i + 1), 0);
          enemyTanke.setDrect(2);
          //启动坦克线程
          new Thread(enemyTanke).start();

          //给该enemyTank加入一个子弹
          Shot shot = new Shot(enemyTanke.getX() + 20, enemyTanke.getY() + 60, enemyTanke.getDrect());
          //加入enemyTank的Vector成员
          enemyTanke.shots.add(shot);
          //启动shot对象
          new Thread(shot).start();
          enemyTankes.add(enemyTanke);
      }

      image1=Toolkit.getDefaultToolkit().getImage(JPanel.class.getResource("/img1.png"));
      image2=Toolkit.getDefaultToolkit().getImage(JPanel.class.getResource("/img2.png"));
      image3=Toolkit.getDefaultToolkit().getImage(JPanel.class.getResource("/img3.png"));
  }

  @Override
  public void paint(Graphics g) {
      super.paint(g);
      g.fillRect(0, 0, 1000, 750);//填充矩形,默认黑色
      //画出自己的坦克
      drawTanke(wenji.getX(),wenji.getY(),g,wenji.getDrect(),1);

      //画出自己的子弹
      if (wenji.shot!=null&&wenji.shot.isLive==true) {
          g.fillOval(wenji.shot.x, wenji.shot.y, 2, 2);
      }

      //如果bombs集合中有对象就画出
      for (int i = 0; i < bombs.size(); i++) {
          Bomb bomb = bombs.get(i);
          if (bomb.life>6){
              g.drawImage(image3,bomb.x,bomb.y,60,60,this);
          }else if (bomb.life>3){
              g.drawImage(image2,bomb.x,bomb.y,60,60,this);
          }else{
              g.drawImage(image1,bomb.x,bomb.y,60,60,this);
          }
          bomb.lifeDown();
          //如果bomb life为0,就从bombs集合中删除
          if (bomb.life==0){
              bombs.remove(bomb);
          }
      }

      //画出敌人坦克
      for (int i = 0; i < enemyTankes.size(); i++) {
          EnemyTanke enemyTanke = enemyTankes.get(i);
          if (enemyTanke.isLive) { //当敌人坦克还活着的时候,我们才去画该坦克
              drawTanke(enemyTanke.getX(), enemyTanke.getY(), g, enemyTanke.getDrect(), 0);
              //画出敌人的子弹
              for (int j = 0; j < enemyTanke.shots.size(); j++) {
                  Shot shot = enemyTanke.shots.get(j);
                  if (shot.isLive == true) {
                      g.fillOval(shot.x, shot.y, 2, 2);
                  } else {
                      enemyTanke.shots.remove(shot);
                  }
              }
          }
      }
  }

  //单独写一个画坦克的方法
  public void drawTanke(int x,int y,Graphics g,int drect,int type){
      switch (type){
          case 0://我方坦克
              g.setColor(Color.cyan);
              break;
          case 1://敌方坦克
              g.setColor(Color.orange);
              break;
      }

      //设置坦克的方向(0:向上,1:向右,2:向下,3:向左)
      switch (drect){
          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("暂时不做处理");
              break;
      }
  }

  //编写方法,判断我方的子弹是否击中敌人坦克
  //什么时候判断我方的子弹是否击中敌人坦克
  public void hitTank(Shot s,EnemyTanke enemyTanke){
      switch (enemyTanke.getDrect()) {
          case 0:
          case 2:
          if (s.x >enemyTanke.getX()&&s.x<enemyTanke.getX()+40&&s.y>enemyTanke.getY()&&s.y<enemyTanke.getY()+60){
              s.isLive=false;
              enemyTanke.isLive=false;
              enemyTankes.remove(enemyTanke);
              Bomb bomb = new Bomb(enemyTanke.getX(), enemyTanke.getY());
              bombs.add(bomb);
          }
          break;
          case 1:
          case 3:
              if(s.x>enemyTanke.getX()&&s.x<enemyTanke.getX()+60&&s.y>enemyTanke.getY()&&s.y<enemyTanke.getY()+40){
                  s.isLive=false;
                  enemyTanke.isLive=false;
                  enemyTankes.remove(enemyTanke);
                  Bomb bomb = new Bomb(enemyTanke.getX(), enemyTanke.getY());
                  bombs.add(bomb);
              }
              break;
      }
  }

  @Override
  public void keyTyped(KeyEvent e) {
  }

  @Override
  public void keyPressed(KeyEvent e) {
      if (e.getKeyCode()==KeyEvent.VK_W){
          wenji.setDrect(0);
          wenji.moveUp();
      }else if (e.getKeyCode()==KeyEvent.VK_D){
          wenji.setDrect(1);
          wenji.moveRight();
      }else if (e.getKeyCode()==KeyEvent.VK_S){
          wenji.setDrect(2);
          wenji.moveDown();
      }else if (e.getKeyCode()==KeyEvent.VK_A){
          wenji.setDrect(3);
          wenji.moveLeft();
      }

      if (e.getKeyCode()==KeyEvent.VK_J){
          wenji.shotEnemyTank();
      }

      this.repaint();
  }

  @Override
  public void keyReleased(KeyEvent e) {

  }

  @Override
  public void run() {
      while (true) {
          try {
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              throw new RuntimeException(e);
          }
          //判断是否击中了敌人坦克
          if (wenji.shot!=null&&wenji.shot.isLive){//如果我的子弹还存活
              //遍历所有敌人的坦克
              for (int i = 0; i <enemyTankes.size(); i++) {
                  EnemyTanke enemyTanke = enemyTankes.get(i);
                  hitTank(wenji.shot,enemyTanke);
              }
          }
          this.repaint();
      }
  }
}
package com.lsq.study.坦克42;

public class Shot implements Runnable{
  int x;
  int y;
  int direct=0;
  int speed = 2;

  boolean isLive=true; //子弹是否还存活

  public Shot(int x, int y, int direct) {
      this.x = x;
      this.y = y;
      this.direct = direct;
  }

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

  @Override
  public void run() {
      while (true) {
          try {
              Thread.sleep(50);
          } catch (InterruptedException e) {
              throw new RuntimeException(e);
          }
          switch (direct) {
              //子弹向上
              case 0:
                  y-=speed;
                  break;
              //子弹向右
              case 1:
                  x+=speed;
                  break;
              //子弹向下
              case 2:
                  y+=speed;
                  break;
              //子弹向左
              case 3:
                  x-=speed;
                  break;
          }
          System.out.println("x="+x+",y="+y);
          //当子弹移动到面板的边界或敌人坦克时,把启动的子弹的线程销毁
          if (!(x>=0&&x<=1000&&y>=0&&y<=750&&isLive)){
              isLive=false;
              break;
          }
      }
  }
}
package com.lsq.study.坦克42;

public class Tanke {
  public int getSpeed() {
      return speed;
  }

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

  private int x;
  private int y;
  private int drect;

  private int speed=1;

  //private boolean isLive=true;

  public void moveUp(){
      y-=speed;
  }

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

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

  public void moveRight(){
      x+=speed;
  }

  public Tanke(int x, int y) {
      this.x = x;
      this.y = y;
  }
  public int getDrect() {
      return drect;
  }

  public void setDrect(int drect) {
      this.drect = drect;
  }

  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;
  }
}
package com.lsq.study.坦克42;

//要画的坦克
public class Wenji extends Tanke {
  Shot shot=null;
  public Wenji(int x, int y) {
      super(x, y);
  }

  public void shotEnemyTank(){
      switch (getDrect()){
          //坦克向上
          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()+20, 3);
              break;
      }
      new Thread(shot).start();
  }
}

例题5

除TankeGame05、Bomb、Shot、Tanke类,其余类全部变化

package com.lsq.study.坦克5;

import java.util.Vector;

public class EnemyTanke extends Tanke implements Runnable {

  Vector<Shot> shots = new Vector<>();
  boolean isLive = true;

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

  @Override
  public void run() {
      while (true) {
          if (isLive&&shots.size()<2){
              Shot shot=null;
              switch (getDrect()){
                  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()+20,3);
                      break;
              }
              shots.add(shot);
              new Thread(shot).start();
          }
          //根据坦克的方向来随机移动
          switch (getDrect()) {
              case 0://向上
                  for (int i = 0; i < 70; i++) {
                      if (getY()>0) {
                          moveUp();
                      }
                  }
                  break;
              case 1://向右
                  for (int i = 0; i <70; i++) {
                      if (getX()+60<1000) {
                          moveRight();
                      }
                  }
                  break;
              case 2://向下
                  for (int i = 0; i < 70; i++) {
                      if (getY()+60<750) {
                          moveDown();
                      }
                  }
                  break;
              case 3://向左
                  for (int i = 0; i < 70; i++) {
                      if (getX()>0)
                      moveLeft();
                  }
                  break;
          }
          try {
              Thread.sleep(2000);
          } catch (InterruptedException e) {
              throw new RuntimeException(e);
          }

          //然后随机改变坦克的方向
          setDrect((int)(Math.random()*4));
          if (!isLive){
              break;//退出线程
          }
      }
  }
}
package com.lsq.study.坦克5;

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

//绘图区(面板)
public class Panel extends JPanel implements KeyListener,Runnable{

  Wenji wenji = null;
  Vector<EnemyTanke> enemyTankes=new Vector<>();
  //当子弹击中坦克是,加入一个Bomb对象到bombs
  Vector<Bomb> bombs=new Vector<>();
  int enemyTankeSize=3;

  //定义3张炸弹图片,用于显示爆炸效果
  Image image1=null;
  Image image2=null;
  Image image3=null;
  public Panel() {
      //初始化我方坦克
      wenji = new Wenji(500, 100);
      wenji.setSpeed(1);

      //初始化敌方坦克
      for (int i = 0; i < enemyTankeSize; i++) {
          EnemyTanke enemyTanke = new EnemyTanke(100 * (i + 1), 0);
          enemyTanke.setDrect(2);
          //启动坦克线程
          new Thread(enemyTanke).start();

          //给该enemyTank加入一个子弹
          Shot shot = new Shot(enemyTanke.getX() + 20, enemyTanke.getY() + 60, enemyTanke.getDrect());
          //加入enemyTank的Vector成员
          enemyTanke.shots.add(shot);
          //启动shot对象
          new Thread(shot).start();
          enemyTankes.add(enemyTanke);
      }

      image1=Toolkit.getDefaultToolkit().getImage(JPanel.class.getResource("/img1.png"));
      image2=Toolkit.getDefaultToolkit().getImage(JPanel.class.getResource("/img2.png"));
      image3=Toolkit.getDefaultToolkit().getImage(JPanel.class.getResource("/img3.png"));
  }

  @Override
  public void paint(Graphics g) {
      super.paint(g);
      g.fillRect(0, 0, 1000, 750);//填充矩形,默认黑色
      //画出自己的坦克
      if (wenji!=null&&wenji.isLive) {
          drawTanke(wenji.getX(), wenji.getY(), g, wenji.getDrect(), 1);
      }
      //画出自己的子弹(设置最多可打5颗)
      for (int i = 0; i < wenji.shots.size(); i++) {
          Shot shot = wenji.shots.get(i);
          if (shot!=null&&shot.isLive==true) {
              g.fillOval(shot.x, shot.y, 2, 2);
          }else { //如果该shot对象已经无效,就把该对象从shots集合中移除
              wenji.shots.remove(shot);
          }
      }


      //如果bombs集合中有对象就画出
      for (int i = 0; i < bombs.size(); i++) {
          Bomb bomb = bombs.get(i);
          if (bomb.life>6){
              g.drawImage(image3,bomb.x,bomb.y,60,60,this);
          }else if (bomb.life>3){
              g.drawImage(image2,bomb.x,bomb.y,60,60,this);
          }else{
              g.drawImage(image1,bomb.x,bomb.y,60,60,this);
          }
          bomb.lifeDown();
          //如果bomb life为0,就从bombs集合中删除
          if (bomb.life==0){
              bombs.remove(bomb);
          }
      }

      //画出敌人坦克
      for (int i = 0; i < enemyTankes.size(); i++) {
          EnemyTanke enemyTanke = enemyTankes.get(i);
          if (enemyTanke.isLive) { //当敌人坦克还活着的时候,我们才去画该坦克
              drawTanke(enemyTanke.getX(), enemyTanke.getY(), g, enemyTanke.getDrect(), 0);
              //画出敌人的子弹
              for (int j = 0; j < enemyTanke.shots.size(); j++) {
                  Shot shot = enemyTanke.shots.get(j);
                  if (shot.isLive == true) {
                      g.fillOval(shot.x, shot.y, 2, 2);
                  } else {
                      enemyTanke.shots.remove(shot);
                  }
              }
          }
      }
  }

  //单独写一个画坦克的方法
  public void drawTanke(int x,int y,Graphics g,int drect,int type){
      switch (type){
          case 0://我方坦克
              g.setColor(Color.cyan);
              break;
          case 1://敌方坦克
              g.setColor(Color.orange);
              break;
      }

      //设置坦克的方向(0:向上,1:向右,2:向下,3:向左)
      switch (drect){
          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("暂时不做处理");
              break;
      }
  }

  //如果我们的坦克可以发射多颗子弹在判断我方子弹是否击中敌人坦克时,就需要把我们的子弹集合中
  //所有的子弹都取出和敌人的所有坦克进行判断
  public void hitEnemyTank(){
      for (int i = 0; i < wenji.shots.size(); i++) {
          Shot shot = wenji.shots.get(i);
          if (shot!=null&&shot.isLive){//如果我的子弹还存活
              //遍历所有敌人的坦克
              for (int j = 0; j <enemyTankes.size(); j++) {
                  EnemyTanke enemyTanke = enemyTankes.get(j);
                  hitTank(shot,enemyTanke);
              }
          }
      }

  }

  //编写方法,判断我方的子弹是否击中敌人坦克
  //什么时候判断我方的子弹是否击中敌人坦克
  public void hitTank(Shot s, Tanke enemyTanke){
      switch (enemyTanke.getDrect()) {
          case 0:
          case 2:
          if (s.x >enemyTanke.getX()&&s.x<enemyTanke.getX()+40&&s.y>enemyTanke.getY()&&s.y<enemyTanke.getY()+60){
              s.isLive=false;
              enemyTanke.isLive=false;
              enemyTankes.remove(enemyTanke);
              Bomb bomb = new Bomb(enemyTanke.getX(), enemyTanke.getY());
              bombs.add(bomb);
          }
          break;
          case 1:
          case 3:
              if(s.x>enemyTanke.getX()&&s.x<enemyTanke.getX()+60&&s.y>enemyTanke.getY()&&s.y<enemyTanke.getY()+40){
                  s.isLive=false;
                  enemyTanke.isLive=false;
                  enemyTankes.remove(enemyTanke);
                  Bomb bomb = new Bomb(enemyTanke.getX(), enemyTanke.getY());
                  bombs.add(bomb);
              }
              break;
      }
  }

  //编写方法判断敌人的坦克是否击中我的坦克
  public void hitWenji(){
      //遍历所有的敌人坦克
      for (int i = 0; i <enemyTankes.size() ; i++) {
          EnemyTanke enemyTanke = enemyTankes.get(i);
          for (int j = 0; j < enemyTanke.shots.size(); j++) {
              Shot shot = enemyTanke.shots.get(j);
              if (wenji.isLive&&shot.isLive)
              hitTank(shot,wenji);
          }
      }
  }

  @Override
  public void keyTyped(KeyEvent e) {
  }

  @Override
  public void keyPressed(KeyEvent e) {
      if (e.getKeyCode()==KeyEvent.VK_W){
          wenji.setDrect(0);
          wenji.moveUp();
      }else if (e.getKeyCode()==KeyEvent.VK_D){
          wenji.setDrect(1);
          wenji.moveRight();
      }else if (e.getKeyCode()==KeyEvent.VK_S){
          wenji.setDrect(2);
          wenji.moveDown();
      }else if (e.getKeyCode()==KeyEvent.VK_A){
          wenji.setDrect(3);
          wenji.moveLeft();
      }

      if (e.getKeyCode()==KeyEvent.VK_J){
          //判断wenji的子弹是否销毁
//           if (wenji.shot==null||!wenji.shot.isLive) {
//               wenji.shotEnemyTank();
//           }

          //发射多颗子弹
          wenji.shotEnemyTank();
      }

      this.repaint();
  }

  @Override
  public void keyReleased(KeyEvent e) {

  }

  @Override
  public void run() {
      while (true) {
          try {
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              throw new RuntimeException(e);
          }
          //判断是否击中了敌人坦克
          hitEnemyTank();

          //判断敌人的坦克是否击中了我们的坦克
          hitWenji();
          this.repaint();
      }
  }
}
package com.lsq.study.坦克5;

import java.util.Vector;

//要画的坦克
public class Wenji extends Tanke {
  Shot shot=null;
  Vector<Shot> shots=new Vector<>();
  public Wenji(int x, int y) {
      super(x, y);
  }

  public void shotEnemyTank(){
      if (shots.size() == 5) {
          return;
      }
      switch (getDrect()){
          //坦克向上
          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()+20, 3);
              break;
      }
      shots.add(shot);
      new Thread(shot).start();
  }
}
posted @ 2023-07-09 00:58  仓鼠的气垫床  阅读(3)  评论(0编辑  收藏  举报