I am a beginner in react and I can't get my rock paper scissors to work.
I am trying to update my react useState variable but it doesn't work. The variable I am trying to update is opponentImage every time I update it, it stays the same. Tried searching the web but got a bit desperate of chatgpt and other sources so thought i would give a try to ask a question. Would be glad if you explain how can I avoid this in the future.
here is the code:
import rockImage from '../assets/rock.png'
import paperImage from '../assets/paper.png'
import scissorsImage from '../assets/scissors.png'
import gsap from 'gsap';
import { forwardRef, useEffect, useState } from 'react'
import Snackbar from '@mui/material/Snackbar';
import MuiAlert from '@mui/material/Alert';
const Alert = forwardRef(function Alert(props, ref) {
return <MuiAlert elevation={6} ref={ref} variant="filled" {...props} />;
});
function RPScissors() {
const [opponentImage, setOpponentImage] = useState();
//
const [openSuccess, setOpenSuccess] = useState(false);
const [openFailed, setOpenFailed] = useState(false);
const [openTie, setOpenTie] = useState(false);
const handleClose = () => {
setOpenSuccess(false)
setOpenFailed(false)
setOpenTie(false)
};
const endGame = (user, opponent) => {
const wonGame =
(user === 'rock' && opponent === 'scissors') ? 1 :
(user === 'rock' && opponent === 'paper') ? 0 :
(user === 'paper' && opponent === 'rock') ? 1 :
(user === 'paper' && opponent === 'scissors') ? 0 :
(user === 'scissors' && opponent === 'paper') ? 1 :
(user === 'scissors' && opponent === 'rock') ? 0 : 2
;
wonGame === 1 ? setOpenSuccess(true) : wonGame === 0 ? setOpenFailed(true): setOpenTie(true);
console.log(`won game: ${wonGame} and opponent image: ${opponentImage}`)
// setTimeout(() => {
// handleReset();
// },4000)
}
const handleReset = () =>{
console.log(`reset`)
setOpponentImage();
}
const handleSelectItem = (selectedItem) => {
//selectedItem is rock paper or scissors
const toX = selectedItem === 'rock' ? 300 : selectedItem === 'paper' ? -150 : -600;
gsap.to(`#${selectedItem}`, {
x: toX,
duration: 2,
ease: 'bounce.out',
})
const arr = selectedItem === 'paper' ? ['rock', 'scissors'] : selectedItem === 'scissors' ? ['rock', 'paper'] : ['paper', 'scissors'];
gsap.to(`#${arr[0]},#${arr[1]}`, {
duration: 0.5,
opacity: 0,
y: -100,
stagger: 0.1,
ease: "back.in"
});
const num = Math.ceil(Math.random() * 3);
const opponentElement = num === 1 ? 'rock' : num === 2 ? 'paper' : 'scissors';
setOpponentImage(opponentElement === 'rock' ? rockImage : opponentElement === 'paper' ? paperImage : scissorsImage)
console.log(`rnd num: ${num}, opponent element: ${opponentElement} opponent image: ${opponentImage}`)
gsap.fromTo('#opponent', { y: 400, },
{
y: 0
, ease: 'bounce.out'
, duration: 1
})
endGame(selectedItem, opponentElement);
}
return (
<>
<Snackbar
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
open={openSuccess}
onClick={() => handleClose()}
autoHideDuration={1000}
>
<Alert severity="success" sx={{ width: '100%' }}>
Won!
</Alert>
</Snackbar>
<Snackbar
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
open={openTie}
onClick={() => handleClose()}
autoHideDuration={1000}
>
<Alert severity="warning" sx={{ width: '100%' }}>
Tie!
</Alert>
</Snackbar>
<Snackbar
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
open={openFailed}
onClose={() => handleClose()}
autoHideDuration={1000}
>
<Alert severity="error" sx={{ width: '100%' }}>
Lose!!
</Alert>
</Snackbar>
<div className="container mx-auto">
<div className="row">
<div className="col">
<div className="mx-auto" id="rock" onClick={() => handleSelectItem('rock')}>
<img src={rockImage} />
</div>
</div>
<div className="col ">
<div className="mx-auto" id="paper" onClick={() => handleSelectItem('paper')}>
<img src={paperImage} />
</div>
</div>
<div className="col">
<div className="mx-auto" id="scissors" onClick={() => handleSelectItem('scissors')}>
<img src={scissorsImage} />
</div>
</div>
<div className={`col d-none ${opponentImage ? 'visible' : 'invisible'}`}>
<div id='opponent'>
<img src={opponentImage} />
</div>
</div>
</div>
</div>
</>
)
}
export default RPScissors;