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="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

功能流程图

三个按钮可以分为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的随机数

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);

【JS入门小游戏】01-骰子游戏的更多相关文章

  1. React.js入门小案例

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title&g ...

  2. 背包DP入门小笔记01背包

    FJUT OJ 2347 http://59.77.139.92/Problem.jsp?pid=2347 采药 TimeLimit:1000MS  MemoryLimit:128MB 64-bit ...

  3. pixi.js 微信小游戏 入手

    pixi是什么?一款h5游戏引擎 优点:简单简洁性能第一 缺点:大多数用的国产三大引擎,pixi资料少,工具少, 为什么学,装逼 用pixi开发小游戏行吗? 行.但要简单处理下 下载官网上的 weap ...

  4. JS扫雷小游戏

    HTML代码 <title> 扫雷 </title> <!-- ondragstart:防拖拽生成新页面 oncontextmenu:屏蔽右键菜单--> <b ...

  5. js实现web网页版台球游戏

    js桌球小游戏在线试玩地址:http://keleyi.com/game/13/ 游戏截图: 完整代码,保存到html文件可以试玩: <!DOCTYPE html PUBLIC "-/ ...

  6. HTML5+JS 《五子飞》游戏实现(八)人机对战

    要想实现人机对战,就必须让电脑自动下棋,而且要知道自动去查找对方的棋子,看看有没有可以挑一对的,有没有可以夹一个的,这样下起来才有意思. 当电脑用户下完棋后,电脑应立即搜索用户的棋子,然后如果没有被吃 ...

  7. HTML5+JS 《五子飞》游戏实现(七)游戏试玩

    前面第一至第六章我们已经把<五子飞>游戏的基本工作都已经讲得差不多了,这一章主要是把所有的代码分享给大家,然后小伙伴们也可以玩一玩. 至于人机对战的我们放到后面讲进行分析. 试玩地址:ht ...

  8. HTML5+JS 《五子飞》游戏实现(三)页面和棋盘棋子

    前面两节,我们已经对<五子飞>有个初步的认识,对走棋路线也有了基本的了解,现在里沃特继续跟大家分享HTML页面,另外把棋盘棋子也画出来. 演示地址:http://www.lyout.com ...

  9. 微信小程序开发的游戏《拼图游戏》

    微信小程序开发的游戏<拼图游戏> 代码直接考进去就能用 pintu.js // pintu.js Page({ /** * 页面的初始数据 */ data: { }, initGame: ...

  10. 课后作业机票,赌骰子游戏,switch的使用实例

    一,课后第三题机票 package com.bd22; import java.util.Scanner; public class AirTicket { public static void ma ...

随机推荐

  1. 【Java EE】Day12 XML、约束(DTD、Schema)、解析方式、Jsoup、选择器(Selector、XPath)

    一.XML介绍 1.概述 Extensible Markup Language--可扩展标记语言 标记语言 :标签构成 可扩展:可以自定义标签 2.功能 存储数据 作为配置文件使用 作为数据载体在网络 ...

  2. 解决笔记本安装centos7后无法调节屏幕亮度

    起因:本人有台老古董笔记本,大约是10年前左右了,三星rv411,配置较低无法安装win7以上的系统.装个CentOS7正好可以拿来学习Linux系统. 但是遇到一个特别恶心的情况,笔记本上调节屏幕亮 ...

  3. python 异步写入文件

    # -*- coding:utf-8 -*-import asyncioimport aiofilesimport time#异步操作时,函数名前必须加上asyncasync def func1(): ...

  4. 一文带你入木三分地理解字符串KMP算法(next指针解法)

    1. KMP算法简介 温馨提示:在通篇阅读完并理解后再看简介效果更佳 以下简介由百度百科提供https://baike.baidu.com/item/KMP%E7%AE%97%E6%B3%95/109 ...

  5. jQuery基本使用

    目录 一:jQuery查找标签 1.基本选择器 二:分组与嵌套 三:组合选择器 四:jQuery基本筛选器 五:属性选择器 1.属性标签 六:JQuery表单筛选器 1.type属性 2.表单对象属性 ...

  6. Linux 下使用Docker 安装 LNMP环境 超详细

    首先在阿里云购买了一台服务器 选择了华南-深圳地区 操作系统选用了 CentOS8.0 64位 1. 初始化账号密码 登陆xshell,开始装Docker 一.安装docker 1.Docker 要求 ...

  7. Redis的数据持久化

    介绍 Redis 的数据持久化方案 Redis 的数据持久化主要有两大机制,AOF 日志和 RDB 快照. AOF 持久化是通过保存 Redis 服务器所执行的写命令来记录数据库状态. RDB 持久化 ...

  8. 【机器学习】李宏毅——Flow-based Generative Models

    前文我介绍了部分关于生成学习的内容,可以参考我这篇博文点此 前面介绍的各个生成模型,都存在一定的问题: 对于PixelRNN这类模型来说,就是从左上角的像素开始一个个地进行生成,那么这个生成顺序是否合 ...

  9. 【转载】七个人生工具,终生受益 | SWOT、PDCA、6W2H、SMART、WBS、时间管理、二八原则

    人类历史原本就是一部追求自身平衡的奋斗史,本文介绍七个人生工具:SWOT.PDCA.6W2H.SMART.WBS.时间管理.二八原则 . 1.SWOT分析法 Strengths:优势 Weakness ...

  10. Shiro-721反序列化漏洞

    漏洞名称 Shiro-721(Apache Shiro Padding Oracle Attack)反序列化 利用条件 Apache Shiro < 1.4.2 漏洞原理 Apache Shir ...