Java GUI键盘监听--绘图(绘制坦克)和事件处理机制(如何让tank动起来)

绘图

坐标系

在这里插入图片描述

坐标体系-像素

1.绘图还必须要搞清一个非常重要的概念-像素一个像素等于多少厘米?
2.计算机在屏幕上显示的内容都是由屏幕上的每一个像素组成的。例如,计算机显示器的分辨率是800×600,
表示计算机屏幕上的每一行由800个点组成,共有600行,整个计算机屏幕共有480 000个像素。
像素是一个密度单位,而厘米是长度单位,两者无法比较

绘图原理

绘图原理
√Component类提供了两个和绘图相关最重要的方法:

  1. paint(Graphics g)绘制组件的外观
  2. repaint()刷新组件的外观。
    当组件第一次在屏幕显示的时候,程序会自动的调用paint()方法来绘制组件。
    √在以下情况paint()将会被调用:
    1.窗口最小化再最大化
    2.窗口的大小发生变化
    3.如果 repaint函数被调用
    √思考题:如何证明上面的三种情况,会调用paint()方法

Graphics 类常用方法

. 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)
fill3DRect(int x,int y,int width,int height,boolean rasied)
raised -一个布尔值,用于确定矩形是否显示为高于表面或蚀刻到表面。
5.填充椭圆fillOval(int x, int y, int width, int height)
6.画图片drawlmage(lmage img, int x, int y, …)
7.画字符串drawString(String str, int x, int y)
8.设置画笔的字体setFont(Font font)
9.设置画笔的颜色setColor(Color c)
演示下的具体用法GraphicsMethod.java
√思考题:如何证明上面的三种情况,会调用paint()方法

代码演示

package 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(1000, 1000);
        //当点击窗口的小×,程序完全退出.
        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);//调用父类的方法完成初始化.
        //演示绘制不同的图形..
        //画直线 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)
        //画出一个圆形.(width==height相同就是在画圆)
        //g.drawOval(10, 10, 100, 100);

        //填充矩形 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. 获取图片资源
        // Image image1=null;
        // image1=Toolkit.getDefaultToolkit().getImage("E:\\Java\\notebook\\out\\production\\bomb_1.gif");
        //最好先去查看一下这张图片的属性,以防最后变形,this代表在当前位置
        //g.drawImage(image1, 10, 10, 332, 255, this);
        //画字符串 drawString(String str, int x, int y)//写字
        //给画笔设置颜色和字体
        //g.setColor(Color.red);
        //"隶书"是什么字体,Font.BOLD是是否加粗,50是字体大小
        //g.setFont(new Font("隶书", Font.BOLD, 50));
        //这里设置的 x:100, y:100, 是 "北京你好"左下角
        //g.drawString("北京你好", 100, 100);
        //设置画笔的字体 setFont(Font font)
        //设置画笔的颜色 setColor(Color c)
    }
}

绘图实践

画一个椭圆

package Draw;

import javax.swing.*;
import java.awt.*;

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(300,400);
        //设置当退出画框时,程序自动结束
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //设置可视化
        this.setVisible(true);
    }

}
//1.先定义一个MyPanel, 继承JPanel类, 画图形,就在面板上画
//说明:
//1. MyPanel 对象就是一个画板
//2. Graphics g 把 g 理解成一支画笔
//3. Graphics 提供了很多绘图的方法
//Graphics g
class MyPanel extends JPanel{//绘图方法
    @Override
    public void paint(Graphics g) {
        super.paint(g);//调用父类方法实现初始化,不能删
        g.drawOval(10,10,100,100);
    }
}

绘制tank

坐标规定
在这里插入图片描述

Tank父类

public class Tank {
    private int x;
    private int y;

    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;
    }
}

MyTank继承父类

public class MyTank extends Tank{
    public MyTank(int x, int y) {
        super(x, y);
    }
}

画板

//绘制Tank活动的区域
public class MyPanel extends JPanel {
//定义我的Tank
    MyTank myTank=null;
    public MyPanel(){
        myTank=new MyTank(100,100);//初始化自己的Tank
    }
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        //将画板填充,默认为黑色
        g.fillRect( 0,0,1000,750);
        drawTank(myTank.getX(),myTank.getY(), g,0,0);
    }
    //设置绘制Tank函数,需要获得Tank的初始位置,画笔g,direction坦克的方向,type敌我坦克
    public void drawTank(int x,int y,Graphics g,int direction,int type){
        switch(type){
            case 0://我方坦克
                g.setColor(Color.cyan);
                break;
            case 1://敌方坦克
                g.setColor(Color.yellow);
                break;
        }
        switch(direction){
            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.drawOval(x+10,y+20,20,20);//圆形炮台
                g.fillOval(x+10,y+20,20,20);//填补炮台
                g.drawLine(x+20,y,x+20,y+30);//炮管
        }
    }
}

窗口

public class TankGame01 extends JFrame {
    private MyPanel mp=null;
    public static void main(String[] args) {
        new TankGame01();
    }
    public TankGame01(){
        mp=new MyPanel();
        this.add(mp);
        this.setSize(1000,750);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }
}

事件处理机制

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

BallMove例子

Mypanel是事件监听者(对接受到的事件进行处理),KeyListener是事件监听接口,窗口是事件源,KeyEvent是事件类型

package Event;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class MoveBall extends JFrame {//画板
    Mypanel mp = null;

    public static void main(String[] args) {
        new MoveBall();
    }

    //注意这里窗口需要添加监听器
    public MoveBall() {//构造器
        mp = new Mypanel();
        this.add(mp);
        //窗口JFrame对象可以监听键盘事件,即可以监听到面板发生的键盘事件
        this.addKeyListener(mp);
        this.setSize(400, 300);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }
}

//先把小圆画出来
//接下来需要实现让小球根据键盘的输入进行指定的移动动作,当然这点我们自己是无法做到的,需要借助Java提供的KeyListener监听器
//Mypanel实现监听器接口,并重写方法
class Mypanel extends JPanel implements KeyListener {
    int x = 10, y = 10;

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        //将小球的x,y坐标设为变量,实现移动
        g.fillOval(x, y, 20, 20);//默认黑色
    }

    //有字符输出时,该方法被调用
    @Override
    public void keyTyped(KeyEvent e) {

    }

    //有键盘键被按下时,该方法被调用
    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_UP) {
            //当按下向上的箭头时触发
            //为了让小球进行移动我们需要将fillOval中小球的x,y坐标设为变量
            y--;
        } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
            y++;
        } else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            x--;
        } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            x++;
        }
        //一定要让画板重绘,调用paint()方法,不然只监听到按键无法实现小球移动
        this.repaint();
    }

    //有键盘键被松开时,该方法被调用
    @Override
    public void keyReleased(KeyEvent e) {

    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值