首页 > 基础资料 博客日记
java 课程设计 2048小游戏带注释
2024-06-23 10:00:04基础资料围观337次
本篇文章分享java 课程设计 2048小游戏带注释,对你有帮助的话记得收藏一下,看Java资料网收获更多编程知识
2048小游戏
功能要求:
每次可以选择上下左右其中一个方向去滑动,每滑动一次,所有的数字方块都会往滑动的方向靠拢外,系统也会在空白的地方乱数出现一个数字方块,相同数字的方块在靠拢、相撞时会相加。不断的叠加最终拼凑出2048这个数字就算成功。
package Other; //声明,表示当前代码所在的包名为 Other
import java.awt.*;//这是 Java 的抽象窗口工具包(Abstract Window Toolkit),提供了创建用户界面和处理图形界面事件的类和接口
import java.awt.event.KeyEvent;//这个类表示键盘事件,例如按键按下和释放。
import java.awt.event.KeyListener;//这个接口用于接收和处理键盘事件
import java.awt.event.MouseEvent;//这个类表示鼠标事件,例如鼠标点击、移动和拖动。
import java.awt.event.MouseListener;//这个类表示鼠标事件,例如鼠标点击、移动和拖动。
import java.awt.event.WindowEvent;//这个类表示窗口事件,例如窗口打开、关闭和最小化。
import java.util.*;//导入了整个 java.util 包中的所有类。java.util 包包含了许多用于数据结构、集合、算法和通用工具的类。
import javax.swing.*;//Java Swing 是一个用于创建图形用户界面(GUI)应用程序的库。它提供了许多类和接口,用于创建窗口、按钮、文本框、标签等用户界面组件。
@SuppressWarnings("serial")
public class Game2048 extends JFrame {
// 移动方向
final public static int MOVE_UP = 0xf37;
final public static int MOVE_DOWN = 0xf36;
final public static int MOVE_LEFT = 0xf35;
final public static int MOVE_RIGHT = 0xf34;
// 游戏状态
final public static int GAME_OVER = 0xf33;
final public static int GAME_CONTINUE = 0xf32;
final public static int GAME_WIN = 0xf31;
// 按钮事件
final public static int BUTTON_NEW_GAME = 0xf30;
final public static int BUTTON_ABOUT = 0xf28;
final public static int BUTTON_EXIT = 0xf27;
/*
这段代码是一个 Java 类,定义了一些常量用于表示游戏 2048 的不同状态和操作。
MOVE_UP、MOVE_DOWN、MOVE_LEFT 和 MOVE_RIGHT 常量表示游戏中方块的移动方向,分别对应上、下、左、右。
GAME_OVER、GAME_CONTINUE 和 GAME_WIN 常量表示游戏的不同状态,分别对应游戏结束、游戏继续和游戏胜利。
BUTTON_NEW_GAME、BUTTON_ABOUT 和 BUTTON_EXIT 常量表示游戏界面上按钮的事件,分别对应新游戏、关于和退出按钮。
这些常量用于在游戏逻辑中表示不同的状态和操作,方便代码的编写和理解。
*/
/**
* 行
*/
private int column;
/**
* 列
*/
private int row;
/**
* 游戏状态
*/
private int gameState;
/**
* 网格集
*/
private HashMap<Point, Cube> viewList = new HashMap<>();
/**
* 计分板
*/
private JMenuItem scoreBoard;
/**
* 新游戏加流程
*/
private int gameLv;
/**
* main函数
*
* @param args
*/
/*
这段代码是一个 Java 类的成员变量定义部分。每个变量都有自己的注释,解释了它们的用途和含义:
- `column`:表示游戏界面的列数。
- `row`:表示游戏界面的行数。
- `gameState`:表示游戏的状态,可能是进行中、结束、获胜等状态。
- `viewList`:是一个 `HashMap<Point, Cube>` 类型的变量,用于存储游戏界面的网格信息。`Point` 表示网格的坐标,`Cube` 表示网格上的方块。
- `scoreBoard`:表示计分板,可能是一个菜单项或者其他用于显示分数的组件。
- `gameLv`:表示游戏的难度等级。
`main` 函数是 Java 程序的入口点,它接收一个 `String` 类型的参数 `args`,用于传递命令行参数。在这个代码片段中,没有看到 `main` 函数的定义,因此无法提供更多关于它的信息。
*/
public static void main(String[] args) {
Game2048 game = new Game2048(400, 500);//创建一个名为 game 的 Game2048 游戏对象,并设置游戏窗口的宽度为 400 像素,高度为 500 像素。
game.setTitle("2048");//设置游戏窗口的标题为 "2048"。
game.setLocationRelativeTo(null);//将游戏窗口的位置设置为居中。
game.setVisible(true);//显示游戏窗口。
game.newGame();//开始新游戏。
}
//创建了一个名为 Game2048 的游戏对象,并设置了游戏窗口的大小、标题和位置。然后,它显示游戏窗口并开始新游戏。
/**
* 构造一个默认大小的界面
*/
public Game2048() {
this(400, 500);
}
/**
* 构造一个指定宽高的界面
*
* @param width
* 宽
* @param height
* 高
*/
public Game2048(int width, int height) {
column = width / 100;
row = height / 100;
this.setLayout(new GridLayout(row, column));
// 事件监听
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
this.setSize(width, height);
// 利用button 绘制网格
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
viewList.put(new Point(i, j), new Cube());
this.add(getView(i, j).getView());
}
}
/*这段代码是一个名为 `Game2048` 的类的构造函数,它接受两个整数参数 `width` 和 `height`,用于设置游戏界面的大小。
首先,它计算了每个网格的大小,并设置了游戏界面的布局为网格布局。然后,它启用了事件监听,以便能够响应窗口事件。接着,它设置了游戏界面的大小。
接下来,它使用循环来绘制游戏的网格。它创建了一个 `Point` 对象来表示每个网格的位置,并将其添加到一个列表中。然后,它创建了一个 `Cube` 对象来表示每个网格,并将其添加到游戏界面中。
最后,它返回了一个包含网格视图的列表,以便在游戏中进行操作。
总体来说,这段代码的作用是创建一个 `Game2048` 游戏对象,并设置游戏界面的大小和布局,然后绘制游戏的网格。*/
// 设置按键监听,添加一个键盘事件监听器的代码。它的作用是当用户在键盘上按下或释放某个键时,会触发监听器中的相应方法。
this.addKeyListener(new MyKeyListener(this));//将一个自定义的MyKeyListener键盘事件监听器添加到当前组件(通常是一个窗口)上。当用户在键盘上按下或释放按键时,MyKeyListener的相应方法将会被触发。
JMenuBar jmb = new JMenuBar();//创建一个菜单栏对象。
JMenu jm = new JMenu("游戏");//创建一个菜单对象,并将其命名为 "游戏"。
JMenuItem item1 = new JMenuItem("新游戏");//创建一个菜单项对象,并将其文本设置为 "新游戏"。
item1.addMouseListener(new MyMouseListener(this,
Game2048.BUTTON_NEW_GAME));//将一个自定义的MyMouseListener鼠标事件监听器添加到菜单项上。当用户鼠标点击该菜单项时,MyMouseListener的相应方法将会被触发。
JMenuItem item2 = new JMenuItem("退出");//创建另一个菜单项对象,并将其文本设置为 "退出"。
item2.addMouseListener(new MyMouseListener(this, Game2048.BUTTON_EXIT));//将另一个自定义的MyMouseListener鼠标事件监听器添加到菜单项上。当用户鼠标点击该菜单项时,MyMouseListener的相应方法将会被触发。
jm.add(item1);//将 "新游戏" 菜单项添加到 "游戏" 菜单中。
jm.add(item2);//将 "退出" 菜单项添加到 "游戏" 菜单中。
JMenu jm2 = new JMenu("关于");//创建另一个菜单对象,并将其命名为 "关于"。
JMenuItem item3 = new JMenuItem("关于");//创建一个菜单项对象,并将其文本设置为 "关于"。
item3.addMouseListener(new MyMouseListener(this, Game2048.BUTTON_ABOUT));//将另一个自定义的MyMouseListener鼠标事件监听器添加到菜单项上。当用户鼠标点击该菜单项时,MyMouseListener的相应方法将会被触发。
jm2.add(item3);//将 "关于" 菜单项添加到 "关于" 菜单中。
scoreBoard = new JMenuItem();//创建一个菜单项对象,用于显示分数板。
jmb.add(jm);//将 "游戏" 菜单添加到菜单栏中。
jmb.add(jm2);//将 "关于" 菜单添加到菜单栏中。
jmb.add(scoreBoard);//将分数板菜单项添加到菜单栏中。
this.setJMenuBar(jmb);//将菜单栏设置为当前窗口的菜单栏。
}
/**
* 向上移动
*/
public void up() {
for (int x = 1; x < row; x++) {
for (int i = 0; i < column; i++) {
move(Game2048.MOVE_UP, x, i, true);
}
}
//这个循环会遍历游戏界面的每一行(除了第一行),以及每一列。对于每个位置,它调用了move()方法,并传入Game2048.MOVE_UP作为移动方向,x和i作为当前位置的行和列索引,以及true作为一个标志,表示这是一个“真实”的移动。
//move()方法根据传入的参数执行方块的移动操作
createCube();
for (int x = 1; x < row; x++) {
for (int i = 0; i < column; i++) {
move(Game2048.MOVE_UP, x, i, false);
}//这个循环会再次遍历游戏界面的每一行(除了第一行),以及每一列。对于每个位置,它再次调用了move()方法,但这次传入Game2048.MOVE_UP作为移动方向,x和i作为当前位置的行和列索引,以及false作为一个标志,表示这是一个“虚拟”的移动,用于创建新的方块。
//同样地,move()方法根据传入的参数执行方块的移动操作。
//其他的移动方法(down()、left()和right())的实现方式与up()方法类似,只是它们的移动方向不同。
//总体来说,这些方法通过循环和调用move()方法来实现方块在游戏界面的上、下、左、右移动,并通过第二个循环来创建新的方块。
}
}
/**
* 向下移动
*/
public void down() {
for (int x = row - 2; x >= 0; x--) {
for (int y = 0; y < column; y++) {
move(Game2048.MOVE_DOWN, x, y, true);
}
}
createCube();
for (int x = row - 2; x >= 0; x--) {
for (int y = 0; y < column; y++) {
move(Game2048.MOVE_DOWN, x, y, false);
}
}
}
/**
* 向左移动
*/
public void left() {
for (int y = 1; y < column; y++) {
for (int x = 0; x < row; x++) {
move(Game2048.MOVE_LEFT, x, y, true);
}
}
createCube();
for (int y = 1; y < column; y++) {
for (int x = 0; x < row; x++) {
move(Game2048.MOVE_LEFT, x, y, false);
}
}
}
/**
* 向右移动
*/
public void right() {
for (int y = column - 2; y >= 0; y--) {
for (int x = 0; x < row; x++) {
move(Game2048.MOVE_RIGHT, x, y, true);
}
}
createCube();
for (int y = column - 2; y >= 0; y--) {
for (int x = 0; x < row; x++) {
move(Game2048.MOVE_RIGHT, x, y, false);
}
}
}
/**
* 移动
*
* @param move_way
* 移动方向
* @param x
* 横坐标
* @param y
* 纵坐标
*/
private void move(int move_way, int x, int y, boolean isAdd) {//这段代码是一个名为 move() 的方法,
//它根据传入的移动方向(move_way)和坐标(x 和 y)执行相应的方块移动操作。
//根据不同的移动方向,它会进行一系列的交换操作。
switch (move_way) {
case Game2048.MOVE_DOWN: { // 这是向下移动的情况。它通过一个循环,从当前位置(x)开始,向下移动到行的最后一个位置(row - 1),每次移动都将当前位置的方块与下一个位置的方块进行交换。这个循环会持续直到到达行的末尾。
for (; x < row - 1; x++) {
swap(getView(x + 1, y), getView(x, y), isAdd);
}
}
break;
case Game2048.MOVE_LEFT: { // 这是向左移动的情况。它通过一个循环,从当前位置(y)开始,向左移动到列的第一个位置(0),每次移动都将当前位置的方块与左边位置的方块进行交换。这个循环会持续直到到达列的开头。
for (; y > 0; y--) {
swap(getView(x, y - 1), getView(x, y), isAdd);
}
}
break;
case Game2048.MOVE_RIGHT: { //这是向右移动的情况。它通过一个循环,从当前位置(y)开始,向右移动到列的最后一个位置(column - 1),每次移动都将当前位置的方块与右边位置的方块进行交换。这个循环会持续直到到达列的末尾。
for (; y < column - 1; y++) {
swap(getView(x, y + 1), getView(x, y), isAdd);
}
}
break;
case Game2048.MOVE_UP: { //这是向上移动的情况。它通过一个循环,从当前位置(x)开始,向上移动到行的第一个位置(0),每次移动都将当前位置的方块与上面位置的方块进行交换。这个循环会持续直到到达行的开头。
for (; x > 0; x--) {
swap(getView(x - 1, y), getView(x, y), isAdd);
}
}
break;
}
}//在每个循环中,它都调用了 swap() 方法来执行方块的交换操作。
//swap() 方法接受三个参数:要交换的两个方块的视图,以及一个布尔值 isAdd,用于指示这次交换是真实的移动还是仅用于创建新方块。
/**
* 单向交换实现移动
*
* @param next
* 移动至目标位置
* @param now
* 需要移动的目标
* @param isAdd
* 是否是第一次移动
*/
private void swap(Cube next, Cube now, boolean isAdd) {//这段代码是一个名为 swap() 的方法,用于在两个 Cube 对象之间进行交换操作。根据布尔值 isAdd 的不同,交换的方式也有所不同。
if (isAdd) {
if (now.getNum() != 0 && next.getNum() == 0) {//如果当前方块 now 的数字不为 0 且下一个方块 next 的数字为 0
next.setText(now.getNum());//将 next 的文本设置为 now 的数字
now.setText(0);//将 now 的文本设置为 0
next.setIsAdded(now.isAdded());//并将 next 的添加状态设置为 now 的添加状态。
now.setIsAdded(false);//调用了 now 对象的 setIsAdded(false) 方法。
} else if (!now.isAdded() && !next.isAdded()//如果当前方块和下一个方块都没有被添加
&& next.getNum() == now.getNum() && now.getNum() != 0) {//且它们的数字相等且不为 0
next.setText(now.getNum() * 2);//将 next 的文本设置为 now 的数字乘以 2
now.setText(0);//将 now 的文本设置为 0
next.setIsAdded(true);//并将 next 的添加状态设置为 true
now.setIsAdded(false);//将 now 的添加状态设置为 false
}
} else {
if (next.getNum() == 0) { //如果下一个方块 next 的数字为 0
next.setText(now.getNum()); //将 next 的文本设置为 now 的数字
now.setText(0); //将 now 的文本设置为 0。
}
now.setIsAdded(false);//无论是否进行添加操作,都将 now 和 next 的添加状态设置为 false。
next.setIsAdded(false);//无论是否进行添加操作,都将 now 和 next 的添加状态设置为 false。
}
}
/**
* 获取指定控件
*
* @param x
* @param y
* @return Cube
*/
private Cube getView(int x, int y) { //定义了一个名为 getView 的私有方法,它接受两个整数类型的参数 x 和 y。
return viewList.get(new Point(x, y));//方法的主体部分,它返回 viewList 集合中对应于 (x, y) 坐标的 Cube 对象。
}//这段代码是一个方法的定义,它的目的是根据给定的 x 和 y 坐标,从一个叫做 viewList 的集合中获取对应的 Cube 对象。
//在这里,viewList 是一个集合,它存储了 Cube 对象。new Point(x, y) 创建了一个新的 Point 对象,其中 x 和 y 是传递给方法的坐标。
//get() 方法是集合的一个方法,用于根据给定的键获取对应的值。在这个例子中,集合的键是 Point 对象,它表示坐标,而值是 Cube 对象。
//因此,整个方法的作用是:根据给定的 x 和 y 坐标,在 viewList 集合中找到对应的 Cube 对象,并返回该对象。
/**
* 生成随机控件 随机位置
*/
private void createCube() {
int x;
int y;
//声明了两个整数变量 x 和 y,用于存储生成的随机位置的坐标。
do {
x = (int) (Math.random() * 1000 % row);
y = (int) (Math.random() * 1000 % column);
} while (getView(x, y).getNum() != 0);
/*
然后,通过调用 Math.random() 函数和一些算术运算,生成一个介于 0 和 1000 之间的随机数,
并将其取模以限制在 row 和 column 的范围内,确保生成的位置在游戏界面内。
接下来,使用一个 do-while 循环,检查生成的位置是否已经存在一个方块。如果方块数量不为 0,则重新生成位置,直到找到一个可用的位置。
一旦找到可用位置,将方块的文本设置为 2 或 4,具体取决于随机数是否大于 0.5。
最后,调用 isOverGame() 方法检查游戏是否结束。
*/
getView(x, y).setText(Math.random() > 0.5 ? 2 : 4);
isOverGame();
}//createCube() 方法是一个用于生成随机控件(在这种情况下是一个方块)的私有方法。
//它的目的是在游戏界面的随机位置创建一个方块。
/**
* 检测游戏状态
*/
private void isOverGame() { //isOverGame() 方法是一个用于检查游戏是否结束的私有方法。
int score = 0; //首先初始化一个变量 score 来存储游戏得分
int state = Game2048.GAME_OVER;//并将状态设置为 GAME_OVER,表示游戏结束。
//然后,使用两个嵌套的循环遍历游戏界面的每个位置。
for (int x = 0; x < row; x++) {
for (int y = 0; y < column; y++) {
// 计算得分
score += getView(x, y).getNum();
//在循环内部,通过调用 getView(x, y).getNum() 方法获取每个位置上方块的数字,并将其加到得分中。
if (getView(x, y).getNum() == 0) { //如果某个位置上的方块数字为 0
state = Game2048.GAME_CONTINUE; //则将状态设置为 GAME_CONTINUE,表示游戏可以继续。
} else if (getView(x, y).getNum() == 2048 * (gameLv + 1)) { //另外,如果某个位置上的方块数字等于 2048 的 (gameLv + 1) 倍
state = Game2048.GAME_WIN; //则将状态设置为 GAME_WIN,表示玩家获胜。
}
}
}
if (state != Game2048.GAME_CONTINUE && state != Game2048.GAME_WIN) { //循环结束后,检查状态是否不等于 GAME_CONTINUE 和 GAME_WIN
gameState = Game2048.GAME_OVER; //如果满足条件,表示游戏结束,将游戏状态设置为 GAME_OVER。
} else {
gameState = state;
}//否则,将游戏状态设置为之前计算的状态。
scoreBoard.setText("得分:" + score);
//最后,通过调用 scoreBoard.setText("得分:" + score) 方法更新得分显示。
}
//这段代码的主要目的是检查游戏是否结束,并根据游戏状态更新得分显示。
//它通过遍历游戏界面的每个位置,计算得分,并根据得分和方块数字来判断游戏的结束状态。
/**
* 获取游戏状态
*
* @return int
*/
public int getGameState() {
return gameState;
}//getGameState() 方法是一个公共方法,用于获取游戏的状态。
//它返回一个整数类型的变量 gameState,表示游戏的当前状态。
/**
* 初始化游戏数据
*/
private void initialise() { //initialise() 方法是一个私有方法,用于初始化游戏数据。
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
getView(i, j).setText(0);
}//在方法内部,使用两个嵌套的循环遍历游戏界面的每个位置,将每个位置上的方块文本设置为 0。
}
createCube();//接下来,调用 createCube() 方法两次,生成两个初始的方块。
createCube();//接下来,调用 createCube() 方法两次,生成两个初始的方块。
gameLv = 0;//然后,将 gameLv 设置为 0,表示游戏难度级别。
this.setTitle("2048小游戏");//最后,通过调用 setTitle("2048") 方法设置游戏窗口的标题为 "2048小游戏"。
}
/**
* 开启新游戏
*/
public void newGame() { //方法是一个用于开启新游戏的公共方法。
if (gameState == Game2048.GAME_CONTINUE) { //首先,检查游戏状态是否为 GAME_CONTINUE
int jop = JOptionPane.showConfirmDialog(null, "是否开始新一轮游戏?", "Tips",
JOptionPane.YES_NO_OPTION);//如果是,表示游戏正在进行中,需要确认是否开始新一轮游戏。
//使用 JOptionPane.showConfirmDialog() 方法显示一个确认对话框,
//提示用户是否开始新一轮游戏,并提供 "是" 和 "否" 两个选项。
if (jop == JOptionPane.YES_OPTION) {
initialise();
}//根据用户的选择,判断 jop 的值。如果用户选择 "是"(即 jop 等于 JOptionPane.YES_OPTION),
//则调用 initialise() 方法初始化游戏数据
} else {
initialise();
}//如果游戏状态不是 GAME_CONTINUE,也会直接调用 initialise() 方法初始化游戏数据。
}
/**
* 重载窗体事件-控制关闭
*/
protected void processWindowEvent(WindowEvent e) { //processWindowEvent() 方法是一个用于处理窗口事件的 protected 方法。它被重载以控制窗口的关闭操作。
if (e.getID() == WindowEvent.WINDOW_CLOSING) { //如果接收到的窗口事件的 ID 为 WindowEvent.WINDOW_CLOSING,表示用户尝试关闭窗口。
if (getGameState() == Game2048.GAME_CONTINUE) { //首先,检查游戏状态是否为 GAME_CONTINUE。如果是,表示游戏正在进行中。
int jop = JOptionPane.showConfirmDialog(null, "是否退出游戏?", //使用 JOptionPane.showConfirmDialog() 方法显示一个确认对话框,询问用户是否退出游戏。
"Tips", JOptionPane.YES_NO_OPTION); //创建一个带有提示信息和 "是"、"否" 两个选项的提示对话框。用户可以根据自己的需求选择相应的选项。
if (jop == JOptionPane.YES_OPTION) {
super.processWindowEvent(e);
}
//根据用户的选择,判断 jop 的值。如果用户选择 "是"(即 jop 等于 JOptionPane.YES_OPTION),则调用父类的 processWindowEvent(e) 方法处理窗口关闭事件。
} else {
super.processWindowEvent(e);
}//如果游戏状态不是 GAME_CONTINUE,也会直接调用父类的 processWindowEvent(e) 方法处理窗口关闭事件。
}
}
/**
* 进入下一难度游戏
*/
public void nextLv() { //是一个公共方法,用于执行游戏等级的提升操作。
gameLv++; //将变量 gameLv 的值增加 1,用于表示游戏等级的增加。
this.setTitle(2048 * (gameLv + 1) + "");//这行代码用于设置游戏窗口的标题。通过计算 2048 * (gameLv + 1) 的结果,并将结果与空字符串拼接,得到最终的标题字符串。每次游戏等级提升时,窗口标题会显示相应的等级信息。
}/*
这段代码的主要目的是在游戏中提升等级,并更新游戏窗口的标题以显示当前的等级信息。每次调用 nextLv() 方法,游戏等级会增加,并且窗口标题会根据等级的变化而更新。
*/
/**
* 关于
*/
public void about() { //是一个公共方法,用于显示关于游戏的信息。
JOptionPane.showMessageDialog(null, "QQ邮箱:1291672308@qq.com");
}/*
这行代码使用 JOptionPane.showMessageDialog() 方法显示一个消息对话框。
null 表示将对话框显示在没有特定父组件的位置。消息对话框的内容是 "QQ 邮箱:1291672308@qq.com",即显示了一个 QQ 邮箱地址。
*/
}
class Cube { //定义一个类,名为 Cube
private int num; //这是一个私有成员变量,用于存储整数类型的数据。
private JButton btn; //这是一个私有成员变量,用于表示按钮对象。
private boolean isAdded; //这是一个私有成员变量,用于表示布尔类型的状态。
/**
* 构造一个方块
*/
public Cube() { //这是 Cube 类的构造方法,用于创建一个 Cube 对象。公共的构造函数 Cube()。
btn = new JButton(); //在构造方法内部,创建了一个新的 JButton 对象,并将其赋值给成员变量 btn。
btn.setFont(new Font("微软雅黑", Font.BOLD, 24)); //设置按钮的字体为 "微软雅黑",字体样式为加粗,字体大小为 24 像素。
btn.setEnabled(false); //将按钮设置为不可用状态,即按钮变为灰色且无法点击。
num = 0; //将成员变量 num 的值初始化为 0。
isAdded = false; //将成员变量 isAdded 的值初始化为 false。
}
/*
*这个构造方法的主要目的是创建一个 Cube 对象,并初始化其成员变量。
*其中,创建了一个按钮对象,并设置了字体样式和大小,以及将按钮设置为不可用状态。
*此外,还将整数变量 num 初始化为 0,以及布尔变量 isAdded 初始化为 false。
*/
/**
* 设置文本内容
*
* @param n
* 数值
*/
public void setText(int n) { //这是一个公共方法,用于设置文本内容。
num = n; //将传入的整数参数 n 赋值给成员变量 num。
btn.setText(n != 0 ? n + "" : "");//如果 n 不等于 0,则将 n 转换为字符串并添加一个空字符串作为后缀,否则设置为空字符串。这行代码的目的是根据 n 的值来设置按钮的文本内容。
}
/*
*这段代码的主要目的是根据传入的整数参数 n 来更新按钮的文本内容。
*如果 n 不等于 0,则将其转换为字符串并显示在按钮上;如果 n 等于 0,则将按钮的文本内容设置为空字符串。
*/
/**
* 获取控件
*
* @return JButton
*/
public JButton getView() { //这是一个公共方法,用于获取控件。
return btn; //返回成员变量 btn,其类型为 JButton。
}/*
这个方法的主要目的是返回 JButton 类型的控件对象,以便外部代码可以获取和操作该按钮。
通过调用 getView() 方法,外部代码可以获取到 Cube 类中维护的按钮控件。
*/
/**
* 获取数值
*
* @return int
*/
public int getNum() { //这是一个公共方法,用于获取数值。
return num; //返回成员变量 num,其类型为整数类型 int。
}/*
这个方法的主要目的是返回整数类型的数值,该数值由成员变量 num 存储。
通过调用 getNum() 方法,外部代码可以获取到 Cube 类中维护的当前数值。
*/
/**
* 是否是相加而成 限当前移动次有效,移动结束后改回默认值-false
*
* @return
*/
public boolean isAdded() { //这是一个公共方法,用于获取是否是相加而成的状态。
return isAdded; //返回成员变量 isAdded,其类型为布尔类型 boolean。
}/*
这个方法的主要目的是返回一个布尔类型的状态值,表示是否是通过相加操作而成。通过调用 isAdded() 方法,外部代码可以获取到 Cube 类中维护的当前相加状态。
根据注释所述,该方法仅在当前移动次有效,并且在移动结束后会将该状态改回默认值 false。
*/
/**
* 修改生成方式
*
* @param b
* true-相加而成
*/
public void setIsAdded(boolean b) { //这是一个公共方法,用于设置生成方式的状态。
isAdded = b; //:将传入的布尔参数 b 赋值给成员变量 isAdded。
}
/*
* 这个方法的主要目的是修改成员变量 isAdded 的值,以控制生成方式的状态。
* 通过调用 setIsAdded(boolean b) 方法,外部代码可以将生成方式的状态设置为相加而成(当 b 的值为 true 时)或其他方式。
*/
}
class MyKeyListener implements KeyListener { //这段代码定义了一个名为 MyKeyListener 的类,
//该类实现了 KeyListener 接口。这个类用于处理键盘事件,并定义了一些常量来表示键盘上的特定按键。
/*
* 键盘代码 w/87 s/83 a/65 d/68 up/38 down/40 left/37 right/39 f1/112 f2/113
* f3/114
*/
final public static int KEY_W = 0xf57; //定义了常量 KEY_W,其值为十六进制数 0xf57。在不同的键盘布局中,W 键可能对应不同的整数值。
final public static int KEY_S = 0xf53; //定义了常量 KEY_S,其值为十六进制数 0xf53。在不同的键盘布局中,S 键可能对应不同的整数值。
final public static int KEY_A = 0xf41; //定义了常量 KEY_A,其值为十六进制数 0xf41。在不同的键盘布局中,A 键可能对应不同的整数值。
final public static int KEY_D = 0xf44; //定义了常量 KEY_D,其值为十六进制数 0xf44。在不同的键盘布局中,D 键可能对应不同的整数值。
final public static int KEY_UP = 0xf26; //定义了常量 KEY_UP,其值为十六进制数 0xf26。在不同的键盘布局中,向上箭头键可能对应不同的整数值。
final public static int KEY_DOWN = 0xf28; //定义了常量 KEY_DOWN,其值为十六进制数 0xf28。在不同的键盘布局中,向下箭头键可能对应不同的整数值。
final public static int KEY_LEFT = 0xf25; //定义了常量 KEY_LEFT,其值为十六进制数 0xf25。在不同的键盘布局中,向左箭头键可能对应不同的整数值。
final public static int KEY_RIGHT = 0xf27; //定义了常量 KEY_RIGHT,其值为十六进制数 0xf27。在不同的键盘布局中,向右箭头键可能对应不同的整数值。
private Game2048 game;
/**
* 构造一个键盘监听器
*
* @param game
* 主界面
*/
public MyKeyListener(Game2048 game) { //是一个公共构造函数的声明,
this.game = game; //它接受一个 Game2048 类型的参数,并将其赋值给内部的 game 变量。
}
@Override //这是一个注解,表示该方法覆盖了父类的同名方法。
public void keyPressed(KeyEvent e) { //这是一个键盘事件监听器的方法,当用户按下键盘上的某个键时会触发该方法。
int keyCode = e.getKeyCode() + 0xf00; //获取用户按下的键的虚拟键码,并将其转换为特定的游戏键值。0xf00 是一个偏移量,用于将键码映射到游戏中定义的键值范围。
switch (game.getGameState()) { //根据游戏的当前状态来处理不同的按键操作。
case Game2048.GAME_CONTINUE: { //处理游戏继续状态下的按键操作。
switch (keyCode) {//根据用户按下的键来执行相应的游戏操作。
case MyKeyListener.KEY_W:
case MyKeyListener.KEY_UP: {
game.up();
}//如果用户按下了 W 键,执行 game.up() 方法,游戏中的方块向上移动。
break;
case MyKeyListener.KEY_S:
case MyKeyListener.KEY_DOWN: {
game.down();
}//如果用户按下了 S 键,执行 game.down() 方法,游戏中的方块向下移动。
break;
case MyKeyListener.KEY_A:
case MyKeyListener.KEY_LEFT: {
game.left();
}//如果用户按下了 A 键,执行 game.left() 方法,游戏中的方块向左移动。
break;
case MyKeyListener.KEY_D:
case MyKeyListener.KEY_RIGHT: {
game.right();
}// 如果用户按下了 D 键,执行 game.right() 方法,游戏中的方块向右移动。
break;
}
}
break;
case Game2048.GAME_OVER: { //这是一个 switch 语句的分支,当 Game2048.GAME_OVER 这个常量的值与 switch 表达式的值匹配时,就会执行这个分支处理游戏结束状态下的按键操作。
int jop = JOptionPane //一个变量,用于存储用户在确认对话框中选择的按钮。它的类型是 int,值是 JOptionPane.YES_OPTION(表示用户选择了是)或 JOptionPane.NO_OPTION(表示用户选择了否)。
.showConfirmDialog(null, "很遗憾,你没能达成本次目标,是否开启新游戏?", "游戏结束",//这行代码调用了 JOptionPane.showConfirmDialog 方法来显示一个确认对话框。第一个参数 null 表示没有父窗口。
//第二个参数是要显示的消息。第三个参数是对话框的标题。第四个参数是对话框的选项类型,这里使用了 JOptionPane.YES_NO_OPTION,表示有两个选项:是和否。
JOptionPane.YES_NO_OPTION);
//综上所述,这段代码会在游戏结束时显示一个确认对话框,询问用户是否要开启新游戏。用户可以选择是或否,选择的结果会存储在变量 jop 中。
if (jop == JOptionPane.YES_OPTION) {
game.newGame();
}
}//如果用户在游戏结束对话框中选择了 "是"(即 JOptionPane.YES_OPTION),执行相应的操作,可能是重新开始游戏。
break;
case Game2048.GAME_WIN: { //理游戏胜利状态下的按键操作。
int jop = JOptionPane.showConfirmDialog(null,
"你已完成本次目标:" + game.getTitle() + ",是否进入更高难度游戏?", "恭喜晋级",
JOptionPane.YES_NO_OPTION); //
//如果用户在游戏胜利对话框中选择了 "是"(即 JOptionPane.YES_OPTION),执行相应的操作进入下一关卡。
if (jop == JOptionPane.YES_OPTION) { //这行代码检查用户在确认对话框中选择的按钮。如果用户选择了 "是"(即 JOptionPane.YES_OPTION),则执行下面的操作。
game.nextLv(); //这行代码调用了 game 对象的 nextLv 方法。
}
}
break; //这行代码结束了 switch 语句的执行,使程序流程跳出当前的 switch 块。
}
}
@Override //这是一个注解,表示该方法覆盖了父类的同名方法。
public void keyReleased(KeyEvent e) {
} //方法在键盘按键释放时被调用。它接收一个 KeyEvent 对象作为参数,该对象包含了关于按键事件的信息,如按键的字符、键码和按下状态等。
@Override //这是一个注解,表示该方法覆盖了父类的同名方法。
public void keyTyped(KeyEvent e) {
} //方法在键盘输入字符时被调用。它也接收一个 KeyEvent 对象作为参数,该对象包含了关于按键输入事件的信息,如输入的字符和键码等。
}
/*
这两段代码是 Java 中定义的两个方法,它们是键盘事件监听器接口 KeyListener 的实现。这个接口用于接收和处理键盘事件,包括按键按下、按键释放和按键输入。
*/
class MyMouseListener implements MouseListener { //这一行声明了一个名为 MyMouseListener 的类,并且该类实现了 MouseListener 接口。MouseListener 接口包含了处理鼠标事件的方法,例如鼠标按下、鼠标释放、鼠标进入和鼠标退出等。
private Game2048 game; //这一行声明了一个私有成员变量 game,它的类型是 Game2048。Game2048 是一个自定义的类或接口,这里它是一个代表游戏的类。
private int btnEvn; //这一行声明了另一个私有成员变量 btnEvn,它的类型是 int。btnEvn 是一个用于表示按钮事件的整数。
public MyMouseListener(Game2048 game, int btnEvn) { //这一行定义了类的构造函数,它接受两个参数:一个 Game2048 类型的对象和一个整数。这些参数将被用于初始化类的成员变量。
this.game = game; //这一行将传入的 game 参数赋值给类的成员变量 game,以便在类的其他地方使用。
this.btnEvn = btnEvn; //这一行将传入的 btnEvn 参数赋值给类的成员变量 btnEvn,以便在类的其他地方使用。
}
/*
这段代码是一个 Java 类的定义,该类名为 MyMouseListener,并且实现了 MouseListener 接口。
这个类的目的是处理鼠标事件,并与游戏的逻辑相关。通过实现 MouseListener 接口的方法,可以在鼠标事件发生时执行相应的操作。
*/
@Override //这是一个注解,表示该方法覆盖了父类的同名方法。
public void mouseClicked(MouseEvent e) {
//当鼠标按钮被单击时调用的方法。
}
@Override //这是一个注解,表示该方法覆盖了父类的同名方法。
public void mouseEntered(MouseEvent e) {
//当鼠标进入组件的边界时调用的方法。
}
@Override //这是一个注解,表示该方法覆盖了父类的同名方法。
public void mouseExited(MouseEvent e) {
//当鼠标退出组件的边界时调用的方法。
}
@Override //这是一个注解,表示该方法覆盖了父类的同名方法。
public void mousePressed(MouseEvent e) {
//当鼠标按钮被按下时调用的方法。
}
/*
*定义了一个名为 MyMouseListener 的类,该类实现了 MouseListener 接口。
*在这个类中,有四个方法,每个方法都使用了 @Override 注解,表示这些方法覆盖了 MouseListener 接口中的同名方法。
*/
@Override //这是一个注解,表示该方法覆盖了父类的同名方法。
//使用 @Override 注解的目的是确保方法的签名与父类中的方法签名匹配,这样可以避免在编译时出现错误。同时,它还可以提高代码的可读性,让开发者更清楚地知道该方法是覆盖了父类的方法
public void mouseReleased(MouseEvent e) { //这是方法的签名,声明了该方法是一个公共的(public),空返回值(void)的方法,接收一个 MouseEvent 类型的参数 e。这个方法在鼠标按钮释放时被调用。
switch (btnEvn) { //这是一个 switch 语句,根据 btnEvn 的值来执行不同的操作。btnEvn 是一个整数类型的变量,它表示按钮事件。
case Game2048.BUTTON_NEW_GAME: { //这是 switch 语句的一个分支,如果 btnEvn 的值等于 Game2048.BUTTON_NEW_GAME,则执行该分支的代码。
game.newGame(); //在这个分支中,调用了 game.newGame() 方法。game 是一个对象,它具有 newGame() 方法,用于重新开始游戏。
}
break; //表示结束当前分支的执行,防止在匹配成功后再执行其他分支。
case Game2048.BUTTON_ABOUT: { //这是另一个分支,如果 btnEvn 的值等于 Game2048.BUTTON_ABOUT,则执行该分支的代码。
game.about(); //在这个分支中,调用了 game.about() 方法。game 对象具有 about() 方法,用于显示关于游戏的信息。
}
break; //同样,表示结束当前分支的执行。
case Game2048.BUTTON_EXIT: { //这是第三个分支,如果 btnEvn 的值等于 Game2048.BUTTON_EXIT,则执行该分支的代码。
game.processWindowEvent(new WindowEvent(game,
WindowEvent.WINDOW_CLOSING)); //在这个分支中,调用了 game.processWindowEvent() 方法,并传递了一个 WindowEvent 对象作为参数。game 对象具有 processWindowEvent() 方法,用于处理窗口事件。
//在这里,传递了一个 WindowEvent.WINDOW_CLOSING 类型的窗口事件,用于关闭窗口。
}
break; //结束当前分支的执行。
}
}
}
文章来源:https://blog.csdn.net/weixin_61861127/article/details/136483156
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签: