坦克大战小游戏(Java)


按照教程写了一个Java小游戏,花了19天时间去抄了一遍,今天终于抄完了 。:.゚ヽ(。◕‿◕。)ノ゚.:。+゚


github地址:https://github.com/qq1367212627/kuaidi


此项目是根据尚学堂的马士兵老师的视频教程写的,有兴趣的同学可以搜索一下,以下是代码


坦克游戏主程序

package TankClient;


import Blood.Blood;
import Missile.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import TankClient.Tank.*;
import Wall.Wall;


public class TankClient extends Frame {
    public static final int GAME_WIDTH = 800;
    public static final int GAME_HEIGHT = 600;
    Tank myTank = new Tank(400, 400,true, Direction.STOP,this);        //将本身的引用传递过去,实现获取Missile的数据
    public ArrayList missiles = new ArrayList();
    public ArrayList expelodes =new ArrayList();
    public ArrayList tanks = new ArrayList();       //多个坦克
    Image offScreenImage = null;
    Wall w1=new Wall(100,200,20,150,this);
    Wall w2=new Wall(300,100,300,20,this);
    private Blood b= new Blood();

    public void paint(Graphics g) {
        g.drawString("炮弹数量:"+missiles.size(),50,50);
        g.drawString("爆炸数量:"+expelodes.size(),50,70);
        g.drawString("敌人数量:"+tanks.size(),50,90);
        g.drawString("生命值:"+myTank.getLife(),50,110);
        if(tanks.size()<=0)addTanks();
        for(int i=0;i


坦克类

package TankClient;

import Blood.Blood;
import Missile.Missile;
import Wall.Wall;
import com.sun.org.apache.bcel.internal.generic.DREM;

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Random;

public class Tank {
    public static final int XSPEED = 5;
    public static final int YSPEED = 5;                 //坦克速度
    public static final int WIDTH = 30;
    public static final int HEIGHT = 30;
    public TankClient tc = null;                                 //持有TankClient的引用实现数据传输
    private Direction ptDir = Direction.D;                //炮筒的方向
    private int x, y;
    private boolean good;                                //敌我标记
    private boolean bL = false, bU = false, bR = false, bD = false; //方向的确定
    public enum Direction {L, LU, U, RU, R, RD, D, LD, STOP};   //方向
    private static Random r = new Random();
    private int step = r.nextInt(8) + 3;                        //延时标记,使得坦克多移动一些距离
    int oldx, oldy;
    private boolean Live = true;                          //记录坦克是否存活
    private Direction dir = Direction.STOP;                 //初始化为停止
    private BloodBar bb = new BloodBar();


    public int getLife() {
        return life;
    }

    public void setLife(int life) {
        this.life = life;
    }

    private int life=100;

    public boolean isGood() {
        return good;
    }

    public void setGood(boolean good) {
        this.good = good;
    }

    public boolean isLive() {
        return Live;
    }

    public void setLive(boolean live) {
        Live = live;
    }

    public Tank(int x, int y, boolean _good) {
        this.x = x;
        this.y = y;
        this.oldx = x;
        this.oldy = y;
        this.good = _good;
    }

    public Tank(int _x, int _y, boolean _good, Direction _dir, TankClient _tc) {    //将TankClient 引用传递,实现Missile的交换
        this(_x, _y, _good);
        this.dir = _dir;
        tc = _tc;
    }

    public void draw(Graphics g) {          //画出
        if (!Live) {
            return;
        }
        if(this.isGood())bb.draw(g);                //若是好坦克,画出血条
        Color c = g.getColor();
        if (good) g.setColor(Color.RED); //我方坦克为红色
        else g.setColor(Color.blue);    //敌方的颜色为蓝色
        g.fillOval(x, y, WIDTH, HEIGHT);
        g.setColor(c);
        switch (ptDir)                           //画出炮筒的方向
        {
            case L:
                g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x, y + Tank.HEIGHT / 2);
                break;
            case LU:
                g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x, y);
                break;
            case U:
                g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH / 2, y);
                break;
            case RU:
                g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH, y);
                break;
            case R:
                g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH, y + Tank.HEIGHT / 2);
                break;
            case RD:
                g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH, y + Tank.HEIGHT);
                break;
            case D:
                g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH / 2, y + Tank.HEIGHT);
                break;
            case LD:
                g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x, y + Tank.HEIGHT);
                break;
        }
        if (x < 0) x = 0;
        if (y < 30) y = 30;
        if (x + Tank.WIDTH > TankClient.GAME_WIDTH) x = TankClient.GAME_WIDTH - Tank.WIDTH;
        if (y + Tank.HEIGHT > TankClient.GAME_HEIGHT) y = TankClient.GAME_HEIGHT - Tank.HEIGHT;//判断坦克是否超出边界,如果超出就停下
        move();
    }

    void move() {               //运动函数
        this.oldx = x;
        this.oldy = y;
        switch (dir) {
            case L:
                x -= XSPEED;
                break;
            case LU:
                x -= XSPEED;
                y -= YSPEED;
                break;
            case U:
                y -= YSPEED;
                break;
            case RU:
                x += XSPEED;
                y -= YSPEED;
                break;
            case R:
                x += XSPEED;
                break;
            case RD:
                x += XSPEED;
                y += YSPEED;
                break;
            case D:
                y += YSPEED;
                break;
            case LD:
                x -= XSPEED;
                y += YSPEED;
                break;
            case STOP:
                break;
        }

        if (!good) {                              //随机产生方向
            if (step == 0) {
                step = r.nextInt(8) + 3;
                Direction[] dirs = Direction.values();
                int rn = r.nextInt(dirs.length);
                while (dirs[rn] == Direction.STOP)
                    rn = r.nextInt(dirs.length);
                dir = dirs[rn];
                ptDir = dir;
            }
            step--;
            if (r.nextInt(40) > 38) this.fire();
        }

    }

    public void keyPressed(KeyEvent e) {            //按键被按住的动作
        int key = e.getKeyCode();
        switch (key) {
            case KeyEvent.VK_LEFT:
                bL = true;
                break;
            case KeyEvent.VK_UP:
                bU = true;
                break;
            case KeyEvent.VK_RIGHT:
                bR = true;
                break;
            case KeyEvent.VK_DOWN:
                bD = true;
                break;
        }
        locateDirection();

        if (this.dir != Direction.STOP)            //保存炮筒的方向
        {
            ptDir = this.dir;
        }
    }

    void locateDirection() {                        //判断方向
        if (bL && !bU && !bR && !bD) dir = Direction.L;
        else if (bL && bU && !bR && !bD) dir = Direction.LU;
        else if (!bL && bU && !bR && !bD) dir = Direction.U;
        else if (!bL && bU && bR && !bD) dir = Direction.RU;
        else if (!bL && !bU && bR && !bD) dir = Direction.R;
        else if (!bL && !bU && bR && bD) dir = Direction.RD;
        else if (!bL && !bU && !bR && bD) dir = Direction.D;
        else if (bL && !bU && !bR && bD) dir = Direction.LD;
        else if (!bL && !bU && !bR && !bD) dir = Direction.STOP;
    }

    public void keyReleased(KeyEvent e) {       //按键释放的操作
        int key = e.getKeyCode();
        switch (key) {
            case KeyEvent.VK_CONTROL:
                if (this.Live) this.fire();            //添加多个炮弹
                break;
            case KeyEvent.VK_LEFT:
                bL = false;
                break;
            case KeyEvent.VK_UP:
                bU = false;
                break;
            case KeyEvent.VK_RIGHT:
                bR = false;
                break;
            case KeyEvent.VK_DOWN:
                bD = false;
                break;
            case KeyEvent.VK_A:
                if(this.isLive())superFire();
                break;
            case KeyEvent.VK_F2:
                if(!tc.myTank.isLive()){
                    tc.myTank.setLive(true);
                    tc.myTank.setLife(100);
                }
                break;
        }
        locateDirection();
    }

    public Missile fire() {                                          //开火方法
        int _x = this.x + Tank.WIDTH / 2 - Missile.WIDTH / 2;
        int _y = this.y + Tank.HEIGHT / 2 - Missile.HEIGHT / 2;     //使子弹从中心发出
        Missile m = new Missile(_x, _y, good, ptDir, this.tc);          //传递自身引用
        this.tc.missiles.add(m);
        return m;
    }

    public Missile fire(Direction Missiledir) {                                          //开火方法
        int _x = this.x + Tank.WIDTH / 2 - Missile.WIDTH / 2;
        int _y = this.y + Tank.HEIGHT / 2 - Missile.HEIGHT / 2;     //使子弹从中心发出
        Missile m = new Missile(_x, _y, good, Missiledir, this.tc);          //传递自身引用
        this.tc.missiles.add(m);
        return m;
    }

    public Rectangle getRect() {
        return new Rectangle(x, y, WIDTH, HEIGHT);
    }

    public boolean coollideWithWall(Wall w) {                   //判断坦克撞墙
        if (this.isLive() && this.getRect().intersects(w.getRect())) {
            this.dir = Direction.STOP;
            this.stay();
            return true;
        }
        return false;
    }

    private void stay(){                        //回溯到上一次的位置
        this.x=this.oldx;
        this.y=this.oldy;
    }

    public boolean coollideWithTank(Tank t){                             //与单辆坦克碰撞
            if (this!=t&&this.isLive() &&t.isLive() && this.getRect().intersects(t.getRect())) {
                this.stay();
                t.stay();
                return true;
            }
        return false;
    }

    public boolean coollideWithTanks(ArrayList tanks){            //与多辆坦克碰撞
        boolean IscoollideWithTanks=false;
        for(int i = 0;i


爆炸类


package TankClient;

import java.awt.*;

/**
 * Created by lewis on 2016/10/5.
 */
public class Explode {
    int x,y;
    private boolean Live=true;
    int step=0;                                             //数组下标,记录爆炸的状态
    TankClient tc=null;
    int [] diameter={4,7,12,18,26,32,49,30,14,6};           //爆炸直径大小

    public boolean isLive() {
        return Live;
    }

    public void setLive(boolean live) {
        Live = live;
    }

    public Explode(int _x,int _y,TankClient _tc){
        x=_x;
        y=_y;
        tc=_tc;
    }

    public void draw(Graphics g){
        if(!Live)return ;
        if(step==diameter.length){
            Live=false;
            step=0;
            return ;
        }
        Color c = g.getColor();
        g.setColor(Color.ORANGE);
        g.fillOval(x,y,diameter[step],diameter[step]);
        step++;
    }
}


墙类

package Wall;

import TankClient.TankClient;

import java.awt.*;

/**
 * Created by lewis on 2016/10/6.
 */
public class Wall{
    int x,y,w,h;
    TankClient tc;

    public Wall(int x, int y, int w, int h, TankClient tc) {
        this.x = x;
        this.y = y;
        this.w = w;
        this.h = h;
        this.tc = tc;
    }

    public void draw(Graphics g){
        g.fillRect(x,y,w,h);
    }

    public Rectangle getRect(){
        return new Rectangle(x,y,w,h);
    }


}


加血血块类


package Blood;

import TankClient.TankClient;

import java.awt.*;

/**
 * Created by lewis on 2016/10/6.
 *          加血模块
 *
 */
public class Blood {
    int x,y,w,h,step=0;
    TankClient tc;
    private boolean Live=true;
    private int[][] pos={                       //血块 轨迹
            {350,300},{360,300},{375,275},{400,200},{360,270},{340,280}
    };

    public Blood(int x, int y, int w, int h, TankClient tc) {
        this.x = x;
        this.y = y;
        this.w = w;
        this.h = h;
        this.tc = tc;
    }

    public Blood() {
        x=pos[0][0];
        y=pos[0][1];
        w=h=15;
        step=0;
    }

    public  void draw(Graphics g){
        if(!this.isLive())return;
        Color c = g.getColor();
        g.setColor( Color.MAGENTA);
        g.fillRect(x,y,w,h);
        g.setColor(c);
        move();
    }

    private void move(){
        step++;
        if(step==pos.length) {step=0;}
        x=pos[step][0];
        y=pos[step][1];
    }

    public Rectangle getRect(){
        return new Rectangle(x,y,w,h);
    }

    public boolean isLive() {
        return Live;
    }

    public void setLive(boolean live) {
        Live = live;
    }
}


子弹类


package Missile;

import TankClient.Tank;
import TankClient.TankClient;
import TankClient.Explode;
import Wall.Wall;

import java.awt.*;
import java.util.ArrayList;


public class Missile {
    public static final int XSPEED = 10;
    public static final int YSPEED = 10;

    public static final int WIDTH = 10;
    public static final int HEIGHT = 10;
    int x, y;
    private TankClient tc;
    private boolean good;
    private boolean Live=true;                       //判断炮弹是否存活
    Tank.Direction dir;

    public boolean isLive() {
        return Live;
    }

    public void setLive(boolean live) {
        Live = live;
    }

    public Missile(int x, int y ,Tank.Direction dir) {
        this.x = x;
        this.y = y;
        this.dir = dir;
    }

    public Missile(int x, int y,boolean _good, Tank.Direction dir,TankClient _tc) {
       this(x,y,dir);
        this.good=_good;
        this.tc=_tc;
    }

    public void draw(Graphics g) {
        if(!Live){
            tc.missiles.remove(this);
            return ;
        }
        Color c = g.getColor();
        g.setColor(Color.BLACK);
        g.fillOval(x, y, WIDTH, HEIGHT);
        g.setColor(c);
        move();
    }

    private void move() {
        switch(dir) {
            case L:
                x -= XSPEED;
                break;
            case LU:
                x -= XSPEED;
                y -= YSPEED;
                break;
            case U:
                y -= YSPEED;
                break;
            case RU:
                x += XSPEED;
                y -= YSPEED;
                break;
            case R:
                x += XSPEED;
                break;
            case RD:
                x += XSPEED;
                y += YSPEED;
                break;
            case D:
                y += YSPEED;
                break;
            case LD:
                x -= XSPEED;
                y += YSPEED;
                break;
        }
        if(x<0||y<0||x>TankClient.GAME_WIDTH||y>TankClient.GAME_HEIGHT) {       //判断炮弹是否跑出边界
            Live=false;
            tc.missiles.remove(this);        //若炮弹跑出边界则从集合中移除
        }
    }

    public Rectangle getRect(){
        return new Rectangle(x,y,WIDTH, HEIGHT);
    }

    public boolean hitTank(Tank t){                                         //判断是否相交
        if(this.Live&&this.getRect().intersects(t.getRect())&&t.isLive()&&this.good!=t.isGood()) {
            if(t.isGood()){                                 //区分坦克对待
                t.setLife(t.getLife()-20);
                if(t.getLife()<=0)t.setLive(false);
            }
            else {
                t.setLive(false);
            }
            this.setLive(false);                            //炮弹死亡
            Explode e = new Explode(x,y,tc);
            tc.expelodes.add(e);
            return true;
        }
        return false;
    }

    public boolean hitTanks(ArrayList tanks) {            //攻击多个坦克
        for (int i = 0; i < tanks.size(); i++){
            if(hitTank(tanks.get(i))){
                return true;
            }
        }
        return false;
    }

    public boolean hitWall(Wall w){                 //判断子弹撞墙
        if(this.isLive()&&this.getRect().intersects(w.getRect())){
            this.setLive(false);                    //撞上墙则设为死亡
            return true;
        }
        return false;
    }

}



你可能感兴趣的:(Java)