Build Rock Papar Scissors Game in VueJS

In this post, I will be demonstrating and going over the steps of how to create Rock. Paper. Scissor Game in VueJS. Where one player is the user and another player is the computer.

Let’s understand the code

 

Data Properties

Let’s define some data proeprties in our Vue Instance which we will use to store different properties required to build this game.

        data: {
            options: ['Rock', 'Paper', 'Scissor'],
            yourWeapon: '',
            computerWeapon: '',
            result: '',
            yourScore: 0,
            computerScore: 0,
            totalRounds: 0,
            fighting : false,
        },

 

options : These are the options which will be used to randomly assign a value to computerWeapon.
yourWeapon, computerWeapon : properties to store the weapon value (either rock, paper or scissor)
result: property to store the result (won, lost or draw)
yourScore, computerScore: properties to store user’s score and computer’s score
totalRounds: property to store total number of rounds played
fighting: Property to store weather currently fight is processing.

User can choose the weapon

As part of the first step let’s create a new method, which will help us to change the user’s weapon.

<div class="r" :class="yourWeapon == 'Rock' ? 'checked' : ''" @click="changeWeapon('Rock')"></div>
<div class="p" :class="yourWeapon == 'Paper' ? 'checked' : ''" @click="changeWeapon('Paper')"></div>
<div class="s" :class="yourWeapon == 'Scissor' ? 'checked' : ''" @click="changeWeapon('Scissor')"></div>

We bind a click event to each of the user’s options, and once the option is clicked we invoke the changeWeapon method to change the user’s weapon. We also make use of v-bind directive to add a checked property to the selected weapon so that it appears in different color styling.


...
changeWeapon(weapon){
    if(this.fighting)
        return;
        
    this.yourWeapon = weapon;
    this.result = '';
    this.computerWeapon = '';
},
...

Game Status

We make use of different properties from our Vue Instance to decide which option to show to the user in the game controls.

<div class="game">
    <div class="chooseWeapon" v-if="!yourWeapon">Choose your Weapon</div>
    <div class="fight" v-if="yourWeapon && !result" v-show="!fighting" @click.once="fight" v-if="fig">FIGHT</div>
    <div class="fighting" v-if="fighting">
        <div class="spinner-border text-danger" role="status">
            <span class="sr-only">Loading...</span>
        </div>
    </div>
    <div class="result" :class="result" v-if="result">{{result.toUpperCase()}}</div>
</div>

If the user’s weapon is empty we show ‘Choose your Weapon’ option, if the user has chosen a weapon we show the Fight option. etc.

Fight Method

In the last step, we have bound the click event on the Fight button to the fight method in our Vue Instance. Let’s implement that method.

fight(){
    this.fighting = true;
    this._pretendProcessing();
},

_fight(){
    this.computerWeapon = this.options[Math.floor(Math.random() * this.options.length)]; 
    if(this.yourWeapon === this.computerWeapon)
        this._draw();
    if(this.computerWeapon === 'Rock'){
        if(this.yourWeapon === 'Paper'){
            this._win();
        }
        if(this.yourWeapon === 'Scissor'){
            this._lost();
        }
    }
    if(this.computerWeapon === 'Paper'){
        if(this.yourWeapon === 'Rock'){
            this._lost();
        }
        if(this.yourWeapon === 'Scissor'){
            this._win();
        }
    }
    if(this.computerWeapon === 'Scissor'){
        if(this.yourWeapon === 'Rock'){
            this._win();
        }
        if(this.yourWeapon === 'Paper'){
            this._lost();
        }
    }
},

_pretendProcessing(){
    var x = 0;
    var intervalID = setInterval(() =>{

        this.computerWeapon = this.options[Math.floor(Math.random() * this.options.length)];

        if (++x === 10) {
            window.clearInterval(intervalID);
            this._fight();
            this.fighting = false;
        }
    }, 100);
},

_draw(){
    this.result = 'draw',
    this.totalRounds++;
},

_win(){
    this.result = 'won';
    this.yourScore++;
    this.totalRounds++;
},

_lost(){
    this.result = 'lost';
    this.computerScore++;
    this.totalRounds++;
},

Showing Scores

We show winning score in Green and losing score in red color.

<div class="d-flex align-items-center you mr-3 justify-content-between">
    <span class="text">You</span><span class="score font-weight-bold" :class="yourScore >= computerScore ? 'text-success' : 'text-danger'"> {{yourScore}}</span>
</div>
<div class="d-flex align-items-center computer">
    <span class="text">Computer</span><span class="score font-weight-bold" :class="computerScore >= yourScore ? 'text-success' : 'text-danger'"> {{computerScore}}</span>
</div>  

Total Rounds & Resetting

At the bottom of the game, we show the total number of rounds a user has played and also a button to reset the game.

<div class="d-flex flex-row justify-content-center text-center controls shadow rounded">
    <div class="flex-fill">
        <button type="button" class="btn btn-info">
            Rounds <span class="badge badge-light">{{totalRounds}}</span>
        </button>
    </div>
    <div class="flex-fill"><button @click="reset" class="btn btn-warning">Reset</button>
    </div>
</div>
reset(){
    this.computerScore = 0;
    this.yourScore = 0;
    this.result = '';
    this.yourWeapon = '';
    this.computerWeapon = '';
    this.totalRounds= 0;
}

This was all about implementing Rock. Paper. Scissor. Game in VueJS. Have fun playing.

Related Articles

If you like our content, please consider buying me a coffee.

Thank you for your support!

Buy me a coffeeBuy me a coffee

Join my VueJS Newsletter

As I advance in my Journey of learning VueJS, I will be working on different exercises and challenges. Subscribe to receive the latest tutorials (every week) directly in your inbox.

    I won't send you spam. Unsubscribe at any time.

    Powered By ConvertKit

    Leave a reply:

    Your email address will not be published.

    Site Footer