• Java 第二阶段提升编程能力【坦克大战1.0】


    代码链接:https://download.csdn.net/download/qq_52354698/86402022?spm=1001.2014.3001.5501

    1. 坦克大战游戏演示

    1. 游戏演示

    在这里插入图片描述

    2. 涉及技术

    1. Java 面向对象编程
    2. 多线程
    3. 文件 i/o 操作
    4. 数据库

    2. Java 绘图坐标体系

    1. 坐标体系-介绍

    坐标源点位于左上角,以像素为单位。在Java坐标系中,第一个为 x 坐标,表示当前位置为水平方向,距离坐标原点 x 个像素;第二个是 y 坐标,表示当前位置为垂直方向,距离坐标原点 y 个像素。

    在这里插入图片描述

    2. 坐标体系-像素

    1. 像素不能单纯理解为多少厘米。
    2. 计算机显示器的分辨率为800x600,表示计算机屏幕上的每一行由800个点组成,共有600行,整个计算机屏幕共有480000个像素。像素是一个密度单位,而厘米是长度单位,两者不能混为一谈。

    3. 介绍-快速入门

    利用java绘制一个圆

    在这里插入图片描述

    package com.qdu.draw;
    
    import javax.swing.*;
    import java.awt.*;
    
    /**
     * @author dell
     * @version 1.0
     */
    public class DrawCircle extends JFrame {
    
        private MyPanel myPanel = null;
    
        public static void main(String[] args) {
    
            new DrawCircle();
    
        }
    
        public DrawCircle() {
            myPanel = new MyPanel();
            this.add(myPanel);
            this.setSize(400, 300);
            this.setVisible(true);
        }
    
    }
    
    class MyPanel extends JPanel {
    
        @Override
        public void paint(Graphics g) {
            super.paint(g);
            g.drawOval(10, 10, 100, 100);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    4. 绘图原理

    Component 类提供了两个和绘图相关的重要的方法

    1. paint(Graphics g)绘制组件的外观
    2. repaint()刷新组件的外观

    当组件第一次在屏幕显示的时候,程序会自动的调用paint()方法来绘制组件
    在以下情况paint()将会被再次调用

    1. 窗口最小化,再最大化
    2. 窗口的大小发生变化
    3. repaint 函数被调用

    5. Graphics 类

    1. 画直线:g.drawLine(10, 10, 100, 100);
      在这里插入图片描述

    2. 画矩形边框:g.drawRect(10, 10, 100, 100);
      在这里插入图片描述

    3. 画椭圆边框:g.drawOval(10, 10, 100, 100)
      在这里插入图片描述

    4. 填充矩形:g.setColor(Color.blue); g.fillRect(10, 10, 100, 100);
      在这里插入图片描述

    5. 填充椭圆:g.setColor(Color.red); g.fillOval(10, 10, 100, 100);
      在这里插入图片描述

    6. 画图片:Image image = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/在人间负债^.jpg")); g.drawImage(image, 10, 10, 1080, 1080, this);
      在这里插入图片描述

    在这里插入图片描述
    7. 画字符串:g.setColor(Color.red); g.setFont(new Font("隶书", Font.BOLD, 50)); g.drawString("北京你好",100,100);
    在这里插入图片描述

    6. 会出坦克

    在这里插入图片描述

    package com.qdu.tankgame;
    
    import javax.swing.*;
    import java.awt.*;
    
    /**
     * @author dell
     * @version 1.0
     */
    public class MyPanel extends JPanel {
    
        Hero hero = null;
    
        public MyPanel() {
            hero = new Hero(100, 100);
        }
    
        @Override
        public void paint(Graphics g) {
            super.paint(g);
            g.fillRect(0, 0, 1000, 750);
            drawTank(hero.getX(), hero.getY(), g, 0, 0);
        }
    
        /**
         * @param x      坦克左上角x坐标
         * @param y      坦克左上角y坐标
         * @param g      画笔
         * @param direct 坦克方向(上下左右)
         * @param type   坦克类型(自己、敌人)
         */
        public void drawTank(int x, int y, Graphics g, int direct, int type) {
            switch (type) {
                case 0:
                    g.setColor(Color.cyan);
                    break;
                case 1:
                    g.setColor(Color.yellow);
                    break;
            }
    
            switch (direct) {
                case 0:
                    //坦克左边的轮子
                    g.fill3DRect(x, y, 10, 60, false);
                    //坦克右边的轮子
                    g.fill3DRect(x + 30, y, 10, 60, false);
                    //坦克中间的矩形
                    g.fill3DRect(x + 10, y + 10, 20, 40, false);
                    //坦克中间的圆形
                    g.fillOval(x + 10, y + 20, 20, 20);
                    //坦克的炮筒
                    g.drawLine(x + 20, y + 30, x + 20, y);
                    break;
                case 1:
                    System.out.println("尚未处理");
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    在这里插入图片描述

    3. Java 事件处理机制

    实现键盘监听事件,来控制小球的移动

    package com.qdu.event_;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.util.logging.XMLFormatter;
    
    /**
     * @author dell
     * @version 1.0
     */
    public class BallMove extends JFrame {
    
        MyPanel myPanel = null;
    
        public static void main(String[] args) {
    
            BallMove ballMove = new BallMove();
    
        }
    
        public BallMove() {
            myPanel = new MyPanel();
            this.add(myPanel);
            this.setSize(400, 300);
            this.addKeyListener(myPanel);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setVisible(true);
        }
    
    }
    
    class MyPanel extends JPanel implements KeyListener {
    
        private int x = 10;
        private int y = 10;
    
        @Override
        public void paint(Graphics g) {
            super.paint(g);
            g.fillOval(x, y, 20, 20);
        }
    
        @Override
        public void keyTyped(KeyEvent e) {
    
        }
    
        @Override
        public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_DOWN) {
                y++;
            } else if (e.getKeyCode() == KeyEvent.VK_UP) {
                y--;
            } else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
                x--;
            } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
                x++;
            }
            this.repaint();
        }
    
        @Override
        public void keyReleased(KeyEvent e) {
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    在这里插入图片描述

    1. 基本说明

    java 事件处理是采用“委派事件模型”。当事件发生时,产生事件的对象,会把此“信息”传递给“事件的监听者”处理,这里所说的“信息”实际上就是java.awt.event事件类库里某个类所创阿金的对象,把它称为“事件的对象”。
    在这里插入图片描述

    2. 机制分析

    在这里插入图片描述

    3. 事件处理机制深入理解

    1. 事件源:事件源是一个产生事件的对象,比如按钮,窗口等。
    2. 事件:事件就是承载事件源状态改变时的对象,比如当键盘事件、鼠标事件、窗口事件等等,会生成一个事件对象,该对象保存着当前时间很多信息。
    3. 事件类型:
      在这里插入图片描述
    4. 时间监听器接口:
      1. 当事件源产生一个事件,可以传送给事件监听者处理
      2. 时间监听者实际上就是一个类,该类实现了某个事件监听接口
      3. 事件监听器接口有多种,不同的时间监听器接口可以监听不同的事件,一个类可以实现多个监听接口

    4. 坦克大战游戏

    1. 让坦克动起来

    package com.qdu.tankgame;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    
    /**
     * @author dell
     * @version 1.0
     */
    public class MyPanel extends JPanel implements KeyListener {
    
        Hero hero = null;
    
        public MyPanel() {
            hero = new Hero(100, 100);
            hero.setSpeed(3);
        }
    
        @Override
        public void paint(Graphics g) {
            super.paint(g);
            g.fillRect(0, 0, 1000, 750);
            drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 0);
        }
    
        /**
         * @param x      坦克左上角x坐标
         * @param y      坦克左上角y坐标
         * @param g      画笔
         * @param direct 坦克方向(上下左右)
         * @param type   坦克类型(自己、敌人)
         */
        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;
            }
    
            //根据坦克方向,来绘制不同的方向的坦克
            //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.drawLine(x + 20, y + 30, x + 20, y);
                    break;
                case 1:
                    //坦克左边的轮子
                    g.fill3DRect(x, y, 60, 10, false);
                    //坦克右边的轮子
                    g.fill3DRect(x, y + 30, 60, 10, false);
                    //坦克中间的矩形
                    g.fill3DRect(x + 10, y + 10, 40, 20, false);
                    //坦克中间的圆形
                    g.fillOval(x + 20, y + 10, 20, 20);
                    //坦克的炮筒
                    g.drawLine(x + 30, y + 20, x + 60, y + 20);
                    break;
                case 2:
                    //坦克左边的轮子
                    g.fill3DRect(x, y, 10, 60, false);
                    //坦克右边的轮子
                    g.fill3DRect(x + 30, y, 10, 60, false);
                    //坦克中间的矩形
                    g.fill3DRect(x + 10, y + 10, 20, 40, false);
                    //坦克中间的圆形
                    g.fillOval(x + 10, y + 20, 20, 20);
                    //坦克的炮筒
                    g.drawLine(x + 20, y + 30, x + 20, y + 60);
                    break;
                case 3:
                    //坦克左边的轮子
                    g.fill3DRect(x, y, 60, 10, false);
                    //坦克右边的轮子
                    g.fill3DRect(x, y + 30, 60, 10, false);
                    //坦克中间的矩形
                    g.fill3DRect(x + 10, y + 10, 40, 20, false);
                    //坦克中间的圆形
                    g.fillOval(x + 20, y + 10, 20, 20);
                    //坦克的炮筒
                    g.drawLine(x + 30, y + 20, x, y + 20);
                    break;
            }
        }
    
        @Override
        public void keyTyped(KeyEvent e) {
    
        }
    
        //处理wdsa键按下的事件
        @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();
            }
            this.repaint();
        }
    
        @Override
        public void keyReleased(KeyEvent e) {
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129

    在这里插入图片描述

    2. 添加敌人坦克

    package com.qdu.tankgame;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.util.Vector;
    
    /**
     * @author dell
     * @version 1.0
     */
    public class MyPanel extends JPanel implements KeyListener {
    
        Hero hero = null;
        Vector<EnemyTank> enemyTanks = new Vector<>();//使用vector保证后续的线程安全
        int enemyTankSize = 3;
    
        public MyPanel() {
            hero = new Hero(100, 100);
            hero.setSpeed(3);
            for (int i = 0; i < enemyTankSize; i++) {
                //创建敌人坦克
                EnemyTank enemyTank = new EnemyTank(100 * (i + 1), 0);
                //设置敌人坦克方向
                enemyTank.setDirect(2);
                //加入坦克
                enemyTanks.add(enemyTank);
            }
        }
    
        @Override
        public void paint(Graphics g) {
            super.paint(g);
            g.fillRect(0, 0, 1000, 750);
            //画出自己的坦克
            drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 0);
            //画出敌人的坦克
            for (int i = 0; i < enemyTanks.size(); i++) {
                EnemyTank enemyTank = enemyTanks.get(i);
                drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 1);
            }
        }
    
        /**
         * @param x      坦克左上角x坐标
         * @param y      坦克左上角y坐标
         * @param g      画笔
         * @param direct 坦克方向(上下左右)
         * @param type   坦克类型(自己、敌人)
         */
        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;
            }
    
            //根据坦克方向,来绘制不同的方向的坦克
            //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.drawLine(x + 20, y + 30, x + 20, y);
                    break;
                case 1:
                    //坦克左边的轮子
                    g.fill3DRect(x, y, 60, 10, false);
                    //坦克右边的轮子
                    g.fill3DRect(x, y + 30, 60, 10, false);
                    //坦克中间的矩形
                    g.fill3DRect(x + 10, y + 10, 40, 20, false);
                    //坦克中间的圆形
                    g.fillOval(x + 20, y + 10, 20, 20);
                    //坦克的炮筒
                    g.drawLine(x + 30, y + 20, x + 60, y + 20);
                    break;
                case 2:
                    //坦克左边的轮子
                    g.fill3DRect(x, y, 10, 60, false);
                    //坦克右边的轮子
                    g.fill3DRect(x + 30, y, 10, 60, false);
                    //坦克中间的矩形
                    g.fill3DRect(x + 10, y + 10, 20, 40, false);
                    //坦克中间的圆形
                    g.fillOval(x + 10, y + 20, 20, 20);
                    //坦克的炮筒
                    g.drawLine(x + 20, y + 30, x + 20, y + 60);
                    break;
                case 3:
                    //坦克左边的轮子
                    g.fill3DRect(x, y, 60, 10, false);
                    //坦克右边的轮子
                    g.fill3DRect(x, y + 30, 60, 10, false);
                    //坦克中间的矩形
                    g.fill3DRect(x + 10, y + 10, 40, 20, false);
                    //坦克中间的圆形
                    g.fillOval(x + 20, y + 10, 20, 20);
                    //坦克的炮筒
                    g.drawLine(x + 30, y + 20, x, y + 20);
                    break;
            }
        }
    
        @Override
        public void keyTyped(KeyEvent e) {
    
        }
    
        //处理wdsa键按下的事件
        @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();
            }
            this.repaint();
        }
    
        @Override
        public void keyReleased(KeyEvent e) {
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146

    在这里插入图片描述

  • 相关阅读:
    第8章 函数探幽
    【单片机毕业设计】【mcuclub-hj-015】基于单片机的水质监控的设计
    点云学习笔记14——ModuleNotFoundError: No module named ‘rospy
    Py_Deep leaning
    使用 Nacos 在 Spring Boot 项目中实现服务注册与配置管理
    Vue 中 == 和 ===、&& 、|| 等操作符的用法
    1.3-参数化
    解决IDEA中maven无法引进okhttp依赖
    Zabbix监控
    CentOS7安装squid代理服务器
  • 原文地址:https://blog.csdn.net/qq_52354698/article/details/126366729