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.