主要遊戲流程
連連看點選兩個圖案後,可消除的邏輯是:
- 兩個所點擊到的圖案相同
- 連線不超過兩個轉彎
因此我們先來寫遊戲主流程的部份,玩家會先點第一個圖案,代表他想要消除這個圖案,接著再消第二個圖案,這時再來判斷是否符合可消除,這部份的流程圖如下:
撰寫的程式碼如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
var app = angular.module('LianLianKan', []); app.controller('myCtrl', function ($scope) { $scope.select1 = new Point(-1, -1); $scope.select2 = new Point(-1, -1); $scope.selected = false; let msgArra = []; $scope.message = msgArra; let board = new Board(); $scope.boardContent = board.board; $scope.click = function (x: number, y: number) { if ($scope.selected) { $scope.select2 = new Point(x, y); if (board.hasSameValue($scope.select1, $scope.select2)) { if (! ($scope.select1.x == x && $scope.select1.y == y) ) {//確認所選的兩個點不一樣 let path = new Path($scope.select1, $scope.select2, board); if(path.canLinkInLine()){ board.clearPoint($scope.select1); board.clearPoint($scope.select2); msgArra.push(path); } } } $scope.selected = false; } else { $scope.select1 = new Point(x, y); $scope.selected = true; } }; }); |
判斷所選圖案是否相同
在上面的程式碼中,可以看到我們用board.hasSameValue($scope.select1, $scope.select2)
來判斷所選的圖是是否相同。我們可以Board的類別增加public hasSameValue(point1: Point, point2: Point): boolean
如下:
1 2 3 |
public hasSameValue(point1: Point, point2: Point): boolean { return this.board[point1.x][point1.y] == this.board[point2.x][point2.y]; } |
連線邏輯撰寫
新建一個類別Path
內容如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
class Path { public point1: Point; public point2: Point; readonly board: Board; public path_Detail:Array<Point>; constructor(point1: Point, point2: Point, board: Board) { this.point1 = point1; this.point2 = point2; this.board = board; } public canLinkInLine(): boolean { console.log("board",this.board); //從上面消 //兩個點都往上找最遠能到達的距離 let point1UP = this.board.getNearByPointByDirection(this.point1, Direction.UP); let point2UP = this.board.getNearByPointByDirection(this.point2, Direction.UP); console.log("point1UP",point1UP,"point2UP",point2UP); //尋找這之中可能存在的路徑 { let min = Math.max(point1UP.x,point2UP.x); let max = Math.min(this.point1.x, this.point2.x); for (var i = max;i>=min;i--){ if (!this.board.hasMiddleValue(new Point(i, this.point1.y), new Point(i, this.point2.y))){ this.path_Detail = [this.point1,new Point(i, this.point1.y),new Point(i, this.point2.y),this.point2]; console.log("same up"); return true; } } } //從下面消 let point1DOWN = this.board.getNearByPointByDirection(this.point1, Direction.DOWN); let point2DOWN = this.board.getNearByPointByDirection(this.point2, Direction.DOWN); console.log("point1DOWN",point1DOWN,"point2DOWN",point2DOWN); { let max = Math.min(point1DOWN.x,point2DOWN.x); let min = Math.max(this.point1.x, this.point2.x); for (var i = min;i<=max;i++){ if (!this.board.hasMiddleValue(new Point(i, this.point1.y), new Point(i, this.point2.y))){ this.path_Detail = [this.point1,new Point(i, this.point1.y),new Point(i, this.point2.y),this.point2]; console.log("same down"); return true; } } } //從左邊消 let point1LEFT = this.board.getNearByPointByDirection(this.point1, Direction.LEFT); let point2LEFT = this.board.getNearByPointByDirection(this.point2, Direction.LEFT); console.log("point1LEFT",point1LEFT,"point2LEFT",point2LEFT); { let min = Math.max(point1LEFT.y,point2LEFT.y); let max = Math.min(this.point1.y, this.point2.y); for (var i = max;i>=min;i--) { if (!this.board.hasMiddleValue(new Point(this.point1.x, i), new Point(this.point2.x, i))) { this.path_Detail = [this.point1, new Point(this.point1.x, i), new Point(this.point2.x, i), this.point2]; console.log("same left"); return true; } } } //從右邊消 let point1RIGHT = this.board.getNearByPointByDirection(this.point1, Direction.RIGHT); let point2RIGHT = this.board.getNearByPointByDirection(this.point2, Direction.RIGHT); console.log("point1RIGHT",point1RIGHT,"point2RIGHT",point2RIGHT); { let max = Math.min(point1RIGHT.y,point2RIGHT.y); let min = Math.max(this.point1.y, this.point2.y); for (var i = min;i<=max;i++) { if (!this.board.hasMiddleValue(new Point(this.point1.x, i), new Point(this.point2.x, i))) { this.path_Detail = [this.point1, new Point(this.point1.x, i), new Point(this.point2.x, i), this.point2]; console.log("same right"); return true; } } } //左右連消 if (this.point1.y != this.point2.y){ //先判斷那個點在左,那個點在右 let leftPoint = (this.point1.y < this.point2.y) ? this.point1:this.point2; let rightPoint = (this.point1.y >= this.point2.y) ? this.point1:this.point2; //取得右邊的點,直線往左最左的那個點 let leftPointRIGHT = this.board.getNearByPointByDirection(leftPoint, Direction.RIGHT); let rightPointLEFT = this.board.getNearByPointByDirection(rightPoint, Direction.LEFT); //參考前一篇文章的圖,右邊最左的點不可超過左邊的點,否則會造成誤判 leftPointRIGHT.y = (leftPointRIGHT.y < rightPoint.y) ? leftPointRIGHT.y : rightPoint.y; rightPointLEFT.y = (rightPointLEFT.y > leftPoint.y) ? rightPointLEFT.y : leftPoint.y; //用迴圈判斷在所有有可能的範圍中是否有可能存在的路徑 if (leftPointRIGHT.y != leftPoint.y && rightPointLEFT.y != rightPoint.y){ for (var i = rightPointLEFT.y; i <= leftPointRIGHT.y; i++) { if (!this.board.hasMiddleValue(new Point(leftPoint.x, i), new Point(rightPoint.x, i))) { this.path_Detail = [leftPoint, new Point(leftPoint.x, i), new Point(rightPoint.x, i), rightPoint]; console.log("same left to right"); return true; } } } } //上下連消 if (this.point1.x != this.point2.x){ let upPoint = (this.point1.x < this.point2.x) ? this.point1:this.point2; let downPoint = (this.point1.x >= this.point2.x) ? this.point1:this.point2; let upPointDOWN = this.board.getNearByPointByDirection(upPoint, Direction.DOWN); let downPointUP = this.board.getNearByPointByDirection(downPoint, Direction.UP); upPointDOWN.x = (upPointDOWN.x < downPoint.x) ? upPointDOWN.x : downPoint.x; downPointUP.x = (downPointUP.x > upPoint.x) ? downPointUP.x : upPoint.x; if (upPointDOWN.x != upPoint.x && downPointUP.x != downPoint.x){ for (var i = downPointUP.x; i <= upPointDOWN.x; i++) { if (!this.board.hasMiddleValue(new Point(i, upPoint.y), new Point(i, downPoint.y))) { this.path_Detail = [upPoint, new Point(i, upPoint.y), new Point(i, downPoint.y), downPoint]; console.log("same top to down"); return true; } } } } return false; } } |
新增類別Board
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
class Board { public board: Array<Array<number>>; constructor() { let content = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]; //產生初始局面 let length = 10; let data = content.concat(content).concat(content).concat(content).sort((a, b) => (Math.random() > .5) ? 1 : 0); this.board = [] for (var i = 0;i<length;i++){ this.board.push(data.slice(i*length, (i+1)*length)) } } //找到這個點四周最遠能到達的直線距離 public getNearByPointByDirection(point: Point, direction: string): Point { let nearByPoint: Point = new Point(point.x, point.y); switch (direction) { case Direction.UP: //搜尋往上走最遠可到達的點 for (var i = point.x-1; i >= 0; i--) { if (this.board[i][point.y] == null) { nearByPoint.x = i; } else { break; } } if (nearByPoint.x == 0) { nearByPoint.x = -1; } break; case Direction.DOWN: //搜尋往下走最遠可到達的點 let maxLengthDOWN = this.board.length; for (var i = point.x+1; i < maxLengthDOWN; i++) { if (this.board[i][point.y] == null) { nearByPoint.x = i; } else { break; } } if (nearByPoint.x == maxLengthDOWN - 1) { nearByPoint.x = maxLengthDOWN; } break; case Direction.RIGHT: //搜尋往右走最遠可到達的點 let maxLengthRIGHT = this.board[0].length; for (var i = point.y+1; i < maxLengthRIGHT; i++) { if (this.board[point.x][i] == null) { nearByPoint.y = i; } else { break; } } if (nearByPoint.y == maxLengthRIGHT - 1) { nearByPoint.y = maxLengthRIGHT; } break; case Direction.LEFT: //搜尋往左走最遠可到達的點 for (var i = point.y-1; i >= 0; i--) { if (this.board[point.x][i] == null) { nearByPoint.y = i; } else { break; } } if (nearByPoint.y == 0) { nearByPoint.y = -1; } break; } return nearByPoint; } //搜尋在兩個點之中是否可以找到一直線可連接 public canFindPath(a: Point, b: Point, direction:string): boolean { return this.hasMiddleValue(a ,b); } //偵測在兩個點中是否可用一條直線做連接 public hasMiddleValue(a: Point, b: Point): boolean { let arr = []; if (a.x == b.x) { if (a.x == -1 || a.x == this.board.length) return false; let max = Math.max(a.y, b.y); let min = Math.min(a.y, b.y); for (var i = min + 1; i < max; i++) { if (this.board[a.x][i] != null) { return true; } } return false; } else if (a.y == b.y) { if (a.y == -1 || a.y == this.board[0].length) return false; let max = Math.max(a.x, b.x); let min = Math.min(a.x, b.x); for (var i = min + 1; i < max; i++) { if (this.board[i][a.y] != null) { return true; } } return false; } else { return true; } } //判斷某兩個點的值是否相同 public hasSameValue(point1: Point, point2: Point): boolean { return this.board[point1.x][point1.y] == this.board[point2.x][point2.y]; } //將盤面上的圖消掉 public clearPoint(point: Point) { this.board[point.x][point.y] = null; point = null; } } |
今日成果:
Live Demo:今日成果展示
今天的專案可至此下載:ironman20181021