注:通过上篇文章,我们了解到游戏的一些基础概念,下面学习如何使用Java写游戏。
上篇链接:
文档:1.什么是游戏.note
简单来讲就是AWT为早期的Java GUI包,功能不是很健全,Swing是对AWT的升级版,提供了更加丰富的功能。
如有兴趣可点击链接查看具体区别与联系(了解)
具体区别与联系
——后续教程均使用(Swing)JFrame
说白了,游戏就是对用户的输入做出实时的反馈(行为)
输入:键盘(按下键盘)、鼠标(点击)
反馈:按下左键物体向左移动,按下右键向右移动,状态的切换:方向、运动、静止、死亡等等。。
使用Java制作游戏,我们无需关心如何从底层获取按键被按下,Java已经帮我们处理了这些,我们只需要关心根据用户的输入做出不同的反馈即可。
同时,难点也就在于如何去获取用户的输入,如何根据不同的输入做出对应的状态切换。
接下来我们学习如何获取输入、如何切换状态。
public class LearnJFrame {
public static void main(String[] args) {
// 创建一个无标题的窗体
JFrame jFrame = new JFrame();
// 设置窗体的大小
jFrame.setSize(800, 600);
// 设置窗体显示的位置,这里是将窗体水平垂直居中显示
jFrame.setLocation((int) (Toolkit.getDefaultToolkit().getScreenSize().getWidth() - jFrame.getWidth()) / 2,
(int) (Toolkit.getDefaultToolkit().getScreenSize().getHeight() - jFrame.getHeight()) / 2);
// 设置窗体关闭按钮点击时窗体的状态
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 设置显示窗体
jFrame.setVisible(true);
}
}
在上面代码的基础上添加一个JLabel组件
// 创建一个标签,标签显示hello
JLabel jLabel=new JLabel("hello");
// 为标签设置位置及宽高
jLabel.setBounds(0,0,200,200);
// 因为标签默认是透明的,也就是只显示文字及内容,不显示背景色,为演示,我们将其设置为不透明
jLabel.setOpaque(true);
// 设置标签的背景色
jLabel.setBackground(new Color(77, 128, 191));
// 将标签添加进窗体中
jFrame.add(jLabel);
运行:
哦~不妙,我们不是将JLabel组件放置在窗体中 x=0,y=0的位置和宽高200了吗,为什么没有用啊???往下看。。
此时,就要引出一个概念:布局
布局,也就是对一块区域(窗体)内的组件进行一定规则的排列,这些不同的排列方式,就是不同的布局方式
Java提供了以下布局管理器便于我们布局:
1.FlowLayout(流式布局管理器)
* 从左到右的顺序排列。
* Panel默认的布局管理器。
2.BorderLayout(边界布局管理器)
* 东,南,西,北,中
* Frame默认的布局管理器。
3.GridLayout(网格布局管理器)
* 规则的矩阵
4.CardLayout(卡片布局管理器)
* 选项卡
5.GridBagLayout(网格包布局管理器)
* 非规则的矩阵
然而我们并没有为JFrame设置布局方式,所有默认的就是边界布局管理器。
这些布局管理器都是针对有一定规则的布局,我们制作游戏,组件的大小及位置不规则,所有并没有什么用,我们使用:
// 清除布局管理器,采用x,y控制其中组件的位置
jFrame.setLayout(null);
Nice鸭~ 现在JFrame就限制不了我们了,我们可以对所有组件进行随意设置在窗体的位置及大小了,有点感觉了叭。。
呕吼!!! 接下来做什么呢?emmmm,让我们来操控组件(改变组件的状态)吧!!!
接下来,我们要使用Java为我们提供的事件监听了:
// 添加窗体监听,事件源:窗体,所以把监听器注册到窗体上
jFrame.addWindowListener(new WindowAdapter() {
// 窗体关闭时
@Override
public void windowClosing(WindowEvent e) {
// 程序结束
System.exit(0);
}
});
2.鼠标监听器
// 为label组件注册事件监听器
jLabel.addMouseListener(new MouseAdapter() {
// 鼠标点击时
@Override
public void mouseClicked(MouseEvent e) {
// 将label组件背景色设置为灰色
jLabel.setBackground(Color.gray);
}
});
运行:点击后Label组件变成了灰色,这不就是我们所说的简单的输入及反馈了嘛
3.键盘监听器
// 为窗体注册一个键盘监听器
jFrame.addKeyListener(new KeyAdapter() {
// 当任意键被按下时
@Override
public void keyPressed(KeyEvent e) {
// jLable向左位移
if(e.getKeyCode()==KeyEvent.VK_LEFT){
jLabel.setLocation(jLabel.getX()-5,jLabel.getY());
}
// jLable向右位移
if(e.getKeyCode()==KeyEvent.VK_RIGHT){
jLabel.setLocation(jLabel.getX()+5,jLabel.getY());
}
}
});
运行:
当按下左键时jLabel向左移动,按下右键时jLabel向右移动
——同学们可能会疑惑上面注册监听器时的语法,就目前阶段而言,建议大家会使用如何注册监听器即可。
大家在学习其他教程时可能会遇到下面的代码,
// 为窗体注册一个键盘监听器,其实就是用一个匿名对象去实现KeyListener接口,
// 而接口必须要全部实现,所以必须实现接口中所有的方法,即使你不需要其中的个别的方法,这就导致了代码的冗余
jFrame.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
// 当任意键被按下时
@Override
public void keyPressed(KeyEvent e) {
// 改变label组件的背景色
jLabel.setBackground(new Color(77, 128, 191));
}
});
所以我们就需要适配器来简化我们的代码了
适配器
什么是适配器
* 在使用监听器的时候, 需要定义一个类事件监听器接口.
* 通常接口中有多个方法, 而程序中不一定所有的都用到, 但又必须重写, 这很繁琐.
* 适配器简化了这些操作, 我们定义监听器时只要继承适配器, 然后重写需要的方法即可.
适配器原理
* 适配器就是一个类, 实现了监听器接口, 所有抽象方法都重写了, 但是方法全是空的.
* 适配器类需要定义成抽象的,因为创建该类对象,调用空方法是没有意义的
* 目的就是为了简化程序员的操作, 定义监听器时继承适配器, 只重写需要的方法就可以了.
——这期教程暂时到这里,大家有什么需求可以钉钉我,或者该笔记下评论。 zwk