草庐IT

day01-GUI坦克大战01

liyuelian 2023-04-16 原文

JavaGUI-坦克大战

1.Java绘图坐标体系

  • 坐标体系介绍:下图说明了一个Java坐标体系。坐标原点位于左上角,以像素为单位。在Java坐标体系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。
  • 坐标体系-像素:
    1. 绘图还必须要搞清一个非常重要的概念-像素 一个像素等于多少厘米?
    2. 计算机在屏幕上显示的内容都是由屏幕上的每一个像素组成的。例如:计算机显示器的分辨率是800*600,表示计算机屏幕上的每一行由800个点组成,共有600行,整个计算机屏幕共有480 000个像素。像素是一个密度单位,而厘米是一个长度单位,两者无法比较。

2.绘图入门和机制

绘图原理:

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

思考:如何证明上面的三种情况会调用paint()方法?

例子1:画出一个圆形

package li.gui;

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

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

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

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

    public DrawCircle() {//构造器
        //初始化面板
        mp = new MyPanel();
        //把面板放入窗口(画框)
        this.add(mp);
        //设置窗口的的大小
        this.setSize(400, 300);
        //当点击窗口的小x时,程序完全退出
        this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        this.setVisible(true);//可以显示
    }
}

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

    // 1.MyPanel 对象就是一个画板
    // 2. Graphics g 把 g理解成一支画笔
    // 3. Graphics提供了很多绘图的方法
    @Override
    public void paint(Graphics g) {//绘图方法
        super.paint(g);//调用父类的方法完成初始化
        System.out.println("paint方法被调用~");
        //画出一个圆形
        g.drawOval(0, 0, 100, 100);
    }
}

在以下情况paint()将会被调用:

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

思考:如何证明上面的三种情况会调用paint()方法?

运行上面的程序,可以看到命令行窗口打印出“paint方法被调用~“的字样。

这时,点击绘制圆形图案窗口的最小化按钮,可以看到命令行窗口又打印了一行paint方法被调用的字样:

拖动打印圆形图案的窗口,调整其大小,可以看到命令行窗口一直显示paint方法被调用:

repaint方法被调用在后面证明。

3.绘图方法

Graphics类

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

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

    在该图形上下文的坐标系中的点 (x1, y1)(x2, y2)之间绘制一条使用当前颜色的线

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

    绘制指定矩形的轮廓, 矩形的左右边缘为xx + width 。 顶部和底部边缘为yy + height

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

    x,y为要绘制的椭圆的左上角的坐标,width为椭圆的宽度,height为椭圆的高度

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

    填写指定的矩形。 矩形的左右边缘为xx + width - 1 。 顶部和底部边缘在yy + height - 1

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

    用当前颜色填充由指定矩形界定的椭圆。x,y为要填充的椭圆的左上角的坐标,width为要填充椭圆的宽度,height为填充椭圆的高度

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

    绘制当前可用的指定图像的大小。 该图像在其图形上下文的坐标空间中的左上角( x,y)处绘制。 图像中的透明像素不会影响已经存在的任何像素

  7. 画字符串drawString(String str,int x,int y)

    使用该图形上下文的当前字体和颜色绘制由指定字符串给出的文本。 最左边角色的基线是在这个图形上下文的坐标系中的位置( x,y)

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

    将此图形上下文的字体设置为指定的字体。 使用此图形上下文的所有后续文本操作都使用此字体。 空参数被默认忽略

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

    将此图形上下文的当前颜色设置为指定的颜色, 使用此图形上下文的所有后续图形操作都使用此指定颜色

例子:演示具体用法

package li.gui;

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

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

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

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

    public DrawCircle() {//构造器
        //初始化面板
        mp = new MyPanel();
        //把面板放入窗口(画框)
        this.add(mp);
        //设置窗口的的大小
        this.setSize(400, 300);
        //当点击窗口的小x时,程序完全退出
        this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        this.setVisible(true);//可以显示
    }
}

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

    // 1.MyPanel 对象就是一个画板
    // 2. Graphics g 把 g理解成一支画笔
    // 3. Graphics提供了很多绘图的方法
    @Override
    public void paint(Graphics g) {//绘图方法
        super.paint(g);//调用父类的方法完成初始化
        //System.out.println("paint方法被调用~");
        //画出一个圆形
        //g.drawOval(0, 0, 100, 100);

        //演示绘制不同的图形
        // 1. 画直线 drawLine(int x1, int y1, int x2, int y2);
        //g.drawLine(10,10,100,100);

        // 2. 画矩形边框 drawRect(int x, int y, int width, int height)
        //g.drawRect(10,10,100,100) ;

        // 3. 画椭圆边框 drawOval(int x,  int y, int width, int height)
        //g.drawOval(10, 10, 100, 80);
        // 4. 填充矩形 fillRect(int x,  int y, int width, int height)
        //先设置画笔的颜色
        //g.setColor(Color.blue);
        //g.fillRect(10,10,100,100);

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

        // 6. 画图片 drawImage(Image img,int x,int y, ...)
        //首先获取图片资源
        //注意图片要放到out目录的项目的根目录下
        //Image image = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bg.png"));
        //g.drawImage(image,10,10,186,282,this);

        // 7. 画字符串 drawString(String str,int x,int y)
        //先设置字体颜色
        g.setColor(Color.green);
        g.setFont(new Font("隶书",Font.BOLD,50));
        g.drawString("闪电五连鞭",100,100);

        // 8. 设置画笔的字体 setFont(Font font)
        // 9. 设置画笔的颜色 setColor(Color c)

    }

}

4.绘制坦克游戏区域

4.1坦克坐标设计

Tank类

package li.TankGame.VersionFirst;

/**
 * @author 李
 * @version 1.0
 */
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;
    }
}

Hero类

package li.TankGame.VersionFirst;

/**
 * @author 李
 * @version 1.0
 */
public class Hero extends Tank{
    public Hero(int x, int y) {
        super(x, y);
    }
}

MyPanel类

package li.TankGame.VersionFirst;

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

/**
 * @author 李
 * @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, 700, 550);//填充矩形,默认为黑色

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

    }

    /** 编写方法,画出坦克
     * @param x      坦克的左上角横坐标
     * @param 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-5,x+20,y+30);//画出炮管
                break;
            default:
                System.out.println("暂时没有处理");

        }

    }

}

TankGame01类(主方法)

package li.TankGame.VersionFirst;

import javax.swing.*;

/**
 * @author 李
 * @version 1.0
 */
public class TankGame01 extends JFrame {
    //定义一个MyPanel
    MyPanel mp = null;
    public static void main(String[] args) {
        TankGame01 tankGame01 = new TankGame01();
    }

    public TankGame01(){
        mp = new MyPanel();
        this.add(mp);//把面板(就是游戏的绘图区域)添加进来
        this.setSize(700,550);//设置大小
        this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);//点击窗口的叉时停止运行
        this.setVisible(true);//设置显示
    }
}

绘图练习:画出如下图形

1.蛤蟆

2.王八

3.小老鼠

有关day01-GUI坦克大战01的更多相关文章

  1. Ruby,使用包含 TK GUI 的 ocra 部署一个 exe - 2

    Ocra无法处理需要“tk”的应用程序require'tk'puts'nope'用奥克拉http://github.com/larsch/ocra不起作用(如链接中的一个问题所述)问题:https://github.com/larsch/ocra/issues/29(Ocra是1.9的"new"rubyscript2exe,本质上它用于将rb脚本部署为可执行文件)唯一的问题似乎是缺少tcl的DLL文件我不认为这是一个问题据我所知,问题是缺少tk的DLL文件如果它们是已知的,则可以在执行ocra时将它们包括在内有没有办法知道tk工作所需的DLL依赖项? 最佳答

  2. ruby-on-rails - rails : Find tasks that were created on a certain day? - 2

    我有一个任务列表(名称、starts_at),我试图在每日View中显示它们(就像iCal)。deftodays_tasks(day)Task.find(:all,:conditions=>["starts_atbetween?and?",day.beginning,day.ending]end我不知道如何将Time.now(例如“2009-04-1210:00:00”)动态转换为一天的开始(和结束),以便进行比较。 最佳答案 deftodays_tasks(now=Time.now)Task.find(:all,:conditio

  3. 什么是0day漏洞?如何预防0day攻击? - 2

    什么是0day漏洞?0day漏洞,是指已经被发现,但是还未被公开,同时官方还没有相关补丁的漏洞;通俗的讲,就是除了黑客,没人知道他的存在,其往往具有很大的突发性、破坏性、致命性。0day漏洞之所以称为0day,正是因为其补丁永远晚于攻击。所以攻击者利用0day漏洞攻击的成功率极高,往往可以达到目的并全身而退,而防守方却一无所知,只有在漏洞公布之后,才后知后觉,却为时已晚。“后知后觉、反应迟钝”就是当前安全防护面对0day攻击的真实写照!为了方便大家理解,中科三方为大家梳理当前安全防护模式下,一个漏洞从发现到解决的三个时间节点:T0:此时漏洞即0day漏洞,是已经被发现,还未被公开,官方还没有相

  4. ruby - Rails 比较 date.end_of_day.to_datetime 和 date.to_datetime.end_of_day 返回的日期对象值时返回 false - 2

    ruby1.9.3dev(2011-09-23修订版33323)[i686-linux]轨道3.0.20最近为什么在与DateTimeonRails相关的RSpecs项目上工作我发现在给定日期以下语句发出的值date.end_of_day.to_datetime和date.to_datetime.end_of_day虽然它们表示相同的日期时间,但比较时返回false。为了确认这一点,我打开了Rails控制台并尝试了以下操作1.9.3dev:053>monday=Time.now.monday=>2013-02-2500:00:00+05301.9.3dev:054>monday.cla

  5. Ruby,从 Date.day_fraction_to_time 获取小时、秒和时间 - 2

    我找到了这个方法here.start=DateTime.nowsleep15stop=DateTime.now#minutesputs((stop-start)*24*60).to_ihours,minutes,seconds,frac=Date.day_fraction_to_time(stop-start)我有以下错误:`':privatemethod`day_fraction_to_time'calledforDate:Class(NoMethodError)我检查了/usr/lib/ruby/1.9.1/date.rb并找到了它:defday_fraction_to_time(

  6. Ruby GUI(非复杂布局) - 2

    我对RubyGUI设计做了很多研究,这似乎是Ruby倾向于落后的领域。我探索了MonkeyBars、wxRuby、fxRuby、Shoes等选项,只是想从Ruby社区获得一些意见。虽然它们绝对可用,但每一个的开发似乎都在下降。我在任何(减去fxRuby书)上都找不到大量有用的文档或用户基础。我只是想制作一个简单的GUI,所以我真的不想花费数百小时来学习更复杂的工具的复杂性或尝试使用甚至不再开发的东西(鞋子是应用程序的类型我正在寻找,但它有很多问题并且没有得到积极开发。)在所有选项中,你们会推荐哪个选项是最快的,并且仍然具有某种开发基础?谢谢! 最佳答案

  7. ruby - shoes 是一个严肃的 ruby​​ GUI 工具包吗? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭9年前。Improvethisquestion有人用鞋子创建真正的桌面GUI应用程序还是仅用于学习目的?shoes可以和qtruby或者gtkforruby​​比吗?

  8. ruby-on-rails - 有谁知道 Ruby On Rails 的任何跨平台 GUI 日志查看器? - 2

    我厌倦了使用:tail-fdevelopment.log跟踪我的Rails日志。相反,我想要在网格中显示信息并允许我对每个日志消息进行排序、过滤和查看堆栈跟踪的东西。有谁知道用于显示Rails日志的GUI工具。理想情况下,我想要一个独立的应用程序(不是Netbeans或Eclipse中的东西) 最佳答案 Splunk,有一个免费版本,限制为500mb,但具有与完整版本相同的所有功能。 关于ruby-on-rails-有谁知道RubyOnRails的任何跨平台GUI日志查看器?,我们在St

  9. 用于桌面应用程序的 Ruby gui - 2

    关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。关闭2年前。Improvethisquestion经过长时间的谷歌搜索,我想知道是否真的存在基于Ruby的维护图形用户界面。这是我检查过的:鞋子:我觉得我不能用它打造坚如磐石的平台Cocoa和MacRuby:没有新鲜消息,几乎没有教程Qt4Ruby:同上FxRuby几乎没有更新...简而言之,我查看了所有呈现的guihere但我不相信...所以:我找不到Cocoa和Qt的正确文档吗?(我希望它是答案!)是否有任何基于

  10. ruby - 使用 Ruby 编写一个简单的 Windows 7 GUI 应用程序 - 2

    关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于StackOverflow来说是偏离主题的,因为它们往往会吸引自以为是的答案和垃圾邮件。相反,describetheproblem以及迄今为止为解决该问题所做的工作。关闭9年前。Improvethisquestion有没有人使用Ruby为Windows7开发一个简单的GUI应用程序?您使用了哪个GUI框架?我正在考虑将tK或WxRuby用于GUI,并使用Ocra进行打包。我是否也需要安装程序才能在用户机器上安装ruby​​和libs?这对我来说是新

随机推荐