/*********************************************************************************** piece.js piece class holds the following piece information: -index of piece -coordinate for current location -coordinate for correct location -4 edges -correct (boolean value indicating whether piece is in correct location) -orientation (correct, rotated 90, 180, or 270 degrees) ***********************************************************************************/ class Piece { constructor(index, x, y, correctX, correctY, lType, rType, tType, bType, orientation) { this.index = index; this.x = x; this.y = y; this.correctX = correctX; this.correctY = correctY; this.left = new Edge(lType); this.right = new Edge(rType); this.top = new Edge(tType); this.bottom = new Edge(bType); this.priority = index; // for starters, adjust later (probably an array or structure in puzzle class) this.correct = 0; this.orientation = orientation; } // getters/setters get index() { return this._index; } set index(i) { this._index = i; } get x() { return this._x; } set x(x) { this._x = x; } get y() { return this._y; } set y(y) { this._y = y; } get correctX() { return this._correctX; } set correctX(x) { this._correctX = x; } get correctY() { return this._correctY; } set correctY(y) { this._correctY = y; } get left() { return this._left; } set left(l) { this._left = l; } get right() { return this._right; } set right(r) { this._right = r; } get top() { return this._top; } set top(t) { this._top = t; } get bottom() { return this._bottom; } set bottom(b) { this._bottom = b; } get priority() { return this._priority; } set priority(p) { this._priority = p; } get correct() { return this._correct; } set correct(c) { this._correct = c; } get correct() { return this._correct; } set correct(c) { this._correct = c; } get orientation() { return this._orientation; } set orientation(x) { this._orientation = x; } // other methods hasOutsideEdge() { if (this.left.isOutsideEdge() || this.right.isOutsideEdge() || this.top.isOutsideEdge() || this.bottom.isOutsideEdge()) { return true; } return false; } // for debugging printInfo() { console.log('************************'); console.log('PIECE' + this.index); console.log('x: ' + this.x); console.log('y: ' + this.y); console.log('correctX: ' + this.correctX); console.log('correctY: ' + this.correctY); console.log('Left edge: ' + this.left.type); console.log('Right edge: ' + this.right.type); console.log('Top edge: ' + this.top.type); console.log('Bottom edge: ' + this.bottom.type); console.log('Correct: ' + this.correct); console.log('************************'); } /*********************************************************************** draw - translates context to midpoint of piece (& rotates to piece orientation) and draws a puzzle piece on given context Parameters: ctx - to draw piece, puzzle - to get needed info like piece dimensions and puzzle image. ************************************************************************/ draw(ctx, puzzle) { ctx.save(); // move context to midpoint of piece ctx.translate(this.x + .5 * puzzle.pieceW, this.y + .5 * puzzle.pieceH); if (this.orientation == 1) { ctx.rotate(Math.PI / 2); } else if (this.orientation == 2) { ctx.rotate(Math.PI); } else if (this.orientation == 3) { ctx.rotate(3* Math.PI / 2); } ctx.beginPath(); // start at top left of piece let topLeftX = puzzle.pieceW / -2; let topLeftY = puzzle.pieceH / -2; ctx.moveTo(topLeftX, topLeftY); // draw top edge if (this.top.type == 'in') { ctx.bezierCurveTo(topLeftX + this.top.keyLoc * .5 * puzzle.pieceW, topLeftY - .1 * puzzle.pieceH, topLeftX + this.top.keyLoc * puzzle.pieceW, topLeftY - .15 * puzzle.pieceH, topLeftX + (this.top.keyLoc - this.top.keySize * .5) * puzzle.pieceW, topLeftY); ctx.bezierCurveTo(topLeftX + (this.top.keyLoc - this.top.curveStartX) * puzzle.pieceW, topLeftY + this.top.curveStartY * puzzle.pieceH, topLeftX + (this.top.keyLoc + this.top.curveEndX) * puzzle.pieceW, topLeftY + this.top.curveEndY * puzzle.pieceH, topLeftX + (this.top.keyLoc + this.top.keySize * .5) * puzzle.pieceW, topLeftY); ctx.bezierCurveTo(topLeftX + this.top.keyLoc * puzzle.pieceW, topLeftY - .15 * puzzle.pieceH, topLeftX + (this.top.keyLoc + (1 - this.top.keyLoc) * .5) * puzzle.pieceW, topLeftY - .1 * puzzle.pieceH, topLeftX + puzzle.pieceW, topLeftY); } else if (this.top.type == 'out') { ctx.bezierCurveTo(topLeftX + this.top.keyLoc * .5 * puzzle.pieceW, topLeftY + .1 * puzzle.pieceH, topLeftX + this.top.keyLoc * puzzle.pieceW, topLeftY + .15 * puzzle.pieceH, topLeftX + (this.top.keyLoc - this.top.keySize * .5) * puzzle.pieceW, topLeftY); ctx.bezierCurveTo(topLeftX + (this.top.keyLoc - this.top.curveStartX) * puzzle.pieceW, topLeftY - this.top.curveStartY * puzzle.pieceH, topLeftX + (this.top.keyLoc + this.top.curveEndX) * puzzle.pieceW, topLeftY - this.top.curveEndY * puzzle.pieceH, topLeftX + (this.top.keyLoc + this.top.keySize * .5) * puzzle.pieceW, topLeftY); ctx.bezierCurveTo(topLeftX + this.top.keyLoc * puzzle.pieceW, topLeftY + .15 * puzzle.pieceH, topLeftX + (this.top.keyLoc + (1 - this.top.keyLoc) * .5) * puzzle.pieceW, topLeftY + .1 * puzzle.pieceH, topLeftX + puzzle.pieceW, topLeftY); } else { ctx.lineTo(topLeftX + puzzle.pieceW, topLeftY); } // draw right edge if (this.right.type == 'in') { ctx.bezierCurveTo(topLeftX + puzzle.pieceW + puzzle.pieceW * .1, topLeftY + this.right.keyLoc * .5 * puzzle.pieceH, topLeftX + puzzle.pieceW + puzzle.pieceW * .15, topLeftY + puzzle.pieceH * this.right.keyLoc, topLeftX + puzzle.pieceW, topLeftY + puzzle.pieceH * (this.right.keyLoc - this.right.keySize * .5)); ctx.bezierCurveTo(topLeftX + puzzle.pieceW - this.right.curveStartY * puzzle.pieceW, topLeftY + (this.right.keyLoc - this.right.curveStartX) * puzzle.pieceH, topLeftX + puzzle.pieceW - this.right.curveEndY * puzzle.pieceW, topLeftY + (this.right.keyLoc + this.right.curveEndX) * puzzle.pieceH, topLeftX + puzzle.pieceW, topLeftY + (this.right.keyLoc + this.right.keySize * .5) * puzzle.pieceH); ctx.bezierCurveTo(topLeftX + puzzle.pieceW + puzzle.pieceW * .15, topLeftY + this.right.keyLoc * puzzle.pieceH, topLeftX + puzzle.pieceW + puzzle.pieceW * .1, topLeftY + (this.right.keyLoc + (1 - this.right.keyLoc) * .5) * puzzle.pieceH, topLeftX + puzzle.pieceW, topLeftY + puzzle.pieceH); } else if (this.right.type == 'out') { ctx.bezierCurveTo(topLeftX + puzzle.pieceW - puzzle.pieceW * .1, topLeftY + this.right.keyLoc * .5 * puzzle.pieceH, topLeftX + puzzle.pieceW - puzzle.pieceW * .15, topLeftY + puzzle.pieceH * this.right.keyLoc, topLeftX + puzzle.pieceW, topLeftY + puzzle.pieceH * (this.right.keyLoc - this.right.keySize * .5)); ctx.bezierCurveTo(topLeftX + puzzle.pieceW + this.right.curveStartY * puzzle.pieceW, topLeftY + (this.right.keyLoc - this.right.curveStartX) * puzzle.pieceH, topLeftX + puzzle.pieceW + this.right.curveEndY * puzzle.pieceW, topLeftY + (this.right.keyLoc + this.right.curveEndX) * puzzle.pieceH, topLeftX + puzzle.pieceW, topLeftY + (this.right.keyLoc + this.right.keySize * .5) * puzzle.pieceH); ctx.bezierCurveTo(topLeftX + puzzle.pieceW - puzzle.pieceW * .15, topLeftY + this.right.keyLoc * puzzle.pieceH, topLeftX + puzzle.pieceW - puzzle.pieceW * .1, topLeftY + (this.right.keyLoc + (1 - this.right.keyLoc) * .5) * puzzle.pieceH, topLeftX + puzzle.pieceW, topLeftY + puzzle.pieceH); } else { ctx.lineTo(topLeftX + puzzle.pieceW, topLeftY + puzzle.pieceH); } // draw bottom edge if (this.bottom.type == 'in') { ctx.bezierCurveTo(topLeftX + (this.bottom.keyLoc + (1 - this.bottom.keyLoc) * .5) * puzzle.pieceW, topLeftY + puzzle.pieceH + .1 * puzzle.pieceH, topLeftX + this.bottom.keyLoc * puzzle.pieceW, topLeftY + puzzle.pieceH + .15 * puzzle.pieceH, topLeftX + (this.bottom.keyLoc + this.bottom.keySize * .5) * puzzle.pieceW, topLeftY + puzzle.pieceH); ctx.bezierCurveTo(topLeftX + (this.bottom.keyLoc + this.bottom.curveStartX) * puzzle.pieceW, topLeftY + puzzle.pieceH - this.bottom.curveStartY * puzzle.pieceH, topLeftX + (this.bottom.keyLoc - this.bottom.curveEndX) * puzzle.pieceW, topLeftY + puzzle.pieceH - this.bottom.curveEndY * puzzle.pieceH, topLeftX + (this.bottom.keyLoc - this.bottom.keySize * .5) * puzzle.pieceW, topLeftY + puzzle.pieceH); ctx.bezierCurveTo(topLeftX + this.bottom.keyLoc * puzzle.pieceW, topLeftY + puzzle.pieceH + .15 * puzzle.pieceH, topLeftX + this.bottom.keyLoc * .5 * puzzle.pieceW, topLeftY + puzzle.pieceH + .1 * puzzle.pieceH, topLeftX , topLeftY + puzzle.pieceH); } else if (this.bottom.type == 'out') { ctx.bezierCurveTo(topLeftX + (this.bottom.keyLoc + (1 - this.bottom.keyLoc) * .5) * puzzle.pieceW, topLeftY + puzzle.pieceH - .1 * puzzle.pieceH, topLeftX + this.bottom.keyLoc * puzzle.pieceW, topLeftY + puzzle.pieceH - .15 * puzzle.pieceH, topLeftX + (this.bottom.keyLoc + this.bottom.keySize * .5) * puzzle.pieceW, topLeftY + puzzle.pieceH); ctx.bezierCurveTo(topLeftX + (this.bottom.keyLoc + this.bottom.curveStartX) * puzzle.pieceW, topLeftY + puzzle.pieceH + this.bottom.curveStartY * puzzle.pieceH, topLeftX + (this.bottom.keyLoc - this.bottom.curveEndX) * puzzle.pieceW, topLeftY + puzzle.pieceH + this.bottom.curveEndY * puzzle.pieceH, topLeftX + (this.bottom.keyLoc - this.bottom.keySize * .5) * puzzle.pieceW, topLeftY + puzzle.pieceH); ctx.bezierCurveTo(topLeftX + this.bottom.keyLoc * puzzle.pieceW, topLeftY + puzzle.pieceH - .15 * puzzle.pieceH, topLeftX + this.bottom.keyLoc * .5 * puzzle.pieceW, topLeftY + puzzle.pieceH - .1 * puzzle.pieceH, topLeftX, topLeftY + puzzle.pieceH); } else { ctx.lineTo(topLeftX, topLeftY + puzzle.pieceH); } // draw left edge if (this.left.type == 'in') { ctx.bezierCurveTo(topLeftX - puzzle.pieceW * .1, topLeftY + (this.left.keyLoc + (1 - this.left.keyLoc) * .5) * puzzle.pieceH, topLeftX - puzzle.pieceW * .15, topLeftY + puzzle.pieceH * this.left.keyLoc, topLeftX, topLeftY + puzzle.pieceH * (this.left.keyLoc + this.left.keySize * .5)); ctx.bezierCurveTo(topLeftX + puzzle.pieceW * this.left.curveStartY, topLeftY + (this.left.keyLoc + this.left.curveStartX) * puzzle.pieceH, topLeftX + puzzle.pieceW * this.left.curveEndY, topLeftY + (this.left.keyLoc - this.left.curveEndX) * puzzle.pieceH, topLeftX, topLeftY + (this.left.keyLoc - this.left.keySize * .5) * puzzle.pieceH); ctx.bezierCurveTo(topLeftX - puzzle.pieceW * .15, topLeftY + this.left.keyLoc * puzzle.pieceH, topLeftX - puzzle.pieceW * .1, topLeftY + this.left.keyLoc * .5 * puzzle.pieceH, topLeftX, topLeftY); } else if (this.left.type == 'out') { ctx.bezierCurveTo(topLeftX + puzzle.pieceW * .1, topLeftY + (this.left.keyLoc + (1 - this.left.keyLoc) * .5) * puzzle.pieceH, topLeftX + puzzle.pieceW * .15, topLeftY + puzzle.pieceH * this.left.keyLoc, topLeftX, topLeftY + puzzle.pieceH * (this.left.keyLoc + this.left.keySize * .5)); ctx.bezierCurveTo(topLeftX - puzzle.pieceW * this.left.curveStartY, topLeftY + (this.left.keyLoc + this.left.curveStartX) * puzzle.pieceH, topLeftX - puzzle.pieceW * this.left.curveEndY, topLeftY + (this.left.keyLoc - this.left.curveEndX) * puzzle.pieceH, topLeftX, topLeftY + (this.left.keyLoc - this.left.keySize * .5) * puzzle.pieceH); ctx.bezierCurveTo(topLeftX + puzzle.pieceW * .15, topLeftY + this.left.keyLoc * puzzle.pieceH, topLeftX + puzzle.pieceW * .1, topLeftY + this.left.keyLoc * .5 * puzzle.pieceH, topLeftX, topLeftY); } // edge piece else { ctx.closePath(); } ctx.clip(); ctx.drawImage(puzzle.image, topLeftX - this.correctX + puzzle.x, topLeftY - this.correctY + puzzle.y, puzzle.width, puzzle.height); ctx.strokeStyle = "black"; ctx.stroke(); ctx.restore(); } }