Next page | Contents page |

Dragging cards: mousemove

In writing the mousemove handler I found I had to make more changes than I can describe in detail. After writing small amounts and retesting several times this is what I ended up with:


function onMousedown (e)
{ var xy = getMousePoint (e);
  var target = findTarget (xy.x, xy.y, GAME.targets);
  if (null === target) return;
  var card = target.card;
  if (!card.faceUp) return;
  var cards = card.column.getSublist (card.columnIndex);
  // array of cards, not a Column
  var nextFaceUp = false, i1 = card.columnIndex - 1;
  if (i1 >= 0 && null !== card.column.getLastCard ())
  { nextFaceUp = card.column.getCard (i1).faceUp; }
  if (!isMovable (cards)) return;
  recordHistory ();
  // Remove cards from their present column and 
  // put them in a new column that can be moved
  var oldCol = card.column;
  var newCol = new Column (oldCol.XT, oldCol.YT);
  for (var i = cards.length - 1; i >= 0; i--)
  { oldCol.removeCard (cards [i]);
  }
  if (!nextFaceUp)
  { var oldLast = oldCol.getLastCard ();
    if (null !== oldLast) oldLast.hide (); // no peeking
  }
  for (i = 0; i < cards.length; i++)
  { newCol.addCard (cards [i]);
  }
  GAME.mouse = {x0:xy.x, y0:xy.y, xL:target.xL, yT:target.yT,
    topCard:card, newCol:newCol, oldCol:oldCol, hasMoved:false}; 
}

function onMousemove (e)
{ if (null === GAME.mouse) return;
  var xy = getMousePoint (e);
  var dx = Math.floor (xy.x - GAME.mouse.x0);
  var dy = Math.floor (xy.y - GAME.mouse.y0);
  if (Math.abs (dx) > GAME.mouse.topCard.width)
  { GAME.mouse.hasMoved = true; }
  var newCol = GAME.mouse.newCol;
  newCol.setXY (GAME.mouse.xL + dx, GAME.mouse.yT + dy);
  GAME.game.draw ();
  newCol.draw ();
}

function onMouseup (e)
{ if (null === GAME.mouse) return;
  var card = GAME.mouse.topCard;
  var oldCol = GAME.mouse.oldCol;
  var newCol = GAME.mouse.newCol;
  if (GAME.mouse.hasMoved)
  { var xy = getMousePoint (e);
    var target = findTarget (xy.x, xy.y, GAME.targets);
    // Is the target suitable for the dragged newCol?
    if (null !== target)
    { var card = target.card;
      if (card.faceUp) // also means not in oldCol
      { if (card.value === newCol.getCard (0).value + 1)
        { moveTo (card.column);
          return;
  } } } }
  for (const COL of GAME.COLUMNS)
  { if (COL !== oldCol)
    { var last = COL.getLastCard ();
      if (null !== last)
      { if (last.suit === card.suit && last.value - 1 === card.value)
        { moveTo (COL);
          return;
  } } } } // Not exact match, so try value match only (not suit):
  for (const COL of GAME.COLUMNS)
  { if (COL !== oldCol)
    { var last = COL.getLastCard ();
      if (null !== last)
      { if (last.value - 1 === card.value)
        { moveTo (COL);
          return;
  } } } } // Is there an empty column to move to?
  for (const COL of GAME.COLUMNS)
  { if (COL !== oldCol)
    { if (null === COL.getLastCard ())
      { moveTo (COL);
        return;
  } } }
  // Nowhere to go, so put cards back where they were:
  undo ();
  GAME.mouse = null;
}

function moveTo (column)
{ column.addColumn (GAME.mouse.newCol);
  var oldLast = GAME.mouse.oldCol.getLastCard ();
  if (null !== oldLast) oldLast.reveal ();
  if (column.endsWithFullSuit ())
  {
    // TO DO
  }
  GAME.game.draw ();
  GAME.mouse = null;
}

The new function moveTo() at the end of that arose because the same sequence of statements occurred several times in the mouseup handler. In this function we should also check whether adding cards to a column causes it to end with a complete descending suit, from King down to Ace, in which case it should be removed. So let's look at that next.

Next page | Contents page |