![](/img/trans.png)
[英]Having issues keeping score in javascript Rock, Paper, Scissors Game
[英]I made a rock paper scissors game with javascript and I'm having trouble with keeping score, I really lost
function computerPlay() { let [min, max] = [1, 3] let randomNumber = Math.floor(Math.random() * (max - min + 1)) + min; if(randomNumber == 1) return 'ROCK' else if(randomNumber == 2) return 'PAPER' else return 'SCISSORS' } function play(playerSelection, computerSelection) { let move = playerSelection; let com = computerSelection; if(move == 'ROCK' && com == 'SCISSORS') return 'ROCK beats SCISSORS'; else if(move == 'ROCK' && com == 'PAPER') return 'PAPER beats ROCK' else if(move == 'SCISSORS' && com == 'ROCK') return 'ROCK beats SCISSORS' else if(move == 'SCISSORS' && com == 'PAPER') return 'SCISSORS beat PAPER' else if(move == 'PAPER' && com == 'SCISSORS') return 'SCISSORS beat PAPER' else if(move == 'PAPER' && com == 'ROCK') return 'PAPER beats ROCK' else if(move == com) return 'DRAW' } let playBtn = document.querySelector('.play-btn'); let container1 = document.querySelector('.container1'); playBtn.addEventListener('click', makeContainer); // This is the function that creates the page that needs the player's input(rock, paper or scissors) function makeContainer() { container1.remove(); let con = document.createElement('div'); con.classList.add('container'); let h1 = document.createElement('h1'); h1.classList.add('one'); h1.textContent = 'ROCK PAPER SCISSORS'; let h12 = document.createElement('h1'); h12.classList.add('two'); h12.textContent = 'ROUND 1'; let h13 = document.createElement('h1'); h13.classList.add('three'); h13.textContent = 'MAKE YOUR MOVE'; let buttons = document.createElement('div'); buttons.classList.add('buttons'); let btn1 = document.createElement('div'); btn1.classList.add('rock'); let span = document.createElement('span'); span.textContent = 'ROCK'; btn1.append(span); let btn2 = document.createElement('div'); btn2.classList.add('paper'); let span2 = document.createElement('span'); span2.textContent = 'PAPER'; btn2.append(span2); let btn3 = document.createElement('div'); btn3.classList.add('scissors'); let span3 = document.createElement('span'); span3.textContent = 'SCISSORS'; btn3.append(span3); buttons.append(btn1, btn2, btn3); con.append(h1, h12, h13, buttons); document.body.append(con); const container = document.querySelector('.container'); const rock = document.querySelector('.rock'); const paper = document.querySelector('.paper'); const scissors = document.querySelector('.scissors'); [rock, paper, scissors].forEach((c) => c.addEventListener('click', (e) => { // console.log(e.target); containerDisappear(container, c) })); } // This function removes the makeContainer page(the one that shows rock paper scissors) and adds a transition to it function containerDisappear(con, r) { let choi = r; con.style.transitionProperty = 'opacity'; con.style.transitionDuration = '1s'; con.style.opacity = '0'; setTimeout(() => con.remove('container'), 1000); animation(choi); } // This function displays the animation that pops up after the the makeContainer page has disappeared function animation(r) { let choic = r; const waitdiv = document.createElement('div'); waitdiv.classList.add('waitdiv'); const div1 = document.createElement('div'); const div2 = document.createElement('div'); const div3 = document.createElement('div'); div1.classList.add('div1'); div2.classList.add('div2'); div3.classList.add('div3'); div1.textContent = 'ROCK...'; div2.textContent = 'PAPER...'; div3.textContent = 'SCISSORS...'; waitdiv.append(div1, div2, div3); document.body.append(waitdiv); setTimeout(() => { div1.style.transitionProperty = 'opacity'; div1.style.transitionDuration = '.6s'; div1.style.opacity = '1'; }, 600); setTimeout(() => { div2.style.transitionProperty = 'opacity'; div2.style.transitionDuration = '.6s'; div2.style.opacity = '1'; }, 1200); setTimeout(() => { div3.style.transitionProperty = 'opacity'; div3.style.transitionDuration = '.6s'; div3.style.opacity = '1'; }, 1800); setTimeout(() => { waitdiv.style.transitionProperty = 'opacity'; waitdiv.style.transitionDuration = '.3s'; waitdiv.style.opacity = '0'; waitdiv.remove(); }, 2400); setTimeout(() => { results(choic) }, 2400); } // This function displays the player's move vs the computer's move and then displays information about who lost /* Theres a 0:1 right at the bottom of this page, it's static, it doesn't update after each move, it's actually one of the things I'm struggling with */ function results(c) { const cShoot = document.createElement('div'); cShoot.classList.add('container-shoot'); const shoot = document.createElement('h1'); shoot.classList.add('shoot'); const round = document.createElement('h1'); round.classList.add('round'); const versus = document.createElement('div'); versus.classList.add('versus'); const v = document.createElement('div'); v.classList.add('v'); const h6 = document.createElement('h6'); const choice = document.createElement('div'); choice.classList.add('choice'); const vs = document.createElement('div'); vs.classList.add('v'); const v2 = document.createElement('div'); v2.classList.add('v'); const choice2 = document.createElement('div'); choice2.classList.add('choice'); const h62 = document.createElement('h6'); // ----------------second part--------------------------------------- const info = document.createElement('div'); info.classList.add('info'); const h2 = document.createElement('h2'); const h3 = document.createElement('h3'); const span = document.createElement('span'); // ---------------------third part------------------------------------ const score = document.createElement('div'); score.classList.add('score'); const span2 = document.createElement('span'); span2.classList.add('player'); const span3 = document.createElement('span'); span3.classList.add('colon'); const span4 = document.createElement('span'); span4.classList.add('com'); // ---------------------time to append stuff-------------------------------------------- cShoot.append(shoot, round, versus, info, score); versus.append(v, vs, v2); v.append(h6, choice); vs.textContent = 'VS'; v2.append(choice2, h62); info.append(h2, h3); h3.append(span); span2.textContent = '0'; span3.textContent = ':'; span4.textContent = '1'; score.append(span2, span3, span4); // ----------------adding text-------------------------------------------- shoot.textContent = 'SHOOT!!!'; round.textContent = 'ROUND 1'; h6.textContent = 'YOU'; choice.textContent = (c.classList.value == 'rock') ? 'ROCK' : c.classList.value == 'paper' ? 'PAPER' : c.classList.value == 'scissors' ? 'SCISSORS' : null; vs.textContent = 'VS'; choice2.textContent = computerPlay(); h62.textContent = 'COM'; h2.textContent = play(choice.textContent, choice2.textContent); span.textContent = s(); if(span.textContent == 'YOU WIN THIS ROUND') span.style.color = 'green'; else span.style.color = 'red' // -------------------------function------------------------------------------------- function s() { if(choice.textContent == 'ROCK' && choice2.textContent == 'SCISSORS') { return 'YOU WIN THIS ROUND' } else if(choice.textContent == 'ROCK' && choice2.textContent == 'PAPER') { return 'YOU LOSE THIS ROUND' } else if(choice.textContent == 'SCISSORS' && choice2.textContent == 'ROCK') { return 'YOU LOSE THIS ROUND' } else if(choice.textContent == 'SCISSORS' && choice2.textContent == 'PAPER') { return 'YOU WIN THIS ROUND' } else if(choice.textContent == 'PAPER' && choice2.textContent == 'SCISSORS') { return 'YOU LOSE THIS ROUND' } else if(choice.textContent == 'PAPER' && choice2.textContent == 'ROCK') { return 'YOU WIN THIS ROUND' } } // -------------------------------------------------------------------------- document.body.append(cShoot); // cShoot is the first variable that was created inside this function, it's the div tha holds everything on this page }
* { margin: 0; padding: 0; box-sizing: border-box; color: white; } body { background-color: #333; } .container { height: 100vh; text-align: center; position: relative; opacity: 1; } .buttons { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); display: flex; column-gap: 30px; } .rock { border-radius: 20px; height: 150px; width: 200px; border: 2px solid red; display: flex; align-items: center; justify-content: center; transition: transform 0.05s; } .rock:hover { cursor: pointer; transform: scale(1.05); } .paper { border-radius: 20px; height: 150px; width: 200px; border: 2px solid red; display: flex; align-items: center; justify-content: center; transition: transform 0.05s; } .paper:hover { cursor: pointer; transform: scale(1.05); } .scissors { border-radius: 20px; height: 150px; width: 200px; border: 2px solid red; display: flex; align-items: center; justify-content: center; transition: transform 0.05s; } .scissors:hover { cursor: pointer; transform: scale(1.05); } span { font-size: 22px; } .one { position: relative; top: 40px; } .two { position: relative; top: 60px; } .three { position: relative; top: 80px; font-size: 23px; } .waitdiv { display: flex; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } .div1 { opacity: 0; font-size: 75px; } .div2 { opacity: 0; font-size: 75px; } .div3 { opacity: 0; font-size: 75px; } .container-shoot { height: 100vh; text-align: center; position: relative; } .shoot { font-size: 80px; position: relative; top: 50px; } .round { position: relative; top: 55px; } .versus { display: flex; text-align: center; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 50px; width: 80%; } .v { display: flex; text-align: center; flex-basis: 100%; justify-content: space-evenly; align-items: center; } .choice { border-radius: 20px; text-align: center; border: 2px solid red; /* font-size: 30px; */ height: 100px; display: flex; align-items: center; } .info { position: absolute; bottom: 150px; left: 50%; transform: translate(-50%, -70px); } .info h3 span { color: white; } .score { position: absolute; bottom: 20px; left: 50%; transform: translate(-50%, -20px); } .score span { font-size: 70px; } .container1 { height: 100vh; position: relative; } .play-btn { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); padding: 15px 30px; cursor: pointer; color: black; font-size: 16px; border-radius: 12px; border: none; } .next { border-radius: 17px; border: none; position: absolute; left: 90%; top: 90%; transform: translate(-50%, -50%); cursor: pointer; padding: 12px 18px; color: black; }
<div class="container1"> <button class="play-btn">PLAY</button> </div>
我用 javascript 制作了一个石头剪刀布游戏,但我在记分时遇到了麻烦。 我需要一种方法来跟踪谁在玩家和计算机之间获胜,该分数应该显示在页面底部。 如果您运行整个代码(html、css 和 javascript),您将在最后一页的底部看到这个示例 我鼓励您运行整个代码
这是我的 HTML 文件:
<div class="container1"><button class="play-btn">PLAY</button></div>
这是我在 JAVASCRIPT 文件中编写的代码:
function computerPlay() {
let [min, max] = [1, 3]
let randomNumber = Math.floor(Math.random() * (max - min + 1)) + min;
if(randomNumber == 1) return 'ROCK'
else if(randomNumber == 2) return 'PAPER'
else return 'SCISSORS'
}
function play(playerSelection, computerSelection) {
let move = playerSelection;
let com = computerSelection;
if(move == 'ROCK' && com == 'SCISSORS') return 'ROCK beats SCISSORS';
else if(move == 'ROCK' && com == 'PAPER') return 'PAPER beats ROCK'
else if(move == 'SCISSORS' && com == 'ROCK') return 'ROCK beats SCISSORS'
else if(move == 'SCISSORS' && com == 'PAPER') return 'SCISSORS beat PAPER'
else if(move == 'PAPER' && com == 'SCISSORS') return 'SCISSORS beat PAPER'
else if(move == 'PAPER' && com == 'ROCK') return 'PAPER beats ROCK'
else if(move == com) return 'DRAW'
}
let arr = [];
let playBtn = document.querySelector('.play-btn');
let container1 = document.querySelector('.container1');
playBtn.addEventListener('click', makeContainer);
这是创建需要玩家输入(石头、纸或剪刀)的页面的函数
function makeContainer() {
container1.remove();
let con = document.createElement('div');
con.classList.add('container');
let h1 = document.createElement('h1');
h1.classList.add('one');
h1.textContent = 'ROCK PAPER SCISSORS';
let h12 = document.createElement('h1');
h12.classList.add('two');
h12.textContent = 'ROUND 1';
let h13 = document.createElement('h1');
h13.classList.add('three');
h13.textContent = 'MAKE YOUR MOVE';
let buttons = document.createElement('div');
buttons.classList.add('buttons');
let btn1 = document.createElement('div');
btn1.classList.add('rock');
let span = document.createElement('span');
span.textContent = 'ROCK';
btn1.append(span);
let btn2 = document.createElement('div');
btn2.classList.add('paper');
let span2 = document.createElement('span');
span2.textContent = 'PAPER';
btn2.append(span2);
let btn3 = document.createElement('div');
btn3.classList.add('scissors');
let span3 = document.createElement('span');
span3.textContent = 'SCISSORS';
btn3.append(span3);
buttons.append(btn1, btn2, btn3);
con.append(h1, h12, h13, buttons);
document.body.append(con);
const container = document.querySelector('.container');
const rock = document.querySelector('.rock');
const paper = document.querySelector('.paper');
const scissors = document.querySelector('.scissors');
[rock, paper, scissors].forEach((c) => c.addEventListener('click', (e) => {
// console.log(e.target);
containerDisappear(container, c)
}));
}
此函数删除 makeContainer 页面(显示石头剪刀布的页面)并为其添加过渡
function containerDisappear(con, r) {
let choi = r;
con.style.transitionProperty = 'opacity';
con.style.transitionDuration = '1s';
con.style.opacity = '0';
setTimeout(() => con.remove('container'), 1000);
animation(choi);
}
该函数显示makeContainer页面消失后弹出的动画
function animation(r) {
let choic = r;
const waitdiv = document.createElement('div');
waitdiv.classList.add('waitdiv');
const div1 = document.createElement('div');
const div2 = document.createElement('div');
const div3 = document.createElement('div');
div1.classList.add('div1');
div2.classList.add('div2');
div3.classList.add('div3');
div1.textContent = 'ROCK...';
div2.textContent = 'PAPER...';
div3.textContent = 'SCISSORS...';
waitdiv.append(div1, div2, div3);
document.body.append(waitdiv);
setTimeout(() => {
div1.style.transitionProperty = 'opacity';
div1.style.transitionDuration = '.6s';
div1.style.opacity = '1';
}, 600);
setTimeout(() => {
div2.style.transitionProperty = 'opacity';
div2.style.transitionDuration = '.6s';
div2.style.opacity = '1';
}, 1200);
setTimeout(() => {
div3.style.transitionProperty = 'opacity';
div3.style.transitionDuration = '.6s';
div3.style.opacity = '1';
}, 1800);
setTimeout(() => {
waitdiv.style.transitionProperty = 'opacity';
waitdiv.style.transitionDuration = '.3s';
waitdiv.style.opacity = '0';
waitdiv.remove();
}, 2400);
setTimeout(() => {
results(choic)
}, 2400);
}
此功能显示玩家的移动与计算机的移动,然后显示有关谁输了的信息 在这个页面的底部有一个 0:1,它是静态的,它不会在每次移动后更新,它实际上是我的东西之一我在挣扎
function results(c) {
const cShoot = document.createElement('div');
cShoot.classList.add('container-shoot');
const shoot = document.createElement('h1');
shoot.classList.add('shoot');
const round = document.createElement('h1');
round.classList.add('round');
const versus = document.createElement('div');
versus.classList.add('versus');
const v = document.createElement('div');
v.classList.add('v');
const h6 = document.createElement('h6');
const choice = document.createElement('div');
choice.classList.add('choice');
const vs = document.createElement('div');
vs.classList.add('v');
const v2 = document.createElement('div');
v2.classList.add('v');
const choice2 = document.createElement('div');
choice2.classList.add('choice');
const h62 = document.createElement('h6');
// ----------------second part---------------------------------------
const info = document.createElement('div');
info.classList.add('info');
const h2 = document.createElement('h2');
const h3 = document.createElement('h3');
const span = document.createElement('span');
// ---------------------third part------------------------------------
const score = document.createElement('div');
score.classList.add('score');
const span2 = document.createElement('span');
span2.classList.add('player');
const span3 = document.createElement('span');
span3.classList.add('colon');
const span4 = document.createElement('span');
span4.classList.add('com');
// ---------------------time to append stuff--------------------------------------------
cShoot.append(shoot, round, versus, info, score);
versus.append(v, vs, v2);
v.append(h6, choice);
vs.textContent = 'VS';
v2.append(choice2, h62);
info.append(h2, h3);
h3.append(span);
span2.textContent = '0';
span3.textContent = ':';
span4.textContent = '1';
score.append(span2, span3, span4);
// ----------------adding text--------------------------------------------
shoot.textContent = 'SHOOT!!!';
round.textContent = 'ROUND 1';
h6.textContent = 'YOU';
choice.textContent = (c.classList.value == 'rock') ? 'ROCK' :
c.classList.value == 'paper' ? 'PAPER' :
c.classList.value == 'scissors' ? 'SCISSORS' : null;
vs.textContent = 'VS';
choice2.textContent = computerPlay();
h62.textContent = 'COM';
h2.textContent = play(choice.textContent, choice2.textContent);
span.textContent = s();
if(span.textContent == 'YOU WIN THIS ROUND') span.style.color = 'green';
else span.style.color = 'red'
// -------------------------function-------------------------------------------------
function s() {
if(choice.textContent == 'ROCK' && choice2.textContent == 'SCISSORS') {
return 'YOU WIN THIS ROUND'
}
else if(choice.textContent == 'ROCK' && choice2.textContent == 'PAPER') {
return 'YOU LOSE THIS ROUND'
}
else if(choice.textContent == 'SCISSORS' && choice2.textContent == 'ROCK') {
return 'YOU LOSE THIS ROUND'
}
else if(choice.textContent == 'SCISSORS' && choice2.textContent == 'PAPER') {
return 'YOU WIN THIS ROUND'
}
else if(choice.textContent == 'PAPER' && choice2.textContent == 'SCISSORS') {
return 'YOU LOSE THIS ROUND'
}
else if(choice.textContent == 'PAPER' && choice2.textContent == 'ROCK') {
return 'YOU WIN THIS ROUND'
}
}
// --------------------------------------------------------------------------
document.body.append(cShoot);
// cShoot is the first variable that was created inside this function, it's the div tha holds everything on this page
}
这是我的css文件:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
color: white;
}
body {
background-color: #333;
}
.container {
height: 100vh;
text-align: center;
position: relative;
opacity: 1;
}
.buttons {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
column-gap: 30px;
}
.rock {
border-radius: 20px;
height: 150px;
width: 200px;
border: 2px solid red;
display: flex;
align-items: center;
justify-content: center;
transition: transform 0.05s;
}
.rock:hover {
cursor: pointer;
transform: scale(1.05);
}
.paper {
border-radius: 20px;
height: 150px;
width: 200px;
border: 2px solid red;
display: flex;
align-items: center;
justify-content: center;
transition: transform 0.05s;
}
.paper:hover {
cursor: pointer;
transform: scale(1.05);
}
.scissors {
border-radius: 20px;
height: 150px;
width: 200px;
border: 2px solid red;
display: flex;
align-items: center;
justify-content: center;
transition: transform 0.05s;
}
.scissors:hover {
cursor: pointer;
transform: scale(1.05);
}
span {
font-size: 22px;
}
.one {
position: relative;
top: 40px;
}
.two {
position: relative;
top: 60px;
}
.three {
position: relative;
top: 80px;
font-size: 23px;
}
.waitdiv {
display: flex;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.div1 {
opacity: 0;
font-size: 75px;
}
.div2 {
opacity: 0;
font-size: 75px;
}
.div3 {
opacity: 0;
font-size: 75px;
}
.container-shoot {
height: 100vh;
text-align: center;
position: relative;
}
.shoot {
font-size: 80px;
position: relative;
top: 50px;
}
.round {
position: relative;
top: 55px;
}
.versus {
display: flex;
text-align: center;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 50px;
width: 80%;
}
.v {
display: flex;
text-align: center;
flex-basis: 100%;
justify-content: space-evenly;
align-items: center;
}
.choice {
border-radius: 20px;
text-align: center;
border: 2px solid red;
/* font-size: 30px; */
height: 100px;
display: flex;
align-items: center;
}
.info {
position: absolute;
bottom: 150px;
left: 50%;
transform: translate(-50%, -70px);
}
.info h3 span {
color: white;
}
.score {
position: absolute;
bottom: 20px;
left: 50%;
transform: translate(-50%, -20px);
}
.score span {
font-size: 70px;
}
.container1 {
height: 100vh;
position: relative;
}
.play-btn {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 15px 30px;
cursor: pointer;
color: black;
font-size: 16px;
border-radius: 12px;
border: none;
}
.next {
border-radius: 17px;
border: none;
position: absolute;
left: 90%;
top: 90%;
transform: translate(-50%, -50%);
cursor: pointer;
padding: 12px 18px;
color: black;
}
“......我在记分方面遇到了麻烦。我需要一种方法来跟踪玩家和电脑之间谁赢了,......”
我无法具体说明 OP( O riginal Post)代码中的问题是什么,因为它太臃肿了。 我没有梳理 200 行代码并最终重写 80% 的代码,而是制作了一个行为和外观与 OP 代码相似的 roshambo 游戏(参见示例 B )。
<form>
& 表单控件
简单游戏的最佳 HTML 布局是<form>
和表单控件。 HTMLFormElement和HTMLFormControlsCollection接口允许我们使用简洁和通用的语法(参见图 IA和图 IB )
图 IA - <form>
和表单控件的简单 HTML 布局
<form id='contacts'>
<fieldset name='group'>
<label>First Name:
<input id='firstname' value='zer0'>
</label>
<label>Last Name:
<input id='lastname' value='0ne'>
</label>
</fieldset>
<fieldset name='group'>
<output id='fullname'></output>
</fieldset>
<fieldset name='group'>
<label>Phone: <input id='phone' type='tel'></label>
<button type='reset'>Reset</button>
<button>Submit</button>
</fieldset>
</form>
图 IB - DOM 接口之间的比较
客观的 | HTMLForm元素 | 常见的 DOM 方法 |
---|---|---|
<form> |
const C = document.forms.contacts |
const C = document.getElementById('contacts') |
所有表单控件 | const all = C.elements |
const all = C.querySelectorAll('fieldset, input, button') |
所有<fieldset> s |
const sets = all.group |
const sets = C.querySelectorAll('fieldset') |
获取<input id='phone'> 的值 |
let cell = all.phone.value |
let cell = C.querySelector('#phone').value |
另请参阅表单属性和方法
特别活动
还有一些专门为<form>
和表单控件制作的事件(参见图 II )。 专门的行为允许我们编写更少的代码并控制哪些元素可以做出反应以及哪些元素可以排除。 此外,重要的是要知道如何通过将事件绑定到多个原始元素(按钮、输入等)的父元素或祖先元素以及编写针对特定元素的事件处理程序来委派事件。
图二- 特别活动
事件 | 标签 | 扳机 | 行为 |
---|---|---|---|
提交 | <form> |
1. 用户专注于文本字段并点击Enter/Return键。 2. 用户点击 <button> 、 <input type='submit'> 或<input type='image'> 。3. .submit() 方法。 |
<form> 会将所有具有[name] 属性的表单控件的值发送到服务器。 如果没有服务器,那么它将返回一个空白页面。 |
重置 | <form> |
1. 用户点击type="reset" 的按钮2. .reset() 方法 |
删除用户输入的所有表单控件值 |
改变 | <form> 和表单控件❉ |
用户在表单控件上/从表单控件上输入数据或选择值然后失去焦点 | |
输入 | <form> 和表单控件❉ |
用户在表单控件上/从表单控件上输入数据或选择值 |
✳ 按钮: <button>
有或没有type
: "button"
、 "submit"
、 "reset"
和<input>
有以下type
之一: "button"
、 "submit"
、 "reset"
、 "image"
❉按钮 ✳ 和<output>
被排除在外
递增.value
属性和闭包- 参见示例 A
.value
属性的表单控件。在 #1 中,我们在函数外部定义了一个变量(可以是数字、数组的索引或来自属性的对象值等),因为一旦函数结束,内部的所有内容都会被垃圾回收,因此值必须是在函数范围之外但在函数范围内,请参阅闭包。
示例 A 和示例 B 中都有详细说明
// Define values outside of function #1 const coin = { sides: ['https://i.ibb.co/QvT4L5k/heads.png', 'https://i.ibb.co/C6Y3HKd/tails.png'], heads: 0, tails: 0 }; // Reference the <form> const UI = document.forms.toss; // Prevent normal <form> behavior during a submit event UI.onsubmit = e => e.preventDefault(); // Bind <form> to click event UI.onclick = flipCoin; // Event handler passes Event Object by default function flipCoin(e) { // Get a random number between 0 and 1 let side = Math.random() < 0.5 ? 0 : 1; // 0 or 1 // Reference the element the user clicked const clk = e.target; // Reference all form controls const IO = this.elements; /* If the user clicked input#flip... ...change it's src... ...increment coin = {heads or tails}... ...assign heads/tails value of {coin} to the <output>s */ if (clk.id === 'flip') { clk.src = coin.sides[side]; side === 0 ? coin.heads += 1 : coin.tails += 1; IO.heads.value = coin.heads; IO.tails.value = coin.tails; } }
<form id='toss'> <input id='flip' src='https://i.ibb.co/QvT4L5k/heads.png' type='image'><br> Heads: <output id='heads'></output><br> Tails: <output id='tails'></output> </form>
// Reference <form> const game = document.forms.roshambo; // Collect all <dialog> into an array const dialogs = [...document.querySelectorAll('dialog')]; // Define an object outside of functions to keep track of the score const score = { turn: 0, wins: 0, lost: 0, draw: 0 }; /* Bind the "DOMContentLoaded" event to the document When all DOM content is loaded... ...close all <dialog>s... ...open the first <dialog> */ document.addEventListener('DOMContentLoaded', function() { dialogs.forEach(d => d.close()); dialogs[0].showModal(); }) // Bind "reset" event to <form> game.onreset = phase0; // Bind "click" event to <form> game.onclick = choice; // Event handler passes Event Object by default function choice(event) { // Reference the tag the user clicked const clicked = event.target; // Reference all form controls const IO = this.elements; /* If the user clicked a [name="clear"]... ...reset all of {score}'s properties to 0... ...trigger a "reset" event on <form> */ if (clicked.name === 'clear') { for (let prop in score) { score[prop] = 0; } this.reset(); } /* If the user clicked a [name="rps"]... ...close all <dialog>... ...open the third <dialog>... ...define an array - index 0 is the value of the clicked <button> converted into a number index 1 is the result of rand() [(0-2), (0-2)]... ...call phase2() passing the array and a reference to all form controls */ if (clicked.name === 'rps') { dialogs.forEach(d => d.close()); dialogs[2].showModal(); let RPS = [parseInt(clicked.value), rand()]; phase2(RPS, IO); } } // Event handler passes the Event Object by default function phase0(event) { // Prevent the <form> from clearing out all of the <output> event.preventDefault(); // Reference all form controls const IO = this.elements; // Close all <dialog>s dialogs.forEach(d => d.close()); // Open the second <dialog> dialogs[1].showModal(); // Increment score: {turn} score.turn += 1; // call phase1() passing the reference to all form controls phase1(IO); } // Pass the reference to all form controls function phase1(IO) { // Reference all form controls in fieldset#choices const io = IO.choices.elements; // Update all <output> under fieldset#choices io.round.value = score.turn; io.wins.value = score.wins; io.lost.value = score.lost; io.draw.value = score.draw; } // Pass the array of numbers and the reference to all form controls function phase2(RPS, IO) { // Define an array of strings const text = ['ROCK..., ', 'PAPER..., ', 'SCISSORS... ']; // Define a number that will be the base amount of ms for timeouts let time = 600; // Call animate() passing array, a selector of tag to append to, and time animate(text, '#animation h1', time); // Call phase3() passing what phase2() passed on the calculated time setTimeout(() => { phase3(RPS, IO); }, (text.length + 4) * time); } // Pass array and reference function phase3(RPS, IO) { // Close all <dialog>s dialogs.forEach(d => d.close()); // Open the fourth <dialog> dialogs[3].showModal(); // Call outcome() passing the array and reference outcome(RPS, IO); } // Displays 'ROCK..., ', 'PAPER..., ', 'SCISSORS... ' at timed intervals function delay(array, title, time) { array.forEach((segment, index) => { setTimeout(() => { const tag = document.createElement('b'); tag.textContent = segment; tag.className = 'fadeIn'; title.append(tag); }, index * time); }); } // Runs delay() and animates "GO!" function animate(array, selector, time = 1000) { const title = document.querySelector(selector); delay(array, title, time); setTimeout(() => { title.replaceChildren(); title.insertAdjacentHTML('beforeend', `<b class='zoom'>GO!</b>`); }, (array.length + 1) * time); setTimeout(() => { title.className = 'fadeOut'; title.replaceChildren(); }, (array.length + 3) * time); title.className = ''; } // Returns a random number in the range of 0-2 function rand() { return Math.floor(Math.random() * 2) + 1; } // Pass the numbers derived from choice(e) function play(pick, comp) { // This is a ternary expression - an abbreviated if/else statement return pick === comp // if user's num equals cpu's num ? 0 // return 0 : comp === pick - 1 // if cpu's num is 1 less than user's num ? 1 // return 1 : comp === 2 && pick === 0 // if cpu num is 2 AND user's num is 0 ? 1 // return 1 : -1; // else return -1 } // Pass the array and reference function outcome(RPS, IO) { // Define an array of RPS const played = ['🪨 Rock', '🧻 Paper', '✂️ Scissors']; // Reference all form controls under fieldset#outcome const io = IO.outcome.elements; // Get the return of play() passing the two numbers of the given array let wld = play(RPS[0], RPS[1]); // Assign values to the <output>s io.you.value = played[RPS[0]]; io.cpu.value = played[RPS[1]]; io.round.value = score.turn; io.draw.value = score.draw; io.wins.value = score.wins; io.lost.value = score.lost; // Determine what will be displayed by the return of play() switch (wld) { case 0: score.draw += 1; io.draw.value = score.draw; io.message.value = "It's a Draw"; io.vs.value = "Ties with"; break; case 1: score.wins += 1; io.wins.value = score.wins; io.message.value = "You Win"; io.vs.value = "Beats"; break; case -1: score.lost += 1; io.lost.value = score.lost; io.message.value = "You Lose"; io.vs.value = "is Beaten by"; break; default: break; } }
@import url('https://fonts.googleapis.com/css2?family=Oswald:wght@300&family=Raleway:wght@500&display=swap'); @keyframes click { 0% { transform: scale(1.0); } 50% { transform: scale(0.9); } 100% { transform: scale(1.0); } } @keyframes fadeIn { 0% { opacity: 0; } 100% { opacity: 1; } } @keyframes fadeOut { 0% { opacity: 1; } 100% { opacity: 0; } } @keyframes zoom { 0% { transform: scale(1); } 100% { transform: scale(4); } } * { margin: 0; padding: 0; box-sizing: border-box; } html, body { height: 100%; } html { font: 300 4vmin/1 Oswald; } body { background-color: #333; color: #fff; } form { position: relative; min-height: 100%; } dialog { position: absolute; top: 20%; left: 50%; display: flex; flex-flow: column nowrap; justify-content: center; align-items: center; min-height: 50vh; border-color: transparent; background-color: #333; transform: translate(-50%); overflow: hidden; } dialog::backdrop { background-color: #333; } .phase { display: flex; flex-flow: column nowrap; justify-content: center; align-items: center; gap: 1rem; min-width: 70vw; padding: 1rem; border-color: transparent; color: #fff; } .buttons { display: flex; flex-flow: row nowrap; justify-content: space-around; align-items: center; gap: 1rem; padding: 1rem; border-color: transparent; } legend { display: flex; flex-flow: column nowrap; justify-content: center; align-items: center; gap: 1rem; margin-left: 50%; padding: 1rem; color: #fff; transform: translateX(-50%); } h1, h2, h3 { font-family: Raleway; white-space: nowrap; } h1 { font-size: 2.5rem; } h2 { font-size: 2.25rem; } h3 { font-size: 1.75rem; } .score { display: flex; justify-content: space-evenly; align-items: center; min-width: 100%; } output, b { display: inline-block; } output::after { content: attr(value); } .wins::before { content: 'Won '; } .lost::before { content: 'Lost '; } .draw::before { content: 'Draw '; } button { display: inline-flex; flex-flow: row nowrap; justify-content: center; align-items: center; height: 4rem; width: 10rem; border: 0.2rem solid red; border-radius: 2rem; color: #fff; font: inherit; font-size: 2rem; font-variant: small-caps; background-color: #333; cursor: pointer; } button:hover { background-color: #fff; color: red; } button:active { animation: click 0.3s forwards; } button:focus { outline: 0; } .fadeIn { animation: fadeIn 0.6s ease-out; } .fadeOut { animation: fadeOut 0.6s ease-in; } .zoom { animation: zoom 0.5s ease-out forwards; } .number { font-family: Consolas; }
<form id="roshambo"> <dialog> <fieldset id='start' class='phase'> <button name='continue' type="reset">Play</button> </fieldset> </dialog> <dialog> <fieldset id='choices' class='phase'> <legend> <h1>Rock, Paper, Scissors</h1> <h2>Round <output name='round' class='number'></output> </h2> <h3>Make Your Move</h3> <h3 class='score'> <b class='wins'> <output name='wins' class='number'></output> </b> <b class='lost'> <output name='lost' class='number'></output> </b> <b class='draw'> <output name='draw' class='number'></output> </b> </h3> </legend> <fieldset class='buttons'> <button name='rps' value='0' type='button'>🪨 Rock</button> <button name='rps' value='1' type='button'>🧻 Paper</button> <button name='rps' value='2' type='button'>✂️ Scissors</button> </fieldset> </fieldset> </dialog> <dialog> <fieldset id='animation' class='phase'> <legend> <h1></h1> </legend> </fieldset> </dialog> <dialog> <fieldset id='outcome' class='phase'> <legend> <h1><output id='message'></output></h1> <h2>Round <output name='round' class='number'></output></h2> <h3>Your <output id='you'></output> <output id='vs'></output> Your Opponent's <output id='cpu'></output> </h3> <h3 class='score'> <b class='wins'> <output name='wins' class='number'></output> </b> <b class='lost'> <output name='lost' class='number'></output> </b> <b class='draw'> <output name='draw' class='number'></output> </b> </h3> </legend> <fieldset class='buttons'> <button name='continue' type='reset'>Continue</button> <button name='clear' type='reset'>Clear</button> </fieldset> </fieldset> </dialog> </form>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.