• 绘图(二)五子棋小游戏


    AWT编程 · 语雀

    仓库Java图形化界面: Java图形化界面学习demo与资料 (gitee.com)

    处理位图

    如果仅仅绘制一些简单的几何图形,程序的图形效果依然比较单调 。 AWT 也允许在组件上绘制位图, Graphics 提供了 drawlmage() 方法用于绘制位图,该方法需要一个Image参数一一代表位图,通过该方法就可 以绘制出指定的位图 。

    位图使用步骤:

    1.创建Image的子类对象BufferedImage(int width,int height,int ImageType),创建时需要指定位图的宽高及类型属性;此时相当于在内存中生成了一张图片;

    2.调用BufferedImage对象的getGraphics()方法获取画笔,此时就可以往内存中的这张图片上绘图了,绘图的方法和之前学习的一模一样;

    3.调用组件的drawImage()方法,一次性的内存中的图片BufferedImage绘制到特定的组件上。

    使用位图绘制组件的好处:

    使用位图来绘制组件,相当于实现了图的缓冲区,此时绘图时没有直接把图形绘制到组件上,而是先绘制到内存中的BufferedImage上,等全部绘制完毕,再一次性的图像显示到组件上即可,这样用户的体验会好一些。

    案例:

    通过BufferedImage实现一个简单的手绘程序:通过鼠标可以在窗口中画图。

    演示代码:

    1. package awt_swimg.day04;
    2. import awt_swimg.day01.Utils;
    3. import javax.swing.*;
    4. import java.awt.*;
    5. import java.awt.event.*;
    6. import java.awt.image.BufferedImage;
    7. public class HandDraw {
    8. //定义画图区的宽高
    9. private final int AREA_WIDTH = 500;
    10. private final int AREA_HEIGHT = 400;
    11. //定义变量,保存上一次鼠标拖动时,鼠标的坐标
    12. private int preX = -1;
    13. private int preY = -1;
    14. //定义一个右键菜单,用于设置画笔的颜色
    15. private PopupMenu popupMenu=new PopupMenu();
    16. private MenuItem redItem = new MenuItem("红色");
    17. private MenuItem greenItem = new MenuItem("绿色");
    18. private MenuItem buleItem = new MenuItem("蓝色");
    19. //定义一个BufferedImage对象
    20. private BufferedImage image = new BufferedImage(AREA_WIDTH, AREA_HEIGHT, BufferedImage.TYPE_INT_RGB);
    21. //获取BufferedImage对象关联的画笔
    22. private Graphics g=image.getGraphics();
    23. //定义窗口对象
    24. private JFrame frame = new JFrame("简单手绘程序");
    25. //定义画布对象
    26. private Canvas canvas=new Canvas(){
    27. @Override
    28. public void paint(Graphics g) {
    29. g.drawImage(image,0,0,null);
    30. }
    31. };
    32. //定义一个Color对象,用来保存用户设置的画笔颜色,默认为黑色
    33. private Color color = Color.BLACK;
    34. public void init(){
    35. redItem.addActionListener(e -> color = Color.red);
    36. greenItem.addActionListener(e -> color = Color.GREEN);
    37. buleItem.addActionListener(e -> color = Color.BLUE);
    38. canvas.addMouseListener(new MouseAdapter() {
    39. @Override
    40. public void mouseReleased(MouseEvent e) {
    41. if (e.isPopupTrigger()) {
    42. popupMenu.show(canvas, e.getX(), e.getY());
    43. }
    44. preX = -1;
    45. preY = -1;
    46. }
    47. });
    48. canvas.addMouseMotionListener(new MouseMotionAdapter() {
    49. @Override
    50. public void mouseDragged(MouseEvent e) {
    51. if (preX > 0 && preY > 0) {
    52. g.setColor(color);
    53. g.drawLine(preX, preY, e.getX(), e.getY());
    54. }
    55. preX = e.getX();
    56. preY = e.getY();
    57. canvas.repaint();
    58. }
    59. });
    60. g.fillRect(0,0,AREA_WIDTH,AREA_HEIGHT);
    61. canvas.setPreferredSize(new Dimension(AREA_WIDTH,AREA_HEIGHT));
    62. canvas.add(popupMenu);
    63. popupMenu.add(redItem);
    64. popupMenu.add(greenItem);
    65. popupMenu.add(buleItem);
    66. frame.add(canvas);
    67. Utils.setJFrame(frame);
    68. }
    69. public static void main(String[] args) {
    70. new HandDraw().init();
    71. }
    72. }

    ImageIO的使用

    在实际生活中,很多软件都支持打开本地磁盘已经存在的图片,然后进行编辑,编辑完毕后,再重新保存到本地磁盘。如果使用AWT要完成这样的功能,那么需要使用到ImageIO这个类,可以操作本地磁盘的图片文件。

    方法名称

    方法功能

    static BufferedImage read(File input)

    读取本地磁盘图片文件

    static BufferedImage read(InputStream input)

    读取本地磁盘图片文件

    static boolean write(RenderedImage im, String formatName, File output)

    往本地磁盘中输出图片文件

    案例:

    编写图片查看程序,支持另存操作

    演示代码:

    1. import javax.imageio.ImageIO;
    2. import java.awt.image.BufferedImage;
    3. import java.io.File;
    4. public class ReadAndSaveImage {
    5. private Frame frame = new Frame("图片查看器");
    6. private BufferedImage image;
    7. private class MyCanvas extends Canvas{
    8. @Override
    9. public void paint(Graphics g) {
    10. if (image!=null){
    11. g.drawImage(image,0,0,image.getWidth(),image.getHeight(),null);
    12. }
    13. }
    14. }
    15. private MyCanvas imageComponent = new MyCanvas();
    16. public void init() throws Exception{
    17. //设置菜单项
    18. MenuBar mb = new MenuBar();
    19. Menu menu = new Menu("文件");
    20. MenuItem openItem = new MenuItem("打开");
    21. MenuItem saveItem = new MenuItem("另存为");
    22. openItem.addActionListener(e -> {
    23. //弹出对话框,选择本地图片
    24. FileDialog oDialog = new FileDialog(frame);
    25. oDialog.setVisible(true);
    26. //读取用户选择的图片
    27. String dir = oDialog.getDirectory();
    28. String file = oDialog.getFile();
    29. try {
    30. image = ImageIO.read(new File(dir,file));
    31. imageComponent.repaint();
    32. } catch (IOException e1) {
    33. e1.printStackTrace();
    34. }
    35. });
    36. saveItem.addActionListener(e -> {
    37. //弹出对话框,另存为
    38. FileDialog sDialog = new FileDialog(frame,"保存图片",FileDialog.SAVE);
    39. sDialog.setVisible(true);
    40. String dir = sDialog.getDirectory();
    41. String file = sDialog.getFile();
    42. try {
    43. ImageIO.write(image,"JPEG",new File(dir,file));
    44. } catch (IOException e1) {
    45. e1.printStackTrace();
    46. }
    47. });
    48. mb.add(menu);
    49. menu.add(openItem);
    50. menu.add(saveItem);
    51. frame.setMenuBar(mb);
    52. frame.add(imageComponent);
    53. frame.setBounds(200,200,800,600);
    54. frame.setVisible(true);
    55. frame.addWindowListener(new WindowAdapter() {
    56. @Override
    57. public void windowClosing(WindowEvent e) {
    58. System.exit(0);
    59. }
    60. });
    61. }
    62. public static void main(String[] args) throws Exception {
    63. new ReadAndSaveImage().init();
    64. }
    65. }

    五子棋

    接下来,我们使用之前学习的绘图技术,做一个五子棋的游戏。

    演示代码:

    1. package awt_swimg.day04;
    2. import awt_swimg.day01.Utils;
    3. import javax.imageio.ImageIO;
    4. import javax.swing.*;
    5. import java.awt.*;
    6. import java.awt.event.*;
    7. import java.awt.image.BufferedImage;
    8. import java.io.File;
    9. import java.io.IOException;
    10. public class Gobang {
    11. //定义三个BufferedImage,分别代表棋盘图、黑子图、白子图
    12. private BufferedImage table;
    13. private BufferedImage black;
    14. private BufferedImage white;
    15. //定义一个BufferedImage,代表当鼠标移动时将要下子的选择框
    16. private BufferedImage selected;
    17. //定义棋盘的宽高,这里的定义尺寸和给定的board.jpg图片的尺寸一致因为棋盘背景是通过图片加载的
    18. private final int TABLE_WIDTH = 535;
    19. private final int TABLE_HEIGHT = 536;
    20. //定义棋盘中,每行和每列可下子的数目,这个数目跟给定的board.jpg中的数目是一致的,都为15
    21. private final int BOARD_SIZE = 15;
    22. //定义每个棋子所占棋盘总宽度的大小比率;每个棋子所占宽度 535/15=35
    23. private final int RATE = TABLE_WIDTH / BOARD_SIZE;
    24. //定义棋盘有效区域与背景图坐标之间的偏移值,x坐标右移5个像素,y坐标下移6个像素
    25. private final int X_OFFSET = 5;
    26. private final int Y_OFFSET = 6;
    27. /*
    28. 定义一个二维数组充当棋盘上每个位置处的棋子;
    29. 该数组的索引与该棋子在棋盘上的坐标需要有一个对应关系:
    30. 例如: 索引[2][3]处的棋子,对一个的真实绘制坐标应该是:
    31. xpos = 2*RATE+X_OFFSET=75;
    32. ypos = 3*RATE+Y_OFFSET=111;
    33. */
    34. private int[][] board = new int[BOARD_SIZE][BOARD_SIZE];//如果存储0,代表没有棋子,如果存储1,代表黑棋,如果存储2,代表白棋
    35. //定义五子棋游戏窗口
    36. private JFrame frame = new JFrame("五子棋游戏");
    37. //定义变量,记录当前选中的坐标点对应的boad数组中对应的棋子索引;
    38. private int selectX = -1;
    39. private int selectY = -1;
    40. //定义一个变量,记录当前用户选择下的是白棋还是黑棋还是清除,清除:0,黑棋:1,白棋:2;
    41. private int chessCategory = 1;
    42. private JPanel canvas = new JPanel() {
    43. @Override
    44. public void paint(Graphics g) {
    45. g.drawImage(table, 0, 0, null);
    46. if (selectX > 0 && selectY > 0) {
    47. g.drawImage(selected, selectX * RATE + X_OFFSET, selectY * RATE + Y_OFFSET, null);
    48. }
    49. for (int i = 0; i < BOARD_SIZE; i++) {
    50. for (int j = 0; j < BOARD_SIZE; j++) {
    51. if (board[i][j] == 2) {
    52. g.drawImage(white, i * RATE + X_OFFSET, j * RATE + Y_OFFSET, null);
    53. }
    54. if (board[i][j] == 1) {
    55. g.drawImage(black, i * RATE + X_OFFSET, j * RATE + Y_OFFSET, null);
    56. }
    57. }
    58. }
    59. }
    60. };
    61. private Panel panel = new Panel();
    62. private Button whiteChess = new Button("白棋");
    63. private Button blackChess = new Button("黑棋");
    64. private Button delete = new Button("删除");
    65. public void init() throws IOException {
    66. //初始化数组,默认
    67. for (int i = 0; i < BOARD_SIZE; i++) {
    68. for (int j = 0; j < BOARD_SIZE; j++) {
    69. board[i][j] = 0;
    70. }
    71. }
    72. canvas.addMouseMotionListener(new MouseMotionAdapter() {
    73. @Override
    74. public void mouseMoved(MouseEvent e) {
    75. selectX = (e.getX() - X_OFFSET) / RATE;
    76. selectY = (e.getY() - Y_OFFSET) / RATE;
    77. canvas.repaint();
    78. }
    79. });
    80. canvas.addMouseListener(new MouseAdapter() {
    81. @Override
    82. public void mouseClicked(MouseEvent e) {
    83. int xChess = (e.getX() - X_OFFSET) / RATE;
    84. int yChess = (e.getY() - Y_OFFSET) / RATE;
    85. board[xChess][yChess] = chessCategory;
    86. canvas.repaint();
    87. }
    88. @Override
    89. public void mouseExited(MouseEvent e) {
    90. selectX = -1;
    91. selectY = -1;
    92. canvas.repaint();
    93. }
    94. });
    95. whiteChess.addActionListener(e -> {
    96. chessCategory = 2;
    97. this.setButtonColor(Color.green,Color.white,Color.white);
    98. });
    99. blackChess.addActionListener(e -> {
    100. chessCategory = 1;
    101. this.setButtonColor(Color.white,Color.green,Color.white);
    102. });
    103. delete.addActionListener(e -> {
    104. chessCategory = 0;
    105. this.setButtonColor(Color.white,Color.white,Color.green);
    106. });
    107. table = ImageIO.read(new File("src/awt_swimg/img/board.jpg"));
    108. white = ImageIO.read(new File("src/awt_swimg/img/white.gif"));
    109. black = ImageIO.read(new File("src/awt_swimg/img/black.gif"));
    110. selected = ImageIO.read(new File("src/awt_swimg/img/selected.gif"));
    111. canvas.setPreferredSize(new Dimension(table.getWidth(), table.getHeight()));
    112. panel.add(whiteChess);
    113. panel.add(blackChess);
    114. panel.add(delete);
    115. frame.add(canvas);
    116. frame.add(panel, BorderLayout.SOUTH);
    117. Utils.setJFrame(frame);
    118. }
    119. public void setButtonColor(Color w,Color b ,Color d){
    120. whiteChess.setBackground(w);
    121. blackChess.setBackground(b);
    122. delete.setBackground(d);
    123. }
    124. public static void main(String[] args) throws IOException {
    125. new Gobang().init();
    126. }
    127. }

  • 相关阅读:
    uniapp和vue3+ts创建自定义下拉选择框组件
    LeetCode简单题之解密消息
    uniapp 首页制作
    SpringCloud集成链路追踪Sleuth+Zipkin
    神经网络在飞行疲劳检测中的应用综述
    敏捷交付的工程效能治理
    LeetCode【69. x 的平方根】
    vsCode 配置 用户代码
    Python杀死Excel?众多模块哪家强
    自助式数据分析平台:JVS智能BI功能介绍(二)数据集管理
  • 原文地址:https://blog.csdn.net/m0_73843666/article/details/132868532