That Javascript has (extended) class!
kevhines
Posted on May 7, 2021
Let's talk extending classes in JavaScript.
I wrote a single page JavaScript game that I called Gibberish Cards. It's kinda like War... but dumber.
It didn't use a typical card deck, and the names of the cards were user defined. This mean I needed a list of what cards were in the game and a subset of those cards that had names. In addition I needed to know which cards a user had in his draw pile and which cards a computer had in his draw pile. I also needed to know which cards the user and computer had in their discard pile. That's 6 arrays of card objects!
So I created a Deck class.
A Simple Class
class Deck {
constructor() {
this.unplayedCards = []
}
addCardtoDeck(card) {
this.unplayedCards.push(card)
}
findCard(id) {
return this.unplayedCards.find(card => card.id === id)
}
}
I called the array of cards unplayedCards because I needed to know which cards had not already been used in the game. I had two functions in this class addCardtoDeck which was great when the game first started as I filled in all those different decks I talked about. And occasionally I need to find a card object so the findCard function was very useful.
But I also needed to keep track of what named cards existed. The computer only ever had named cards, and I didn't need to keep the named and unnamed cards separate for the user so I only needed a list of all the named cards in the game before starting.
Rather then keep track of those named cards in all Deck classes I extended the Deck class to an AllCards class.
Extending and Using super
class AllCards extends Deck {
constructor() {
super()
this.namedCards = []
}
addCardtoDeck(card) {
super.addCardtoDeck(card)
if (card.name) {
this.namedCards.push(card)
}
}
resetNamed() {
this.namedCards = this.unplayedCards.filter(card => card.name)
}
}
Because this extends from Deck I had access to the findCard and addCardtoDeck function. My constructor needed both an unplayedCards array and a namedCards array. I used the code from the Deck class by calling the super() method in the constructor.
I determined which cards were named as I filled cards into those arrays via AddCardtoDeck so I also had to extend that function. You can see in the extended function I call super.addCardtoDeck(card) to add a card to my unplayedCards array but then I have new code where I add any named cards to the namedCard array.
This would be a pointless array in the user's deck and the computer's deck so I avoided the two extra array of card objects.
I also created a function just in the AllCards class called resetNamed() which is useful after a game ends. If a user wants to play again I don't want to re-upload all the card details from the database so it recreates the namedCards array with any cards that got named during the most recent game.
There was also a lot of functions I used in the two game decks that I never needed to use for the repository of all cards so I extended another class from Deck.
Another Extended Class
class PlayableDeck extends Deck {
constructor() {
super()
this.playedCards = []
}
// here is where I placed all the functions
// only applicable to this class.
}
Similar to the AllCards* class this extends from **Deck, uses super to create a this.unplayedCards array but then also creates an array for game decks that keeps track of which cards have been played since the last reshuffle. A discard pile, if you will. I called that playedCards.
Now that I had a PlayableDeck class I was able to create a slew of functions for game play that did not need to sit in the Deck class.
- drawCard() - randomly draws an unplayed card
- moveCardToPlayed(card) - moves a card (say that card I got from drawCard()) into the playedCards array.
- removeCardFromDeck() - removes a card from played. This is used when your opponent takes your card.
- totalCards() and totalUnplayedCards() to keep track of draw and discard piles. These are also critical to know when you need to reshuffle or when you've lost the game!
- clear() - this function is clearing all cards after a game ends so you can start a new game cleanly.
3 Uniquely Similar Objects!
By extending the class I was able to have 3 Deck objects used in my code that didn't have functions or arrays baked in they would never use. It made the code cleaner and made testing easier while I coded the gameplay functionality.
Extend your classes! It's easy!
Posted on May 7, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.