当前位置: 首页 > 图灵资讯 > 技术篇> Java实现坦克大战1.0

Java实现坦克大战1.0

来源:图灵教育

坦克大战1.0java 绘图坐标系统坐标系-介绍

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

Java实现坦克大战1.0_事件监听器

坐标系统-像素

绘图还必须找出一个非常重要的概念——像素等于多少厘米?

屏幕上显示的计算机内容由屏幕上的每个像素组成。例如,计算机显示器的分辨率为800×600意味着计算机屏幕上的每行由800个点组成,共600行,整个计算机屏幕共480行 000像素。像素是密度单位,厘米是长度单位,两者无法比拟。

介绍-快速入门绘图原理

在面板上画一个小圆。

与绘图相关的Component类提供了两种最重要的方法:1. paint(Graphics g)绘制组件的外观

repaint()刷新组件的外观。

当组件首次显示在屏幕上时,程序会自动调用paint()来绘制组件。在以下情况下,paint(将被调用:

1.最小化窗口,最大化窗口

2.窗户的大小发生了变化

3.调用repaint方法

Graphics 类

你可以理解Graphics类是画笔,它为我们提供了各种绘制图形的方法:[参考jdk帮助文档]

1.画直线 drawLine(int x1,int y1,int x2,int y2)

2.画矩形边框 drawRect(int x, int y, int width, int height)

3.画椭圆边框 drawOval(int x, int y, int width, int height)

4.填充矩形 fillRect(int x, int y, int width, int height)

5.填充椭圆 fillOval(int x, int y, int width, int height)

6.画图片 drawlmage(Image img, int x, int y. ..)

7.画字符串 drawString(String str, int x, int y) 以左下角为参考系。

8.设置画笔字体 setFont(Font font)

9.设置画笔的颜色 setColor(Color c)

package com.hspedu.draw;import javax.swing.*;import java.awt.*;@SuppressWarnings({"all"})public class DrawCircle extends JFrame { //JFrame对应窗口,它可以理解为一个画框    //定义面板    private MyPanel mp = null;    public static void main(String[] args) {        new DrawCircle();        System.out.println(“退出程序~”;    }    public DrawCircle() {//构造器        ///初始化面板        mp = new MyPanel();        ///把面板放在窗口(画框)        this.add(mp);        //设置窗口大小        this.setSize(400, 300);        //当点击窗口时×,完全退出程序.        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        this.setVisible(true);//可显示    }}//1.先定义一个MyPanel, 继承JPanel, 画图形,在面板上画class MyPanel extends JPanel {    //说明:    //1. MyPanel 对象是画板    //2. Graphics g 把 g 理解成画笔    //3. Graphics 提供了许多绘图方法    //Graphics g    @Override    public void paint(Graphics g) {///绘图方法        super.paint(g); ////调用父类的方法完成初始化.        System.out.println("paint 调用方法~");        ///画一个圆.        //g.drawOval(10, 10, 100, 100);        ///演示绘制不同的图形..        //画直线 drawLine(int x1,int y1,int x2,int y2)        //g.drawLine(10, 10, 100, 100);        ///画矩形边框 drawRect(int x, int y, int width, int height)        //g.drawRect(10, 10, 100, 100);        ///画椭圆边框 drawOval(int x, int y, int width, int height)        //填充矩形 fillRect(int x, int y, int width, int height)        //设置画笔的颜色///        g.setColor(Color.blue);//        g.fillRect(10, 10, 100, 100);        //填充椭圆 fillOval(int x, int y, int width, int height)//        g.setColor(Color.red);//        g.fillOval(10, 10, 100, 100);        //画图片 drawImage(Image img, int x, int y, ..)        //1. 获取图片资源, /bg.png 这意味着获取项目的根目录 bg.png 图像资源///        Image image = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bg.png"));//        g.drawImage(image, 10, 10, 175, 221, this);        ///画字符串 drawString(String str, int x, int y)//写字        ///给画笔设置颜色和字体        g.setColor(Color.red);        g.setFont(new Font(“隶书”, Font.BOLD, 50));        ///设置在这里 100, 100, 是 左下角,“北京你好”        g.drawString(你好,北京”, 100, 100);        ///设置画笔字体 setFont(Font font)        //设置画笔的颜色 setColor(Color c)    }}
绘出坦克

Java实现坦克大战1.0_java_02

java 基本说明处理机制

java事件处理采用“委派事件模型”。当事件发生时,事件发生的对象将将“信息”传递给“事件监听者”。这里提到的“信息”实际上是java.awt.event事件库中某类创建的对象称为“事件对象”。

示意图

Java实现坦克大战1.0_java_03

深入了解事件处理机制
  1. 我们前面提到了几个重要的概念事件来源、事件和事件监控器。让我们全面介绍它们.
  2. 事件源:事件源是产生事件的对象,如按钮、窗口等。
  3. 事件:事件是承载事件源状态变化时的对象,如键盘事件、鼠标事件、窗口事件等。,这将生成一个保存大量当前事件信息的事件对象。例如,Keyevent对象包含按键的Code值。 java.awt.event包和javax.swing.event包定义了各种事件类型
  4. 事件类型:查阅jdk文档
  5. 事件监听器接口:(1)当事件源产生事件时,可以传送给事件监听器处理(2)事件监听器实际上是一个类别,实现了事件监听器接口。比如我们之前案例中的MyPanle就是一个类别,它实现了KeyListener接口,可以作为事件监听器来处理接收到的事件。(3)事件监听器接口有很多种。不同的事件监听器接口可以监控不同的事件,一个类可以实现Java中的多个监听接口(4).awt.event包和javax.swing.event包中的定义。列出常用的事件监听器接口,查看jdk文档。
坦克动起来

现在让我们学习java事件处理机制和java绘图技术。请尝试如何使您的坦克通过按钮控制上、下、左(wdsa表示)的移动。

Java实现坦克大战1.0_java_04

package com.hspedu.tankgame2;/** * 敌人的坦克 */public class EnemyTank extends Tank {    public EnemyTank(int x, int y) {        super(x, y);    }}
package com.hspedu.tankgame2;public class Hero extends Tank {    public Hero(int x, int y) {        super(x, y);    }}
package com.hspedu.tankgame2;import javax.swing.*;import java.awt.event.KeyListener;public class Hsptankgame0 extends JFrame {    //定义MyPanel    MyPanel mp = null;    public static void main(String[] args) {        Hsptankgame0 hsptankgame0 = new Hsptankgame0();    }    public Hsptankgame0() {        mp = new MyPanel();        this.add(mp);///把面板(即游戏的绘图区域)        this.setSize(1000, 750);        // 引用一个接口可以指向实现该接口的对象(mp实现该接口) this.addKeyListener(KeyListener I);        this.addKeyListener(mp); //让JFrame 监控mp键盘事件        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        this.setVisible(true);    }}
package com.hspedu.tankgame2;import javax.swing.*;import java.awt.*;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.util.Vector;/** * 坦克大战的绘图区域 */////监听 键盘事件, Keylistenerpublicic实现 class MyPanel extends JPanel implements KeyListener {    //定义我的坦克    Hero hero = null;    //定义敌人坦克,放入Vector    Vector<EnemyTank> enemyTanks = new Vector<>();    int enemyTankSize = 3;    public MyPanel() {        hero = new Hero(100, 100);///初始化自己的坦克        ///初始化敌人坦克        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(), 1);        //画敌人的坦克, Vector遍历        for (int i = 0; i < enemyTanks.size(); i++) {            ///取出坦克            EnemyTank enemyTank = enemyTanks.get(i);            drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.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;        }        //按坦克方向,绘制相应形状的坦克        //direct 表示方向(0: 向上 1 向右 2 向下 3 向左 )        //        switch (direct) {            case 0: //表示向上                g.fill3DRect(x, y, 10, 60, false);///画坦克左轮子                g.fill3DRect(x + 30, y, 10, 60, false);///画坦克右侧的轮子                g.fill3DRect(x + 10, y + 10, 20, 40, false);///画坦克盖                g.fillOval(x + 10, y + 20, 20, 20);//画圆盖                g.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;            default:                System.out.println(“暂时未处理”);        }    }    @Override    public void keyTyped(KeyEvent e) {    }    ///处理wdsa 按键的情况    @Override    public void keyPressed(KeyEvent e) {        System.out.println(e.getKeyCode());        if (e.getKeyCode() == KeyEvent.VK_W) {//按W键            //改变坦克的方向            hero.setDirect(0);//            ///修改坦克坐标 y -= 1            hero.moveUp();        } else if (e.getKeyCode() == KeyEvent.VK_D) {///D键, 向右            hero.setDirect(1);            hero.moveRight();        } else if (e.getKeyCode() == KeyEvent.VK_S) {//S键            hero.setDirect(2);            hero.moveDown();        } else if (e.getKeyCode() == KeyEvent.VK_A) {//A键            hero.setDirect(3);            hero.moveLeft();        }        //让面板重画,如果不重绘,就不会有变化        this.repaint();    }    @Override    public void keyReleased(KeyEvent e) {    }}
package com.hspedu.tankgame2;public class Tank {    private int x;///坦克的横坐标    private int y;///坦克纵坐标    private int direct = 0;///坦克方向 0 上1 右 2下 3左    private int speed = 1;    public int getSpeed() {        return speed;    }    public void setSpeed(int speed) {        this.speed = speed;    }    //上右下左移动方法    public void moveUp() {        y -= speed;    }    public void moveRight() {        x += speed;    }    public void moveDown() {        y += speed;    }    public void moveLeft() {        x -= speed;    }    public int getDirect() {        return direct;    }    public void setDirect(int direct) {        this.direct = direct;    }    public Tank(int x, int y) {        this.x = x;        this.y = y;    }    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;    }}
作业

画三辆敌人坦克,注意颜色。如图所示:

  1. 因为敌人的坦克在MyPanel上,我们的代码在MyPanel上
  2. 因为敌人的坦克背后有自己特殊的属性和方法,所以可以单独打开EnemyTank
  3. 敌人坦克数量多,可以放入集合Vector ,考虑多线程问题

代码同上。