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;
}
相关推荐
小小小小宇14 分钟前
前端模拟一个setTimeout
前端
萌萌哒草头将军18 分钟前
🚀🚀🚀 不要只知道 Vite 了,可以看看 Farm ,Rust 编写的快速且一致的打包工具
前端·vue.js·react.js
芝士加1 小时前
Playwright vs MidScene:自动化工具“双雄”谁更适合你?
前端·javascript
Carlos_sam2 小时前
OpenLayers:封装一个自定义罗盘控件
前端·javascript
前端南玖2 小时前
深入Vue3响应式:手写实现reactive与ref
前端·javascript·vue.js
wordbaby3 小时前
React Router 双重加载器机制:服务端 loader 与客户端 clientLoader 完整解析
前端·react.js
itslife3 小时前
Fiber 架构
前端·react.js
3Katrina3 小时前
妈妈再也不用担心我的课设了---Vibe Coding帮你实现期末课设!
前端·后端·设计
hubber3 小时前
一次 SPA 架构下的性能优化实践
前端
可乐只喝可乐3 小时前
从0到1构建一个Agent智能体
前端·typescript·agent