Java学习第四十七天<线程作业><坦克大战项目>
package chapter20.Homework;
import java.util.Scanner;
public class Homework01 {
public static void main(String[] args) {
A a = new A();
B b = new B(a);
a.start();
b.start();
}
}
class A extends Thread{
private boolean loop=true;
public void setLoop(boolean loop) {
this.loop = loop;
}
@Override
public void run() {
while (loop){
System.out.println((int)(Math.random()*100+1));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class B extends Thread{
private A a;
private Scanner scanner=new Scanner(System.in);
public B(A a) {//构造器中传入A对象 拿到loop属性
this.a = a;
}
@Override
public void run() {
while (true){
System.out.println("请输入:");
char key=scanner.next().toUpperCase().charAt(0);
if (key=='Q'){
a.setLoop(false);
System.out.println("B线程退出");
break;
}
}
}
}
public class Homework02 {
public static void main(String[] args) {
T t = new T();
new Thread(t).start();
new Thread(t).start();
}
}
class T implements Runnable{//多个线程共享资源,用Runnable实现
private int money =10000;
@Override
public void run() {
while (true){
synchronized (this){
if(money<1000){//在这实现线程同步,哪个线程争到this对象锁(非公平锁),执行代码块 争夺不到就会阻塞
System.out.println("余额不足");
break;
}
money-=1000;
System.out.println(Thread.currentThread().getName()+"取出1000剩余"+money);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
坦克大战
3 我方坦克发射子弹
package chapter19.TankGame03;
public class Tank {
private int x;
private int y;
private int direct;
private int speed;
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 int getY() {
return y;
}
public void moveUp(){
y-=speed;
}
public void moveRight(){
x+=speed;
}
public void moveLeft(){
x-=speed;
}
public void moveDown(){
y+=speed;
}
}
package chapter19.TankGame03;
import java.util.Vector;
public class Enemy extends Tank {
public Enemy(int x, int y) {
super(x, y);
}
}
package chapter19.TankGame03;
public class Hero extends Tank {
Shot shot=null;
public Hero(int x, int y) {
super(x, y);
}
public void shotEnemyTank(){
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(),2);
break;
case 3:
shot=new Shot(getX(),getY()+20,3);
break;
}
new Thread(shot).start();
}
}
package chapter19.TankGame03;
public class Shot implements Runnable{
int x;//子弹坐标
int y;
int direction=0;
int speed=10;
boolean isLive=true;
public Shot(int x, int y, int direction) {
this.x = x;
this.y = y;
this.direction = direction;
}
@Override
public void run() {
while (true){
//线程休眠,看到子弹运动
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
switch (direction){
case 0://向上
y-=speed;
break;
case 1://向右
x+=speed;
break;
case 2://向下
y+=speed;
break;
case 3://向上
x-=speed;
break;
}
System.out.println("子弹"+x+y);
if (!(x>=0&&x<=1000&&y>=0&&y<=750)){
isLive=false;
break;
}
}
}
}
package chapter19.TankGame03;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;
public class MyPanel extends JPanel implements KeyListener,Runnable {//监听键盘 为实现子弹重绘,要实现Runnable作为线程
//定义我的坦克
Hero hero=null;
Vector<Enemy> enemies=new Vector<>();
int enemySize=3;
public MyPanel() {
hero=new Hero(100,100);//初始化自己的坦克
hero.setSpeed(20);
for (int i=0;i<enemySize;i++){
Enemy enemy = new Enemy((100 * (i + 1)), 0);//先初始化再放容器内
enemy.setDirect(2);
enemies.add(enemy);
}
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.fillRect(0,0,1000,750);//填充矩形 默认黑色 画游戏黑色背景
drawTank(hero.getX(),hero.getY(),g,hero.getDirect(),1);
for (int i = 0; i <enemies.size() ; i++) {//考虑销毁后的数量
Enemy enemy = enemies.get(i);
drawTank(enemy.getX(),enemy.getY(),g,enemy.getDirect(),0);
}
if (hero.shot!=null&&hero.shot.isLive==true){
drawShot(hero.shot.x,hero.shot.y,g);
}
}
//编写方法,封装画坦克
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);//炮筒
g.setColor(Color.white);
for (int i = 1; i <6 ; i++) {
g.drawLine(x+2,y+10*i,x+8,y+10*i);
}
for (int i = 1; i <6 ; i++) {
g.drawLine(x+32,y+10*i,x+38,y+10*i);
}
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);
g.setColor(Color.white);
for (int i = 1; i <6 ; i++) {
g.drawLine(x+10*i,y+2,x+10*i,y+8);
}
for (int i = 1; i <6 ; i++) {
g.drawLine(x+10*i,y+32,x+10*i,y+38);
}
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);
g.setColor(Color.white);
for (int i = 1; i <6 ; i++) {
g.drawLine(x+2,y+10*i,x+8,y+10*i);
}
for (int i = 1; i <6 ; i++) {
g.drawLine(x+32,y+10*i,x+38,y+10*i);
}
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);
g.setColor(Color.white);
for (int i = 1; i <6 ; i++) {
g.drawLine(x+10*i,y+2,x+10*i,y+8);
}
for (int i = 1; i <6 ; i++) {
g.drawLine(x+10*i,y+32,x+10*i,y+38);
}
break;
default:
System.out.println("暂时没有处理");
}
}
public void drawShot(int x,int y,Graphics g){
g.fill3DRect(x,y,5,5,false);
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {//处理wdsa键按下情况
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();
}
if (e.getKeyCode()==KeyEvent.VK_J){
hero.shotEnemyTank();
}
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void run() {//每隔10ms重绘,刷新区域
while (true){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.repaint();
}
}
}
package chapter19.TankGame03;
import javax.swing.*;
public class TankGame03 extends JFrame {
MyPanel mp=null;//定义一个面板
public static void main(String[] args) {
TankGame03 tankGame01 = new TankGame03();
}
public TankGame03() {
mp=new MyPanel();//创建面板
this.add(mp);//放入窗口
this.setSize(1000,750);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.addKeyListener(mp);//让窗口监听键盘
new Thread(mp).start();
}
}
4 敌方发射子弹 敌方坦克消失 坦克爆炸 敌方坦克移动 控制坦克移动范围 坦克发射多发子弹 敌方移动发射 我方击中爆炸
package chapter19.TankGame04;
public class Tank {
private int x;
private int y;
private int direct;
private int speed;
boolean isLive=true;
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 int getY() {
return y;
}
public void moveUp(){
y-=speed;
}
public void moveRight(){
x+=speed;
}
public void moveLeft(){
x-=speed;
}
public void moveDown(){
y+=speed;
}
}
package chapter19.TankGame04;
import java.util.Vector;
public class Enemy extends Tank implements Runnable{
Vector<Shot> shots=new Vector<>();
boolean isLive=true;
public Enemy(int x, int y) {
super(x, y);
}
@Override
public void run() {
while (true){
if(isLive&&shots.size()==0){//shots中没子弹时候,创建一个子弹放入到shots集合并启动
Shot s=null;
//判断坦克方向,创建对弈子弹
switch (getDirect()){
case 0:
s = new Shot(getX() + 20, getY(), 0);
break;
case 1:
s = new Shot(getX() + 60, getY()+20, 1);
break;
case 2:
s = new Shot(getX() + 20, getY()+60, 2);
break;
case 3:
s = new Shot(getX(), getY()+20, 3);
break;
}
shots.add(s);
new Thread(s).start();
}
//根据坦克方向继续移动
switch (getDirect()){
case 0:
//保持一个方向走30步
for (int i = 0; i <30 ; i++) {
if (getY()>=0){//到边界就不能动
moveUp();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 1:
for (int i = 0; i <30 ; i++) {
if (getX()+60<1000){
moveRight();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 2:
for (int i = 0; i <30 ; i++) {
if (getY()+60<750){
moveDown();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 3:
for (int i = 0; i <30 ; 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;//退出线程
}
}
}
}
package chapter19.TankGame04;
import java.util.Vector;
public class Hero extends Tank {
Shot shot=null;
Vector<Shot> shots=new Vector<Shot>();//可发射多个子弹
public Hero(int x, int y) {
super(x, y);
}
public void shotEnemyTank(){
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(),2);
break;
case 3:
shot=new Shot(getX(),getY()+20,3);
break;
}
//新建的shot放到shots
shots.add(shot);
new Thread(shot).start();
}
}
package chapter19.TankGame04;
public class Shot implements Runnable{
int x;//子弹坐标
int y;
int direction=0;
int speed=10;
boolean isLive=true;
public Shot(int x, int y, int direction) {
this.x = x;
this.y = y;
this.direction = direction;
}
@Override
public void run() {
while (true){
//线程休眠,看到子弹运动
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
switch (direction){
case 0://向上
y-=speed;
break;
case 1://向右
x+=speed;
break;
case 2://向下
y+=speed;
break;
case 3://向上
x-=speed;
break;
}
System.out.println("子弹"+x+y);
if (!(x>=0&&x<=1000&&y>=0&&y<=750&&isLive)){
isLive=false;
System.out.println("子弹线程退出");
break;
}
}
}
}
package chapter19.TankGame04;
public class Bomb {
int x,y;
int life =20;//生命周期
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 chapter19.TankGame04;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;
public class MyPanel extends JPanel implements KeyListener,Runnable {//监听键盘 为实现子弹重绘,要实现Runnable作为线程
//定义我的坦克
Hero hero=null;
Vector<Enemy> enemies=new Vector<>();
//定义一个vector,用于存放炸弹//当子弹击中坦克时,加入一个炸弹到bombs
Vector<Bomb> bombs=new Vector<>();
int enemySize=3;
//定义三张图片显示爆炸效果
Image image1=null;
Image image2=null;
Image image3=null;
public MyPanel() {
hero=new Hero(500,100);//初始化自己的坦克
hero.setSpeed(20);
for (int i=0;i<enemySize;i++){
Enemy enemy = new Enemy((100 * (i + 1)), 0);//先初始化再放容器内
enemy.setDirect(2);
enemy.setSpeed(2);
//启动线程,动起来
new Thread(enemy).start();
Shot shot = new Shot(enemy.getX() + 20, enemy.getY() + 60, enemy.getDirect());//给敌人坦克加入子弹
enemy.shots.add(shot);
new Thread(shot).start();
enemies.add(enemy);
}
image1= Toolkit.getDefaultToolkit().getImage("D:/Documents/Pictures/Saved Pictures/111.png");
image2= Toolkit.getDefaultToolkit().getImage("D:/Documents/Pictures/Saved Pictures/222.png");
image3= Toolkit.getDefaultToolkit().getImage("D:/Documents/Pictures/Saved Pictures/333.png");
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.fillRect(0,0,1000,750);//填充矩形 默认黑色 画游戏黑色背景
if (hero!=null&&hero.isLive){
drawTank(hero.getX(),hero.getY(),g,hero.getDirect(),1);
}
for (int i = 0; i <enemies.size() ; i++) {//考虑销毁后的数量
Enemy enemy = enemies.get(i);
if (enemy.isLive){
drawTank(enemy.getX(),enemy.getY(),g,enemy.getDirect(),0);
for (int j = 0; j <enemy.shots.size() ; j++) {//画出所有子弹
Shot shot=enemy.shots.get(j);//取出子弹
if (shot.isLive){
drawShot(shot.x,shot.y,g);
}else {
enemy.shots.remove(shot);
}
}
}
}
for (int i = 0; i <hero.shots.size() ; i++) {//将hero的子弹集合shots遍历取出
Shot shot = hero.shots.get(i);
if (shot!=null&&shot.isLive==true){
drawShot(shot.x,shot.y,g);
}else {//如果shot对象已经无效,就从shots集合中销毁
hero.shots.remove(shot);
}
}
for (int i=0;i<bombs.size();i++){//如果bombs集合中有对象,就画出
Bomb bomb = bombs.get(i);
if (bomb.life>6){
g.drawImage(image1,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(image3,bomb.x,bomb.y,60,60,this);
}
bomb.lifeDown();//炸弹生命值减少
if (bomb.life==0){
bombs.remove(bomb);
}
}
}
//编写方法,封装画坦克
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);//炮筒
g.setColor(Color.white);
for (int i = 1; i <6 ; i++) {
g.drawLine(x+2,y+10*i,x+8,y+10*i);
}
for (int i = 1; i <6 ; i++) {
g.drawLine(x+32,y+10*i,x+38,y+10*i);
}
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);
g.setColor(Color.white);
for (int i = 1; i <6 ; i++) {
g.drawLine(x+10*i,y+2,x+10*i,y+8);
}
for (int i = 1; i <6 ; i++) {
g.drawLine(x+10*i,y+32,x+10*i,y+38);
}
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);
g.setColor(Color.white);
for (int i = 1; i <6 ; i++) {
g.drawLine(x+2,y+10*i,x+8,y+10*i);
}
for (int i = 1; i <6 ; i++) {
g.drawLine(x+32,y+10*i,x+38,y+10*i);
}
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);
g.setColor(Color.white);
for (int i = 1; i <6 ; i++) {
g.drawLine(x+10*i,y+2,x+10*i,y+8);
}
for (int i = 1; i <6 ; i++) {
g.drawLine(x+10*i,y+32,x+10*i,y+38);
}
break;
default:
System.out.println("暂时没有处理");
}
}
public void drawShot(int x,int y,Graphics g){
g.fill3DRect(x,y,5,5,false);
}
public void hitHero(){
//遍历所有坦克
for (int i = 0; i <enemies.size() ; i++) {
Enemy enemy = enemies.get(i);
for (int j = 0; j <enemy.shots.size() ; j++) {
Shot shot = enemy.shots.get(j);
//判断是否击中
if (hero.isLive&&shot.isLive){
hitTank(shot,hero);
}
}
}
}
public void hitEnemy(){
for (int i = 0; i <hero.shots.size() ; i++) {
Shot shot = hero.shots.get(i);
if (shot!=null&&shot.isLive){//判断是否击中敌人
for (int j = 0; j <enemies.size() ; j++) {
Enemy enemy = enemies.get(j);
hitTank(shot,enemy);
}
}
}
}
public void hitTank(Shot s,Tank tank){//判断子弹是否击中敌人
Bomb bomb=new Bomb(tank.getX(), tank.getY());
switch (tank.getDirect()){
case 0://向上
case 2://向下
if (s.x>=tank.getX()&&s.x<=tank.getX()+40&&s.y>=tank.getY()&&s.y<=tank.getY()+60){
s.isLive=false;
tank.isLive=false;
//子弹击中坦克,将坦克丛容器中除掉
enemies.remove(tank);
//创建炸弹对象,加入到bombs集合
bombs.add(bomb);
}
break;
case 1://向右
case 3://向左
if (s.x>=tank.getX()&&s.x<=tank.getX()+60&&s.y>=tank.getY()&&s.y<=tank.getY()+40){
s.isLive=false;
tank.isLive=false;
enemies.remove(tank);
//创建炸弹对象,加入到bombs集合
bombs.add(bomb);
}
break;
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {//处理wdsa键按下情况
if (e.getKeyCode()== KeyEvent.VK_W){