|
@@ -4,11 +4,17 @@ function DeckScope(scope) {
|
|
|
options = options || {};
|
|
|
this.$el = $(root);
|
|
|
this.elements = { $dropPlace: "#Deck" };
|
|
|
- this.proxies = [ "select", "track", "place" ];
|
|
|
+ this.proxies = [ "select", "track", "place", 'restoreCards' ];
|
|
|
this.cards = [ [], [] ];
|
|
|
this.trfs = [ [], [] ];
|
|
|
this.__super__.constructor.call(this),
|
|
|
this.$dropPlace.droppable({ accept: this.place });
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ this.restoredCards = [[], []]
|
|
|
+ this.selectedPos = {}
|
|
|
}
|
|
|
|
|
|
var padding = {
|
|
@@ -40,6 +46,7 @@ function DeckScope(scope) {
|
|
|
},
|
|
|
card.on("dragstart", this.select),
|
|
|
card.on("dragmove", this.track),
|
|
|
+ card.$el.on('revert', this.restoreCards)
|
|
|
card.$el.doubletap(function(){
|
|
|
scope.apiProvider.actionDiscard(card)
|
|
|
}),
|
|
@@ -53,6 +60,65 @@ function DeckScope(scope) {
|
|
|
});
|
|
|
},
|
|
|
|
|
|
+ restoreCards: function(){
|
|
|
+ if(this.restoredCards && this.needRestore){
|
|
|
+ var trfs = this.trfs
|
|
|
+ for(var i = 0; i < 15; i++){
|
|
|
+ for(var j = 0; j < 2; j++){
|
|
|
+ var card = this.restoredCards[j][i]
|
|
|
+ if(card && card != selected){
|
|
|
+ card.$el.transform({
|
|
|
+ from: [trfs[card.pos.y][card.pos.x].x, trfs[card.pos.y][card.pos.x].y].join(' '),
|
|
|
+ to: [trfs[j][i].x, trfs[j][i].y].join(' ')
|
|
|
+ })
|
|
|
+
|
|
|
+ card.pos = {
|
|
|
+ x: i,
|
|
|
+ y: j
|
|
|
+ }
|
|
|
+
|
|
|
+ card.direction = null
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.needRestore = false
|
|
|
+ this.cards = this.restoredCards.map(function (row){ return row.concat() })
|
|
|
+ this.normalizeCards()
|
|
|
+ this.dropDiraction()
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ normalizeCards: function(){
|
|
|
+ for(var i = 0; i < 15; i++){
|
|
|
+ for(var j = 0; j < 2; j++){
|
|
|
+ var card = this.cards[j][i]
|
|
|
+ if(card){
|
|
|
+ card.pos = {
|
|
|
+ x: i,
|
|
|
+ y: j
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ dropDiraction: function(){
|
|
|
+ for(var i = 0; i < 15; i++){
|
|
|
+ for(var j = 0; j < 2; j++){
|
|
|
+ var card = this.cards[j][i]
|
|
|
+ if(card){
|
|
|
+ card.direction = null
|
|
|
+ }
|
|
|
+ if(this.restoredCards){
|
|
|
+ card = this.restoredCards[j][i]
|
|
|
+ if(card){
|
|
|
+ card.direction = null
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
render: function() {
|
|
|
this.each(function(card, i, j) {
|
|
|
if (null != card) {
|
|
@@ -64,18 +130,39 @@ function DeckScope(scope) {
|
|
|
},
|
|
|
|
|
|
track: function(e) {
|
|
|
- this.each(function(card, i, j) {
|
|
|
- if (card && card.$el[0] != e.target && card.intersect($(e.target)).res && !card.$el.attr("animated") && scope.Card.selected.length < 2) {
|
|
|
- var shift = e.detail.x > card.centerX() ? i - 1 : i + 1
|
|
|
- shift = shift > 14 ? shift - 2 : shift
|
|
|
- shift = 0 > shift ? shift + 2 : shift
|
|
|
- this.move({ i: i, j: j}, {i: shift, j: j})
|
|
|
- moved = true
|
|
|
- prevX = e.detail.x
|
|
|
- prevY = e.detail.y
|
|
|
- return !1;
|
|
|
+ var selectedPos = this.getSelectedPos()
|
|
|
+ for(var i = 0; i < 15; i++){
|
|
|
+ for(var j = 0; j < 2; j++){
|
|
|
+ var card = this.cards[j][i]
|
|
|
+ if (card && card.$el[0] != e.target && (selectedPos.x == i && selectedPos.y == j) && !card.$el.attr("animated") && scope.Card.selected.length < 2) {
|
|
|
+ var shift = e.detail.x > card.centerX() ? i - 1 : i + 1
|
|
|
+ if(shift > 14 || shift < 0){
|
|
|
+ shift = shift > 14 ? shift - 2 : shift
|
|
|
+ shift = 0 > shift ? shift + 2 : shift
|
|
|
+ }
|
|
|
+ else if(shift < i && this.leftDeadEnd(j, i)){
|
|
|
+ shift = i + 1
|
|
|
+ }
|
|
|
+ else if(shift > i && this.rightDeadEnd(j, i)){
|
|
|
+ shift = i - 1
|
|
|
+ }
|
|
|
+ else if(card.direction == this.direction(i, shift)){
|
|
|
+ shift = card.direction == 'left' ? i - 1 : i + 1
|
|
|
+ }
|
|
|
+ this.move({ i: i, j: j}, {i: shift, j: j})
|
|
|
+ this.needRestore = true
|
|
|
+ moved = true
|
|
|
+ prevX = e.detail.x
|
|
|
+ prevY = e.detail.y
|
|
|
+ this.selectedPos = { x: i, y: j}
|
|
|
+ return !1;
|
|
|
+ }
|
|
|
}
|
|
|
- });
|
|
|
+ }
|
|
|
+
|
|
|
+ if((this.selectedPos.x != selectedPos.x || this.selectedPos.y != selectedPos.y)){
|
|
|
+ this.restoreCards()
|
|
|
+ }
|
|
|
},
|
|
|
|
|
|
move: function(fst, snd){
|
|
@@ -105,14 +192,39 @@ function DeckScope(scope) {
|
|
|
card = this.cards[fst.j][j]
|
|
|
if(card != selected){
|
|
|
|
|
|
- card.$el.transform({
|
|
|
- from: [trfs[fst.j][j].x, trfs[fst.j][j].y].join(' '),
|
|
|
- to: [trfs[fst.j][direction(j)].x, trfs[fst.j][direction(j)].y].join(' ')
|
|
|
- })
|
|
|
+ var self = this
|
|
|
|
|
|
- if(selected){
|
|
|
- selected.dragHandler.initTrf = [trfs[fst.j][j].x, trfs[fst.j][j].y]
|
|
|
- }
|
|
|
+ ;(function (card, fst_j, j, dir_j, deck){
|
|
|
+ card.$el.transform({
|
|
|
+ from: [trfs[fst_j][j].x, trfs[fst_j][j].y].join(' '),
|
|
|
+ to: [trfs[fst_j][dir_j].x, trfs[fst_j][dir_j].y].join(' ')
|
|
|
+ })
|
|
|
+
|
|
|
+ card.direction = deck.direction(j, dir_j)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ }(card, fst.j, j, direction(j), this))
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
;((this.cards[fst.j][j] = this.cards[fst.j][direction(j)]) || {}).pos = {x:j, y:fst.j}
|
|
|
;(this.cards[fst.j][direction(j)] = card).pos = {x:direction(j), y:fst.j}
|
|
@@ -122,40 +234,75 @@ function DeckScope(scope) {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ this.normalizeCards()
|
|
|
},
|
|
|
|
|
|
select: function(e) {
|
|
|
- selected = null, this.each(function(card) {
|
|
|
- return card && card.$el[0] == e.target ? (selected = card, !1) : !0;
|
|
|
- });
|
|
|
+ selected = null;
|
|
|
+ selected = e.detail.target.owner
|
|
|
+ this.restoredCards = this.cards.map(function (row){ return row.concat() })
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
},
|
|
|
|
|
|
place: function(target, x, y) {
|
|
|
try{
|
|
|
- var trfs = this.trfs, pos = this.$dropPlace.position(), width = this.$dropPlace.width(), height = this.$dropPlace.height(), placeWidth = Math.round(width / 15), placeHeight = Math.round(height / 2), truePosX = Math.floor((x - pos.left) / placeWidth), posY = Math.floor((y - pos.top) / placeHeight);
|
|
|
- scope.Card.selected.sort(function(a, b) {
|
|
|
- return (a.pos.x > b.pos.x) - (b.pos.x > a.pos.x);
|
|
|
- });
|
|
|
- var dropResult, idx = scope.Card.selected.indexOf(target.owner), cards = scope.Card.selected.length ? scope.Card.selected.concat() : [ target.owner ];
|
|
|
- if (cards.every(function(card, i) {
|
|
|
- return posX = truePosX + (i - idx) * (card != target.owner), null == this.cards[posY][posX] || this.cards[posY][posX] == card;
|
|
|
- }, this)) for (var card, i = 0, l = cards.length; l > i; i++) card = cards[i], posX = truePosX + (i - idx) * (card != target.owner),
|
|
|
- (dropResult = null == this.cards[posY][posX] || this.cards[posY][posX] == selected) && (this.cards[posY][posX] != card && (null != card.pos.x && null != card.pos.y ? this.cards[card.pos.y][card.pos.x] = this.cards[card.pos.y][card.pos.x] == card ? null : this.cards[card.pos.y][card.pos.x] : (this.$el.trigger("take", {
|
|
|
- detail: {
|
|
|
- card: card
|
|
|
+ var trfs = this.trfs,
|
|
|
+ posX = this.getSelectedPos().x,
|
|
|
+ posY = this.getSelectedPos().y
|
|
|
+
|
|
|
+ scope.Card.selected.sort(function (a, b){
|
|
|
+ return (a.pos.x > b.pos.x) - (b.pos.x > a.pos.x)
|
|
|
+ })
|
|
|
+
|
|
|
+ var idx = scope.Card.selected.indexOf(target.owner),
|
|
|
+ cards = scope.Card.selected.length ? scope.Card.selected.concat() : [target.owner],
|
|
|
+ dropResult
|
|
|
+
|
|
|
+ if(cards.every(function (card, i){
|
|
|
+ return this.cards[posY][posX] == null || this.cards[posY][posX] == card
|
|
|
+ }, this)){
|
|
|
+
|
|
|
+ for(var i = 0, l = cards.length, card; i < l; i++){
|
|
|
+ card = cards[i]
|
|
|
+
|
|
|
+ if(dropResult = (this.cards[posY][posX] == null || this.cards[posY][posX] == selected)){
|
|
|
+
|
|
|
+ if(this.cards[posY][posX] != card){
|
|
|
+ if(card.pos.x != null && card.pos.y != null){
|
|
|
+ this.cards[card.pos.y][card.pos.x] = this.cards[card.pos.y][card.pos.x] == card ? null : this.cards[card.pos.y][card.pos.x]
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ this.$el.trigger('take', { detail: { card: card }})
|
|
|
+ this.justTaken = true
|
|
|
+ }
|
|
|
+ ;(this.cards[posY][posX] = card).pos = {x:posX,y:posY}
|
|
|
+ this.normalizeCards()
|
|
|
+ this.restoredCards = null
|
|
|
+ selected = null
|
|
|
+ }
|
|
|
+
|
|
|
+ ;(function(card){
|
|
|
+ card.$el.transform({
|
|
|
+ from: card.$el.attr('transform').slice(10,-1),
|
|
|
+ to: [trfs[posY][posX].x, trfs[posY][posX].y].join(' ')
|
|
|
+ }).then(function(){
|
|
|
+ card.dragHandler.storeTrf()
|
|
|
+ })
|
|
|
+ }(card))
|
|
|
+ }
|
|
|
}
|
|
|
- }), this.justTaken = !0), (this.cards[posY][posX] = card).pos = {
|
|
|
- x: posX,
|
|
|
- y: posY
|
|
|
- }), function(card) {
|
|
|
- card.$el.transform({
|
|
|
- from: card.$el.attr("transform").slice(10, -1),
|
|
|
- to: [ trfs[posY][posX].x, trfs[posY][posX].y ].join(" ")
|
|
|
- }).then(function() {
|
|
|
- card.dragHandler.storeTrf();
|
|
|
- });
|
|
|
- }(card));
|
|
|
- return dropResult;
|
|
|
+ this.dropDiraction()
|
|
|
+ }
|
|
|
+ return dropResult
|
|
|
}
|
|
|
catch(e){
|
|
|
return false
|
|
@@ -179,6 +326,7 @@ function DeckScope(scope) {
|
|
|
value: tile[2]
|
|
|
});
|
|
|
card.pos = {x:i, y:j};
|
|
|
+ this.normalizeCards()
|
|
|
card.on('dragstart', this.select);
|
|
|
card.on('dragmove', this.track);
|
|
|
card.$el.doubletap(function() { scope.apiProvider.actionDiscard(card) });
|
|
@@ -219,9 +367,77 @@ function DeckScope(scope) {
|
|
|
return result
|
|
|
},
|
|
|
|
|
|
- dir: function() {
|
|
|
- for (var i = 0; 15 > i; i++) this.cards[0][i] && this.cards[0][i].log();
|
|
|
- for (var i = 0; 15 > i; i++) this.cards[1][i] && this.cards[1][i].log();
|
|
|
+ getSelectedPos: function(){
|
|
|
+ if(selected){
|
|
|
+ var x = selected.centerX(),
|
|
|
+ y = selected.centerY(),
|
|
|
+ pos = this.$dropPlace.position(),
|
|
|
+ width = this.$dropPlace.width(),
|
|
|
+ height = this.$dropPlace.height(),
|
|
|
+ placeWidth = Math.round(width / 15),
|
|
|
+ placeHeight = Math.round(height / 2),
|
|
|
+ posX = Math.floor((x - pos.left) / placeWidth),
|
|
|
+ posY = Math.floor((y - pos.top) / placeHeight) - 1
|
|
|
+
|
|
|
+
|
|
|
+ return {
|
|
|
+ x: posX,
|
|
|
+ y: posY
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return {
|
|
|
+ x: -1,
|
|
|
+ y: -1
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ leftDeadEnd: function(row, from){
|
|
|
+ for(var i = from; i >= 0; i--){
|
|
|
+ if(!this.cards[row][i] || this.cards[row][i] == selected){
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true
|
|
|
+ },
|
|
|
+
|
|
|
+ rightDeadEnd: function(row, from){
|
|
|
+ for(var i = from+1; i < 15; i++){
|
|
|
+ if(!this.cards[row][i] || this.cards[row][i] == selected){
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true
|
|
|
+ },
|
|
|
+
|
|
|
+ direction: function(from, to){
|
|
|
+ return from < to ? 'left' : 'right'
|
|
|
+ },
|
|
|
+
|
|
|
+ dir: function(){
|
|
|
+ console.group('Cards')
|
|
|
+ console.group()
|
|
|
+ for(var i = 0; i < 15; i++){
|
|
|
+ if(this.cards[0][i]){
|
|
|
+ this.cards[0][i].log()
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ console.log('%c■', 'color: #333')
|
|
|
+ }
|
|
|
+ }
|
|
|
+ console.groupEnd()
|
|
|
+ console.group()
|
|
|
+ for(var i = 0; i < 15; i++){
|
|
|
+ if(this.cards[1][i]){
|
|
|
+ this.cards[1][i].log()
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ console.log('%c■', 'color: #333')
|
|
|
+ }
|
|
|
+ }
|
|
|
+ console.groupEnd()
|
|
|
+ console.groupEnd()
|
|
|
}
|
|
|
});
|
|
|
|