一、坦克大战游戏演示

1.1 界面演示

image.png

1.2 为什么写这个项目

  1. 好玩
  2. 涉及到Java各个方面的技术
    1. Java面向对象编程
    2. 多线程
    3. 文件I/O操作
    4. 数据库
  3. 巩固旧知识,学习新知识

1.3 写项目前的提醒

  1. 编写坦克大战游戏,你需要有一 定的java基础,最核心的部分跟着课程学习完成
  2. 记住一点:成为一个编程高手的秘诀就是:思考——编程——思考——-编程

二、Java绘图坐标体系

2.1 坐标体系 - 介绍

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

2.2 坐标体系 - 像素

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

2.3 快速入门

先给大家写一个小案例,在面板上画一个小圆,然后借这个案例,来讲解java绘图技术原理。(DrawCircle.java)

  1. package com.hsp.tank01.zone_;
  2. import javax.swing.*;
  3. import java.awt.*;
  4. /**
  5. * @author HarborGao
  6. * @version 1.0
  7. */
  8. public class DrawCircle extends JFrame{ //JFrame对应窗口
  9. //定义一个面板
  10. private MyPanel mp = null;
  11. public static void main(String[] args) {
  12. new DrawCircle();
  13. }
  14. public DrawCircle() { //构造器
  15. //初始化面板
  16. mp = new MyPanel();
  17. //把面板放入到窗口
  18. this.add(mp);
  19. //设置窗口的大小
  20. this.setSize(410,300);
  21. this.setVisible(true); //设置窗口为可见
  22. }
  23. }
  24. //1. 先定义一个MyPanel,继承JPanel类,画图形,就在这个面板上画
  25. class MyPanel extends JPanel {
  26. //说明:
  27. //1. MyPanel 对象就是一个画板
  28. //2. Graphics g 把 g 理解成一支画笔
  29. //3. Graphics 提供了很多绘图的方法
  30. @Override
  31. public void paint(Graphics g) { //绘图方法
  32. super.paint(g); //调用父类方法完成初始化 一定要保留
  33. //画出一个圆
  34. System.out.println("paint方法被调用");
  35. g.drawOval(10,10,100,100);
  36. }
  37. }

image.png

2.4 绘图原理

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

  1. paint(Graphics g) 绘制组件的外观
  2. repaint() 刷新组件的外观

当组件第一次在屏幕显示的时候,程序会自动地调用 paint() 方法来绘制组件。
在以下情况 paint() 将会被调用:

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

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

三、Java绘图技术

3.1 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. 画图片 drawImage(Image img, int x, int y, …)
  7. 画字符串 drawString(String str, int x, int y)
  8. 设置画笔的字体 setFont(Font font)
  9. 设置画笔的颜色 setColor(Color c)

3.2 案例演示

  1. package com.hsp.tank01.zone_;
  2. import javax.swing.*;
  3. import java.awt.*;
  4. /**
  5. * @author HarborGao
  6. * @version 1.0
  7. */
  8. public class DrawCircle extends JFrame{ //JFrame对应窗口
  9. //定义一个面板
  10. private MyPanel mp = null;
  11. public static void main(String[] args) {
  12. new DrawCircle();
  13. }
  14. public DrawCircle() { //构造器
  15. //初始化面板
  16. mp = new MyPanel();
  17. //把面板放入到窗口
  18. this.add(mp);
  19. //设置窗口的大小
  20. this.setSize(410,300);
  21. this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //当点击窗口的 × ,就会退出程序
  22. this.setVisible(true); //设置窗口为可见
  23. }
  24. }
  25. //1. 先定义一个MyPanel,继承JPanel类,画图形,就在这个面板上画
  26. class MyPanel extends JPanel {
  27. //说明:
  28. //1. MyPanel 对象就是一个画板
  29. //2. Graphics g 把 g 理解成一支画笔
  30. //3. Graphics 提供了很多绘图的方法
  31. @Override
  32. public void paint(Graphics g) { //绘图方法
  33. super.paint(g); //调用父类方法完成初始化 一定要保留
  34. //画出一个圆
  35. //System.out.println("paint方法被调用");
  36. // g.drawOval(10,10,100,100);
  37. //演示绘制不同的图形
  38. //1. 画直线 drawLine(int x1, int y1, int x2, int y2)
  39. // g.drawLine(10,10,100,100);
  40. //2. 画矩形边框 drawRect(int x, int y, int width, int height)
  41. g.drawRect(20,20,100,200);
  42. //3. 画椭圆边框 drawOval(int x, int y, int width, int height)
  43. //4. 填充矩形 fillRect(int x, int y, int width, int height)
  44. g.setColor(Color.BLUE);
  45. g.fillRect(10,10,100,50);
  46. //5. 填充椭圆 fillOval(int x, int y, int width, int height)
  47. g.setColor(Color.red);
  48. g.fillOval(60,60,60,60);
  49. //6. 画图片 drawImage(Image img, int x, int y, ...)
  50. //(1) 获取图片资源 /bg.jpg 表示在该项目的根目录获取 bg.jpg 图片资源
  51. Image image = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bg.jpg"));
  52. g.drawImage(image,80,80,150,150,this);
  53. //7. 画字符串 drawString(String str, int x, int y) 就是写字
  54. g.setColor(Color.green);
  55. g.setFont(new Font("隶书",Font.BOLD,30));
  56. //注意:这里设置的 x y 是字符串的左下角
  57. g.drawString("北京你好",100,60);
  58. //8. 设置画笔的字体 setFont(Font font)
  59. //9. 设置画笔的颜色 setColor(Color c)
  60. }
  61. }

3.3 绘出坦克

坦克大战游戏中,我们会用到坦克,现在我们就利用Java绘图技术来画出一个小坦克,完成我们的坦克大战游戏1.0版本!

  1. 创建坦克类 ```java package com.hsp.tank01.tankgame;

public class Tank { private int x; //坦克的横坐标 private int y; //坦克的纵坐标

  1. public Tank(int x, int y) {
  2. this.x = x;
  3. this.y = y;
  4. }
  5. public int getX() {
  6. return x;
  7. }
  8. public void setX(int x) {
  9. this.x = x;
  10. }
  11. public int getY() {
  12. return y;
  13. }
  14. public void setY(int y) {
  15. this.y = y;
  16. }

}

  1. 2. **我方坦克类**
  2. ```java
  3. package com.hsp.tank01.tankgame;
  4. public class Hero extends Tank{
  5. public Hero(int x, int y) {
  6. super(x, y);
  7. }
  8. }
  1. 画板 - 绘制坦克 ```java package com.hsp.tank01.tankgame;

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

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

  1. public MyPanel() {
  2. hero = new Hero(100, 100); //初始化自己的坦克
  3. }
  4. @Override
  5. public void paint(Graphics g) {
  6. super.paint(g);
  7. g.fillRect(0, 0, 1000, 750); //填充矩形,默认是黑色
  8. //画出坦克-封装到方法
  9. drawTank(hero.getX(), hero.getY(), g, 0, 0);
  10. drawTank(hero.getX(), hero.getY() + 100, g, 0, 1);
  11. drawTank(hero.getX() + 50, hero.getY() + 100, g, 0, 1);
  12. drawTank(hero.getX() + 100, hero.getY() + 100, g, 0, 1);
  13. }
  14. //编写方法,画出坦克
  15. /**
  16. * @param x 坦克的左上角x坐标
  17. * @param y 坦克的左上角y坐标
  18. * @param g 画笔
  19. * @param direct 坦克的方向(上下左右)
  20. * @param type 坦克类型
  21. */
  22. public void drawTank(int x, int y, Graphics g, int direct, int type) {
  23. //根据不同类型的坦克,设置不同的颜色
  24. switch (type) {
  25. case 0: //我方坦克
  26. g.setColor(Color.cyan);
  27. break;
  28. case 1: //敌方坦克
  29. g.setColor(Color.yellow);
  30. break;
  31. }
  32. //根据坦克的方向,来绘制坦克
  33. switch (direct) {
  34. case 0: //向上
  35. g.fill3DRect(x, y, 10, 60, false);
  36. g.fill3DRect(x + 30, y, 10, 60, false);
  37. g.fill3DRect(x + 10, y + 10, 20, 40, false);
  38. g.fillOval(x + 10, y + 20, 20, 20);
  39. g.drawLine(x + 20, y, x + 20, y + 20);
  40. break;
  41. default:
  42. System.out.println("暂时没处理");
  43. break;
  44. }
  45. }

}

  1. 4. **游戏运行窗口**
  2. ```java
  3. package com.hsp.tank01.tankgame;
  4. import javax.swing.*;
  5. public class HspTankGame01 extends JFrame {
  6. MyPanel mp = null;
  7. public static void main(String[] args) {
  8. HspTankGame01 game01 = new HspTankGame01();
  9. }
  10. public HspTankGame01() {
  11. mp = new MyPanel();
  12. this.add(mp);
  13. this.setSize(1000,750);
  14. this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  15. this.setVisible(true);
  16. }
  17. }

四、Java事件处理机制

4.1 快速上手 - 让小球动起来

  1. package com.hsp.event_;
  2. import javax.swing.*;
  3. import java.awt.*;
  4. import java.awt.event.KeyEvent;
  5. import java.awt.event.KeyListener;
  6. /**
  7. * @author HarborGao
  8. * @version 1.0
  9. * 演示小球通过键盘控制上下左右的移动 -> 讲解Java的事件控制
  10. */
  11. public class BallMove extends JFrame{
  12. MyPanel mp = null;
  13. public static void main(String[] args) {
  14. new BallMove();
  15. }
  16. public BallMove() {
  17. mp = new MyPanel();
  18. this.add(mp);
  19. this.setSize(400,300);
  20. //窗口JFrame 对象可以监听键盘事件,即可以监听到面板上发生的键盘事件
  21. this.addKeyListener(mp); //MyPanel实现了KeyListener,所以mp实例可以作为参数传入
  22. this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  23. this.setVisible(true);
  24. }
  25. }
  26. //画板,可以画出小球
  27. //KeyListener 是一个监听器,可以监听键盘事件
  28. class MyPanel extends JPanel implements KeyListener {
  29. //为了让小球可以移动,我们把它的左上角的坐标设置成变量
  30. int x = 10;
  31. int y = 10;
  32. @Override
  33. public void paint(Graphics g) {
  34. super.paint(g);
  35. g.fillOval(x,y,20,20); // 绘制小球
  36. }
  37. //有字符输出时,该方法就会监听到
  38. @Override
  39. public void keyTyped(KeyEvent e) {
  40. }
  41. //当某个键按下时,该方法就会被触发
  42. @Override
  43. public void keyPressed(KeyEvent e) {
  44. //System.out.println((char)e.getKeyCode() + "被按下");
  45. //根据用户按下的不同键,来处理小球的移动(上下左右的键)
  46. if (e.getKeyCode() == KeyEvent.VK_DOWN) {
  47. y++; //小球向下移动
  48. } else if (e.getKeyCode() == KeyEvent.VK_UP) {
  49. y--; //小球向上移动
  50. } else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
  51. x--; //小球向左移动
  52. } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
  53. x++; //小球向右移动
  54. }
  55. //让面板重绘
  56. this.repaint();
  57. }
  58. //当某个键松开时,该方法就会被触发
  59. @Override
  60. public void keyReleased(KeyEvent e) {
  61. }
  62. }

4.2 基本说明

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

4.3 示意图

坦克大战【1】 - 图4

4.4 机制分析

image.png

4.5 事件处理机制深入理解

  1. 事件源:事件源是一个产生事件的对象,比如按钮,窗口等
  2. 事件:事件就是承载事件源状态改变时的对象,比如键盘事件、鼠标事件、窗口事件等等,会生成一个事件对象,该对象保存着当前事件很多信息,比如 KeyEvent 对象含有被按下键的 Code值。java.awt.event包 和 javax.swing.event包 中定义了各种事件类型
  3. 事件类型:查阅jdk文档 | 事件类 | 说明 | | —- | —- | | ActionEvent | 通常在按下按钮,或双击一个列表项或选中某个菜单时发生 | | AdjustmentEvent | 当操作一个滚动条时发生 | | ComponentEvent | 当一个组件隐藏,移动,改变大小时发生 | | ContainerEvent | 当一个组件从容器中加入或者删除时发生 | | FocusEvent | 当一个组件获得或者失去焦点时发生 | | ItemEvent | 当一个复选框或者列表项被选中时,当一个选择框或选择菜单被选中 | | KeyEvent | 当键盘的按键被按下、松开时发生 | | MouseEvent | 当鼠标被拖动,移动,点击,按下,松开… 时发生 | | TextEvent | 当文本框和文本域的文本发生改变时发生 | | WindowEvent | 当一个窗口激活,关闭,失效,恢复,最小化… 时发生 |

  4. 事件监听器接口:

    1. 当事件源产生一个事件,可以传送给事件监听者处理
    2. 事件监听者实际上就是一个类,该类实现了某个事件监听器接口
      比如前面案例中MyPanel类实现了 KeyListener 接口,它就可以作为一个事件监听者,对接收到的事件进行处理
    3. 事件监听器接口有多种,不同的事件监听器接口可以监听不同的事件,一个类可以实现多个监听接口
    4. 这些接口在 java.awt.event包 和 javax.swing.event包 中定义。
      列出常用的事件监听器接口,具体可查看jdk文档

image.png

五、坦克大战游戏 (1.0版)

5.1 让坦克动起来

通过上面学习的Java事件处理机制和Java绘图技术,来实现让我们的坦克可以通过按键控制上下左右(wsad表示)的移动。

5.2 坦克类

  1. package com.hsp.tank01.tankgame02;
  2. /**
  3. * @author HarborGao
  4. * @version 1.0
  5. */
  6. public class Tank {
  7. private int x; //坦克的横坐标
  8. private int y; //坦克的纵坐标
  9. private int direct; //坦克方向 0:向上 1:向右 2:向下 3:向左
  10. private int type; //坦克类型 0:我方坦克 1:敌方坦克
  11. private int speed = 1; //坦克速度
  12. public Tank(int x, int y) {
  13. this.x = x;
  14. this.y = y;
  15. }
  16. public Tank(int x, int y, int direct, int type) {
  17. this.x = x;
  18. this.y = y;
  19. this.direct = direct;
  20. this.type = type;
  21. }
  22. //上右下左移动方法
  23. public void moveUp() {
  24. y -= speed;
  25. }
  26. public void moveRight() {
  27. x += speed;
  28. }
  29. public void moveDown() {
  30. y += speed;
  31. }
  32. public void moveLeft() {
  33. x -= speed;
  34. }
  35. public int getX() {
  36. return x;
  37. }
  38. public void setX(int x) {
  39. this.x = x;
  40. }
  41. public int getY() {
  42. return y;
  43. }
  44. public void setY(int y) {
  45. this.y = y;
  46. }
  47. public int getDirect() {
  48. return direct;
  49. }
  50. public void setDirect(int direct) {
  51. this.direct = direct;
  52. }
  53. public int getType() {
  54. return type;
  55. }
  56. public void setType(int type) {
  57. this.type = type;
  58. }
  59. public int getSpeed() {
  60. return speed;
  61. }
  62. public void setSpeed(int speed) {
  63. this.speed = speed;
  64. }
  65. }

5.3 MyPanel 类

  1. package com.hsp.tank01.tankgame02;
  2. import javax.swing.*;
  3. import java.awt.*;
  4. import java.awt.event.KeyEvent;
  5. import java.awt.event.KeyListener;
  6. /**
  7. * @author HarborGao
  8. * @version 1.0
  9. */
  10. public class MyPanel extends JPanel implements KeyListener {
  11. //定义我的坦克
  12. Hero hero = null;
  13. public MyPanel() {
  14. hero = new Hero(300, 300); //初始化自己的坦克
  15. hero.setSpeed(3);
  16. }
  17. @Override
  18. public void paint(Graphics g) {
  19. super.paint(g);
  20. g.fillRect(0, 0, 1000, 750); //填充矩形,默认是黑色
  21. //画出坦克-封装到方法
  22. drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), hero.getType());
  23. }
  24. /**
  25. * @param x 坦克的左上角x坐标
  26. * @param y 坦克的左上角y坐标
  27. * @param g 画笔
  28. * @param direct 坦克的方向(上下左右)
  29. * @param type 坦克类型
  30. */
  31. public void drawTank(int x, int y, Graphics g, int direct, int type) {
  32. //根据不同类型的坦克,设置不同的颜色
  33. switch (type) {
  34. case 0: //我方坦克
  35. g.setColor(Color.cyan);
  36. break;
  37. case 1: //敌方坦克
  38. g.setColor(Color.yellow);
  39. break;
  40. }
  41. //根据坦克的方向,来绘制对应的坦克
  42. //direct表示方向(0:向上 1:向右 2:向下 3:向左)
  43. switch (direct) {
  44. case 0: //表示向上
  45. g.fill3DRect(x, y, 10, 60, false);
  46. g.fill3DRect(x + 30, y, 10, 60, false);
  47. g.fill3DRect(x + 10, y + 10, 20, 40, false);
  48. g.fillOval(x + 10, y + 20, 20, 20);
  49. g.drawLine(x + 20, y, x + 20, y + 20);
  50. break;
  51. case 1: //表示向右
  52. g.fill3DRect(x - 10, y + 10, 60, 10, false);
  53. g.fill3DRect(x - 10, y + 40, 60, 10, false);
  54. g.fill3DRect(x, y + 20, 40, 20, false);
  55. g.fillOval(x + 10, y + 20, 20, 20);
  56. g.drawLine(x + 50, y + 30, x + 20, y + 30);
  57. break;
  58. case 2: //表示向下
  59. g.fill3DRect(x, y, 10, 60, false);
  60. g.fill3DRect(x + 30, y, 10, 60, false);
  61. g.fill3DRect(x + 10, y + 10, 20, 40, false);
  62. g.fillOval(x + 10, y + 20, 20, 20);
  63. g.drawLine(x + 20, y + 60, x + 20, y + 20);
  64. break;
  65. case 3:
  66. g.fill3DRect(x - 10, y + 10, 60, 10, false);
  67. g.fill3DRect(x - 10, y + 40, 60, 10, false);
  68. g.fill3DRect(x, y + 20, 40, 20, false);
  69. g.fillOval(x + 10, y + 20, 20, 20);
  70. g.drawLine(x - 10, y + 30, x + 20, y + 30);
  71. break;
  72. }
  73. }
  74. @Override
  75. public void keyTyped(KeyEvent e) {
  76. }
  77. @Override
  78. public void keyPressed(KeyEvent e) {
  79. if (e.getKeyCode() == KeyEvent.VK_W) {
  80. hero.moveUp();
  81. hero.setDirect(0);
  82. } else if (e.getKeyCode() == KeyEvent.VK_D) {
  83. hero.moveRight();
  84. hero.setDirect(1);
  85. } else if (e.getKeyCode() == KeyEvent.VK_S) {
  86. hero.moveDown();
  87. hero.setDirect(2);
  88. } else if (e.getKeyCode() == KeyEvent.VK_A) {
  89. hero.moveLeft();
  90. hero.setDirect(3);
  91. }
  92. this.repaint();
  93. }
  94. @Override
  95. public void keyReleased(KeyEvent e) {
  96. }
  97. }

5.4 游戏运行窗口

  1. package com.hsp.tank01.tankgame02;
  2. import javax.swing.*;
  3. /**
  4. * @author HarborGao
  5. * @version 1.0
  6. */
  7. public class TankGame01 extends JFrame {
  8. MyPanel mp = null;
  9. public static void main(String[] args) {
  10. TankGame01 game01 = new TankGame01();
  11. }
  12. public TankGame01() {
  13. mp = new MyPanel();
  14. this.add(mp);
  15. this.setSize(1000,750);
  16. this.addKeyListener(mp); //监听
  17. this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  18. this.setVisible(true);
  19. }
  20. }

六、本章作业

在上面的基础上添加敌方坦克类,并将创建的敌方坦克实例放入到集合中【需考虑线程安全】,然后在面板中调用显示三辆敌方坦克。

敌方坦克类

  1. package com.hsp.tank01.tankgame02;
  2. /**
  3. * @author HarborGao
  4. * @version 1.0
  5. */
  6. public class Enemy extends Tank{
  7. public Enemy(int x, int y) {
  8. super(x, y);
  9. }
  10. public Enemy(int x, int y, int direct, int type) {
  11. super(x, y, direct, type);
  12. }
  13. }

MyPanel类

  1. package com.hsp.tank01.tankgame02;
  2. import javax.swing.*;
  3. import java.awt.*;
  4. import java.awt.event.KeyEvent;
  5. import java.awt.event.KeyListener;
  6. import java.util.Vector;
  7. /**
  8. * @author HarborGao
  9. * @version 1.0
  10. */
  11. public class MyPanel extends JPanel implements KeyListener {
  12. //定义我的坦克
  13. Hero hero = null;
  14. //定义敌人坦克,放入到 Vector
  15. Vector<Enemy> enemies = new Vector<>();
  16. int enemyTankSize = 3;
  17. public MyPanel() {
  18. hero = new Hero(200, 150); //初始化自己的坦克
  19. hero.setSpeed(3);
  20. //初始化敌人坦克
  21. for (int i = 1; i <= enemyTankSize; i++) {
  22. enemies.add(new Enemy(100*i,10, 2,1));
  23. }
  24. }
  25. @Override
  26. public void paint(Graphics g) {
  27. super.paint(g);
  28. g.fillRect(0, 0, 1000, 750); //填充矩形,默认是黑色
  29. //画出坦克-封装到方法
  30. drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), hero.getType());
  31. //画出敌人的坦克
  32. for (Enemy o : enemies) {
  33. drawTank(o.getX(),o.getY(),g,o.getDirect(),o.getType());
  34. }
  35. }
  36. /**
  37. * @param x 坦克的左上角x坐标
  38. * @param y 坦克的左上角y坐标
  39. * @param g 画笔
  40. * @param direct 坦克的方向(上下左右)
  41. * @param type 坦克类型
  42. */
  43. public void drawTank(int x, int y, Graphics g, int direct, int type) {
  44. //根据不同类型的坦克,设置不同的颜色
  45. switch (type) {
  46. case 0: //我方坦克
  47. g.setColor(Color.cyan);
  48. break;
  49. case 1: //敌方坦克
  50. g.setColor(Color.yellow);
  51. break;
  52. }
  53. //根据坦克的方向,来绘制对应的坦克
  54. //direct表示方向(0:向上 1:向右 2:向下 3:向左)
  55. switch (direct) {
  56. case 0: //表示向上
  57. g.fill3DRect(x, y, 10, 60, false);
  58. g.fill3DRect(x + 30, y, 10, 60, false);
  59. g.fill3DRect(x + 10, y + 10, 20, 40, false);
  60. g.fillOval(x + 10, y + 20, 20, 20);
  61. g.drawLine(x + 20, y, x + 20, y + 20);
  62. break;
  63. case 1: //表示向右
  64. g.fill3DRect(x - 10, y + 10, 60, 10, false);
  65. g.fill3DRect(x - 10, y + 40, 60, 10, false);
  66. g.fill3DRect(x, y + 20, 40, 20, false);
  67. g.fillOval(x + 10, y + 20, 20, 20);
  68. g.drawLine(x + 50, y + 30, x + 20, y + 30);
  69. break;
  70. case 2: //表示向下
  71. g.fill3DRect(x, y, 10, 60, false);
  72. g.fill3DRect(x + 30, y, 10, 60, false);
  73. g.fill3DRect(x + 10, y + 10, 20, 40, false);
  74. g.fillOval(x + 10, y + 20, 20, 20);
  75. g.drawLine(x + 20, y + 60, x + 20, y + 20);
  76. break;
  77. case 3:
  78. g.fill3DRect(x - 10, y + 10, 60, 10, false);
  79. g.fill3DRect(x - 10, y + 40, 60, 10, false);
  80. g.fill3DRect(x, y + 20, 40, 20, false);
  81. g.fillOval(x + 10, y + 20, 20, 20);
  82. g.drawLine(x - 10, y + 30, x + 20, y + 30);
  83. break;
  84. }
  85. }
  86. @Override
  87. public void keyTyped(KeyEvent e) {
  88. }
  89. @Override
  90. public void keyPressed(KeyEvent e) {
  91. if (e.getKeyCode() == KeyEvent.VK_W) {
  92. hero.moveUp();
  93. hero.setDirect(0);
  94. } else if (e.getKeyCode() == KeyEvent.VK_D) {
  95. hero.moveRight();
  96. hero.setDirect(1);
  97. } else if (e.getKeyCode() == KeyEvent.VK_S) {
  98. hero.moveDown();
  99. hero.setDirect(2);
  100. } else if (e.getKeyCode() == KeyEvent.VK_A) {
  101. hero.moveLeft();
  102. hero.setDirect(3);
  103. }
  104. this.repaint();
  105. }
  106. @Override
  107. public void keyReleased(KeyEvent e) {
  108. }
  109. }

学习参考(致谢):

  1. B站 @程序员鱼皮 Java学习一条龙
  2. B站 @韩顺平 零基础30天学会Java