栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java完成经典坦克大战项目源码

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java完成经典坦克大战项目源码

 

图片是类与类之间的包位置关系,与代码的导包操作相关

​

 [点击并拖拽以移动] 


图片是类之间的关系,以及工具类的包位置

package com.tank.app;

import com.tank.game.GameFrame;


public class GameMain {
    public static void main(String[] args) {

        new GameFrame();
        //注意在这种项目中尽量使用fori去遍历而不使用forEach去遍历,因为forEach的底层是迭代器,迭代器在
        //删除过程中会产生异常,并且难以排查
    }
}

 

package com.tank.game;


import com.tank.Map.GameMap;
import com.tank.Map.MapTile;
import com.tank.tank.EnemyTank;
import com.tank.tank.MyTank;
import com.tank.tank.Tank;
import com.tank.util.MyUtil;
import com.tank.util.TankPool;

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static com.tank.util.constant.*;//这里就将该资源下的所有常量等导入



public class GameFrame extends Frame implements Runnable{
    private Image over=null;
    private BufferedImage image=new BufferedImage(FRAME_WIDTH,FRAME_HEIGHT,BufferedImage.TYPE_4BYTE_ABGR);
    public static int gameState;//用来记录状态
    public static int menuIndex;//用来记录选中的菜单选项
    private Tank myTank;
    //标题栏的高度
    public static int titleBarH;
    public static ArrayList enemies=new ArrayList<>();

    public static GameMap map;
    //游戏的主窗口类
    //所有的游戏的展示内容都在该类中进行实现
   public GameFrame(){

       initEventListener();
       initFrame();//所有方法都在这里进行初始化

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

   }
   public void initGame(){
       gameState=STATE_MENU;
   }

    public static int getGameState() {
        return gameState;
    }

    public static void setGameState(int gameState) {
        GameFrame.gameState = gameState;
    }

    private void initFrame(){
       setTitle(GAME_TITLE);//设置窗口主题

       setSize(FRAME_WIDTH,FRAME_HEIGHT);
       setLocation(FRAME_X,FRAME_Y);
       setResizable(false);//设置不可拉伸

       setVisible(true);
       titleBarH=getInsets().top;
       //创建坦克


   }

   private void drawMenu(Graphics g){
       //绘制
       g.setColor(Color.black);
       //g.fillRect(0,0,FRAME_WIDTH,FRAME_HEIGHT);//背景黑色
       setBackground(Color.black);

       final int STR_WIDTH=76;
       int x= FRAME_WIDTH-STR_WIDTH>>1;
       int y=FRAME_HEIGHT/3;
       final int DIS=50;
       g.setColor(Color.white);
       for (int i = 0; i < MENUS.length; i++) {
           if(i==menuIndex){
               //说明是我们选中的那一个
               g.setColor(Color.red);
           }else{
               g.setColor(Color.white);
           }
           g.drawString(MENUS[i],x,y+DIS*i );
       }

   }


    private void drawOver(Graphics g) {
       //游戏结束时候的draw
        if(over==null){
            over= MyUtil.createImage("res/theEnd.png");
        }
        int imgW=over.getWidth(null);
        int imgH=over.getHeight(null);

        g.drawImage(over,FRAME_WIDTH-imgW>>1,FRAME_HEIGHT-imgH>>1,null);
        g.setColor(Color.white);
        g.drawString(OVER_STR0,10,FRAME_HEIGHT-20);
        g.drawString(OVER_STR1,FRAME_WIDTH-200,FRAME_HEIGHT-20);
    }
    private void drawEnemy(Graphics g){
       for(int i=0;iMENUS.length-1){
                    menuIndex=0;
                }
                //repaint();//窗口重新绘制
                break;
            case KeyEvent.VK_ENTER:
                //TODO
                newGame();
                break;
        }
    }

    private void newGame() {
       //开始新游戏的方法
        gameState=STATE_RUN;
        //在游戏开始的时候重新启动一个线程用来控制敌人坦克的控制
        myTank=new MyTank(100,100,Tank.DIR_DOWN);

        map=new GameMap();

        new Thread() {
            @Override
            //内部类也要重写run方法才能实现
            public void run(){
                while(true){
                    if(enemies.size() bullets=new ArrayList<>();//类似于弹夹,用来管理所有的子弹类
    private List explodes=new ArrayList<>();//存储爆炸的容器


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

    public Tank() {
        initTank();
    }
    private void initTank(){
        hp=DEFAULT_HP;
        color= MyUtil.getRandomColor();
        name=MyUtil.getRandomName();//拿到随机名字
    }

    //坦克的逻辑处理
    private void logic(){
        switch(state){
            case STATE_STAND:
                break;
            case STATE_MOVE:
                move();
                break;
            case STATE_DIE:
                break;
        }

    }

    private void move() {
        //根据方向处理坐标
        oldX=x;
        oldY=y;
        switch(dir){
            case DIR_UP:
                y-=speed;
                if(yFRAME_HEIGHT-RADIUS){
                    y=FRAME_HEIGHT-RADIUS;
                }
                break;
            case DIR_LEFT:
                x-=speed;
                if(xFRAME_WIDTH-RADIUS){
                    x=FRAME_WIDTH-RADIUS;
                }
                break;
        }
    }

    //坦克的绘制,将其自动线程控制
    public void draw(Graphics g){
        //这里是每一个帧数都在调用,坦克要每一帧都要知道
        logic();

        drawTankImage(g);//用图片绘制

        drawBullets(g);//绘画子弹

        drawName(g);

        bloodBar.draw(g);//绘画血条
    }

    public abstract void drawTankImage(Graphics g);

    private void drawTank(Graphics g){
        g.setColor(color);

        //绘制坦克的⚪
        g.fillOval(x-RADIUS,y-RADIUS,RADIUS<<1,RADIUS<<1);
        int endX=x;
        int endY=y;
        switch(dir){
            case DIR_UP:
                endY=y-RADIUS;
                break;
            case DIR_DOWN:
                endY=y+RADIUS;
                break;
            case DIR_LEFT:
                endX=x-RADIUS;
                break;
            case DIR_RIGHT:
                endX=x+RADIUS;
                break;
        }
        g.drawLine(x,y,endX,endY);
    }

    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 getAtk() {
        return atk;
    }

    public void setAtk(int atk) {
        this.atk = atk;
    }

    public int getHp() {
        return hp;
    }

    public void setHp(int hp) {
        this.hp = hp;
    }

    public int getSpeed() {
        return speed;
    }

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

    public int getDir() {
        return dir;
    }

    public void setDir(int dir) {
        this.dir = dir;
    }

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }

    public List getBullets() {
        return bullets;
    }

    public void setBullets(List bullets) {
        this.bullets = bullets;
    }
    private  long fireTime;

    public void fire(){
        //开火的方法
        if(System.currentTimeMillis()-fireTime> FIRE_INTERVAL) {
            int bulletX = x;
            int bulletY = y;
            switch (dir) {
                case DIR_UP:
                    bulletY -= RADIUS;
                    break;
                case DIR_DOWN:
                    bulletY += RADIUS;
                    break;
                case DIR_LEFT:
                    bulletX -= RADIUS;
                    break;
                case DIR_RIGHT:
                    bulletX += RADIUS;
                    break;
            }
            //这里子弹就可以直接从对象池中拿了
            Bullet bullet = BulletPool.get();
            bullet.setX(bulletX);
            bullet.setY(bulletY);
            bullet.setDir(dir);
            bullet.setAtk(atk);
            bullet.setColor(color);
            bullet.setVisible(true);

            bullets.add(bullet);//要进行反复创建销毁,否则就会一直增加

            fireTime=System.currentTimeMillis();//不断去更新时间
        }
    }
    private void drawBullets(Graphics g){
        //在进行绘画的同时判断是否有已经需要销毁的子弹,进行回收
        for(Bullet b: bullets){
            b.draw(g);
        }
        for(int i=0;i bullets){
        for(Bullet bullet: bullets){
            if(MyUtil.isCollide(x,y,RADIUS,bullet.getX(),bullet.getY())){
                //碰撞到了
                //子弹消失
                bullet.setVisible(false);
                //坦克受到伤害,用一个方法来写
                hurt(bullet);
                //添加爆炸特效
//                explodes.add(new Explode(x-RADIUS,y+RADIUS));
                addExplode(x-RADIUS,y+RADIUS-10);
            }
        }
    }
    private void addExplode(int x,int y){
        Explode explode= ExplodePool.get();
        explode.setX(x);
        explode.setY(y);
        explode.setVisible(true);
        explodes.add(explode);//注意还要添加到本身的容器中
    }
    private void hurt(Bullet bullet){
        //坦克受到伤害的方法完成
        int atk=bullet.getAtk();

        hp-=atk;

        //这里还要有坦克死亡的方法
        if(isDie()) {
            die();
        }

    }
    private void die(){
        if(isEnemy){
            //敌人死了
            TankPool.theReturn(this);//死亡后归还
        }else{
            //玩家死了
            //切换游戏状态
            delaySecondToOver(3000);
        }
    }
    public boolean isDie(){
        return hp<=0;
    }
    //添加爆炸效果
    public void drawExplode(Graphics g){
        for(Explode explode:explodes){
            explode.draw(g);
        }
        for (int i = 0; i < explodes.size(); i++) {
            if(!explodes.get(i).isVisible()){
                Explode remove=explodes.remove(i);
                ExplodePool.theReturn(remove);//返回对象池
                i--;
            }
        }
    }
    //画出名字
    public void drawName(Graphics g){
        g.setColor(color);
        g.setFont(constant.TANK_NAME);

        g.drawString(name,x-RADIUS,y-40);
    }

    //这里用一个内部类来表示坦克的血量对象
    class BloodBar{
        //血量对象
        public static final int BAR_LENGTH=50;
        public static final int BAR_HEIGHT=4;

        public  void draw(Graphics g){
            //绘画血条,底色为黄色
            g.setColor(Color.yellow);
            g.fillRect(x-RADIUS,y-RADIUS-BAR_HEIGHT*2,BAR_LENGTH,BAR_HEIGHT);
            //红色的当前血量
            g.setColor(Color.RED);
            g.fillRect(x-RADIUS,y-RADIUS-BAR_HEIGHT*2,hp*BAR_LENGTH/DEFAULT_HP,BAR_HEIGHT);
            //蓝色的边框
            g.setColor(Color.BLUE);
            g.drawRect(x-RADIUS,y-RADIUS-BAR_HEIGHT*2,BAR_LENGTH,BAR_HEIGHT);
        }
    }
    public void resetBullet(){
        for(Bullet b:bullets){
            //在游戏重置的时候调用此方法
            BulletPool.theReturn(b);
        }
        bullets.clear();//清空
    }

    //坦克的子弹与所有砖块的碰撞逻辑
    public void BulletCollide(List tiles){
        for(MapTile m:tiles){
            if(m.getType()== MapTile.TYPE_COVER)
                continue;
            if(m.isCollideBullet(bullets)){
                //发生碰撞,爆炸效果
                if(m.getType()==MapTile.TYPE_HARD)
                    continue;
                addExplode(m.getX()+MapTile.radius-20,m.getY()+MapTile.radius-20);
                //设置地图块销毁
                m.setVisible(false);
                if(m.isHouse()) {
                    delaySecondToOver(3000);
                }
            }
        }
    }
    private void delaySecondToOver(int seconds){
        new Thread(){
            public void run(){
                try {
                    Thread.sleep(seconds);
                    GameFrame.gameState= STATE_OVER;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }
    //地图块和坦克的碰撞
    public boolean isCollideTile(List tiles){
        for(MapTile tile:tiles){
            if(tile.getType()==MapTile.TYPE_COVER)
                continue;
            int tileX=tile.getX();
            int tileY=tile.getY();
            //这里是取点判断是否和坦克碰撞上
            boolean Collide=MyUtil.isCollide(x,y,RADIUS,tileX,tileY);
            if(Collide)
                return true;

            tileX+=RADIUS*2-10;
            Collide=MyUtil.isCollide(x,y,RADIUS,tileX,tileY);
            if(Collide)
                return true;

            tileX+=RADIUS*2-10;
            Collide=MyUtil.isCollide(x,y,RADIUS,tileX,tileY);
            if(Collide)
                return true;

            tileY+=RADIUS*2-10;
            Collide=MyUtil.isCollide(x,y,RADIUS,tileX,tileY);
            if(Collide)
                return true;

            tileY+=RADIUS*2-10;
            Collide=MyUtil.isCollide(x,y,RADIUS,tileX,tileY);
            if(Collide)
                return true;

            tileX-=RADIUS*2-10;
            Collide=MyUtil.isCollide(x,y,RADIUS,tileX,tileY);
            if(Collide)
                return true;

            tileX-=RADIUS*2-10;
            Collide=MyUtil.isCollide(x,y,RADIUS,tileX,tileY);
            if(Collide)
                return true;

            tileY-=RADIUS*2-10;
            Collide=MyUtil.isCollide(x,y,RADIUS,tileX,tileY);
            if(Collide)
                return true;
        }
        return false;
    }
    public void back(){
        x=oldX;
        y=oldY;
    }
}

public class MyTank extends Tank {
    //将坦克图片替换为自己做的
    private static Image[] tankImg;
    //还有敌人的坦克

    static{
        //静态代码块中初始化坦克
        tankImg=new Image[4];
        tankImg[0]= MyUtil.createImage("res/tank.png");//这个方法来将图片加载进去
        tankImg[1]=MyUtil.createImage("res/tank2.png");
        tankImg[2]= MyUtil.createImage("res/tank3.png");
        tankImg[3]=MyUtil.createImage("res/tank4.png");


    }
    public MyTank(int x, int y, int dir) {
        super(x, y, dir);
    }

    public void drawTankImage(Graphics g){
            g.drawImage(tankImg[getDir()], getX()- RADIUS, getY() - RADIUS, null);

    }

}

package com.tank.tank;

import com.tank.game.GameFrame;
import com.tank.util.MyUtil;
import com.tank.util.TankPool;

import java.awt.*;

import static com.tank.util.constant.*;

public class EnemyTank extends Tank{
    private double aiTime;//记录时间
    private static Image[] enemyImg;

    static {
        enemyImg = new Image[4];
        enemyImg[0] = MyUtil.createImage("res/tank.png");//这个方法来将图片加载进去
        enemyImg[1] = MyUtil.createImage("res/tank2.png");
        enemyImg[2] = MyUtil.createImage("res/tank3.png");
        enemyImg[3] = MyUtil.createImage("res/tank4.png");
    }
    public EnemyTank(int x, int y, int dir) {
        super(x, y, dir);
        aiTime=System.currentTimeMillis();
    }

    public EnemyTank() {
        aiTime=System.currentTimeMillis();
    }

    public static Tank createEnemy(){
        //创建敌人坦克类
        int x= MyUtil.getRandomNumber(0,2)==0?RADIUS: FRAME_WIDTH-2*RADIUS;
        int y= GameFrame.titleBarH+RADIUS;
        int dir=DIR_DOWN;
        Tank enemy= TankPool.get();
        enemy.setX(x);
        enemy.setY(y);
        enemy.setDir(dir);
        enemy.setHp(DEFAULT_HP);//每次创建的时候要给其赋值,不然就会拿到血条已经空的坦克
        enemy.isEnemy = true;//标识为敌人
        //TODO
        enemy.setState(STATE_MOVE);
        return enemy;
    }

    public void drawTankImage(Graphics g){
        ai();
        g.drawImage(enemyImg[getDir()], getX() - RADIUS, getY() - RADIUS, null);
    }
    private void ai(){
        //简单ai控制敌人
        if(System.currentTimeMillis()-aiTime>=ENEMY_AI_INTERVAL){
            //当超过五秒
            this.setState(MyUtil.getRandomNumber(0,2)==0?STATE_STAND:STATE_MOVE);
            //还要记得重置时间,还要改变方向
            setDir(MyUtil.getRandomNumber(DIR_UP,DIR_RIGHT+1));
            aiTime=System.currentTimeMillis();
        }
        if(Math.random()>1;
    public static final int FRAME_Y=768-FRAME_HEIGHT>>1;
    //游戏的状态也作为常量
    //1:游戏菜单
    public static final int STATE_MENU=0;
    public static final int STATE_HELP=1;
    public static final int STATE_ABOUT=2;
    public static final int STATE_RUN=3;
    public static final int STATE_OVER=4;

    public static final String[] MENUS ={
            "开始游戏",
            "继续游戏",
            "游戏帮助",
            "游戏关于",
            "退出游戏"
    };
    public static final Font font=new Font("宋体",Font.BOLD,24);
    public static final Font TANK_NAME=new Font("宋体",Font.BOLD,12);

    public static final int REPAINT_INTERVAL=20;//

    public static final int ENEMY_MAX_COUNT=10;//敌人最大数量
    public static final int ENEMY_BORN_TIME=5000;

    public static final int ENEMY_AI_INTERVAL=5000;//这么长时间就换一次方向和状态
    public static final double ENEMY_FIRE_INTERVAL= 0.03;//这是发射子弹的概率

    public static final int TANK_ATK=80;


    public static final String OVER_STR0="ESC键退出游戏";
    public static final String OVER_STR1="ENTER键回到主菜单";

    public  static int FIRE_INTERVAL=500;//子弹发射间隔时间

    public static String HOUSE_NAME="家";
}

package com.tank.util;

import com.tank.tank.EnemyTank;
import com.tank.tank.Tank;

import java.util.ArrayList;

public class TankPool {
    //敌人坦克对象池,自己的坦克只有一辆,不需要对象池
    private static int ENEMY_COUNT=10;
    private static ArrayList enemies=new ArrayList<>();

    static{
        for (int i = 0; i < ENEMY_COUNT; i++) {
            enemies.add(new EnemyTank());
        }
    }

    public static Tank get(){
        if(enemies.size()!=0){
            return enemies.remove(0);
        }else{
            return new EnemyTank();
        }
    }

    public static void theReturn(Tank enemyTank){
        if(enemies.size()==ENEMY_COUNT){
            return;
        }
        enemies.add(enemyTank);
    }
}

package com.tank.game;

import com.tank.tank.Tank;
import com.tank.util.BulletPool;

import java.awt.*;
import static com.tank.util.constant.*;

public class Bullet {
    private boolean isVisible=true;
    public static final int DEFAULT_SPEED= Tank.DEFAULT_SPEED*2;
    public static final int RADIUS=4;
    //子弹类
    private int x,y;
    private int speed=DEFAULT_SPEED;
    private int atk;
    private int dir;//方向
    private Color color;

    public Bullet(int x, int y, int atk, int dir,Color color) {
        //isVisible=true;
        this.x = x;
        this.y = y;
        this.atk = atk;
        this.dir = dir;
        this.color=color;
    }

    public Bullet() {
        //对象池的专用,所有属性值全部都是默认
    }

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }

    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 getAtk() {
        return atk;
    }

    public void setAtk(int atk) {
        this.atk = atk;
    }

    public int getDir() {
        return dir;
    }

    public void setDir(int dir) {
        this.dir = dir;
    }

    //绘画
    public void draw(Graphics g){
        if(!isVisible){
            //已经不可见
            return;
        }
        logic();
        g.setColor(color);
        g.fillOval(x-RADIUS,y-RADIUS,RADIUS<<1,RADIUS<<1);
    }
    private void logic(){
        //子弹运动的逻辑
        move();
    }
    private void move(){
        switch (dir){
            case Tank.DIR_UP:
                y-=speed;
                if(y<=0) {
                    isVisible = false;
                }
                break;
            case Tank.DIR_DOWN:
                y+=speed;
                if(y>FRAME_HEIGHT) {
                    isVisible = false;
                }
                break;
            case Tank.DIR_LEFT:
                x-=speed;
                if(x<=0) {
                    isVisible = false;
                }
                break;
            case Tank.DIR_RIGHT:
                x+=speed;
                if(x>FRAME_WIDTH) {
                    isVisible = false;
                }
                break;
        }
    }

    public void setVisible(boolean visible) {
        this.isVisible=visible;
    }
    public boolean Visible(){
        return isVisible;
    }
}

package com.tank.util;

import com.tank.game.Bullet;

import java.util.ArrayList;
import java.util.List;

public class BulletPool {
    private static final int DEFAULT_POOL_SIZE=200;//定义池子大小
    //子弹池类
    private static List pool=new ArrayList<>();
    static{
        for (int i = 0; i < DEFAULT_POOL_SIZE; i++) {
            pool.add(new Bullet());
        }
    }

    public static Bullet get(){
        Bullet bullet=null;
        if(pool.size()==0){
            bullet=new Bullet();
        }else {
            bullet = pool.remove(0);
        }
        return bullet;
    }
    //在销毁之后还要还回来
    public static void theReturn(Bullet b){
        if(pool.size()==DEFAULT_POOL_SIZE){
            return;
        }
        pool.add(b);
    }
}

package com.tank.game;

import com.tank.util.MyUtil;

import java.awt.*;

public class Explode {
    //控制爆炸效果的类
    private static final int EXPLODE_COUNT=9;//没三帧显示一次
    private static Image []images=new Image[3];

    private static int imageWidth;
    private static int imageHeight;
    static{
        for (int i = 0; i < 3; i++) {
            images[i]= MyUtil.createImage("res/boom_"+i+".png");//拿到图片资源
        }
        imageWidth=images[0].getWidth(null)/2;
        imageHeight=images[0].getHeight(null);
    }
    private int x,y;
    private int index;//记录现在的帧数
    public boolean visible=true;//刚创建时候为true

    public Explode(int x, int y) {
        this.x = x;
        this.y = y;
        index=0;//初始化为0
    }

    public Explode() {
        index=0;
    }

    public void draw(Graphics g){
        if(!visible)return;

        g.drawImage(images[index/3],x-imageWidth,y-imageHeight,null);
        index++;

        if(index>EXPLODE_COUNT-1){
            visible=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 getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }

    public boolean isVisible() {
        return visible;
    }

    public void setVisible(boolean visible) {
        this.visible = visible;
    }
}

package com.tank.util;

import com.tank.game.Explode;

import java.util.ArrayList;

public class ExplodePool {
    //将爆炸对象封装为对象池进行销毁和创建
    private static final int EXPLODE_COUNT=200;//默认为最大为200个
    private static final ArrayList explodes=new ArrayList<>();
    static{
        for (int i = 0; i < EXPLODE_COUNT; i++) {
            explodes.add(new Explode());
        }
        //创建
    }
    public static Explode get(){
        if(explodes.size()!=0){
            return explodes.remove(0);
        }else{
            return new Explode();
        }
    }
    //销毁之后还要还回来
    public static void theReturn(Explode e){
        if(explodes.size()==EXPLODE_COUNT){
            return;
        }
        explodes.add(e);
    }
}

package com.tank.Map;

import com.tank.game.Bullet;
import com.tank.game.GameFrame;
import com.tank.tank.Tank;
import com.tank.util.MyUtil;
import com.tank.util.constant;

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

public class MapTile {
    //砖块类
    private  int type=TYPE_NORMAL;
    public static final int TYPE_NORMAL=0;
    public static final int TYPE_HOUSE=1;
    public static final int TYPE_COVER=2;
    public static final int TYPE_HARD=3;



    public  static Image []tileImg=new Image[4];
    public static int tileW=50;
    public static int radius = tileW >> 1;
    private  boolean Visible=true;
    public String name;
    static{
        tileImg[0]= MyUtil.createImage("res/wall.png");
        tileImg[1]=MyUtil.createImage("res/house.png");
        tileImg[2]=MyUtil.createImage("res/cover.png");
        tileImg[3]=MyUtil.createImage("res/hard.png");
        if(tileW<=0){
            tileW=tileImg[3].getWidth(null);
        }
    }

    private int x,y;//左上角坐标

    public MapTile(int x, int y) {
        this.x = x;
        this.y = y;
        if(tileW<=0){
            tileW=tileImg[3].getWidth(null);
        }
    }

    public MapTile() {
        if(tileW<=0){
            tileW=tileImg[3].getWidth(null);
        }
    }

    public  boolean isVisible() {
        return Visible;
    }

    public  void setVisible(boolean visible) {
        Visible = visible;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    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 void draw(Graphics g){
        if(!Visible){
            return;
        }
        if(tileW<=0){
            tileW=tileImg[0].getWidth(null);
        }
        g.drawImage(tileImg[type],x,y,null);

        if(name!=null){
            g.setColor(Color.blue);
            g.drawString(name,x+radius/2,y+radius*3/2);
        }
    }

    public boolean isCollideBullet(List bullets){
        if(!Visible){
            return false;
        }
        for(Bullet b:bullets){
            int bulletX=b.getX();
            int bulletY=b.getY();

            boolean collide=MyUtil.isCollide(x+ radius,y+radius,radius,bulletX,bulletY);
            if(collide){
                //发生碰撞之后子弹消失
                b.setVisible(false);
                return true;
            }
        }
        return false;
    }
    public boolean isHouse(){
        return type==TYPE_HOUSE;
    }
}

package com.tank.Map;

import com.tank.game.GameFrame;
import com.tank.tank.Tank;
import com.tank.util.MapPool;
import com.tank.util.MyUtil;
import com.tank.util.constant;

import java.awt.*;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
import java.util.List;

public class GameMap {
    //游戏地图类
    private static ArrayList tiles=new ArrayList<>();

    private static final int MAP_X= Tank.RADIUS*3;
    private static final int MAP_Y=Tank.RADIUS*3;
    public static final int MAP_WIDTH= constant.FRAME_WIDTH-Tank.RADIUS*6;
    public static final int MAP_HEIGHT=constant.FRAME_HEIGHT-Tank.RADIUS*8- GameFrame.titleBarH;

    private  TankHouse house=new TankHouse();//

    public GameMap() {
        init(1);
    }

    public ArrayList getTiles() {
        return tiles;
    }

    public  void setTiles(ArrayList tiles) {
        GameMap.tiles = tiles;
    }

    private void init(int level){
   //通过解析文件的方式来获取方法参数,从而绘制出地图,需要传进来是第几关
        try {
            loadLevel(level);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private void loadLevel(int level) throws IOException {
        Properties prop=new Properties();//通过文件加载进来
        prop.load(new FileInputStream("level/lv_"+level+".txt"));

        //然后将文件中的信息加载进来
        int enemyCount=Integer.parseInt(prop.getProperty("enemyCount"));
        int enemyType=Integer.parseInt(prop.getProperty("enemyType"));
        String method=prop.getProperty("method");
        int invokeCount=Integer.parseInt(prop.getProperty("invokeCount"));
        String []paras=new String[invokeCount];
        for (int i = 0; i < invokeCount; i++) {
            paras[i]=prop.getProperty("parma"+(i+1));
        }

        invokeMethod(method,paras);
        addTile();
    }
    private void invokeMethod(String name,String []params){
        for(String param:params){
            String []split=param.split(",");
            int []arr = new int[split.length];
            for(int i=0;i tiles,int x,int y){
        //判断砖块与砖块是否发生重叠
        int tileX;
        int tileY;
        for(MapTile tile:tiles){
            tileX=tile.getX();
            tileY=tile.getY();
            if (Math.abs(tileX - x) < MapTile.tileW && Math.abs(tileY - y) < MapTile.tileW) {
                return true;
            }
        }
        return false;
    }
    public  void clearDestoryTile(){
        for (int i = 0; i < tiles.size(); i++) {
            if(!tiles.get(i).isVisible()){
                //不可见就删除并且返回对象池
                MapTile tile=tiles.remove(i);
                MapPool.theReturn(tile);

            }
        }
    }
    
    //生成一行的块
    public void addRow(int startX,int startY,int endX,int type,int DIS){
        int count = (endX-startX)/(MapTile.tileW+DIS);
        for (int i = 0; i < count; i++) {
            MapTile tile =MapPool.get();
            tile.setType(type);
            tile.setX(startX+i*(MapTile.tileW+DIS));
            tile.setY(startY);
            tiles.add(tile);
        }
    }
    public void addCol(int startX,int startY,int endY,int type,int DIS) {
        int count = (endY - startY) / (MapTile.tileW + DIS);
        for (int i = 0; i < count; i++) {
            MapTile tile = MapPool.get();
            tile.setType(type);
            tile.setY(startY + i * (MapTile.tileW + DIS));
            tile.setX(startX);
            tiles.add(tile);
        }
    }
    public void addRec(int startX,int startY,int endX,int endY,int type,int DIS){
        int rows=(endY-startY)/(MapTile.tileW+DIS);

        for(int i=0;i>1;
    public static final int HOUSE_Y=constant.FRAME_HEIGHT-2*MapTile.tileW;

    public  ArrayList tiles=new ArrayList<>();
    public TankHouse(){
        tiles.add(new MapTile(HOUSE_X,HOUSE_Y));
        tiles.add(new MapTile(HOUSE_X,HOUSE_Y+MapTile.tileW));
        tiles.add(new MapTile(HOUSE_X+MapTile.tileW,HOUSE_Y));
        tiles.add(new MapTile(HOUSE_X+2*MapTile.tileW,HOUSE_Y));
        tiles.add(new MapTile(HOUSE_X+2*MapTile.tileW,HOUSE_Y+MapTile.tileW));
        tiles.add(new MapTile(HOUSE_X+MapTile.tileW,HOUSE_Y+MapTile.tileW));

        tiles.get(tiles.size()-1).setType(MapTile.TYPE_HOUSE);
    }

    public  ArrayList getTiles() {
        return tiles;
    }

    public  void setTiles(ArrayList tiles) {
        this.tiles = tiles;
    }
}

#第一关的关卡信息,注意文件中不能有空格
#敌人数量
enemyCount=50
#敌人坦克类型
enemyType=0
#地图生成的方式通过调用哪一种方法来实现
method=addRow
#该方法调用的次数来绘制
invokeCount=5
#注意方法调用时应该传入的参数
#int startX,int startY,int endX,int type,int DIS
parma1=0,0,0,0,0
parma2=0,2,0,3,2
parma3=0,4,0,3,0
parma4=0,6,0,0,2
parma5=0,8,0,2,0

这里给出的是第一个关卡,后续的可以自己设置难度以及通关等界面,只需要在文件中定义,然后代码解析文件即可
​
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/924884.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号