JS-石头剪刀布

一、前言

  • js小玩具
  • 两种模式,内置循环重置
  • 全随机,无结果干预

二、效果及素材

效果

素材

三、代码注释详解

js

xml 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<title>石头剪刀布</title>
</head>
<link rel="stylesheet" href="./style/石头剪刀布.css">

<body>
	<div class="box">
		<div class="select-mode">
			<div class="select-mode-label">模式选择:</div>
			<select name="mode" id="select" onchange="changeMode()">
				<option value="once">单局模式</option>
				<option value="twice">三局两胜</option>
			</select>
		</div>
		<h2 class="title">石头剪刀布</h2>
		<div class="game-region">
			<div class="left-box">
				<img src="./imgs/剪刀.png" alt="">
				<div class="role">用户 (胜场: <span class="user-num" :data-num="0">0</span>)</div>
			</div>
			<div>
				<img src="./imgs/vs.png" alt="">
			</div>
			<div class="right-box">
				<img src="./imgs/剪刀.png" alt="">
				<div class="role">电脑 (胜场: <span class="computer-num" :data-num="0">0</span>)</div>
			</div>
		</div>
		<div class="operate">
			<button class="start btn" onclick="start()">开始</button>
			<button class="reset btn" onclick="init()">重置</button>
		</div>
	</div>
</body>
<script>
	// 模式下拉
	let select = document.querySelector('#select')
	/**
	* 设置默认模式为:三局两胜
	* 单局模式: once
	* 三局两胜: twice
	*/
	select.value = 'twice';
	// 用户胜场
	let userNum = document.querySelector('.user-num')
	// 电脑胜场
	let computerNum = document.querySelector('.computer-num')
	// 用户图片
	let userImg = document.querySelector('.left-box img')
	// 电脑图片
	let computerImg = document.querySelector('.right-box img')
	// 图片路径数组
	let srcList = ['./imgs/剪刀.png', './imgs/石头.png', './imgs/布.png']
	// 开始/停止
	let startBtn = document.querySelector('.start')
	// 提示词
	let title = document.querySelector('.title')
	// 下拉变动
	function changeMode() {
		// console.log(select.value);
		init()
	}
	// 随机数
	function randomNum() {
		return Math.floor(Math.random() * 3)
	}
	// 定时器
	let timer = null
	// 开始/停止
	let startFlag = 'start'
	// 开始/停止
	function start() {
		title.innerHTML = '石头剪刀布'
		if (startFlag === 'start') {
			if (resultFlag === 'end') init()
			// 点击时为开始
			// 状态及文字置反
			// 开启定时器随机变化
			startFlag = 'stop'
			startBtn.innerHTML = '停止'
			timer = setInterval(() => {
				userImg.dataset.desc = randomNum()
				userImg.src = srcList[userImg.dataset.desc]
				computerImg.dataset.desc = randomNum()
				computerImg.src = srcList[computerImg.dataset.desc]
			}, 200)
		} else {
			// 点击时为停止
			// 状态及文字置反
			// 清除定时器并置空
			startFlag = 'start'
			startBtn.innerHTML = '开始'
			clearInterval(timer)
			timer = null
			judgeResult()
		}
	}
	// 结果
	let resultFlag = 'afoot'
	// 胜负判断
	function judgeResult() {
		const userChoice = userImg.dataset.desc
		const computerChoice = computerImg.dataset.desc
		// console.log(userChoice, 'userChoice');
		// console.log(computerChoice, 'computerChoice');
		let result = userChoice - computerChoice
		// console.log(result, 'result');// 0平局 1 -2用户胜利 
		if (result === 0) {
			title.innerHTML = '平局'
		} else if (result === 1 || result === -2) {
			title.innerHTML = '用户胜利'
			userNum.innerHTML = Number(userNum.innerHTML) + 1
			console.log(userNum.innerHTML, 'userNum.innerHTML');

		} else {
			title.innerHTML = '电脑胜利'
			computerNum.innerHTML = Number(computerNum.innerHTML) + 1
			console.log(computerNum.innerHTML, 'computerNum.innerHTML');
		}
		stop()
	}
	// 文字判定逻辑终止
	function stop() {
		if (select.value === 'twice') {
			// 三局两胜且胜场为2
			if (Number(userNum.innerHTML) === 2 || Number(computerNum.innerHTML) === 2) {
				resultFlag = 'end'
				showResultAlert()
			}
		} else {
			// 单局模式且胜场为1
			if (Number(userNum.innerHTML) === 1 || Number(computerNum.innerHTML) == 1) {
				resultFlag = 'end'
				showResultAlert()
			}
		}
	}
	// 显示结果弹窗
	function showResultAlert() {
		setTimeout(() => {
			alert('本局' + title.textContent);
		}, 0);
	}
	// 初始化
	function init() {
		userNum.innerHTML = 0
		computerNum.innerHTML = 0
		userImg.src = srcList[0]
		computerImg.src = srcList[0]
		resultFlag = 'afoot'
		title.innerHTML = '石头剪刀布'
	}
	init()
</script>

</html>

css

css 复制代码
.box {
  width: 100%;
  padding-top: 20px;
}
.box .title {
  color: #f4ea2a;
  text-align: center;
}
.box .select-mode {
  margin: 0 auto;
  display: flex;
  justify-content: center;
  align-items: center;
}
.box .game-region {
  width: 400px;
  height: 150px;
  margin: 20px auto 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.box .game-region img {
  width: 100px;
  height: 100px;
  transition: transform 0.1s ease;
}
.box .game-region .role {
  color: #f4ea2a;
}
.box .operate {
  width: 400px;
  height: 100px;
  margin: 0 auto;
  display: flex;
  justify-content: center;
  align-items: center;
}
.box .operate .btn {
  width: 100px;
  height: 40px;
  border-radius: 5%;
  background-color: #f4ea2a;
  border: none;
  color: #fff;
  margin-left: 10px;
}
.box .operate .btn:hover {
  cursor: pointer;
}
相关推荐
Nan_Shu_6141 小时前
Web前端面试题(2)
前端
知识分享小能手1 小时前
React学习教程,从入门到精通,React 组件核心语法知识点详解(类组件体系)(19)
前端·javascript·vue.js·学习·react.js·react·anti-design-vue
蚂蚁RichLab前端团队2 小时前
🚀🚀🚀 RichLab - 花呗前端团队招贤纳士 - 【转岗/内推/社招】
前端·javascript·人工智能
孩子 你要相信光2 小时前
css之一个元素可以同时应用多个动画效果
前端·css
萌萌哒草头将军2 小时前
Oxc 和 Rolldown Q4 更新计划速览!🚀🚀🚀
javascript·vue.js·vite
huangql5203 小时前
npm 发布流程——从创建组件到发布到 npm 仓库
前端·npm·node.js
Qlittleboy3 小时前
uniapp如何使用本身的字体图标
javascript·vue.js·uni-app
Days20503 小时前
LeaferJS好用的 Canvas 引擎
前端·开源
小白菜学前端3 小时前
vue2 常用内置指令总结
前端·vue.js
林_深时见鹿3 小时前
Vue + ElementPlus 自定义指令控制输入框只可以输入数字
前端·javascript·vue.js