基于Java實(shí)現(xiàn)連連看游戲的示例代碼
前言
連連看游戲顧名思義就是找出具有關(guān)聯(lián)關(guān)系的事物并進(jìn)行相應(yīng)處理,經(jīng)歷了從桌面游戲、在線游戲再到社交游戲三個(gè)過(guò)程,形式多種多樣。游戲的核心要求是將兩個(gè)能用三根以?xún)?nèi)的直線連接的關(guān)聯(lián)事物(相同事物)消除(或進(jìn)行其他處理)。一般的連連看小游戲規(guī)則和操作都簡(jiǎn)單明了易上手,但也有很多新版本的連連看游戲加入了各類(lèi)道具和游戲模式來(lái)豐富游戲內(nèi)容,很好地增強(qiáng)了游戲的娛樂(lè)性,也帶給玩家長(zhǎng)期的挑戰(zhàn)性和新鮮感。
《連連看》游戲用java語(yǔ)言實(shí)現(xiàn),采用了swing技術(shù)進(jìn)行了界面化處理,設(shè)計(jì)思路用了面向?qū)ο笏枷搿?/p>
主要需求
在業(yè)務(wù)需求方面,第一,具備連連看基本游戲功能。選擇兩個(gè)圖形,判斷是否滿足一定條件,條件即兩個(gè)圖形一致且二者之間存在轉(zhuǎn)彎少于3的路徑。當(dāng)判定滿足這一條件后,兩張圖片被消除。第二,具備附加功能:計(jì)時(shí)功能、重新開(kāi)始功能、刷新當(dāng)前界面功能等。
在用戶需求有兩個(gè)方面,一方面,要求游戲界面整齊美觀,長(zhǎng)時(shí)間使用也應(yīng)盡可能的減小對(duì)游戲的審美疲勞。另一方面,要求游戲體驗(yàn)良好。在運(yùn)行游戲的過(guò)程中,能保證數(shù)據(jù)安全,游戲能穩(wěn)定、高速地運(yùn)行。對(duì)于游戲本身,用戶往往要求游戲功能相對(duì)完善,游戲具備可娛樂(lè)性,并且游戲規(guī)則易理解,游戲操作既要簡(jiǎn)單同時(shí)也應(yīng)有難度,在保證游戲操作順滑、響應(yīng)快速的情況下,游戲能具有一定的挑戰(zhàn)性。
主要設(shè)計(jì)
1、界面設(shè)計(jì)
游戲主界面以窗口形式給出,用戶操作的游戲功能部分由各個(gè)組件構(gòu)成,通過(guò)彈出的提示框開(kāi)始游戲活動(dòng),用戶通過(guò)點(diǎn)擊窗口上的各個(gè)組件完成操作。
在游戲的界面上,還有一個(gè)特殊的面板,漏斗面板,漏斗面板上繪制了一個(gè)沙漏狀的倒計(jì)時(shí)裝置,該裝置通過(guò)線程控制,時(shí)間變量每更新一次,漏斗面上重新繪制一次,每次繪制的線條通過(guò)判斷條件設(shè)置擺放位置,隨著時(shí)間的遞增,沙漏狀的倒計(jì)時(shí)裝置就動(dòng)態(tài)的開(kāi)始倒計(jì)時(shí),直至最后五秒,顯示提示信息,倒計(jì)時(shí)結(jié)束后,彈出游戲失敗提示框。
2、游戲執(zhí)行的實(shí)現(xiàn)
因?yàn)槊恳淮芜x擇難度模式后、每通過(guò)一關(guān)游戲后都將開(kāi)始一局新游戲。最終狀態(tài)有兩種,游戲失敗和游戲結(jié)束。
3、記分、記關(guān)數(shù)的實(shí)現(xiàn)
游戲過(guò)程中,每消除一對(duì)相同圖片,得分10,8×8格式的二維圖片集,一共64張圖片,共計(jì)32對(duì),所以每過(guò)一關(guān)得分是320分,消除34對(duì)后的得分。在每一難度下的每一關(guān)通過(guò)后,記分不清0,繼續(xù)記分。但切換到不同難度時(shí),得分會(huì)清0
4、刷新功能的實(shí)現(xiàn)
游戲中每一關(guān)只有一次使用刷新功能的機(jī)會(huì),此功能鍵觸發(fā)的響應(yīng)事件,會(huì)調(diào)用chongzai()方法,按照當(dāng)前狀態(tài)未消除的圖片個(gè)數(shù)重新在二維按鈕排列的其他位置排放其他圖片。
5、重新開(kāi)始游戲功能的實(shí)現(xiàn)
重新開(kāi)始游戲功能實(shí)際也是開(kāi)始新游戲功能,重新開(kāi)始布局的過(guò)程。將圖片成對(duì)的顯示在場(chǎng)景中,并打亂調(diào)用的是newMap()方法。在該方法中,用了一個(gè)數(shù)組以數(shù)字標(biāo)記的形式來(lái)記錄加載的圖片是哪種圖片,在每次加載圖片的時(shí)候是一張圖片連續(xù)加載兩次,以保證加載圖片成對(duì)。然后用數(shù)組的隨機(jī)方法將數(shù)組打亂。
6、游戲的連接算法
連連看游戲中對(duì)于用戶來(lái)說(shuō)最簡(jiǎn)單的呈現(xiàn),就是單擊兩個(gè)連在一起的相同的圖像時(shí),這兩個(gè)圖像就會(huì)消去,但是在Java代碼中是如何實(shí)現(xiàn)的呢?連連看游戲的聯(lián)通算法一般包括回溯法和堆棧實(shí)現(xiàn)的迷宮算法。
根據(jù)游戲規(guī)則能知道,即使不是緊鄰的兩個(gè)相同的圖像塊消去時(shí)也不能超過(guò)兩次轉(zhuǎn)彎。
功能截圖
游戲開(kāi)始主界面:
這是簡(jiǎn)單模式:

中等模式:

困難模式:

變態(tài)模式:

代碼實(shí)現(xiàn)
public class LianLianKan extends JFrame {
private static final long serialVersionUID = 1L;
public LianLianKan() {
LianLianKanJPanel llk = new LianLianKanJPanel();
add(llk);
}
class LianLianKanJPanel extends JPanel implements ActionListener,ItemListener {
private static final long serialVersionUID = 1L;//序列化時(shí)為了保持版本的兼容性,即在版本升級(jí)時(shí)反序列化仍保持對(duì)象的唯一性。
private int[][] map = new int[8][8];//8*8的正方形
private int kind, randomx, randomy, randomx1, randomy1; // 種類(lèi),隨機(jī)x
private int coordinatex, coordinatey, coordinatex1, coordinatey1; // 坐標(biāo)X
private Point lineStart = new Point(0, 0);
private int clicktimes;
private int jishushengyu;//計(jì)數(shù)剩余
private int Kinds = 4;
private int score;
private int guanshu;//關(guān)數(shù)
loudou ld = new loudou();// 漏斗
JButton BlockButton[][] = new JButton[8][8];//
Choice difficultChoice = new Choice();
JButton newgameButton = new JButton("重新開(kāi)始");
JButton reLoad = new JButton("刷新");
ImageIcon ii = new ImageIcon("src/im/bk.jpg");
ImageIcon aIcon = new ImageIcon("src/im/1.gif");
ImageIcon bIcon = new ImageIcon("src/im/2.gif");
ImageIcon cIcon = new ImageIcon("src/im/3.gif");
ImageIcon dIcon = new ImageIcon("src/im/4.gif");
ImageIcon eIcon = new ImageIcon("src/im/5.gif");
ImageIcon fIcon = new ImageIcon("src/im/6.gif");
ImageIcon gIcon = new ImageIcon("src/im/7.gif");
ImageIcon hIcon = new ImageIcon("src/im/8.gif");
ImageIcon iIcon = new ImageIcon("src/im/9.gif");
ImageIcon jIcon = new ImageIcon("src/im/10.gif");
ImageIcon kIcon = new ImageIcon("src/im/11.gif");
ImageIcon lIcon = new ImageIcon("src/im/12.gif");
ImageIcon mIcon = new ImageIcon("src/im/13.gif");
ImageIcon nIcon = new ImageIcon("src/im/14.gif");
ImageIcon oIcon = new ImageIcon("src/im/15.gif");
public LianLianKanJPanel() {
this.setLayout(null);
newMap();
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
BlockButton[i][j] = new JButton();
add(BlockButton[i][j]);
BlockButton[i][j].addActionListener(this);//監(jiān)聽(tīng)器
BlockButton[i][j].setBounds(30 + j * 40, 30 + i * 40, 31,34);
// BlockButton[i][j].setBorderPainted(false);
// BlockButton[i][j].setVisible(true);
}
}
difficultChoice.add("簡(jiǎn)單");
difficultChoice.add("中等");
difficultChoice.add("困難");
difficultChoice.add("變態(tài)");
newgameButton.setBounds(map[0].length * 40 + 80, 40, 100, 20);
newgameButton.setBackground(Color.white);
newgameButton.setBorderPainted(false); //去邊框
reLoad.setBounds(map[0].length * 40 + 100, 80, 60, 20);
reLoad.setBackground(Color.white);
reLoad.setBorderPainted(false);
difficultChoice.setBounds(map[0].length * 40 + 100, 120, 60, 20);
difficultChoice.addItemListener(this);
newgameButton.addActionListener(this);
reLoad.addActionListener(this);
this.add(newgameButton);
this.add(reLoad);
this.add(difficultChoice);
// /-------------------------漏斗
ld.setBounds(map[0].length * 40 + 100, 200, 70, 150);// 漏斗
ld.setBackground(Color.black);
this.add(ld);
}
class loudou extends JPanel implements Runnable {
private static final long serialVersionUID = 1L;
private int dijiguan;
int remainTimes = 0; // 時(shí)間
int x1 = 0;
int y1 = 30;
int x2 = 60;
int y2 = 150;
Thread nThread1;//線程
JLabel overJLabel = new JLabel();
JDialog dialog = new JDialog();
public loudou() {
nThread1 = new Thread(this);
nThread1.start();
this.setLayout(null);
this.add(overJLabel);
overJLabel.setBounds(0, 0, 200, 50);
overJLabel.setForeground(Color.white);
}
public void setdijiguan(int x) {
this.dijiguan = x;
}
public void paintComponent(Graphics g) // 畫(huà)畫(huà)函數(shù)
{
super.paintComponent(g);
g.setColor(Color.green);
for (int i = 0; i < 56; i++) {
g.drawLine(x1 + i / 2 + 2, y1 + i, x2 - i / 2 - 2, y1 + i);
}
if (remainTimes < 55) {
for (int i = 0; i < remainTimes; i++) {
g.drawLine(x1 + i / 2 + 2, y2 - i - 1, x2 - i / 2 - 2, y2 - i
- 1);
}
g.drawLine((x1 + x2) / 2, (y1 + y2) / 2, (x1 + x2) / 2, y2 - 2);
g.drawLine((x1 + x2) / 2 + 1, (y1 + y2) / 2 + 1, (x1 + x2) / 2 + 1,y2 - 2);//兩條豎線
g.setColor(getBackground());
for (int i = 0; i < remainTimes; i++) {
g.drawLine(x1 + i / 2 + 2, y1 + i, x2 - i / 2 - 2, y1 + i);//覆蓋上邊的倒三角
}
}
if (remainTimes >= 50 && remainTimes <= 55)
overJLabel.setText(55-remainTimes +"s");
if (remainTimes == 56)
overJLabel.setText("OVER");
}
public void setTimes(int x) {
this.remainTimes = x;
}
public int getTimes() {
return remainTimes;
}
public void run() {
while (dijiguan < 20) {
if (remainTimes == 0) {
JOptionPane.showMessageDialog(null, "游戲開(kāi)始?");
}
if (remainTimes == 56) {
JOptionPane.showMessageDialog(null, "時(shí)間到!游戲結(jié)束!");
}
remainTimes++;
repaint();
try {
if (dijiguan < 6)
Thread.sleep(1500 - dijiguan * 100);
if (dijiguan >= 6 && dijiguan <= 8)
Thread.sleep(1000 - (dijiguan - 5) * 50);
if (dijiguan > 8)
Thread.sleep(850 - (dijiguan - 8) * 20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
//是父類(lèi)JPanel里的方法,會(huì)把整個(gè)面板用背景色重畫(huà)一遍,起到清屏的作用
g.drawImage(ii.getImage(), 0, 0, this);
//繪制兩個(gè)文本字符串
g.setColor(Color.white);
g.drawString("得分: " + score, 430, 165);
g.drawString("第 " + (guanshu + 1) + " 關(guān)", 430, 190);
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
switch (map[i][j]) {
case 0:
BlockButton[i][j].setVisible(false);
break;
case 1:
BlockButton[i][j].setIcon(aIcon);
break;
case 2:
BlockButton[i][j].setIcon(bIcon);
break;
case 3:
BlockButton[i][j].setIcon(cIcon);
break;
case 4:
BlockButton[i][j].setIcon(dIcon);
break;
case 5:
BlockButton[i][j].setIcon(eIcon);
break;
case 6:
BlockButton[i][j].setIcon(fIcon);
break;
case 7:
BlockButton[i][j].setIcon(gIcon);
break;
case 8:
BlockButton[i][j].setIcon(hIcon);
break;
case 9:
BlockButton[i][j].setIcon(iIcon);
break;
case 10:
BlockButton[i][j].setIcon(jIcon);
break;
case 11:
BlockButton[i][j].setIcon(kIcon);
break;
case 12:
BlockButton[i][j].setIcon(lIcon);
break;
case 13:
BlockButton[i][j].setIcon(mIcon);
break;
case 14:
BlockButton[i][j].setIcon(nIcon);
break;
case 15:
BlockButton[i][j].setIcon(oIcon);
break;
default:
break;
}
}
}
}
//重載
public void chongzai() {
jishushengyu = 0;
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
if (map[i][j] > 0) {
jishushengyu++;
}
}
}
int[][] map1 = new int[8][8];
this.map = map1;
Random random = new Random();
for (int i = 0; i < jishushengyu / 2; i++) {
kind = random.nextInt(Kinds) + 1;//0~3+1 === 1~4
do {
randomx1 = random.nextInt(8);//0-8隨機(jī)數(shù)
randomy1 = random.nextInt(8);
} while (map[randomy1][randomx1] > 0);
map[randomy1][randomx1] = kind;
do {
randomx = random.nextInt(8);
randomy = random.nextInt(8);
} while (map[randomy][randomx] > 0);
map[randomy][randomx] = kind;
}
repaint();
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
BlockButton[i][j].setVisible(true);
}
}
}
public void newGame() {
// JOptionPane.showMessageDialog(null,"你按了開(kāi)始按鈕");
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
BlockButton[i][j].setEnabled(true);
BlockButton[i][j].setVisible(true);
}
}
int[][] map = new int[8][8];
this.map = map;
newMap();
ld.setTimes(0);
score = 0;
guanshu = 0;
ld.setdijiguan(guanshu);
}
public void guoguan() {
int jishushengyu2 = 0;
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
if (map[i][j] > 0) {
jishushengyu2++;
}
}
}
if (jishushengyu2 == 0) {
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
BlockButton[i][j].setEnabled(true);
BlockButton[i][j].setVisible(true);
}
}
int[][] map = new int[8][8];
this.map = map;
newMap();
ld.setTimes(0);
guanshu++;
ld.setdijiguan(guanshu);
reLoad.setEnabled(true);
}
}
public void newMap() {
ArrayList<Integer> numbers = new ArrayList<Integer>();//鏈表
for (int i = 0; i < Kinds; i++) {
numbers.add(i + 1);//加到列表尾部
numbers.add(i + 1);
}//每一次重新布局的時(shí)候,能保證一定有前幾種難度中的圖片類(lèi)型
Random random = new Random();
int temp = 0;
for (int i = 0; i < 32- Kinds; i++) {
temp = random.nextInt(Kinds) + 1;//0~kinds-1之間的隨機(jī)數(shù)在加1
numbers.add(temp);
numbers.add(temp);
}
Collections.shuffle(numbers);//隨機(jī)打亂原來(lái)的順序
map = new int[8][8];
temp = 0;
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
//JOptionPane.showMessageDialog(null, numbers.get(temp));
map[i][j] = numbers.get(temp++).intValue();//get方法返回第i個(gè)元素,intvalue 返回int類(lèi)型
}
}
}
public void itemStateChanged(ItemEvent e) {
// TODO 自動(dòng)生成的方法存根
if (e.getSource() == difficultChoice) {
String selected = difficultChoice.getSelectedItem();
if (selected == "簡(jiǎn)單") {
Kinds = 4;
newGame();
repaint();
} else if (selected == "中等") {
Kinds = 8;
newGame();
repaint();
} else if (selected == "困難") {
Kinds = 12;
newGame();
repaint();
} else if (selected == "變態(tài)") {
Kinds = 15;
newGame();
repaint();
}
}
}
public void actionPerformed(ActionEvent e) {
// TODO 自動(dòng)生成的方法存根
if (ld.getTimes() >56) {
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
BlockButton[j][i].setEnabled(false);
}
}
}
if (e.getSource() == reLoad) {
chongzai();
reLoad.setEnabled(false);
}
if (e.getSource() == newgameButton) {
newGame();
reLoad.setEnabled(true);
}
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
if (e.getSource() == BlockButton[j][i]) {
clicktimes++; // 點(diǎn)擊的次數(shù)
lineStart.move(i, j);
if (clicktimes % 2 == 1) {
coordinatex1 = i;
coordinatey1 = j;
BlockButton[coordinatey1][coordinatex1].setEnabled(false);
BlockButton[coordinatey][coordinatex].setEnabled(true);
// BlockButton[j][i].setEnabled(false);
}
if (clicktimes % 2 == 0) {
coordinatex = i;
coordinatey = j;
BlockButton[coordinatey][coordinatex].setEnabled(false);
BlockButton[coordinatey1][coordinatex1].setEnabled(true);
}
}
}
}
this.requestFocus();
clearBlock();
/*
* for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) {
* BlockButton[j][i].setEnabled(true); }
*
* }
*/
repaint();
}
// --------------------------------------------------------------------------
// 判斷在一列之內(nèi)兩圖片之間是否全部是空白或直接相鄰
private boolean containsAllOrNoneZeroInColumn(int posX1, int posY1,
int posX2, int posY2) {
// 直接相連,因而不包含空白
if (Math.abs(posY1 - posY2) == 0) {
return true;
}
int a = posY1 < posY2 ? posY1 : posY2;
int b = posY1 < posY2 ? posY2 : posY1;//y值:a小 b大
for (int j = a + 1; j < b; j++) {
if (map[posX1][j] != 0) {
return false;
}
}
return true;
}
// 判斷在一行之內(nèi)兩圖片之間是否全部是空白或直接相鄰
private boolean containsAllOrNoneZeroInRow(int posX1, int posY1,
int posX2, int posY2) {
// 直接相連,因而不包含空白
if (Math.abs(posX1 - posX2) == 0) {
return true;
}
int a = posX1 < posX2 ? posX1 : posX2;
int b = posX1 < posX2 ? posX2 : posX1;
for (int i = a + 1; i < b; i++) {
if (map[i][posY1] != 0) {
return false;
}
}
return true;
}
// 是否可以一直線相連
private boolean isLinkByOneLine(int posX1, int posY1, int posX2,
int posY2) {
if (posX1 != posX2 && posY1 != posY2) {
return false;
}
if (posX1 == posX2) {
if (containsAllOrNoneZeroInColumn(posX1, posY1, posX2, posY2)) {
return true;
}
}
if (posY1 == posY2) {
if (containsAllOrNoneZeroInRow(posX1, posY1, posX2, posY2)) {
return true;
}
}
return false;
}
// 是否可以?xún)芍本€相連
private boolean isLinkByTwoLines(int posX1, int posY1, int posX2,
int posY2) {
if (posX1 != posX2 && posY1 != posY2) {
// x1,y1 to x2,y1 to x2,y2
if (containsAllOrNoneZeroInRow(posX1, posY1, posX2, posY1)
&& map[posX2][posY1] == 0
&& containsAllOrNoneZeroInColumn(posX2, posY1, posX2,
posY2)) {
return true;
}
// x1,y1 to x1,y2 to x2,y2
if (containsAllOrNoneZeroInColumn(posX1, posY1, posX1, posY2)
&& map[posX1][posY2] == 0
&& containsAllOrNoneZeroInRow(posX1, posY2, posX2,
posY2)) {
return true;
}
}
return false;
}
// 是否可以三直線相連
private boolean isLinkByThreeLines(int posX1, int posY1, int posX2,
int posY2) {
if (isOnSameEdge(posX1, posY1, posX2, posY2)) {
return true;
}
if (isOnThreeLinesLikeArc(posX1, posY1, posX2, posY2)) {
return true;
}
if (isOnThreeLinesLikeZigzag(posX1, posY1, posX2, posY2)) {
return true;
}
return false;
}
// 是否可以三直線相連,似U形
private boolean isOnThreeLinesLikeArc(int posX1, int posY1, int posX2,
int posY2) {
if (isOnUpArc(posX1, posY1, posX2, posY2)) {
return true;
}
if (isOnDownArc(posX1, posY1, posX2, posY2)) {
return true;
}
if (isOnLeftArc(posX1, posY1, posX2, posY2)) {
return true;
}
if (isOnRightArc(posX1, posY1, posX2, posY2)) {
return true;
}
return false;
}
// ∪
private boolean isOnUpArc(int posX1, int posY1, int posX2, int posY2) {
// Y --> 0
int lessY = posY1 < posY2 ? posY1 : posY2; //找小y
for (int j = lessY - 1; j >= 0; j--) {
if (containsAllOrNoneZeroInRow(posX1, j, posX2, j)
&& containsAllOrNoneZeroInColumn(posX1, posY1, posX1, j)
&& containsAllOrNoneZeroInColumn(posX2, posY2, posX2, j)
&& map[posX1][j] == 0 && map[posX2][j] == 0) {
return true;
}
}
if (isOnSameEdge(posX1, 0, posX2, 0)
&& containsAllOrNoneZeroInColumn(posX1, posY1, posX1, 0)
&& containsAllOrNoneZeroInColumn(posX2, posY2, posX2, 0)
&& (map[posX1][0] == 0 && map[posX2][0] == 0
|| map[posX1][0] == 0
&& map[posX2][0] == map[posX2][posY2] || map[posX1][0] == map[posX1][posY1]
&& map[posX2][0] == 0)) {
return true;
}
return false;
}
// ∩
private boolean isOnDownArc(int posX1, int posY1, int posX2, int posY2) {
int moreY = posY1 < posY2 ? posY2 : posY1;
for (int j = moreY + 1; j <= 8 - 1; j++) {
if (containsAllOrNoneZeroInRow(posX1, j, posX2, j)
&& containsAllOrNoneZeroInColumn(posX1, posY1, posX1, j)
&& containsAllOrNoneZeroInColumn(posX2, posY2, posX2, j)
&& map[posX1][j] == 0 && map[posX2][j] == 0) {
return true;
}
}
if (isOnSameEdge(posX1, 8 - 1, posX2, 8 - 1)
&& containsAllOrNoneZeroInColumn(posX1, posY1, posX1, 8 - 1)
&& containsAllOrNoneZeroInColumn(posX2, posY2, posX2, 8 - 1)
&& (map[posX1][8 - 1] == 0 && map[posX2][8 - 1] == 0
|| map[posX1][8 - 1] == map[posX1][posY1]
&& map[posX2][8 - 1] == 0 || map[posX1][8 - 1] == 0
&& map[posX2][8 - 1] == map[posX2][posY2])) {
return true;
}
return false;
}
// ﹚
private boolean isOnLeftArc(int posX1, int posY1, int posX2, int posY2) {
int lessX = posX1 < posX2 ? posX1 : posX2;
for (int i = lessX - 1; i >= 0; i--) {
if (containsAllOrNoneZeroInColumn(i, posY1, i, posY2)
&& containsAllOrNoneZeroInRow(i, posY1, posX1, posY1)
&& containsAllOrNoneZeroInRow(i, posY2, posX2, posY2)
&& map[i][posY1] == 0 && map[i][posY2] == 0) {
return true;
}
}
if (isOnSameEdge(0, posY1, 0, posY2)
&& containsAllOrNoneZeroInRow(0, posY1, posX1, posY1)
&& containsAllOrNoneZeroInRow(0, posY2, posX2, posY2)
&& (map[0][posY1] == 0 && map[0][posY2] == 0
|| map[0][posY1] == map[posX1][posY1]
&& map[0][posY2] == 0 || map[0][posY1] == 0
&& map[0][posY2] == map[posX2][posY2])) {
return true;
}
return false;
}
// (
private boolean isOnRightArc(int posX1, int posY1, int posX2, int posY2) {
int moreX = posX1 < posX2 ? posX2 : posX1;
for (int i = moreX + 1; i <= 8 - 1; i++) {
if (containsAllOrNoneZeroInColumn(i, posY1, i, posY2)
&& containsAllOrNoneZeroInRow(i, posY1, posX1, posY1)
&& containsAllOrNoneZeroInRow(i, posY2, posX2, posY2)
&& map[i][posY1] == 0 && map[i][posY2] == 0) {
return true;
}
}
if (isOnSameEdge(8 - 1, posY1, 8 - 1, posY2)
&& containsAllOrNoneZeroInRow(posX1, posY1, 8 - 1, posY1)
&& containsAllOrNoneZeroInRow(posX2, posY2, 8 - 1, posY2)
&& (map[8 - 1][posY1] == 0 && map[8 - 1][posY2] == 0
|| map[8 - 1][posY1] == map[posX1][posY1]
&& map[8 - 1][posY2] == 0 || map[8 - 1][posY1] == 0
&& map[8 - 1][posY2] == map[posX2][posY2])) {
return true;
}
return false;
}
// 是否可以三直線相連,似之字形N
private boolean isOnThreeLinesLikeZigzag(int posX1, int posY1,
int posX2, int posY2) {
if (isOnZigzagWith1Row2Cols(posX1, posY1, posX2, posY2)) {
return true;
}
if (isOnZigzagWith2Rows1Col(posX1, posY1, posX2, posY2)) {
return true;
}
return false;
}
// 是否可以三直線相連,似之字形, 兩行一列 Z
private boolean isOnZigzagWith2Rows1Col(int posX1, int posY1,
int posX2, int posY2) {
int moreX = posX1 < posX2 ? posX2 : posX1;
int lessX = posX1 < posX2 ? posX1 : posX2;
for (int i = lessX + 1; i < moreX; i++) {
if (containsAllOrNoneZeroInColumn(i, posY1, i, posY2)
&& containsAllOrNoneZeroInRow(i, posY1, posX1, posY1)
&& containsAllOrNoneZeroInRow(i, posY2, posX2, posY2)
&& map[i][posY1] == 0 && map[i][posY2] == 0) {
return true;
}
}
return false;
}
// 是否可以三直線相連,似之字形, 一行兩列
private boolean isOnZigzagWith1Row2Cols(int posX1, int posY1,
int posX2, int posY2) {
int moreY = posY1 < posY2 ? posY2 : posY1;
int lessY = posY1 < posY2 ? posY1 : posY2;
for (int j = lessY + 1; j < moreY; j++) {
if (containsAllOrNoneZeroInRow(posX1, j, posX2, j)
&& containsAllOrNoneZeroInColumn(posX1, posY1, posX1, j)
&& containsAllOrNoneZeroInColumn(posX2, posY2, posX2, j)
&& map[posX1][j] == 0 && map[posX2][j] == 0) {
return true;
}
}
return false;
}
// 是否處于游戲區(qū)域的4條邊的同一邊上
private boolean isOnSameEdge(int posX1, int posY1, int posX2, int posY2) {
if ((posY1 == posY2 && posY2 == 0)
|| (posY1 == posY2 && posY2 == 8 - 1)
|| (posX1 == posX2 && posX2 == 0)
|| (posX1 == posX2 && posX2 == 8 - 1)) {
return true;
}
return false;
}
// --------------------------------------------------------------------------
public boolean ifcanTouch(int posX1, int posY1, int posX2, int posY2) {
if (isLinkByOneLine(posX1, posY1, posX2, posY2)) {
return true;
}
// 是否可以?xún)芍本€相連
if (isLinkByTwoLines(posX1, posY1, posX2, posY2)) {
return true;
}
// 是否可以三直線相連
if (isLinkByThreeLines(posX1, posY1, posX2, posY2)) {
return true;
}
return false;
}
public void clearBlock() {
if (clicktimes >=2) {
if (map[coordinatey1][coordinatex1] == map[coordinatey][coordinatex]
&& !((coordinatex1 == coordinatex) && (coordinatey1 == coordinatey))) {
if (ifcanTouch(coordinatey1, coordinatex1, coordinatey,
coordinatex)) {
if (map[coordinatey1][coordinatex1] > 0)
score = score + 10;
map[coordinatey1][coordinatex1] = 0;
map[coordinatey][coordinatex] = 0;
guoguan();
}
}
}
}
}
public static void main(String[] args) {
String lookAndFeel ="javax.swing.plaf.metal.MetalLookAndFeel";//swing 外觀和感覺(jué)
try {
UIManager.setLookAndFeel(lookAndFeel);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
LianLianKan frame = new LianLianKan();
frame.setTitle("連連看");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(100, 100, 560, 430);
frame.setLocation(440, 100);
// frame.setSize(600, 500);
frame.setSize(540, 440);
frame.setVisible(true);
}
}
總結(jié)
通過(guò)此次的《連連看》游戲?qū)崿F(xiàn),讓我對(duì)swing的相關(guān)知識(shí)有了進(jìn)一步的了解,對(duì)java這門(mén)語(yǔ)言也有了比以前更深刻的認(rèn)識(shí)。
java的一些基本語(yǔ)法,比如數(shù)據(jù)類(lèi)型、運(yùn)算符、程序流程控制和數(shù)組等,理解更加透徹。java最核心的核心就是面向?qū)ο笏枷?,?duì)于這一個(gè)概念,終于悟到了一些。
以上就是基于Java實(shí)現(xiàn)連連看游戲的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于Java連連看游戲的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot如何接收Post請(qǐng)求Body里面的參數(shù)
這篇文章主要介紹了SpringBoot如何接收Post請(qǐng)求Body里面的參數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
SpringSecurity動(dòng)態(tài)加載用戶角色權(quán)限實(shí)現(xiàn)登錄及鑒權(quán)功能
這篇文章主要介紹了SpringSecurity動(dòng)態(tài)加載用戶角色權(quán)限實(shí)現(xiàn)登錄及鑒權(quán)功能,很多朋友感覺(jué)這個(gè)功能很難,今天小編通過(guò)實(shí)例代碼給大家講解,需要的朋友可以參考下2019-11-11
淺談為什么阿里巴巴要禁用Executors創(chuàng)建線程池
這篇文章主要介紹了淺談為什么阿里巴巴要禁用Executors創(chuàng)建線程池,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02
SpringBoot?快速實(shí)現(xiàn)?api?接口加解密功能
在項(xiàng)目中,為了保證數(shù)據(jù)的安全,我們常常會(huì)對(duì)傳遞的數(shù)據(jù)進(jìn)行加密,Spring?Boot接口加密,可以對(duì)返回值、參數(shù)值通過(guò)注解的方式自動(dòng)加解密,這篇文章主要介紹了SpringBoot?快速實(shí)現(xiàn)?api?接口加解密功能,感興趣的朋友一起看看吧2023-10-10
一個(gè)例子帶你看懂Java中synchronized關(guān)鍵字到底怎么用
synchronized是Java里的一個(gè)關(guān)鍵字,起到的一個(gè)效果是"監(jiān)視器鎖",它的功能就是保證操作的原子性,同時(shí)禁止指令重排序和保證內(nèi)存的可見(jiàn)性,下面這篇文章主要給大家介紹了關(guān)于如何通過(guò)一個(gè)例子帶你看懂Java中synchronized關(guān)鍵字到底怎么用的相關(guān)資料,需要的朋友可以參考下2022-10-10

