【JS入门小游戏】01-骰子游戏

  • 【JS入门小游戏】01-骰子游戏已关闭评论
  • 110 次浏览
  • A+
所属分类:Web前端
摘要

游戏出自Udemy的JS课程中提到的一个游戏,课程主要是对JS部分进行详细的从0开始的讲解,本篇文章是对整个游戏的分析,包括HTMK,CSS和JS,也主要对JS进行刨析。


01-骰子游戏

游戏出自Udemy的JS课程中提到的一个游戏,课程主要是对JS部分进行详细的从0开始的讲解,本篇文章是对整个游戏的分析,包括HTMK,CSS和JS,也主要对JS进行刨析。

游戏链接:https://pig-game-v2.netlify.app/

游戏规则:开始玩家1点击ROLL DICE开始投掷骰子,如果点数为2-6,计入当前得分并可以继续投掷并累加得分到当前得分,如果点数为1,直接结束本轮交换到玩家2并清空已有当前得分,在途中可以主动选择HOLD按钮保持当前得分到个人总分,并结束本轮交换到玩家2开始游戏;两个玩家依次交换并累计总分,直到一方总分达到100分结束游戏。点击New Game可以重新开始游戏。

HTML

HTML的部分比较简单,基本布局为body>main>(section×2>h2+p2+div)+img+button×3,即:

  <main>     <section>       <h2></h2>       <p2></p2>       <div></div>     </section>     <section>       <h2></h2>       <p2></p2>       <div></div>     </section>     <img src="" alt="">     <button></button>     <button></button>     <button></button>   </main> 

加入类和id的详细描述

  <main>     <!-- 玩家1 -->     <section class="player player--0 player--active">       <h2 class="name" id="name--0">PLAYER 1</h2>       <!-- 总得分 -->       <p2 class="score" id="score--0">0</p2>       <div class="current">         <p class="current-label">CURRENT</p>         <!-- 当前轮得分 -->         <p class="current-score" id="current--0">0</p>       </div>     </section>     <!-- 玩家2 -->     <section>       <h2 class="name" id="name--1">PLAYER 2</h2>       <p2 class="score" id="score--1">0</p2>       <div class="current">         <p class="current-label">CURRENT</p>         <p class="current-score" id="current--1">0</p>       </div>     </section>     <!-- 显示骰子 -->     <img src="dice-1.png" alt="【JS入门小游戏】01-骰子游戏" alt="dice" class="dice">     <button class="btn btn--new">NEW GAME</button>     <button class="btn btn--dice">ROLL DICE</button>     <button class="btn btn--hold">HOLD</button>     <script src="script.js"></script>   </main> 

CSS

@import url('https://fonts.googleapis.com/css2?family=Nunito&display=swap');  * {   margin: 0;   padding: 0;   box-sizing: inherit; }  html {   font-size: 62.5%;   box-sizing: border-box; }  body {   font-family: 'Nunito', sans-serif;   font-weight: 400;   height: 100vh;   color: #333;   background-image: linear-gradient(to top left, #753682 0%, #bf2e34 100%);   display: flex;   align-items: center;   justify-content: center; }  main {   position: relative;   width: 100rem;   height: 60rem;   background-color: rgba(255, 255, 255, 0.35);   backdrop-filter: blur(200px);   filter: blur();   box-shadow: 0 3rem 5rem rgba(0, 0, 0, 0.25);   border-radius: 9px;   overflow: hidden;   display: flex; }  .player {   flex: 50%;   padding: 9rem;   display: flex;   flex-direction: column;   align-items: center;   transition: all 0.75s; }  .name {   position: relative;   font-size: 4rem;   text-transform: uppercase;   letter-spacing: 1px;   word-spacing: 2px;   font-weight: 300;   margin-bottom: 1rem; }  .score {   font-size: 8rem;   font-weight: 300;   color: #c7365f;   margin-bottom: auto; }  .player--active {   background-color: rgba(255, 255, 255, 0.4); } .player--active .name {   font-weight: 700; } .player--active .score {   font-weight: 400; }  .player--active .current {   opacity: 1; }  .current {   background-color: #c7365f;   opacity: 0.8;   border-radius: 9px;   color: #fff;   width: 65%;   padding: 2rem;   text-align: center;   transition: all 0.75s; }  .current-label {   text-transform: uppercase;   margin-bottom: 1rem;   font-size: 1.7rem;   color: #ddd; }  .current-score {   font-size: 3.5rem; }  .btn {   position: absolute;   left: 50%;   transform: translateX(-50%);   color: #444;   background: none;   border: none;   font-family: inherit;   font-size: 1.8rem;   text-transform: uppercase;   cursor: pointer;   font-weight: 400;   transition: all 0.2s;    background-color: white;   background-color: rgba(255, 255, 255, 0.6);   backdrop-filter: blur(10px);    padding: 0.7rem 2.5rem;   border-radius: 50rem;   box-shadow: 0 1.75rem 3.5rem rgba(0, 0, 0, 0.1); }  .btn::first-letter {   font-size: 2.4rem;   display: inline-block;   margin-right: 0.7rem; }  .btn--new {   top: 4rem; } .btn--roll {   top: 39.3rem; } .btn--hold {   top: 46.1rem; }  .btn:active {   transform: translate(-50%, 3px);   box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.15); }  .btn:focus {   outline: none; }  .dice {   position: absolute;   left: 50%;   top: 16.5rem;   transform: translateX(-50%);   height: 10rem;   box-shadow: 0 2rem 5rem rgba(0, 0, 0, 0.2); }  .player--winner {   background-color: #2f2f2f; }  .player--winner .name {   font-weight: 700;   color: #c7365f; } .hidden{   display: none; }  

其中值得关注的几个效果:

backdrop-filter属性允许您对元素后面的区域执行,诸如"模糊"或"改变颜色"等效果。因为它适用于元素后面的所有内容, 所以要查看效果, 必须使元素或其背景至少部分透明。

backdrop-filter: blur(200px);//使得后面的变模糊200px 

letter-spacing字间距:添加每个字母或汉字之间的空白

word-spacing词间距:增加或减少字与字之间的空白

text-transform

描述
none 默认。定义带有小写字母和大写字母的标准的文本。
capitalize 文本中的每个单词以大写字母开头。
uppercase 定义仅有大写字母。
lowercase 定义无大写字母,仅有小写字母。
inherit 规定应该从父元素继承 text-transform 属性的值。

按钮按下动效

.btn:active {   transform: translate(-50%, 3px);//按下下移3px   box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.15);//按下加入阴影 } 

JS

功能流程图

【JS入门小游戏】01-骰子游戏

三个按钮可以分为3个功能:

  1. 投掷骰子:根据随机数产生1-6随机数后显示对应点数图片,并判断是否为1,为1交换玩家;不为1,点数累计入当前分并更新当前分。
  2. 保持分数:将当前累计得分计入到总分后判断是否满足达到100,没有交换玩家,有则结束游戏。
  3. 点击新游戏:将所有当前得分与总分归0,重新设置玩家1为当前玩家。

模块思想

函数封装复用

由流程图可见,在投掷骰子和保持分数功能中都可能执行到交换玩家的流程,因此将交换玩家作为一个自定函数来实现复用,另外涉及重新开始新游戏功能,游戏初始化也可作为函数复用。

代码

首先获取其中之后需要的元素,包括:

  1. 一张骰子图片;
  2. 两个玩家,玩家1,玩家2;
  3. 三个按钮,上文依次提到过;
  4. 四个分数,依次为玩家1当前得分,玩家1总分,玩家2当前得分,玩家2总分;
const diceEl = document.querySelector('.dice'); const player0El = document.querySelector('.player--0'); const player1El = document.querySelector('.player--1'); const btnNew = document.querySelector('.btn--new'); const btnRoll = document.querySelector('.btn--roll'); const btnHold = document.querySelector('.btn--hold'); const score0El = document.querySelector('#score--0'); const score1El = document.querySelector('#score--1'); const current0El = document.querySelector('#current--0'); const current1El = document.querySelector('#current--1'); 

init()初始化函数

let scores, currentScore, activePlayer;//分别为总分,当前得分,目前在玩玩家 let playing;//用于判断游戏是否结束 const init = function () {   scores = [0, 0]; //两队比分   currentScore = 0;   activePlayer = 0;//初始玩家1为在玩玩家   playing = true;    current0El.textContent = 0;   current1El.textContent = 0;   score0El.textContent = 0;   score1El.textContent = 0;    diceEl.classList.add('hidden');//hidden内容为display:none;开始添加hidden为不显示图片   player0El.classList.remove('player--winner');//以下四个为初始化类,winner为胜利类,active为当前在玩类   player1El.classList.remove('player--winner');   player0El.classList.add('player--active');   player1El.classList.remove('player--active'); }; init(); 

投掷骰子功能

通过模板文字根据不同数字显示不同点数图片

diceEl.src = `dice-${dice}.png`;//dice为1-6的随机数 

【JS入门小游戏】01-骰子游戏

exchange()交换玩家

const exchange = function () {   document.getElementById(`current--${activePlayer}`).textContent = 0;//交换前恢复先前玩家当前得分   activePlayer = 1 - activePlayer;//玩家0,1切换   currentScore = 0;//重新设置当前得分   document.getElementById(`current--${activePlayer}`).textContent =     currentScore;//更新当前玩家的当前分数   player0El.classList.toggle('player--active');//toggle方法为若有该类则删除,无该类则添加   player1El.classList.toggle('player--active'); }; 
btnRoll.addEventListener('click', function () {   if (playing) {//游戏未结束     const dice = Math.trunc(Math.random() * 6) + 1;     diceEl.classList.remove('hidden');     diceEl.src = `dice-${dice}.png`;      if (dice !== 1) {       currentScore += dice;       document.getElementById(`current--${activePlayer}`).textContent =         currentScore;//更新当前玩家的当前分数     } else {       exchange();//交换玩家     }   } }); 

保持分数功能

btnHold.addEventListener('click', function () {   if (playing) {     scores[activePlayer] += currentScore;//添加到对应玩家总分     document.getElementById(`score--${activePlayer}`).textContent =       scores[activePlayer];//更新总分     if (scores[activePlayer] >= 100) {       playing = false;       document         .querySelector(`.player--${activePlayer}`)         .classList.add('player--winner');       document         .querySelector(`.player--${activePlayer}`)         .classList.remove('player--active');       diceEl.classList.add('hidden');     } else {       exchange();     }   } }); 

重新开始游戏

btnNew.addEventListener('click', init);