Java基础语法练习42(基本绘图-基本的事件处理机制-小坦克的绘制-键盘控制坦克移动)

news2025/3/19 18:21:56

目录

一、图形的基本绘制

1.基本介绍: 

2.入门代码如下:

3.常用图形的绘制, 示例代码如下:

 二、坦克的绘制

三、事件处理机制

四、坦克的移动


一、图形的基本绘制

1.基本介绍: 

  • Component 类提供了两个和绘图相关最重要的方法:
  1. paint (Graphics g) 绘制组件的外观
  2. repaint () 刷新组件的外观。
  • 当组件第一次在屏幕显示的时候,程序会自动的调用 paint () 方法来绘制组件。
  • 在以下情况 paint () 将会被调用:
  1. 窗口最小化,再最大化
  2. 窗口的大小发生变化
  3. repaint 方法被调用

2.入门代码如下:

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

public class Draw001 extends JFrame { //JFrame对应窗口,可以理解成是一个画框

    //定义一个面板
    private MyPanel mp = null;

    public Draw001() {//构造器
        //初始化面板
        mp = new MyPanel();
        //把面板放入到窗口(画框)
        this.add(mp);
        //设置窗口的大小
        this.setSize(400, 300);
        //当点击窗口的小×,程序完全退出.
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);//可以显示
    }
    public static void main(String[] args) {
        new Draw001();

    }
}

//1.先定义一个MyPanel, 继承JPanel 类, 画图形,就在面板上画
class MyPanel extends JPanel {

    //1. MyPanel 对象就是一个画板
    //2. Graphics g 把 g 理解成一支画笔
    //3. Graphics 提供了很多绘图的方法

    public void paint(Graphics g) {
        super.paint(g);
        g.drawOval(10,10,100,100);
    }

}

3.常用图形的绘制, 示例代码如下:

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

public class Draw001 extends JFrame { //JFrame对应窗口,可以理解成是一个画框

    //定义一个面板
    private MyPanel mp = null;

    public Draw001() {//构造器
        //初始化面板
        mp = new MyPanel();
        //把面板放入到窗口(画框)
        this.add(mp);
        //设置窗口的大小
        this.setSize(1000, 800);
        //当点击窗口的小×,程序完全退出.
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);//可以显示
    }
    public static void main(String[] args) {
        new Draw001();

    }
}

//1.先定义一个MyPanel, 继承JPanel 类, 画图形,就在面板上画
class MyPanel extends JPanel {

    //1. MyPanel 对象就是一个画板
    //2. Graphics g 把 g 理解成一支画笔
    //3. Graphics 提供了很多绘图的方法

    public void paint(Graphics g) {
        super.paint(g);
        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(110, 110, 100, 100);

        //填充椭圆 fillOval(int x, int y, int width, int height)
        g.setColor(Color.red);
        g.fillOval(220, 220, 100, 60);

        //画图片 drawImage(Image img, int x, int y, ..)
        //1. 获取图片资源,/FJ.png 表示在该项目的根目录去获取 FJ.png 图片资源
        Image image = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/FJ.png"));
        g.drawImage(image, 50, 50, 100, 90, 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)



    }

}

 二、坦克的绘制

绘制出如上图的坦克,以便后续编写坦克大战的游戏,创建一个包,创建如上右图的四个类

Tank代码如下:

package TankModel;

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 int getY() {
        return y;
    }
    public void setX(int x) {
        this.x = x;
    }
    public void setY(int y) {
        this.y = y;
    }
}

Hero代码如下:

package TankModel;

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

MyPanel代码如下:

package TankModel;

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

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


    }

    //坦克的左上角x坐标,坦克的左上角y坐标,画笔,坦克方向(上下左右),坦克类型
    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;
            default:
                System.out.println("暂时没有处理");
        }


    }


}

TankGame01代码如下:

package TankModel;

import javax.swing.*;

public class TankGame01 extends JFrame {

    //定义MyPanel
    MyPanel mp = null;

    public TankGame01() {
        mp = new MyPanel();
        this.add(mp);//把面板(就是游戏的绘图区域)
        this.setSize(1000,750);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }

    public static void main(String[] args) {
        TankGame01 tankGame01 = new TankGame01();

    }


}

三、事件处理机制

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

示例代码如下:

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

public class BallMove01 extends JFrame {

    MyPanel mp = null;
    public BallMove01() {
        mp = new MyPanel();
        this.add(mp);
        this.setSize(400, 300);

        //窗口JFrame 对象可以监听键盘事件, 即可以监听到面板发生的键盘事件
        this.addKeyListener(mp);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
        //窗口JFrame 对象可以监听键盘事件, 即可以监听到面板发生的键盘事件
       /* this.addKeyListener(mp);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);*/
    }

    public static void main(String[] args) {
        BallMove01 ballMove01 = new BallMove01();

    }
}

//
class MyPanel extends JPanel implements KeyListener {

    //为了让小球可以移动, 把他的左上角的坐标(x,y)设置变量
    int x = 10;
    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) {
        //System.out.println((char)e.getKeyCode() + "被按下..");

        //根据用户按下的不同键,来处理小球的移动 (上下左右的键)
        //在 java 中,会给每一个键,分配一个值(int)
        if(e.getKeyCode() == KeyEvent.VK_DOWN) {//KeyEvent.VK_DOWN 就是向下的箭头对应的 code
            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) {

    }
}

四、坦克的移动

在一个包内创建以上四个类,代码如下:

Tank代码如下:

package TankGame0001;

public class Tank {
    private int x;  //坦克的横坐标
    private int y;  //坦克的纵坐标
    private int direct;  //0:上 1:右 2:下  3:左
    private int speed = 1;

    public Tank(int x, int y) {
        this.x = x;
        this.y = y;
    }
    public int getX() {
        return x;
    }
    public int getY() {
        return y;
    }
    public void setX(int x) {
        this.x = x;
    }
    public void setY(int y) {
        this.y = y;
    }
    public int getDirect() {
        return direct;
    }
    public void setDirect(int direct) {
        this.direct = direct;
    }
    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;
    }

}

Hero代码如下:

package TankGame0001;

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

MyPanel代码如下:

package TankGame0001;

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

public class MyPanel extends JPanel implements KeyListener {
    //定义我的坦克
    Hero hero = null;

    public MyPanel(){

        hero=new Hero(100,100);//初始化自己坦克
        hero.setSpeed(2);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.fillRect(0, 0, 1000, 750);//填充矩形,默认黑色

        //画出坦克-封装方法
        drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 1);


    }

    //坦克的左上角x坐标,坦克的左上角y坐标,画笔,坦克方向(上下左右),坦克类型
    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: //表示向右
                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) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        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) {

    }
}

TankGame02代码如下:

package TankGame0001;

import javax.swing.*;

public class TankGame02 extends JFrame {

    //定义MyPanel
    MyPanel mp = null;

    public TankGame02() {
        mp = new MyPanel();
        this.add(mp);//把面板(就是游戏的绘图区域)
        this.setSize(1000,750);
        this.addKeyListener(mp);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }

    public static void main(String[] args) {
        TankGame02 tankGame01 = new TankGame02();

    }


}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2317931.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RabbitMQ 入门

RabbitMQ 入门 1RabbitMQ 介绍 RabbitMQ 是信息传输的中间者。本质上,他从生产者(producers)接收消息,转发这些消息给消费者(consumers).换句话说,他能够按根据你指定的规则进行消息转发、缓冲…

yolo环境 pytorch环境配置 CUDA安装

我的成功案例:首先安装python 3.12.9的conda虚拟环境 (如果不安装3.12的会报错误ModuleNotFoundError:没有名为“numpy._core”的模块) 然后安装11.8cuda (其实我是可以最高安装12.6的cuda但我实测,太高版…

ESP32(4)TCP通信

本章重点讲解 lwIP 的 Socket接口如何配置 TCP客户端,并在此基础上实现收发功能。 TCP Client 连接流程 在实现 TCP 协议之前,用户需要按照以下步骤配置结构体 sockaddr_in 的成员变量,以便建立 TCPClient 连接: ①:…

数学建模:MATLAB循环神经网络

一、简述 1.循环神经网络 循环神经网络(RNN)是一种用于处理序列数据的神经网络。不同于传统的前馈神经网络,RNN在隐藏层中加入了自反馈连接,使得网络能够对序列中的每个元素执行相同的操作,同时保持一个“记忆”状态…

EagleTrader为何重申重要数据前后2分钟禁止交易?

3月12日,美国公布了2月份的CPI数据。 美国2月未季调CPI年率录得2.8%,为去年11月来新低,低于市场预期的2.9%。 美国2月季调后CPI月率录得0.2%,为去年10月来新低,预期值为0.3%,前值为0.5%。 数据公布后&#…

个人blog系统 前后端分离 前端js后端go

系统设计: 1.使用语言:前端使用vue,并使用axios向后端发送数据。后端使用的是go的gin框架,并使用grom连接数据库实现数据存储读取。 2.设计结构: 最终展示:仅展示添加模块,其他模块基本相似 前…

单元测试mock

一、背景 现在有A类,B类,C类,A类依赖B类,依赖C类,如果想要测试A类中的某个方法的业务逻辑。A类依赖其他类,则把其他类给mock,然后A类需要真实对象。这样就可以测试A类中的方法。 举例:Ticket类需要调用Flight类和Pas…

GreenKGC: A Lightweight Knowledge Graph Completion Method(论文笔记)

CCF等级:A 发布时间:2023年7月 代码位置 25年3月17日交 目录 一、简介 二、原理 1.整体 2.表示学习 3.特征修剪 4.决策学习 三、实验性能 1.主要结果 2.消融实验 四、结论和未来工作 一、简介 传统知识图谱补全方法中,嵌入维度…

SSM基础专项复习5——Maven私服搭建(2)

系列文章 1、SSM基础专项复习1——SSM项目整合-CSDN博客 2、SSM基础专项复习2——Spring 框架(1)-CSDN博客 3、SSM基础专项复习3——Spring框架(2)-CSDN博客 4、SSM基础专项复习4——Maven项目管理工具(1&#xff…

ASP4644四通道降压稳压器的工业高效电源管理方案

ASP4644工业级型号(ASP4644I6B)是一款专为工业场景设计的四通道降压稳压器,支持-40C至85C工作温度。其核心特性包括: 宽输入电压范围:4V–14V,适配工业现场多变的电源环境。 高负载能力:单通道…

RabbitMq C++客户端的使用

1.RabbitMq介绍 RabbitMQ 是一款开源的消息队列中间件,基于 AMQP(高级消息队列协议)实现,支持多种编程语言和平台。以下是其核心特点和介绍: 核心特点 多语言支持 提供 Java、Python、C#、Go、JavaScript 等语言的客…

用通义大模型写爬虫程序,汇总各科成绩

需求:根据各科网址,输入学号、姓名查询成绩。 中间反反复复很多次,本文只记下重点的几次和大模型的沟通历史。 输入界面 查询界面 round0(最初的问题) 请在windows下,使用python的selenium库&#xff0…

电商项目Ts版本

文章目录 项目地址一、环境安装1.1 配置作为导入1.2 文件目录 二、路由2.1 publicRoutes 项目地址 教程作者:教程地址: 代码仓库地址: 所用到的框架和插件: dbt airflow一、环境安装 1.1 配置作为导入 vite.config.ts impor…

HarmonyOS Next中的弹出框使用

HarmonyOS Next弹出框概述及分类 弹出框是一种模态窗口,通常用于在保持当前上下文环境的同时,临时展示用户需关注的信息或待处理的操作。用户需在模态弹出框内完成相关交互任务之后,才能退出模态模式。弹出框可以不与任何组件绑定&#xff0…

FPGA中级项目4——DDS实现

FPGA中级项目4——DDS实现 DDS简介 DDS(直接数字频率合成器,Direct Digital Frequency Synthesis)是一种基于数字信号处理技术的频率合成方法,广泛应用于通信、雷达、仪器仪表等领域。在 FPGA中实现 DDS 具有灵活性高、集成度强、…

STM32 DAC详解:从原理到实战输出正弦波

目录 一、DAC基础原理1.1 DAC的作用与特性1.2 DAC功能框图解析 二、DAC配置步骤2.1 硬件配置2.2 初始化结构体详解 三、DAC数据输出与波形生成3.1 数据格式与电压计算3.2 正弦波生成实战3.2.1 生成正弦波数组3.2.2 配置DMA传输3.2.3 定时器触发配置 四、常见问题与优化建议4.1 …

基于PyQt5与Open3D的轻量化BIM工具开发指南(下)‌

‌基于PyQt5与Open3D的轻量化BIM工具开发指南(下)‌ ‌——参数化建模、数据导出与性能优化‌ 【跳转】基于PyQt5与Open3D的轻量化BIM工具开发指南(上)‌ ‌四、详细实现步骤(Part 2)‌ ‌3. 参数化建模…

Pytest项目_day01(HTTP接口)

HTTP HTTP是一个协议(服务器传输超文本到浏览器的传送协议),是基于TCP/IP通信协议来传输数据(HTML文件,图片文件,查询结果等)。 访问域名 例如www.baidu.com就是百度的域名,我们想…

在vue项目中,使用Patch请求,实现根据id修改某张发票的日结状态

目录 前言 一.问题描述 二.后端实现 1.分析 2.检查后端拦截器,看看是否允许接收Patch类型的请求 3.编写Dto 4.编写controller层 5.编写service层 6.mapper层 7.使用apifox,测试后端接口的可用性 三.前端实现 1.封装api(本质是ax…

某快餐店用户市场数据挖掘与可视化

1、必要库的载入 import pandas as pd import matplotlib.pyplot as plt import seaborn as sns2、加载并清洗数据 # 2.1 加载数据 df pd.read_csv(/home/mw/input/survey6263/mcdonalds.csv)# 2.2 数据清洗 # 2.2.1 检查缺失值 print(缺失值情况:) print(df.isn…