Next page | Contents page |

Display the cards

In our spider file we already have

Spider.prototype.draw = function ()
{ // TO DO

and now we need to flesh out the details. Drawing will fairly evidently work column by column, drawing the cards in each column. We will need new methods called draw() in both Column and Card. As far as Spider is concerned:

Spider.prototype.draw = function ()
{ GAME.g2.fillStyle = '#000';
  GAME.g2.fillRect (0, 0, GAME.cnv.width, GAME.cnv.height);
  for (const COLUMN of GAME.COLUMNS) COLUMN.draw ();
  // to do: remainder pile

The first 2 statements draw a black background for the entire canvas. The order of drawing the columns is immaterial so I have chosen to use a for-of loop instead of a basic for loop.

Then we need a new draw() method in Column (because Spider does not want to know the internal structure of Column). We have already set the position of the top left corner of each column when it was constructed (previous page) but we left a detail about card width which should now be addressed.

All cards will have the same width and height so I decided to set those as properties of Card.prototype, to be inherited by all cards. In cardA.js add this function (not method):

function setCardWidth (wd)// All cards the same size
{ Card.prototype.width = Math.floor (wd);
  Card.prototype.height = Math.floor (wd * 4 / 3);
  // For centring the glyph within the card:
  var wd128 = wd / 128;
  Card.prototype.dx = Math.round (8 * wd128);
  Card.prototype.dy = Math.round (24 * wd128);

The height is set from the width as a constant (rather arbitrary) 4:3 ratio. As the comment explains there are 2 offsets for centring the card glyph (as described on the Unicode page). The formulas for dx and dy were found by experimenting: running the program repeatedly with various trial values.

setCardWidth() should be called from the constructor for Spider after setting COL_WIDTH:

  setCardWidth (0.9 * COL_WIDTH);

Now consider the draw() method for Column:

Column.prototype.draw = function ()
{ for (var i = 0, y = this.YT;
       i < this.CARDS.length; i++, y += this.DY)
  { var card = this.CARDS [i];
    card.draw (this.XL, y);
} };

I have not used a for-of loop here because I want to be absolutely sure about the ordering of the cards.

That simple method calls card.draw() with an (x, y) position (once again, Column does not want to know about the internal structure of a Card):

Card.prototype.draw = function (xLeft, yTop)
{ var g2 = GAME.g2;
  g2.font = this.height + "px sans-serif";
  g2.fillStyle = (this.faceUp) ? '#fff' : '#077'; // white or cyan
  g2.fillRect (xLeft, yTop, this.width, this.height);
  if (this.faceUp
   && (this.suit === SUITS.DIAMOND || this.suit === SUITS.HEART))
  { g2.fillStyle = '#f00'; // red
  else g2.fillStyle = '#000'; // black
  g2.fillText (this.getGlyph (),
               xLeft + this.dx, yTop + this.height - this.dy);

After setting a background rectangle and making the font size the full height of a card we draw the glyph as text: a single unicode character!

If you have followed along doing everything so far you should be able to run the HTML file from your IDE and see an initial randomly shuffled deal.

Next we will consider how to click on cards to make them move.

Next page | Contents page |