HTML+JS+websocket actual combat "Yu GI Oh" online card game

Posted by everisk on Mon, 07 Mar 2022 20:47:18 +0100

At the beginning of this chapter, we will combine js code to see the implementation of specific functions of the game. The general plan is to first introduce the basic functions throughout the game, and then introduce them one by one according to different function keys and function blocks. The functions related to online in the function will be described in detail in the chapter of realizing online.

Card group system

First of all, let's introduce the main body of the whole game to store materials and the realization of card group.

1. Card group structure:

The card set of the game is essentially a simple string array, which loads and stores the path (or URL) of each card picture when the game is initialized. The card deck is a stack in structure and follows the principle of last in first out (LIFO), that is, the cards sent into the deck are placed at the top of the deck by default. If the shuffle is not carried out, the last cards will be drawn first in the latest drawing, just like a gun cartridge.


There are two basic operations of stack, POP (out of stack) and PUSH (in stack). When drawing cards, we perform POP operation to remove the cards at the top of the card set from the card set and send them to the player's hand. When we encounter some effects and need to put the hand or the card on the field back to the top of the card set, we will execute the PUSH operation to press the specified card into the top of the card set. If you need to put back the card set before cutting and washing, you can execute the shuffle function after performing the PUSH operation.

Of course, sometimes we need to select the specified cards from the card deck and take out the effect. At this time, the specified cards need to be removed from the card deck. If it is just a simple POP operation, we have to take out the cards one by one until the desired cards, which is very troublesome. JS provides a splice() method, which allows us to directly delete or replace one or more elements in the array. We only need to provide the index value of the element and the number of elements to be deleted. In this method, we can provide the serial number of the specified card in the deck, and delete only one element, that is, the selected card will be eliminated from the deck. After elimination, the position will not be left blank, but filled up by other cards behind, which means that the index of some cards in the card group will also change. This function will be discussed in detail later.

2. Loading of card set:

Before the game begins, players of both sides need to load their own card sets.

First, we need to use several global variables:

P1DeckName is used to indicate which deck we want to load in this game. A card group name essentially represents a card group folder. We can have multiple card group folders and fill in the one to be used in this game by ourselves:

var P1DeckName = "Deck_KaiMa";  //Our brand group name




P1DeckNum is used to indicate the number of cards in the card deck (it has not yet realized automatic reading of all files in the folder, so this variable can not be used):

var P1DeckNum = 50;  //Number of cards in our deck

P1Deck string array used to store all picture URLs of the card set:

var P1Deck = [];  //Our deck (store all our cards src)

Then, push each picture path in the card group folder into the string array through the circular method:

//Save all card paths of P1 card set
for (var i=0; i<P1DeckNum; i++) {
    var cardsrc = "image/cards/" + P1DeckName + "/" + i + ".jpg"
    P1Deck.push(cardsrc);
}

Of course, before that, we have changed the file names of all cards in the deck folder to numbers:



After loading, shuffle again, otherwise the sequence is fixed every time:

/*Generate random number */
function getRandom(min, max) {
    return Math.floor(Math.random() * (max - min + 1) + min);
}

/*Clone array */
function cloneArr(arr) {
    // copy from the first character
    // slice(start,end) method can return the selected element from the existing array.
    return arr.slice(0);
}

/*Array shuffle */
function shuffle(arr) {
    let newArr = [];
    newArr = arr;
    for (let i = 0; i < newArr.length; i++) {
        let j = getRandom(0, i);
        let temp = newArr[i];
        newArr[i] = newArr[j];
        newArr[j] = temp;
    }
    return newArr;
}

P1Deck = shuffle(cloneArr(P1Deck));  //Deck shuffle

3. Realization of card drawing in card group:

Drawing cards from the deck is to transfer the card url in the deck array to the hand slot. Before implementing this js function, let's review the contents of the hand area in the html file:

<div class="item">
	<img id="p1-hand0" class="card" onmouseover="showCardInfo('hand', this.src, 0, 'player1')" onclick="selectCard(this.id, 'hand', this.src, 0, 'player1')" src="">
</div>

There are 8 such img tags in our hand card area, corresponding to 8 hand card slots respectively. Each tag has an independent id, and the src attribute is left blank by default, and other attributes are ignored for the time being.


Each time we execute the card drawing function, we need to determine an empty hand card slot and obtain its id, and then assign the image url of the card to its src attribute. After assignment, the image of the card will be displayed in the web page.

To ensure that the slot to be assigned is empty, we need to judge the src value of each slot one by one. Since the value of src attribute is not "" or null after it is left blank, but the default path is the path where the html file is stored, I set a global variable emptysrc here to store the default path, and obtain the path from any empty img element after the html file is loaded for other functions to determine the empty card slot.

//Get an empty img src path to facilitate other functions to judge whether the card slot is empty
//window.onload causes the function to execute after the html is fully loaded
var emptysrc;
window.onload = function() {
  var handID = 'p1-field0';  //Select any card slot id
  element = document.getElementById(handID);
  emptysrc = element.src;
  P1Deck = shuffle(cloneArr(P1Deck));  //shuffle the cards
}

Note: the name of the local variable handID here is wrong. Here I choose the id of a battlefield card slot instead of the hand card slot, but it does not affect the operation effect of the function. The default value of empty src is the same.


Next, implement the card drawing function drawCard():

Traverse all 8 hand card slots of our company:
	Get current card slot id;
	Through the card slot id Get the current card slot object;
	
	If (the card slot object is an empty card slot):
		Pair deck array P1Deck implement POP Operation, put the picture at the top of the card set url Pushed out and assigned to the card slot object src Attributes;
		Stop traversal immediately;
/*Draw the top card of the deck to the hand card */
function drawCard() {
    for (var i=0; i<8; i++) {
        var handID = 'p1-hand' + i.toString();
        element = document.getElementById(handID);
        if (element.src == emptysrc) {  //If the slot is empty
          element.src = P1Deck.pop();

          /*Trigger card drawing sound effect */
          var snd = new Audio("sound/draw.wav");
          snd.play();

          /**
           * Tell the opponent which hand card slot has added a card
           */
          messageHand('add', i);
          break;
        }
    }
}

Note: the online functions in the code will be summarized and introduced together with the online chapter.


In the last step, the condition for triggering drawCard() is that the player clicks the card back picture representing the card group in the card group area of the game interface, and we find the corresponding element in html:

<div class="item deck">
	<img id="deck_r" class="card" src="image/cards/cardback.jpg" alt="cardback" onclick="drawCard()">
</div>

This is also an img tag. src sets the url of the picture on the back of the card, and the onclick attribute sets the card drawing function drawCard() we have written, so that when you click the picture on the back of the card, a card will be added to the empty card slot in the hand area.

Other functions will be introduced in the following chapters.


Project source code can be moved to my Github:
YGO-Online-Combat

Topics: Javascript Front-end html5 Game Development