这个类是坦克的大战的绘图区域,实现功能最也最为的复杂,这个类用到了java的绘图
简单的学习这个绘图原理的使用
public class DrawCircle extends JFrame{//JFrame对应的窗口,可以理解为一个画框
//定义一个面板
private MyPanel mp = null;
public static void main(String[] args) {
new DrawCircle();
}
public DrawCircle(){
//初始化面板
mp = new MyPanel();//构造器
//把我们的面板放入我们的窗口
this.add(mp);
//设置窗口的大小
this.setSize(400,300);
//可以显示
this.setVisible(true);
//当点击窗口的小x,程序完全退出
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
//1.首先定义一个面板MyPanel,继承JPanel类,画图形,就在面板上画
class MyPanel extends JPanel{
//说明:
//1.MyPanel 对象就是一个画板
//2.Graphics g 把g理解为一个画笔
//3.Graphics 提供了很多绘图的方法
@Override
public void paint(Graphics g){//绘图方法
super.paint(g);
//画出一个圆
g.drawOval(10,10,10,100);
}
}
package tankgame3;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;
/**
* 坦克大战的绘图区域
*/
//为了监听键盘事件,实现KeyLister
public class MyPanel extends JPanel implements KeyListener, Runnable {
//定义我的坦克
private int hitNums;
private Hero hero = null;
private Boolean flag = false;
//定义敌人的坦克
Vector anemyTanks = new Vector<>();
//定义一个存放 Node对象的 Vector,用来存放继续游戏时的坦克
Vector nodes = Recorder.getNodesAndAanemyNums();
//定义Vector用于存放炸弹
//说明,当子弹击中坦克时,加入Bomb对象到Bombs
Vector bombs = new Vector<>();
//定义三张图片用于爆炸效果
Image image1 = null;
Image image2 = null;
Image image3 = null;
public MyPanel(String key){
//传入 anemyTanks 并记录
Recorder.setAnemyTanks(anemyTanks);
//初始化自己坦克
hero = new Hero(50,600);
// 判断是重新开始,还是继续游戏
switch (key){
case "1"://重新开始
//
Recorder.setHitTankNums(0);
//初始化敌人坦克
for (int i = 0; i < 5; i++) {
//创建一个敌人坦克
AnemyTank anemyTank = new AnemyTank((100 * (i + 1)), 0);
//将 anemyTanks设置个AnemyTank
anemyTank.setAnemyTanks(anemyTanks);
//设置方向
anemyTank.setDirect(2);
//启动敌方坦克
Thread thread = new Thread(anemyTank);
thread.start();
//给anemyTank加入一个子弹
Shot shot = new Shot(anemyTank.getX() + 20, anemyTank.getY() + 60, anemyTank.getDirect());
//加入enemyTank的Vector成员
anemyTank.getShots().add(shot);
//启动shot对象
new Thread(shot).start();
anemyTanks.add(anemyTank);
}
break;
case "2"://继续游戏
for (int i = 0; i < nodes.size(); i++) {
Node node = nodes.get(i);
//创建一个敌人坦克
AnemyTank anemyTank = new AnemyTank(node.getX(), node.getY());
//将 anemyTanks设置个AnemyTank
anemyTank.setAnemyTanks(anemyTanks);
//设置方向
anemyTank.setDirect(node.getDireact());
//启动敌方坦克
Thread thread = new Thread(anemyTank);
thread.start();
//给anemyTank加入一个子弹
Shot shot = new Shot(anemyTank.getX() + 20, anemyTank.getY() + 60, anemyTank.getDirect());
//加入enemyTank的Vector成员
anemyTank.getShots().add(shot);
//启动shot对象
new Thread(shot).start();
anemyTanks.add(anemyTank);
}
break;
default:
System.out.println("你输入的有误:");
}
//初始化图片对象
image1 = Toolkit.getDefaultToolkit().getImage(MyPanel.class.getResource("/3.png"));
image2 = Toolkit.getDefaultToolkit().getImage(MyPanel.class.getResource("/2.png"));
image3 = Toolkit.getDefaultToolkit().getImage(MyPanel.class.getResource("/1.png"));
}
//编写方法,显示我方击落敌方坦克的信息
public void showHitInfo(Graphics g){
//画出玩家的总成绩
g.setColor(Color.black);
Font font = new Font("宋体", Font.BOLD, 18);
g.setFont(font);
g.drawString("你累计击败敌方坦克", 810,30 );
drawTank(820, 60, g, 0, 0);//画出个敌方坦克
g.setColor(Color.black);//这里需要重新获取黑色
g.drawString(String.valueOf(Recorder.getHitTankNums()), 900, 100);
}
@Override
public void
paint(Graphics g) {
super.paint(g);
g.fillRect(0,0,800, 750);//填充矩形,默认黑色
showHitInfo(g);
if (hero != null && hero.isLife()){
//画出坦克--封装方法
drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 1);
}
//将hero中的shots集合遍历取出绘制,发射多颗子弹
for (int i = 0; i < hero.getShots().size(); i++) {
Shot shot = hero.getShots().get(i);
if (shot != null && shot.isLive()){
g.setColor(Color.blue);
g.fill3DRect(shot.getX(),shot.getY(), 10, 10, false);
}else {//如果子弹已经失效,移除
hero.getShots().remove(shot);
}
}
//画出敌人的坦克
for (int i = 0; i < anemyTanks.size(); i++){
//取出坦克
AnemyTank anemyTank = this.anemyTanks.get(i);
//判断当前的坦克是否存活
if (anemyTank.isLive()){//当敌人坦克是存活的
drawTank(anemyTank.getX(), anemyTank.getY(), g, anemyTank.getDirect(), 0);
//取出enemyTank所有子弹
for (int j = 0; j < anemyTank.getShots().size(); j++){
//取出子弹准备绘制
Shot shot = anemyTank.getShots().get(j);
//绘制
if (shot.isLive()){//isLive == true;
g.draw3DRect(shot.getX(), shot.getY(), 5, 5, false);
}else {
//移除子弹
anemyTank.getShots().remove(shot);
}
}
}
}
//如果bombs集合中有对象,就画出
for (int i = 0; i < bombs.size(); i++) {
//取出炸弹
Bomb bomb = bombs.get(i);
//根据当前bomb对象的life去画出对应的图像
if (bomb.getLife() > 6){
g.drawImage(image1, bomb.getX(), bomb.getY(), 60, 60, this);
}else if (bomb.getLife() > 3){
g.drawImage(image2, bomb.getX(), bomb.getY(), 60, 60, this);
}else {
g.drawImage(image3, bomb.getX(), bomb.getY(), 60, 60, this);
}
//让这个炸弹的生命值减少
bomb.lifeDown();
//如果bomb life为0,就从bombs的集合中删除
if (bomb.getLife() == 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;
}
//根据坦克方向来绘制坦克
//direct表示方向(0:向上 1:向右 2:向下 3:向左)
//
switch (direct){
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.fill3DRect(x+18,y,4,20,false);
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.fill3DRect(x+30,y+18,30,4,false);
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.fill3DRect(x+18,y+30,4,30,false);
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.fill3DRect(x,y+18,30,4,false);
break;
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
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){
System.out.println("用户按下了J,开始射击");
// 发射一颗子弹
// if (hero.getShot() == null || !hero.getShot().isLive()){
// hero.shotEnemyTank();
// }
//发射多颗子弹
hero.shotEnemyTank();
}
this.repaint();
}
//判断敌方坦克打到我方坦克
public void hitMyTank(){
//遍历所有的敌方坦克
for (int i = 0; i < anemyTanks.size(); i++) {
//取出敌方坦克
AnemyTank anemyTank = anemyTanks.get(i);
//遍历他的所有子弹
for(int j = 0; j < anemyTank.getShots().size(); j++){
Shot s = anemyTank.getShots().get(j);
//判断shot是否击中我方的坦克
if(hero.isLife() && s.isLive()){
hitTank(s, hero);
}
}
}
}
//如果我们可以发射多颗子弹
//在判断我方的坦克是否命中敌人时,需要把所有子弹遍历出来,挨个判断
//编写方法,判断我方的坦克是否命中目标
//什么时候判断我方坦克击中敌方的坦克
public void hitTank(Shot s, Tank tank){
switch (tank.getDirect()){
case 0://方向为上
if (s.getX() > tank.getX() && s.getX() < tank.getX() + 40
&& s.getY() > tank.getY() && s.getY() <= tank.getY() + 60
){
s.setLive(false);
tank.setLife(false);
//当我的子弹击中敌人的坦克后,将tank拿掉就可以了
anemyTanks.remove(tank);
//当我方击毁一个敌方坦克时,进行数据更改
if (tank instanceof AnemyTank){
Recorder.addHitTankNums();
}
//创建Bomb对象,加入到Bombs集合中来
Bomb bomb = new Bomb(tank.getX(),tank.getY());
bombs.add(bomb);
}
break;
case 1://方向为右
if (s.getX() > tank.getX() && s.getX() < tank.getX() + 60
&& s.getY() > tank.getY() && s.getY() < tank.getY() + 40
){
s.setLive(false);
tank.setLife(false);
//当我的子弹击中敌人的坦克后,将tank拿掉就可以了
anemyTanks.remove(tank);
//当我方击毁一个敌方坦克时,进行数据更改
if (tank instanceof AnemyTank){
Recorder.addHitTankNums();
}
//创建Bomb对象,加入到Bombs集合中来
Bomb bomb = new Bomb(tank.getX(),tank.getY());
bombs.add(bomb);
}
break;
case 2://方向为下
if (s.getX() > tank.getX() && s.getX() < tank.getX() + 60
&& s.getY() > tank.getY() && s.getY() <= tank.getY() + 40
){
s.setLive(false);
tank.setLife(false);
//当我的子弹击中敌人的坦克后,将tank拿掉就可以了
anemyTanks.remove(tank);
//当我方击毁一个敌方坦克时,进行数据更改
if (tank instanceof AnemyTank){
Recorder.addHitTankNums();
}
//创建Bomb对象,加入到Bombs集合中来
Bomb bomb = new Bomb(tank.getX(),tank.getY());
bombs.add(bomb);
}
break;
case 3:
if (s.getX() > tank.getX() && s.getX() < tank.getX() + 40
&& s.getY() > tank.getY() && s.getY() < tank.getY() + 60
){
s.setLive(false);
tank.setLife(false);
//当我的子弹击中敌人的坦克后,将tank拿掉就可以了
anemyTanks.remove(tank);
//当我方击毁一个敌方坦克时,进行数据更改
if (tank instanceof AnemyTank){
Recorder.addHitTankNums();
}
//创建Bomb对象,加入到Bombs集合中来
Bomb bomb = new Bomb(tank.getX(),tank.getY());
bombs.add(bomb);
}
break;
}
}
public void hitAnemyTank(){
for (int i = 0; i < hero.getShots().size(); i++) {
Shot shot = hero.getShots().get(i);
//判断是否击中敌人的坦克
if (shot != null && shot.isLive()) {//当我的子弹还活着
//遍历敌人所有的坦克
for (int j = 0; j < anemyTanks.size(); j++) {
AnemyTank anemyTank = anemyTanks.get(j);
hitTank(shot, anemyTank);
}
}
}
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void run() {
//每隔100毫秒,重绘区域
while (true){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//判断我方子弹是否击中敌方的 坦克
hitAnemyTank();
hitMyTank();
this.repaint();
}
}
}
package tankgame3;
import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Scanner;
public class WwyTankGame1 extends JFrame {
//定义一个MyPanel
private MyPanel mp = null;
static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
WwyTankGame1 wwyTankGame = new WwyTankGame1();
}
public WwyTankGame1(){
System.out.println("请输入选择: 1.新游戏 2.继续上局");
String key = scanner.next();
mp = new MyPanel(key);
//开启多线程
Thread thread = new Thread(mp);
thread.start();
this.add(mp);//绘图区域
this.setSize(1000,750);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.addKeyListener(mp);
//在JFrame 中增加相应关闭窗口的处理
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
Recorder.keepRecord();
System.exit(0);
}
});
}
}
package tankgame3;
import java.util.Vector;
public class AnemyTank extends Tank implements Runnable{
private boolean isLive = true;
//炮弹
private Vector shots = new Vector<>();
//获取所有的敌人的坦克
private Vector anemyTanks = new Vector<>();
public AnemyTank(int x, int y) {
super(x, y);
}
public Vector getShots() {
return shots;
}
public boolean isLive() {
return isLive;
}
public void setLive(boolean live) {
isLive = live;
}
public void setShots(Vector shots) {
this.shots = shots;
}
public Vector getAnemyTanks() {
return anemyTanks;
}
//这里提供一个方法,可以将 Mypanel 的成员 anemyTanks 成员变量设置到本类
public void setAnemyTanks(Vector anemyTanks) {
this.anemyTanks = anemyTanks;
}
//编写方法,判断当前这个敌人的坦克,是否和 anemyTanks 中的其他坦克发生重叠或者碰撞
public boolean isTouchAnemyTank(){
//判断当前敌人坦克的方向(this)方向
switch (this.getDirect()){
case 0://上
//让当前坦克和所有的敌人坦克比较
for (int i = 0; i < anemyTanks.size(); i++) {
//从vector取出一个坦克来
AnemyTank anemyTank = anemyTanks.get(i);
//不和自己比较
if (anemyTank != this){
//如果敌人坦克是上下
//敌人的位置坐标x:[anemyTank.getX(), anemyTank.getX() + 40]
// y:[anemyTank.getY(), nemyTank.getY() + 60]
if (anemyTank.getDirect() == 0 || anemyTank.getDirect() == 2){
//敌人坦克左上坐标
if (this.getX() >= anemyTank.getX()
&& this.getX() <= anemyTank.getX() + 40
&& this.getY() >= anemyTank.getY()
&& this.getY() <= anemyTank.getY() + 60) {
return true;
}
//敌人坦克右下的坐标
if (this.getX() + 40 >= anemyTank.getX()
&& this.getX() + 40 <= anemyTank.getX() + 40
&& this.getY() >= anemyTank.getY()
&& this.getY() <= anemyTank.getY() + 60) {
return true;
}
}
//如果敌人的坦克是左右
if (anemyTank.getDirect() == 1 || anemyTank.getDirect() == 3){
//敌人坦克左上坐标
if (this.getX() >= anemyTank.getX()
&& this.getX() <= anemyTank.getX() + 60
&& this.getY() >= anemyTank.getY()
&& this.getY() <= anemyTank.getY() + 40) {
return true;
}
//敌人坦克左下的坐标
if (this.getX() + 40 >= anemyTank.getX()
&& this.getX() + 40 <= anemyTank.getX() + 60
&& this.getY() >= anemyTank.getY()
&& this.getY() <= anemyTank.getY() + 40) {
return true;
}
}
}
}
case 1:
//让当前坦克和所有的敌人坦克比较
for (int i = 0; i < anemyTanks.size(); i++) {
//从vector取出一个坦克来
AnemyTank anemyTank = anemyTanks.get(i);
//不和自己比较
if (anemyTank != this){
//如果敌人坦克是上下
//敌人的位置坐标x:[anemyTank.getX(), anemyTank.getX() + 40]
// y:[anemyTank.getY(), nemyTank.getY() + 60]
if (anemyTank.getDirect() == 0 || anemyTank.getDirect() == 2){
//敌人坦克右上坐标
if (this.getX() + 60 >= anemyTank.getX()
&& this.getX() + 60 <= anemyTank.getX() + 40
&& this.getY() >= anemyTank.getY()
&& this.getY() <= anemyTank.getY() + 60) {
return true;
}
//敌人坦克右下的坐标
if (this.getX() + 60 >= anemyTank.getX()
&& this.getX() + 60 <= anemyTank.getX() + 40
&& this.getY() + 40 >= anemyTank.getY()
&& this.getY() + 40 <= anemyTank.getY() + 60) {
return true;
}
}
//如果敌人的坦克是左右
if (anemyTank.getDirect() == 1 || anemyTank.getDirect() == 3){
//敌人坦克右上边坐标
if (this.getX() + 60 >= anemyTank.getX()
&& this.getX() +60 <= anemyTank.getX() + 60
&& this.getY() + 60 >= anemyTank.getY()
&& this.getY() <= anemyTank.getY() + 40) {
return true;
}
//敌人坦克右下的坐标
if (this.getX() + 60 >= anemyTank.getX()
&& this.getX() + 60 <= anemyTank.getX() + 60
&& this.getY() + 40 >= anemyTank.getY()
&& this.getY() + 40 <= anemyTank.getY() + 40) {
return true;
}
}
}
}
case 2:
//让当前坦克和所有的敌人坦克比较
for (int i = 0; i < anemyTanks.size(); i++) {
//从vector取出一个坦克来
AnemyTank anemyTank = anemyTanks.get(i);
//不和自己比较
if (anemyTank != this){
//如果敌人坦克是上下
//敌人的位置坐标x:[anemyTank.getX(), anemyTank.getX() + 40]
// y:[anemyTank.getY(), nemyTank.getY() + 60]
if (anemyTank.getDirect() == 0 || anemyTank.getDirect() == 2){
//敌人坦克左下坐标
if (this.getX() >= anemyTank.getX()
&& this.getX() <= anemyTank.getX() + 40
&& this.getY() + 60 >= anemyTank.getY()
&& this.getY() + 60 <= anemyTank.getY() + 60) {
return true;
}
//敌人坦克右下的坐标
if (this.getX() + 40 >= anemyTank.getX()
&& this.getX() + 40 <= anemyTank.getX() + 40
&& this.getY() + 60 >= anemyTank.getY()
&& this.getY() + 60 <= anemyTank.getY() + 60) {
return true;
}
}
//如果敌人的坦克是左右
if (anemyTank.getDirect() == 1 || anemyTank.getDirect() == 3){
//敌人坦克左边坐标
if (this.getX() >= anemyTank.getX()
&& this.getX() <= anemyTank.getX() + 60
&& this.getY() + 60 >= anemyTank.getY()
&& this.getY() + 60 <= anemyTank.getY() + 40) {
return true;
}
//敌人坦克右边的坐标
if (this.getX() + 40 >= anemyTank.getX()
&& this.getX() + 40 <= anemyTank.getX() + 60
&& this.getY() + 60 >= anemyTank.getY()
&& this.getY() + 60 <= anemyTank.getY() + 40) {
return true;
}
}
}
}
case 3:
//让当前坦克和所有的敌人坦克比较
for (int i = 0; i < anemyTanks.size(); i++) {
//从vector取出一个坦克来
AnemyTank anemyTank = anemyTanks.get(i);
//不和自己比较
if (anemyTank != this){
//如果敌人坦克是上下
//敌人的位置坐标x:[anemyTank.getX(), anemyTank.getX() + 40]
// y:[anemyTank.getY(), nemyTank.getY() + 60]
if (anemyTank.getDirect() == 0 || anemyTank.getDirect() == 2){
//敌人坦克左上坐标
if (this.getX() >= anemyTank.getX()
&& this.getX() <= anemyTank.getX() + 40
&& this.getY() >= anemyTank.getY()
&& this.getY() <= anemyTank.getY() + 60) {
return true;
}
//敌人坦克左下的坐标
if (this.getX() >= anemyTank.getX()
&& this.getX() <= anemyTank.getX() + 40
&& this.getY() + 40 >= anemyTank.getY()
&& this.getY() + 40 <= anemyTank.getY() + 60) {
return true;
}
}
//如果敌人的坦克是左右
if (anemyTank.getDirect() == 1 || anemyTank.getDirect() == 3){
//敌人坦克左上坐标
if (this.getX() >= anemyTank.getX()
&& this.getX() <= anemyTank.getX() + 60
&& this.getY() >= anemyTank.getY()
&& this.getY() <= anemyTank.getY() + 40) {
return true;
}
//敌人坦克左下的坐标
if (this.getX() >= anemyTank.getX()
&& this.getX() <= anemyTank.getX() + 60
&& this.getY() + 40 >= anemyTank.getY()
&& this.getY() + 40 <= anemyTank.getY() + 40) {
return true;
}
}
}
}
}
return false;
}
@Override
public void run() {
while(true){
//如果一个子弹都没有就new一个
//并启动
if (isLive && getShots().size() < 2){
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() - 60, getY() + 20, 3);
break;
}
getShots().add(s);
new Thread(s).start();
}
//根据坦克的方向继续移动
switch (getDirect()){
case 0://向上
for (int i = 0; i < 30; i++) {
if (getY() > 0 && !isTouchAnemyTank() ) {
moveUp();
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 1://向右
for (int i = 0; i < 30; i++) {
if (getX() < 800 && !isTouchAnemyTank()){
moveRight();
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 2://向下
for (int i = 0; i < 30; i++) {
if (getY() < 750 && !isTouchAnemyTank()) {
moveDown();
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 3://向左
for (int i = 0; i < 30; i++) {
if (getX() > 0 && !isTouchAnemyTank())
moveLeft();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
}
//休眠50毫秒
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//然后随机的改变
setDirect((int)(Math.random() * 4));
//写多线程时,一定要考虑到线程什么时候结束
if (!isLive){
break;
}
}
}
}
package tankgame3;
public class Bomb {
private int x, y;//炸弹的坐标
private int life = 9;//炸弹的生命周期
private boolean isLife = true;
public Bomb(int x, int y) {
this.x = x;
this.y = y;
}
//减少生命值
public void lifeDown(){
if(life > 0){
life--;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
isLife = false;
}
}
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 getLife() {
return life;
}
public void setLife(int life) {
this.life = life;
}
public boolean isLife() {
return isLife;
}
public void setLife(boolean life) {
isLife = life;
}
}
package tankgame3;
import java.io.*;
import java.util.Vector;
/**
* 该类记录文件信息和文件交互
*/
public class Recorder {
//定义变量记录我方击毁敌人坦克数
private static int hitTankNums = 0;
//定义IO对象
private static BufferedWriter bw = null;
private static BufferedReader br = null;
private static String recordFile = "d:\\xiangmu\\abc\\a.txt";
private static Vector anemyTanks = null;
//定义一个node 的Vector,用于恢复信息
private static Vector nodes = new Vector<>();
//添加一个方法,用于读取recordFile,恢复相关的信息
public static Vector getNodesAndAanemyNums(){
try {
br = new BufferedReader(new FileReader(recordFile));
//循环读取文件,生成 nodes 集合
String line = "";//255 40 0
while ((line = br.readLine()) != null){
String[] s = line.split(" ");
if (s.length == 3){
Node node = new Node(Integer.parseInt(s[0]), Integer.parseInt(s[1]), Integer.parseInt(s[2]));
nodes.add(node);
}else if (s.length == 1){
line = s[0];
int hitTankNums = Integer.parseInt(line);
setHitTankNums(hitTankNums);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return nodes;
}
//添加一个方法,当游戏退出时,将hitTankNums 保存到 recordFile;
public static void keepRecord(){
try {
bw = new BufferedWriter(new FileWriter(recordFile));
//记录每个存活的敌方坦克
for (int i = 0; i < anemyTanks.size(); i++) {
AnemyTank anemyTank = anemyTanks.get(i);
if (anemyTank.isLive()){
bw.write(anemyTank.getX() + " " +anemyTank.getY() + " " + anemyTank.getDirect() + "\r\n");
}
}
bw.write(hitTankNums + "\r\n");
} catch (IOException e) {
e.printStackTrace();
}finally {
if (bw != null){
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static int getHitTankNums() {
return hitTankNums;
}
public static Vector getAnemyTanks() {
return anemyTanks;
}
public static void setAnemyTanks(Vector anemyTanks) {
Recorder.anemyTanks = anemyTanks;
}
public static void setHitTankNums(int hitTankNums) {
Recorder.hitTankNums = hitTankNums;
}
public static void addHitTankNums(){
Recorder.hitTankNums++;
}
}
package tankgame3;
/**
* 用来记录上次游戏结束的坦克的信息,用来实现继续游戏
*/
public class Node {
private int x;
private int y;
private int direact;
public Node(int x, int y, int direact) {
this.x = x;
this.y = y;
this.direact = direact;
}
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 getDireact() {
return direact;
}
public void setDireact(int direact) {
this.direact = direact;
}
}
package tankgame3;
/**
* 子弹类
*/
public class Shot implements Runnable{
private int x;//子弹的横坐标
private int y;//子弹的纵坐标
private int direct;//子弹的方向
private int speed = 5;//子弹的速度
private 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;
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
public boolean isLive() {
return isLive;
}
public void setLive(boolean live) {
isLive = live;
}
@Override
public void run() {
while(true){
//休眠500毫秒
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//根据方向来改变x,y坐标
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 <= 800 && y >= 0 && y <= 750 && isLive)){
isLive = false;
System.out.println("子弹的线程退出");
break;
}
}
}
}
package tankgame3;
/**
* 坦克类
*/
public class Tank {
private int x;//坦克的横坐标
private int y;//坦克的纵坐标
private int direct;//坦克的方向
private boolean life = true;//坦克是否存活
public Tank(int x, int y) {
this.x = x;
this.y = y;
}
public boolean isLife() {
return life;
}
public void setLife(boolean life) {
this.life = life;
}
//坦克移动
//上移
public void moveUp(){
if (getY() > 0){
y-=1;
}
}
//下移
public void moveDown(){
if (getY() < 800) {
y+=1;
}
}
//左移
public void moveLeft(){
if (getX() > 0) {
x-=1;
}
}
//右移
public void moveRight(){
if (getX() < 750){
x+=1;
}
}
public int getDirect() {
return direct;
}
public void setDirect(int direct) {
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;
}
}
package tankgame3;
import java.util.Vector;
/**
* 这个是我们的坦克
*/
public class Hero extends Tank {
//定义一个Shot对象,表示一个射击行为(线程)
private Shot shot = null;
//可以发射多颗子弹
private Vector shots = new Vector<>();
private boolean life = true;
public boolean isLife() {
return life;
}
public void setLife(boolean life) {
this.life = life;
}
public Hero(int x, int y) {
super(x, y);
}
public Shot getShot() {
return shot;
}
public void setShot(Shot shot) {
this.shot = shot;
}
public Vector getShots() {
return shots;
}
public void setShots(Vector shots) {
this.shots = shots;
}
public void shotEnemyTank(){
//只能存储五颗子弹,如果子弹数目大于5就不再存贮
if (getShots().size() == 5){
return;
}
//创建Shot对象,根据当前Hero对象的位置和方向来创建shot
//只有当当前子弹消亡才能再次发射子弹
switch (getDirect()){
case 0://向上
shot = new Shot(getX() + 18, getY(), 0);
break;
case 1://向右
shot = new Shot(getX() + 30, getY() + 18, 1);
break;
case 2://向下
shot = new Shot(getX() + 18,getY() + 30, 2);
break;
case 3://向左
shot = new Shot(getX(), getY() + 18, 3);
break;
}
//把新建的shot放入到集合中
shots.add(shot);
//启动我们的shot线程
new Thread(shot).start();
}
}