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;
}
相关推荐
white-persist3 分钟前
Python实例方法与Python类的构造方法全解析
开发语言·前端·python·原型模式
新中地GIS开发老师41 分钟前
Cesium 军事标绘入门:用 Cesium-Plot-JS 快速实现标绘功能
前端·javascript·arcgis·cesium·gis开发·地理信息科学
Superxpang1 小时前
前端性能优化
前端·javascript·vue.js·性能优化
左手吻左脸。1 小时前
解决el-select因为弹出层层级问题,不展示下拉选
javascript·vue.js·elementui
李白的故乡1 小时前
el-tree-select名字
javascript·vue.js·ecmascript
Rysxt_1 小时前
Element Plus 入门教程:从零开始构建 Vue 3 界面
前端·javascript·vue.js
隐含1 小时前
对于el-table中自定义表头中添加el-popover会弹出两个的解决方案,分别针对固定列和非固定列来隐藏最后一个浮框。
前端·javascript·vue.js
大鱼前端1 小时前
Turbopack vs Webpack vs Vite:前端构建工具三分天下,谁将胜出?
前端·webpack·turbopack
你的人类朋友1 小时前
先用js快速开发,后续引入ts是否是一个好的实践?
前端·javascript·后端