Xem mẫu

The drop Method Figure 8.5. Drag constraint lines on the game board Snap-to You can see snap-to at work when the dragged chess piece “snaps” into place in the center of the square on which it was dropped. The snap-to happens in the drop method: File: chess.js (excerpt) this.drop = function() { var calcX = 0; var calcY = 0; var deltaX = 0; var deltaY = 0; var colX = 0; var colY = 0; 267 Licensed to siowchen@darke.biz Chapter 8: Drag and Drop with AJAX Chess calcX = this.div.offsetLeft; calcY = this.div.offsetTop; deltaX = calcX % Chess.squareSize; deltaY = calcY % Chess.squareSize; calcX = this.getSnap(deltaX, calcX); calcY = this.getSnap(deltaY, calcY); calcX = calcX + Chess.pieceOffset - 1; calcY = calcY + Chess.pieceOffset - 1; this.div.style.left = calcX + `px`; this.div.style.top = calcY + `px`; colX = Chess.calcColFromPos(calcX); colY = Chess.calcColFromPos(calcY); if (Chess.selectPiece.wasMoved(colX, colY)) { Chess.doMove(colX, colY); } else { this.div.style.zIndex = 5; } this.div = null; }; The important variables to watch here are deltaX and deltaY. These are the re-mainders from calculations in which the X and Y mouse positions are divided by the size of a square (we get these remainders by using the modulo operator, %). deltaX and deltaY are the distances between the position at which the piece was dropped and the nearest edge of a square, along the X and Y axes respectively. Once we have this number, we can figure which direction to “snap” the piece in by checking whether the number is bigger or smaller than half the height (or width) of the square. We do this using the getSnap method: File: chess.js (excerpt) this.getSnap = function(delta, pos) { if (delta > (Chess.squareSize / 2)) { pos += (Chess.squareSize - delta); } else { pos -= delta; } return pos; }; This makes good sense if you think about it—we can work out which way the piece should jump by seeing whether it covers another square by more than half. 268 Licensed to siowchen@darke.biz The doMove Method Once we’ve got the piece snapping into place, it’s time to save this move to the back end in drop. We save our piece positions as row and column coordinates — not pixel positions — inside Piece objects, so we have to translate the piece’s position into row and column numbers with the calcColFromPos method. Despite its name, this method calculates both row and column coordinates—the math involved is exactly the same regardless of whether we’re talking about rows or columns. This is a short method that just divides the piece’s pixel position by the size of a board square: File: chess.js (excerpt) this.calcColFromPos = function(pos) { var self = Chess; return parseInt(pos / self.squareSize); }; Once we know the column numbers for the new piece’s position, we perform a final check to make sure the player didn’t drag the piece around the board and drop it right back in its original position. We perform this check with the wasMoved method of the Piece class. The column number for each Piece is stored in the pos property. That property is a two-item array that stores the piece’s coordinates on the board. The wasMoved method checks to make sure the values in the pos array have changed, like this: File: chess.js (excerpt) this.wasMoved = function(colX, colY) { if (colX == this.pos[0] && colY == this.pos[1]) { return false; } else { return true; } }; If we can verify that yes, the piece is actually in a new spot, then it’s time to go ahead and save that change to the back end. We do this with the doMove method in the main Chess class. The doMove Method The doMove method actually takes care of updating the pos property of the Piece object that the user is moving, looks for captured pieces, then saves the changes to the back end. 269 Licensed to siowchen@darke.biz Chapter 8: Drag and Drop with AJAX Chess Here’s the first chunk of the method: File: chess.js (excerpt) this.doMove = function(colX, colY) { var self = Chess; var occPieceId = ``; var cmd = null; var move = null; var err = ``; self.selectPiece.backUpPos(); self.selectPiece.updatePos(colX, colY); Making a Backup Always back up your data. That’s a lesson many of us have had to learn the hard way! Before we save the move, we need to make a backup snapshot of the moved piece’s original position data. We’ll use this backup to put the piece back where it originally started if there’s some kind of error. We use the backupPos method of the Piece to make the backup: File: chess.js (excerpt) this.backUpPos = function() { this.origPos = [this.pos[0], this.pos[1]]; }; That method just sets the origPos property to the same array values that were originally in the pos property. Once we have a backup of the original position info, it’s time to update the pos property of the Piece so that we can send it along to the back end to be saved. The updatePos method of the Piece class does this: File: chess.js (excerpt) this.updatePos = function(colX, colY) { this.pos = [colX, colY]; }; Error Checking The next section in the doMove method checks for errors, to make sure that users can’t do something goofy, like capture their own pieces: 270 Licensed to siowchen@darke.biz Aborting the Move on Error File: chess.js (excerpt) if ((!self.lastMove.moveTime) && (self.selectPiece.color == `black`)) { err = `White has to go first.`; } else if ((self.lastMove.moveTime) && (self.selectPiece.color == self.lastMove.movePiece.color)) { err = `Same color as previous move.`; } else { occPieceId = self.getOccupyingPieceId(); if (occPieceId.indexOf(self.selectPiece.color) > -1) { err = `Cannot capture a piece of your own color.`; } } The last section in the error-checking code also looks to see if any piece was captured. It uses the getOccupyingPieceId method to put the id of any captured piece in Chess’s occPieceId property. Here’s the code for that method: File: chess.js (excerpt) this.getOccupyingPieceId = function() { var self = Chess; var p = null; for (var i in self.pieceList) { p = self.pieceList[i]; if ((self.selectPiece.pos[0] == p.pos[0] && self.selectPiece.pos[1] == p.pos[1]) && (self.selectPiece.id != p.id)) { return p.id; } } return ``; }; If the square is unoccupied, the method just returns an empty string, which tells us that no piece has been captured. Aborting the Move on Error If there is an error, we alert the user and put the piece back where it was. This is what happens in the next bit of doMove: 271 Licensed to siowchen@darke.biz ... - tailieumienphi.vn
nguon tai.lieu . vn