一.项目简介:
连连看是一种消除类益智游戏,核心要求是在规定的时间内,消除游戏界面中选中的两张相同的图案,直至完全消除所有图案。 这款游戏操作简单 (只需单击鼠标左键操作)、面向人群广泛,在限时操作的游戏要求下,吸引玩家自发地锻炼观察能力、判断能力和反应能力,故从推出至今颇受欢迎。该游戏不仅能调节精神状态,还能在游戏中锻炼我们的眼力视野和集中力,开发思维能力的同时培养面对困难时具备攻克困难的信心。
二.项目采用技术:
此次设计所使用的语言为Java语言,开发环境为JDK Version11.0.2,开发工具为Idea。主要应用Swing组件,Java小程序,事件及接口等。本系统主要是运用Swing组件和事件处理技术,进行界面的绘制,鼠标的操作,以及积分的显示等功能。
三.功能需求分析:
1. 游戏界面设计:系统界面简单,功能较完善,易上手,可以激发玩家的乐趣;通用性好,扩展性强。本系统可以适用于各种人群,具有优越的通用性能。
2. 游戏规则设计:选择两个图形,判断是否满足一定条件,条件即两个图形一致且二者之间存在转弯少于3的路径。当判定满足这一条件后,两张图片被消除,在运行一次游戏过程中,点击两个不同的图片时,不会消除两个图片,在点击第一个图片时图片内数字被圈出,点击第二个图片时因为图片不匹配,两张图片没有消失。在运行一次游戏过程中,点击满足存在多于三个连接路径的两张图片,同样也不能消除。记分功能正确,每消除一对图片得分100,得分数在游戏界面上能明确标识,直观的显示出当前的游戏状态。当游戏没有可以连接的数字后可以点击重列,可以打乱其中的数字的位置再进行游戏。
四.项目亮点:
1.界面简洁,操作方便。系统界面简单,功能较完善,易上手,可以激发玩家的乐趣。
2. 通用性好,扩展性强。
3.运用Swing组件和事件处理技术。
4.重列功能。
五.系统主要功能截图:
六.核心代码
public void init() {
mainFrame = new JFrame("JKJ连连看");
thisContainer = mainFrame.getContentPane();
thisContainer.setLayout(new BorderLayout());
centerPanel = new JPanel();
southPanel = new JPanel();
northPanel = new JPanel();
thisContainer.add(centerPanel, "Center");
thisContainer.add(southPanel, "South");
thisContainer.add(northPanel, "North");
centerPanel.setLayout(new GridLayout(6, 5));
for (int cols = 0; cols < 6; cols++) {
for (int rows = 0; rows < 5; rows++) {
diamondsButton[cols][rows] = new JButton(String.valueOf(grid[cols + 1][rows + 1]));
diamondsButton[cols][rows].addActionListener(this);
centerPanel.add(diamondsButton[cols][rows]);
}
}
exitButton = new JButton("退出");
exitButton.addActionListener(this);
resetButton = new JButton("重列");
resetButton.addActionListener(this);
newlyButton = new JButton("再来一局");
newlyButton.addActionListener(this);
southPanel.add(exitButton);
southPanel.add(resetButton);
southPanel.add(newlyButton);
fractionLable.setText("分数:"+score);
northPanel.add(fractionLable);
int width=Toolkit.getDefaultToolkit().getScreenSize().width;
int height=Toolkit.getDefaultToolkit().getScreenSize().height;
mainFrame.setBounds((width-500)/2,(height-500)/2, 500, 500);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setResizable(false);
mainFrame.setVisible(true);
}
这段代码的主要功能是初始化一个名为“JKJ连连看”的游戏。这个游戏的主要界面由一个JFrame窗口组成,其中包含了一个中心面板、一个南面板和一个北面板。中心面板是游戏的主要区域,它包含了一个6x5的网格,每个网格都是一个按钮。南面板包含了三个按钮:退出、重列和再来一局。北面板包含了一个标签,用于显示当前的分数。
public void randomBuild() {
int randoms, cols, rows;
for (int twins = 1; twins <= 15; twins++) { //生成15个随机数
randoms = (int) (Math.random() * 15 + 1);
for (int alike = 1; alike <= 2; alike++) { //每次将这个数放在两个位置
cols = (int) (Math.random() * 6 + 1);
rows = (int) (Math.random() * 5 + 1); //随机生成数组坐标[cols,rows]
while (grid[cols][rows] != 0) { //如果这个位置已经赋值了,重新生成。
cols = (int) (Math.random() * 6 + 1);
rows = (int) (Math.random() * 5 + 1);
}
this.grid[cols][rows] = randoms; //将这个随机数赋到数组中。
}
}
}
这段代码主要功能是重新生成一个新的连连看游戏。 这个函数会将当前的游戏状态保存到一个名为“save”的数组中,并将所有的数字从当前的网格中删除。 然后,它会随机生成一个新的网格,并将之前保存的数字放回到新的网格中。 最后,这个函数会重新初始化游戏界面,并将所有数字为0的按钮隐藏起来。
public void xiao() { // 相同的情况下能不能消去。仔细分析,不一条条注释
if ((x0 == x && (y0 == y + 1 || y0 == y - 1))|| ((x0 == x + 1 || x0 == x - 1) && (y0 == y))) { // 判断是否相邻
remove();
} else {
for (j = 0; j < 7; j++) {
if (grid[x0][j] == 0) { // 判断第一个按钮同行哪个按钮为空
if (y > j) { // 如果第二个按钮的Y坐标大于空按钮的Y坐标说明第一按钮在第二按钮左边
for (i = y - 1; i >= j; i--) { // 判断第二按钮左侧直到第一按钮中间有没有按钮
if (grid[x][i] != 0) {
k = 0;
break;
} else {
k = 1;
} // K=1说明通过了第一次验证
}
if (k == 1) {
linePassOne();
}
}
if (y < j) { // 如果第二个按钮的Y坐标小于空按钮的Y坐标说明第一按钮在第二按钮右边
for (i = y + 1; i <= j; i++) { // 判断第二按钮左侧直到第一按钮中间有没有按钮
if (grid[x][i] != 0) {
k = 0;
break;
} else {
k = 1;
}
}
if (k == 1) {
linePassOne();
}
}
if (y == j) {
linePassOne();
}
}
if (k == 2) {
if (x0 == x) {
remove();
}
if (x0 < x) {
for (n = x0; n <= x - 1; n++) {
if (grid[n][j] != 0) {
k = 0;
}
if (grid[n][j] == 0 && n == x - 1) {
remove();
}
}
}
if (x0 > x) {
for (n = x0; n >= x + 1; n--) {
if (grid[n][j] != 0) {
k = 0;
break;
}
if (grid[n][j] == 0 && n == x + 1) {
remove();
}
}
}
}
}
for (i = 0; i < 8; i++) { // 列
if (grid[i][y0] == 0) {
if (x > i) {
for (j = x - 1; j >= i; j--) {
if (grid[j][y] != 0) {
k = 0;
break;
} else {
k = 1;
}
}
if (k == 1) {
rowPassOne();
}
}
if (x < i) {
for (j = x + 1; j <= i; j++) {
if (grid[j][y] != 0) {
k = 0;
break;
} else {
k = 1;
}
}
if (k == 1) {
rowPassOne();
}
}
if (x == i) {
rowPassOne();
}
}
if (k == 2) {
if (y0 == y) {
remove();
}
if (y0 < y) {
for (n = y0; n <= y - 1; n++) {
if (grid[i][n] != 0) {
k = 0;
break;
}
if (grid[i][n] == 0 && n == y - 1) {
remove();
}
}
}
if (y0 > y) {
for (n = y0; n >= y + 1; n--) {
if (grid[i][n] != 0) {
k = 0;
break;
}
if (grid[i][n] == 0 && n == y + 1) {
remove();
}
}
}
}
}
}
}
public void linePassOne() {
if (y0 > j) { // 第一按钮同行空按钮在左边
for (i = y0 - 1; i >= j; i--) { // 判断第一按钮同左侧空按钮之间有没按钮
if (grid[x0][i] != 0) {
k = 0;
break;
} else {
k= 2;
} // K=2说明通过了第二次验证
}
}
if (y0 < j) { // 第一按钮同行空按钮在与第二按钮之间
for (i = y0 + 1; i <= j; i++) {
if (grid[x0][i] != 0) {
k = 0;
break;
} else {
k = 2;
}
}
}
}
public void rowPassOne() {
if (x0 > i) {
for (j = x0 - 1; j >= i; j--) {
if (grid[j][y0] != 0) {
k = 0;
break;
} else {
k = 2;
}
}
}
if (x0 < i) {
for (j = x0 + 1; j <= i; j++) {
if (grid[j][y0] != 0) {
k = 0;
break;
} else {
k = 2;
}
}
}
}
//消去按钮算法
public void remove() {
firstButton.setVisible(false);
secondButton.setVisible(false); //两个按钮不可见
fraction(); //改变分数
pressInformation = false; //点击按钮键清掉
k = 0; //可消除标志清空
grid[x0][y0] = 0;
grid[x][y] = 0; //按钮键值清零
}
这段代码主要功能是消除两个相同的按钮。 这个函数会判断两个按钮是否相邻,如果相邻,那么这个函数会直接调用“remove()”函数来消除这两个按钮。如果两个按钮不相邻,那么这个函数会判断第一个按钮和第二个按钮是否在同一行。如果在同一行,那么这个函数会调用“linePassOne()”函数来判断第二个按钮和空按钮之间是否有其他的按钮。如果第二个按钮在空按钮的左边,那么这个函数会从第二个按钮的左侧开始向右遍历直到空按钮的位置。如果第二个按钮在空按钮的右边,那么这个函数会从第二个按钮的右侧开始向左遍历,直到空按钮的位置。如果第二个按钮和空按钮之间没有其他的按钮,那么这个函数会调用“remove()”函数来消除这两个按钮。如果第一个和第二个按钮不在同一行,那么这个函数会调用“rowPassOne()”函数来判断第二个按钮和空按钮之间是否有其他的按钮。如果第二个按钮在空按钮的上面,那么这个函数会从第二个按钮的上方开始向下遍历,直到空按钮的位置。如果第二个按钮在空按钮的下面,那么这个函数会从第二个按钮的下方开始向上遍历,直到空按钮的位置。如果第二个按钮和空按钮之间没有其他的按钮,那么这个函数会调用“remove()”函数来消除这两个按钮。
public void actionPerformed(ActionEvent e) {
if (e.getSource() == newlyButton) {
int grid[][] = new int[8][7];
this.grid = grid;
randomBuild();
score=0;
mainFrame.setVisible(false);
pressInformation = false;
init();
}
if (e.getSource() == exitButton)
System.exit(0);
if (e.getSource() == resetButton)
reload();
for (int cols = 0; cols < 6; cols++) {
for (int rows = 0; rows < 5; rows++) {
if (e.getSource() == diamondsButton[cols][rows])
estimateEven(cols + 1, rows + 1, diamondsButton[cols][rows]);
}
}
}
这段代码包含了一个名为“actionPerformed”的函数。 这个函数是在用户点击按钮时被调用的。如果用户点击“newlyButton”按钮,那么这个函数会创建一个新的游戏界面,并重新开始游戏。如果用户点击“exitButton”按钮,那么这个函数会退出游戏。如果用户点击“resetButton”按钮,那么这个函数会重新加载游戏。最后,这个函数会遍历整个游戏界面,检查哪些按钮被点击了。如果一个按钮被点击了,那么这个函数会调用“estimateEven()”函数来判断这个按钮是否可以消除。
七:团队成员负责模块
姓名 | 负责模块 |
胡俊芝 | 游戏规则设置 |
刘益嘉 | 创建游戏窗口 |
张浩 | 第一次游戏结束后的选择 |
八:项目git地址:
九:团队成员git提交记录