zoukankan      html  css  js  c++  java
  • JAVA课程设计(坦克大战)

    2019-01-16

    坦克大战游戏背景:

    1. 需求分析

    1.1环境要求

    操作系统:Windows 7(SP1)以上

    JAVA虚拟机:JDK1.8以上

    开发环境:Eclipse(4.5以上)

    1.2角色设定

    用户在系统中扮演的角色,以及可以执行的职责。

    玩 家 操纵玩家坦克,与敌方坦克作战,同时保护本基地。敌方坦克随机移动,发射子弹。

    1.3设定玩家(玩家一,玩家二,即一个人玩还是两个人玩),我方坦克的方向和子弹由用户控制,所有墙块都可以打碎,但是铁墙是打不碎的,草地不能阻止坦克和子弹的前进,河流能阻止坦克前进,但是不能阻止子弹前进。我方基地被毁则游戏结束,自己的坦克被毁游戏也结束,唯一赢得方式是消灭所有的敌方坦克,则可以进入下一关。一关比一关的难度大,通过地图来实现。

    一·团队介绍

    团队名称:阳光四人组

    学号   班级  姓名  简介
     201721123094  网络1714  何昕桐(组长)  学习能力强,漂亮又可爱
     201721123068  网络1713  梁琦珧  有思想,有能力,有担当
     201721123093  网络1714  李志婷  有专研精神,刻苦,积极向上
     201721123069  网络1713  陈慧琳  低调~

    团员任务分配:

    成员 任务 博客链接
    何昕桐 坦克类 (电脑坦克类,玩家坦克类),代码整合 https://www.cnblogs.com/hexintong99/p/10279072.html 
    梁琦珧 枚举,子弹类,工具类 https://www.cnblogs.com/liangqiyao/p/10275786.html 
    李志婷 GUI界面(游戏面板,登录面板,主窗体) https://www.cnblogs.com/lizhiting/p/10275909.html 
    陈慧琳 基地类,墙块类,爆炸效果类,地图类 https://www.cnblogs.com/chenhuilin/p/10275855.html 

    这个坦克游戏几位同志可是很辛苦啦!经过重重考虑,联网功能和游戏排行榜还是未成功实现:

    时间太短,能力有限啊!

    二·项目git

    1.项目git地址

    https://gitee.com/mayun126/TankWar.git

    2.项目git提交记录截图

    三·项目功能架构图与主要功能流程图

    1.项目功能架构图

    2.功能流程图

     

    3.面向对象类设计图

    Wall:

     Visible:

     乖乖献上了类图:

     四·项目运行截图和屏幕录制

    演示:

     

    双人游戏和界面地图的设计是我们这个课设的特点:

     

    1.游戏面板:绘制游戏界面,将所有游戏元素展现出来

    2.显示关卡面板(第几关开始提示):登录面板和游戏面板的过渡界面,只有一个闪烁的动画效果

    3.主窗体:整个面板最外层载体,一个800*600的窗体

    4.登录面板:选择游戏模式是单人还是双人

    五·项目关键代码

    代码太多,主要列出了主要的类以及特色的功能代码,耐心看看,O(∩_∩)O哈哈~

    玩家坦克类:

    public class Tank extends VisibleImage{
        GamePanel gamePanel; //游戏界面,提供当前面板的内容进行判断
        Direction direction; //移动方向
        protectedbooleanalive=true; //是否存活
        protectedintspeed=3; //移动速度
        privatebooleanattackCoolDown =true;//攻击冷却状态
        privateintattackCoolDownTime =500;//攻击冷却时间毫秒间隔500ms发射子弹
        TankType type;//坦克类型
        private String upImage; //向上移动时的图片
        private String downImage;//向下移动时的图片
        private String rightImage;//向右移动时的图片
        private String leftImage;//向左移动时的图片
        
        //坦克构造方法初始化横纵坐标xy
        //url默认为向上的图片
        public Tank(int x,int y,String url,GamePanel gamePanel,TankType type){
            super(x,y,url);
            this.gamePanel=gamePanle;
            this.type=type;
            direction= Directon.UP;
            switch(type){
            case player1://玩家1
                upImage=ImageUtil.PLAYER1_UP_IMAGE_URL;
                downImage=ImageUtil.PLAYER1_DOWN_IMAGE_URL;
                rightImage=ImageUtil.PLAYER1_LEFT_IMAGE_URL;
                leftImage=ImageUtil.PLAYER1_RIGHT_IMAGE_URL;
                break;
            case player2://玩家2
                upImage=ImageUtil.PLAYER2_UP_IMAGE_URL;
                downImage=ImageUtil.PLAYER2_DOWN_IMAGE_URL;
                rightImage=ImageUtil.PLAYE2_LEFT_IMAGE_URL;
                leftImage=ImageUtil.PLAYER2_RIGHT_IMAGE_URL;
                break;
            case bot: 
                upImage=ImageUtil.BOT_UP_IMAGE_URL;
                downImage=ImageUtil.BOT_DOWN_IMAGE_URL;
                rightImage=ImageUtil.BOT_LEFT_IMAGE_URL;
                leftImage=ImageUtil.BOT_RIGHT_IMAGE_URL;
                break;
            } 
        } 
        //向左
        public void leftward(){
            if(direxction!=Directon.LEFT)  setImage(leftImage);//若之前的移动方向不是左移,跟换左移图片
            direxction=Directon.LEFT;
            if(!hitWall(x-speed,y)&&hitTank(x-speed,y)){
                x-=speed;//横坐标递减
                moveToborder();//判断是否移动到游戏面板的边界
            }
        }
        //向右
        public void rightward(){
            if(direxction!=Directon.RIGHT)  setImage(rightImage);
            direxction=Directon.RIGHT;
            if(!hitWall(x+speed,y)&&hitTank(x+speed,y)){
                x+=speed;
                moveToborder();//判断是否移动到游戏面板的边界
            }
        }
        //向上
        public void upward(){
            if(direxction!=Directon.UP)  setImage(upImage);
            direxction=Directon.UP;
            if(!hitWall(x,y-speed)&&hitTank(x,y-speed)){
                y-=speed;
                moveToborder();//判断是否移动到游戏面板的边界
            }
        }
        //向下
        public void downward(){
            if(direxction!=Directon.DOWN)  setImage(downImage);
            direxction=Directon.DOWN;
            if(!hitWall(x,y+speed)&&hitTank(x,y+speed)){
                y+=speed;
                moveToborder();//判断是否移动到游戏面板的边界
            }
        }
        //是否撞到墙块
        public boolean hitWall(int x,int y){
            Rectangle next=new Rectangle(x,y,width,height);//创建坦克移动后的目标区域
            List<Wall> walls=gamePanel.getWalls();//获取面板上所有的墙体对象
            for(int i=0,length=walls.size();i<length;i++){
                Wall w=walls.get(i);//获取墙块对象
                if(w instanceof GrassWall){//碰到草坪
                    continue; 
                }elseif(w.hit(next)){ //撞到墙
                    return true;
                }
            }
            return false;//没撞到墙
        }
    
        //是否撞到坦克
        public boolean hitTank(int x,int y){
            Rectangle next=new Rectangle(x,y,width,height);//创建坦克移动后的目标区域
            List<Tank> tanks=gamePanel.getTanks();//获取面板上所有的坦克对象
            for(int i=0,length=tanks.size();i<length;i++){
                Tank t=tanks.get(i);//获取坦克对象
                if(!this.equals(t)){//此坦克与自身不是一个对象
                if(t.isAlive()&&t.hit(next)){//此坦克存活并且与自身相撞
                    return true;
                   }
                }
            }
            return false;//没撞到坦克
            }
        //移动到面板的边界
        protected void moveToBorder(){
            if(x<0){
                x=0;
            }else if(x>gamePanel.getWidth()-width){
                x=gamePanel.getWidth-width;
            }
            if(y<0){
                y=0;
            }else if(y>gamePanel.getHeight()-height){
                y=gamePanel.getHeight-height
            }
            }
        //获取坦克头
        private Point getHeadPoint(){
            Point p=new Point();//创建头对象,作为头点
            switch(direxction){//判断移动方向
            case UP:
                p.x=x+width/2;
                p.y=y;
                break;
            case DOWN:
                p.x=x+width/2;
                p.y=y+height;
                break;
            case RIGHT:
                p.x=x+width;
                p.y=y+height/2;
                break;
            case LEFT:
                p.x=x;
                    p.y=y+height/2; 
                    break;
                    default:
                        p=null;
            }
            return p;//返回头点
            }
        //攻击
        public void attack(){
            if(attackCoolDown){//如果攻击功能完成冷却
                Point p=getHeadPoint();//获取坦克头对象
                Bullet b=new Bullet(p.x-Bullet.LENGTH/2,p.y-Bullet.LENGTH/2,direction,gamePanel,type);
                gamePanel.addBullet(b);//游戏面板添加子弹
                new AttackCD().start();//开始冷却倒计时
            }
            }
        //坦克是否存活
        public boolean isAlive(){
            return alive;
            }
        public void setAlive(boolean alive){
            this.alive=alive;
            }
        //坦克的速度
        public void setSpeed(int speed){
            this.speed=speed;
            }
        //攻击冷却时间线程
        private class AttackCD extends Thread{
            public void run(){
                attackCoolDown=false;//将攻击功能设置为冷却状态
                try{
                    Tread.sleep(attackCoolDown);//休眠0.5秒
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
                attackCoolDown=true;//将攻击功能解除冷却状态
            }
            }
        //获取攻击功能是否处于冷却
        public boolean isAttackCoolDown(){
            return attackCoolDown;
            }
        public void setAttackCoolDownTime(int attackCoolDownTime){
            this.attackCoolDownTime=attackCoolDownTime;
            } 
    }

    敌方坦克类:

    public class Bot extends Tank{
        private Random random=new Random();//
        private Direction dir;
        private int fresh=GamePanel.FRESH;
        private int MoveTimer=0;
    
        public Bot(int x,int y,GamePanel gamePanel,TankType type) {
            super(x,y,ImageUtil.BOT_DOWN_IMAGE_URL,gamePanel,type);
            dir=Direction.DOWN;
            setAttackCoolDownTime(1000);
            //setSpeed(2);
        }
        public void go() {
            if(isAttackCoolDown()) {
                attack();
            }
            if(MoveTimer>=3000) {
                dir=randomDirection();
                MoveTimer=0;
            }else {
                MoveTimer+=fresh;
            }
            switch(dir) {
            case UP:
                upward();
                break;
            case DOWN: 
                downward();
                break;
            case RIGHT:
                rightward();
                break;
            case LEFT:
                leftward();
                break;
            }
        }    protected void moveToBorder() {
            if(x<0) {
                x=0;
                dir=randomDirection();
            }else if(x>gamePanel.getWidth()-width) {
                x=gamePanel.getWidth()-width;
                dir=randomDirection();
            }
            if(y<0) {
                y=0;
                dir=randomDirection();
            }else if(y>gamePanel.getHeight()-height) {
                y=gamePanel.getHeight()-height;
                dir=randomDirection();
            }
    
        }
    
        //重写碰到坦克的方法
        boolean hitTank(int x,int y) {
            Rectangle next=new Rectangle(x,y,width,height);//创建坦克移动后的目标区域
            List<Tank> tanks=gamePanel.getTanks();//获取面板上所有的坦克对象
            for(int i=0,length=tanks.size();i<length;i++){
                Tank t=tanks.get(i);//获取坦克对象
                if(!this.equals(t)){//此坦克与自身不是一个对象
                    if(t.isAlive()&&t.hit(next)){//此坦克存活并且与自身相撞
                        if(t instanceof Bot) {
                            dir=randomDirection();
                        }
                        return true;
                    }
                }
            }
            return false;//没撞到坦克
        }    public Direction randomDirection() {
            int rnum =random.nextInt(4);
            switch(rnum) {
            case 0:
                return Direction.UP;
            case 1:
                return Direction.RIGHT;
            case 2:
                return Direction.LEFT;
            default:
                return Direction.DOWN;
            }
        }    public void attack() {
            int rnum =random.nextInt(100);
            if(rnum<4) {
                super.attack();
            }
        }
    }

    子弹类:

    public class Bullet extends VisibleImage{
        
        Direction direction;
        static final int LENGTH = 8; //子弹的(正方体)边长
        private GamePanel gamePanel;//游戏面板
        private int speed = 7;//移动速度
        private boolean alive = true;//子弹是否有效
        Color color = Color.ORANGE;//子弹颜色
        TankType owner;//发出子弹的坦克类型
        
        /**
         * 子弹构造方法
         * 
         * @param x - 子弹的初始横坐标
         * @param y - 子弹的初始纵坐标
         * @param direction - 子弹的发射方向
         * @param gamePanel - 游戏面板对象
         * @param Owner - 发出子弹的坦克类型
         */
        public Bullet(int x, int y, Direction direction, GamePanel gamePanel, TankType owner) {
            super(x, y, LENGTH, LENGTH); //调用父类构造方法
            // TODO 自动生成的构造函数存根
            this.direction = direction;
            this.gamePanel = gamePanel;
            this.owner = owner;
            init();//初始化组件
        }
        /**
         * 初始化组件
         */
        private void init() {
            // TODO 自动生成的方法存根
            Graphics g = image.getGraphics();//获取图片的绘图方法
            g.setColor(Color.WHITE);//使用白色绘图
            g.fillRect(0, 0, LENGTH, LENGTH);// 绘制一个铺满整个图片的白色实心矩形
            g.setColor(color);//使用子弹颜色
            g.fillOval(0, 0, LENGTH, LENGTH);// 铺满整个图片的实心圆形
            g.setColor(Color.BLACK); //使用黑色
            g.drawOval(0, 0, LENGTH-1, LENGTH-1); //绘制黑色边框,防止出界
        }
        /**
         * 子弹移动
         */
        public void move() {
            switch(direction) { //判断移动方向
            case UP:
                upward();
                break;
            case DOWN:
                downword();
                break;
            case LEFT:
                leftword();
                break;
            case RIGHT:
                rightword();
                break;
            }
        }
        /**
         * 移动函数
         */
        private void rightword() {
            // TODO 自动生成的方法存根
            x += speed;
            moveToBorder();
        }
    
        private void leftword() {
            // TODO 自动生成的方法存根
            x -= speed;
            moveToBorder(); //移动出面板后销毁子弹
        }
    
        private void downword() {
            // TODO 自动生成的方法存根
            y += speed;
            moveToBorder();
        }
    
        private void upward() {
            // TODO 自动生成的方法存根
            y -= speed;
            moveToBorder();
        }
        
        /**
         * 击中坦克
         */
        public void hitTank() {
            List<Tank> tanks = gamePanel.getTanks(); //获取坦克的集合
            for(int i = 0,length = tanks.size();i<length;i++) {//遍历坦克集合
                 Tank t = tanks.get(i);
                 if (t.isAlive()&&this.hit(t)) {//坦克活着并且子弹击中坦克
                     switch (owner) {
                    case player1://玩家的子弹
                    case player2:
                        if (t instanceof Bot) {//击中电脑
                            alive = false;//子弹销毁
                            t.setAlive(false);//电脑坦克死亡
                        }else if(t instanceof Tank){//击中玩家
                            alive = false;
                        }
                        break;
                    case bot://电脑的子弹
                        if (t instanceof Bot) {
                            alive = false;
                        }else if (t instanceof Tank) {
                            alive = false;
                            t.setAlive(false);
                        }
                        break;
                    default:
                        alive = false;
                        t.setAlive(false);
                        break;
                    }
                    
                }
            }
        }
        //击中基地
        public void hitBase() {
            Base b=gamePanel.getBase();
            if(this.hit(b)) {
                alive =false;
                b.setAlive(false);
            }
        }
        public void hitWall(){
            List<Wall> walls=gamePanel.getWalls();
            for(int i=0,length=walls.size();i<length;i++) {
                Wall w=walls.get(i);
                if(this.hit(w)) {
                    if(w instanceof BrickWall) {
                        alive=false;
                        w.setAlive(false);
                    }
                    if(w instanceof IronWall) {
                        alive=false;
                    }
                }
            }
        }
        //移除面板边界时销毁子弹
        private void moveToBorder() {
            if(x < 0|| x > gamePanel.getWidth() - getWidth()|| y < 0 || y > gamePanel.getHeight() - getHeight()) {
                dispose();
            }
        }
        //
        private synchronized void dispose() {
            alive=false;
        }
       //
        public boolean isAlive() {
            return alive;
        } 
    }

    主窗体:

    1.调整屏幕尺寸及位置

    2.建立窗口事件监听,使得在关闭窗口时会提示我们是否就此退出游戏。

    3.添加登录面板。

    public class MainFrame extends JFrame{
        public MainFrame()
        {
            setTitle("坦克大战");
            setSize(800,610);
            setResizable(false);
            Toolkit tool=Toolkit.getDefaultToolkit();
            Dimension d=tool.getScreenSize();
            setLocation((d.width-getWidth())/2, (d.height-getHeight())/2);
            setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
            addListener();
            setPanel(new LoginPanel(this));
        }
     private void addListener(){
         addWindowListener(new WindowAdapter() {
             public void windowClosing(WindowEvent e)
             {
                 int closeCode=JOptionPane.showConfirmDialog(MainFrame.this, "是否退出游戏","提示!",
                         JOptionPane.YES_NO_OPTION);
                 if(closeCode==JOptionPane.YES_OPTION) {
                     System.exit(0);
             }
         }
     });
     }
     public void setPanel(JPanel panel)
     {
         Container c=getContentPane();
         c.removeAll();
         c.add(panel);
         c.validate();
     }
    }

    碰撞检测:

    public class VisibleImage {
        /**
         * 横、纵坐标
         */
        public int x;
        public int y;
        /**
         * 长、宽
         */
        int width;
        int height;
        
        /**
         * 图像对象
         */
        BufferedImage image;
    
        /**
         * 构造方法
         * @param x -横坐标
         * @param y -纵坐标
         * @param width -宽
         * @param height -高
         */
        public VisibleImage(int x, int y, int width, int height) {
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
            image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);//实例化图片
        }
        /**
         * 构造方法
         * @param x -横坐标
         * @param y -纵坐标
         * @param url -图片路径
         */
        public VisibleImage(int x, int y, String url) {
            this.x = x;
            this.y = y;
            try {
                image = ImageIO.read(new File(url));//获取此路径的图片对象
                this.width = image.getWidth();
                this.height = image.getHeight();
            }catch (IOException e) {
                // TODO: handle exception
                e.printStackTrace();
            }
        }
        /**
         * 获取图片
         * @return 所显示的图片
         */
        public BufferedImage getImage() {
             return image;
         }
         /**
          * 设置图片
          * @param image -所显示的图片
          */
        public void setImage(BufferedImage image) {
             this.image = image;
         }
        /**
          * 设置图片
          * @param image -所显示的图片
          */
        public void setImage(String url) {
             try {
                 this.image = ImageIO.read(new File(url));
             }catch (IOException e) {
                // TODO: handle exception
                 e.printStackTrace();
            }
         }
        /**
         * 判断是否发生碰撞
         * @param v - 目标图片对象
         * @return 如果两者相交,返回true,否则返回false
         */
        public boolean hit(VisibleImage v) {
            return hit(v.getBounds());//执行重载方法
        }
        /**
         * 判断是否发生碰撞
         * @param r - 目标边界
         * @return 如果两者相交,返回true,否则返回false
         */
        public boolean hit(Rectangle r){
            if(r == null) {
                return false; //不发生碰撞
            }
            return getBounds().intersects(r); //判断边界对象是否相交
        }
        /**
         * 获取边界对象
         */
        public Rectangle getBounds() {
            //创建一个坐标在(x,y)位置,宽高为(width,height)的矩形边界对象并返回
            return new Rectangle(x, y, width, height);
        }
        /**
         * setter,getter方法获取并设置长宽高
         */
        public int getWidth() {
            return width;
        }
        public void setWidth(int width) {
            this.width = width;
        }
        public int getHeight() {
            return height;
        }
        public void setHeight(int height) {
            this.height = height;
        }
        @Override
        public String toString() {
            return "VisibleImage [x=" + x + ", y=" + y + ", width=" + width + ", height=" + height + "]";
        }
        
    }

    碰撞:子弹的碰撞有销毁他人,自我销毁,而坦克没有该功能。

    刷新帧:(关键技术)

    public GamePanel(MainFrame frame,int level,GameType gameType)
        {
            this.frame =frame ;
            this.level=level;
            this.gameType=gameType;
            setBackground(Color.GRAY);
            init();
            Thread t=new FreshThead();
            t.start();
            addListener();
        }
        private void init()
        {
            bullets=new ArrayList<Bullet>();
            allTanks=new ArrayList<>();
            walls=new ArrayList<>();
            boomImage=new ArrayList<>();
            image=new BufferedImage(794,572,BufferedImage.TYPE_INT_BGR);
            g2 =image.createGraphics();
    
            playerTanks=new ArrayList<>();
            play1=new Tank(278,537,ImageUtil.PLAYER1_UP_IMAGE_URL,this,TankType.player1);
            if(gameType==GameType.TWO_PLAYER)
            {
                play2=new Tank(500,537,ImageUtil.PLAYER2_UP_IMAGE_URL,this,TankType.player2);
                playerTanks.add(play2);
            }
            playerTanks.add(play1);
            botTanks=new Vector<>();
            botTanks.add(new Bot(botX[0],1,this,TankType.bot));
            botTanks.add(new Bot(botX[1],1,this,TankType.bot));
            botTanks.add(new Bot(botX[2],1,this,TankType.bot));
            botReadyCount-=3;
            allTanks.addAll(playerTanks);
            allTanks.addAll(botTanks);
            base=new Base(367,532);
            initWalls();
        }
        private void addListener()
        {
            frame.addKeyListener(this);
        }
        private void initWalls()
        {
            Map map=Map.getMap(level);
            walls.addAll(map.getWalls());
            walls.add(base);
        }
        public void paint(Graphics g)
        {
            paintTankActoin();
            CreateBot();
            paintImage();
            g.drawImage(image, 0, 0, this);
        }
        private void paintImage()
        {
            g2.setColor(Color.BLACK);
            g2.fillRect(0, 0, image.getWidth(),image.getHeight() );
            panitBoom();
            paintBotTanks();
            paintBotCount();
            panitPlayerTanks();
            allTanks.addAll(playerTanks);
            allTanks.addAll(botTanks);
            paintWalls();
            paintBullets();
            if(botSurplusCount==0)
            {
                stopThread();
                paintBotCount();
                g2.setFont(new Font("楷体",Font.BOLD,50));
                g2.setColor(Color.GREEN);
                g2.drawString("胜利", 250, 400);
                gotoNextLevel();
            }
            if(gameType ==GameType.ONE_PLAYER)
            {
                if(!play1.isAlive()) {
                    stopThread();
                    boomImage.add(new Boom(play1.x,play1.y));
                    panitBoom();
                    paintGameOver();
                    gotoPrevisousLevel();
                }
    
            }
            else {//双人模式
                if(play1.isAlive()&&!play2.isAlive())
                {
                    survivor=play1;
                }
                else if(!play1.isAlive()&&play2.isAlive())
                {
                    survivor=play2;
                }
                else if(!(play1.isAlive()||play2.isAlive())) {
                    stopThread();
                    boomImage.add(new Boom(survivor.x,survivor.y));
                    panitBoom();
                    paintGameOver();
                    gotoPrevisousLevel();//重新进入本关
                }
            }
            if(!base.isAlive())
            {
                stopThread();
                paintGameOver();
                base.setImage(ImageUtil.BREAK_BASE_IMAGE_URL);
                gotoPrevisousLevel();
    
            }
            g2.drawImage(base.getImage(),base.x,base.y,this);
        }
    
        private void paintBotCount() {
            g2.setFont(new Font("楷体",Font.BOLD,25));
            g2.setColor(Color.BLUE);
            g2.drawString("敌方坦克剩余:"+ botSurplusCount, 10,30);
    
        }
        private void paintGameOver()
        {
            g2.setFont(new Font("楷体",Font.BOLD,50));
            g2.setColor(Color.RED);
            g2.drawString("Game Over !",250,400);
    
        }
        private void panitBoom()
        {
            for(int i=0;i<boomImage.size();i++) {
                Boom boom=boomImage.get(i);
                if(boom.isAlive())
                {
                    boom.show(g2);
                }
                else
                {
                    boomImage.remove(i);
                    i--;
                }
            }
        }
        private void paintWalls()
        {
            for(int i=0;i<walls.size();i++)
            {
                Wall w=walls.get(i);
                if(w.isAlive())
                {
                    g2.drawImage(w.getImage(),w.x,w.y,this);
    
                }
                else {
                    walls.remove(i);
                    i--;
                }
            }
        }
        private void paintBullets()
        {
            for(int i=0;i<bullets.size();i++)
            {
                Bullet b=bullets.get(i);
                if(b.isAlive()) {
                    b.move();
                    b.hitBase();
                    b.hitWall();
                    b.hitTank();
                    g2.drawImage(b.getImage(), b.x,b.y,this);
                }else {
                    bullets.remove(i);
                    i--;
                }
            }
        }
        private void paintBotTanks()
        {
            for(int i=0;i<botTanks.size();i++)
            {
                Bot t=(Bot)botTanks.get(i);
                if(t.isAlive()) {
                    t.go();
                    g2.drawImage(t.getImage(), t.x,t.y,this);
                }else {
                    botTanks.remove(i);
                    i--;
                    boomImage.add(new Boom(t.x,t.y));
                    decreaseBot();
                }
            }
        }
        private void panitPlayerTanks()
        {
            for(int i=0;i<playerTanks.size();i++)
            {
                Tank t=playerTanks.get(i);
                if(t.isAlive()) {
                    g2.drawImage(t.getImage(), t.x,t.y,this);
                }else {
                    playerTanks.remove(i);
                    i--;
                    boomImage.add(new Boom(t.x,t.y));
    
                }
            }
        }
        private synchronized void stopThread()
        {
            frame.removeKeyListener(this);
            finish=true;
        }
    
        private class FreshThead extends Thread
        {
            public void run()
            {
                while(!finish)
                {
                    repaint();
                    try
                    {
                        Thread.sleep(FRESH);
    
                    }
                    catch(InterruptedException e)
                    {
                        e.printStackTrace();
                    }
    
                }
            }
        }
        private void CreateBot()
        {
            createBotTimer +=FRESH;
            if(botTanks.size()<botMaxInMap&&botReadyCount>0&&createBotTimer>=4000)
            {
                int index=r.nextInt(3);
                Rectangle bornRect=new Rectangle(botX[index],1,35,35);
                for(int i=0,lengh=allTanks.size();i<lengh;i++)
                {
                    Tank t=allTanks.get(i);
                    if(t.isAlive()&&t.hit(bornRect))
                    {
                        return;
                    }
                }
                botTanks.add(new Bot(botX[index],1,GamePanel.this,TankType.bot));
                botReadyCount--;
                createBotTimer=0;
            }
        }
        private void gotoNextLevel() {
            Thread jump=new JumpPageThead(Level.nextLevel());
            jump.start();
        }
        private void gotoPrevisousLevel() {
            Thread jump=new JumpPageThead(Level.previsousLevel());
            jump.start();
        }
        public void decreaseBot()
        {
            botSurplusCount--;
        }
        @Override
        public void keyPressed(KeyEvent e) {
            // TODO 自动生成的方法存根
            switch(e.getKeyCode())
            {
            case KeyEvent.VK_Y:
                y_key=true;
                break;
            case KeyEvent.VK_W:
                w_key=true;
                a_key=false;
                s_key=false;
                d_key=false;
                break;
            case KeyEvent.VK_A:
                w_key=false;
                a_key=true;
                s_key=false;
                d_key=false;
                break;
            case KeyEvent.VK_S:
                w_key=false;
                a_key=false;
                s_key=true;
                d_key=false;
                break;
            case KeyEvent.VK_D:
                w_key=false;
                a_key=false;
                s_key=false;
                d_key=true;
                break;
            case KeyEvent.VK_HOME:
            case KeyEvent.VK_NUMPAD1:
                num1_key=true;
                break;
            case KeyEvent.VK_UP:
                up_key=true;
                down_key=false;
                right_key=false;
                left_key=false;
                break;
            case KeyEvent.VK_DOWN:
                up_key=false;
                down_key=true;
                right_key=false;
                left_key=false;
                break;
            case KeyEvent.VK_LEFT:
                up_key=false;
                down_key=false;
                right_key=false;
                left_key=true;
                break;
            case KeyEvent.VK_RIGHT:
                up_key=false;
                down_key=false;
                right_key=true;
                left_key=false;
                break;
            }
        }
        private void paintTankActoin()
        {
            if(y_key)
            {
                play1.attack();
            }
            if(w_key)
            {
                play1.upward();
            }
            if(d_key)
            {
                play1.rightward();
            }
            if(a_key)
            {
                play1.leftward();
            }
            if(s_key)
            {
                play1.downward();
            }
            if(gameType==GameType.TWO_PLAYER)
            {
                if(num1_key)
                {
                    play2.attack();
                }
    
                if(up_key)
                {
                    play2.upward();
                }
                if(right_key)
                {
                    play2.rightward();
                }
    
                if(left_key)
                {
                    play2.leftward();
                }
                if(down_key)
                {
                    play2.downward();
                }
            }
        }
        @Override
        public void keyReleased(KeyEvent e) {
            // TODO 自动生成的方法存根
            switch(e.getKeyCode())
            {
            case KeyEvent.VK_Y:
                y_key=false;
                break;
            case KeyEvent.VK_W:
                w_key=false;
                break;
            case KeyEvent.VK_A:
                a_key=false;
                break;
            case KeyEvent.VK_S:
                s_key=false;
                break;
            case KeyEvent.VK_D:
                d_key=false;
                break;
            case KeyEvent.VK_HOME:
            case KeyEvent.VK_NUMPAD1:
                num1_key=false;
                break;    
            case KeyEvent.VK_UP:
                up_key=false;
                break;
            case KeyEvent.VK_DOWN:
                down_key=false;
                break;
            case KeyEvent.VK_LEFT:
                left_key=false;
                break;
            case KeyEvent.VK_RIGHT:
                right_key=false;
                break;
            }
        }
        public void addBullet(Bullet b)
        {
            bullets.add(b);
        }
        public List<Wall>getWalls(){
            return walls;
        }
        public Base getBase()
        {
            return base;
        }
        public List<Tank>getTanks()
        {
            return allTanks;
        }
        
        private class JumpPageThead extends Thread{
            int level;
            public JumpPageThead (int level)
            {
                this.level=level;
            }
            public void run()
            {
                try {
                    Thread.sleep(1000);
                    frame.setPanel(new LevelPanel(level,frame,gameType));
    
                }catch(InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
        }
    
        @Override
        public void keyTyped(KeyEvent e) {
            // TODO 自动生成的方法存根
            
        }
    
    }

     帧是一个量词,一个静态的画面就是一帧,帧的刷新频率决定了动画是否流畅。

    repaint();每隔一段时间画一张图片,这样实现了刷新的效果。在游戏面板的构造方法里创建游戏帧线程,结束通过一个finsh来判断。

    六·项目代码扫描结果及改正

     提交检查前请先将IDE中提示的所有警告(warning)解决。然后使用,阿里巴巴静态代码扫描工具(https://www.cnblogs.com/bb1119/p/7672939.html)对自己的项目进行扫描,并根据提示改正。

    1.代码扫描结果

     

    2.改正

    l 对if-else语句进行大括号补充
    l 对命名包文件进行修改,让它符合javac的命名规范
    l Switch-case语句必须以default结尾,对此进行补充

    七·尚待改进

      本次的坦克大战课设实现的是一些最基本坦克大战游戏功能,比较简单易懂,对于该游戏我们还存在很多的不足,比如可以尝试着做能够联网的多人游戏,一个游戏排行榜(好友,非好友)。

     

  • 相关阅读:
    jquery中attr和prop的区别
    Server.MapPath用法
    ERP登录(八)
    ViewBag、ViewData和TempData的使用和区别
    ERP权限系统(七)
    C#泛型(三)
    ERP员工入登记查询(六)
    ERP员工入职登记(五)
    MVC学习IIS的不同版本(一)
    兔子谋杀案
  • 原文地址:https://www.cnblogs.com/chenhuilin/p/10275664.html
Copyright © 2011-2022 走看看