Hello, For reasons of readability I do not add the entirety of my code, so don't panic if you don't see a piece of code called somewhere here.
Problem Summary: I'm drawing in a canvas and displaying the player's ping and fps by updating the ServerInfos component from a requestAnimationFrame, and this results in blocking my move because it's reloading my current component where my canvas
Any help or advice is also welcome! :)
Screen for you to understand the component we are talking about and what it is used for: click for see my screen
ServerInfos component code:
export default function ServerInfos({props}) {
const {left, top, ping, fps} = props
const changeColorByMs = () => {
if (ping < 80) {
return '#00FF00'
} else if (ping < 200) {
return 'rgb(250, 184, 86)'
} else {
return 'rgb(253, 97, 97)'
}
}
const changeColorByFps = () => {
if (fps > 50) {
return '#00FF00'
} else if (fps > 30) {
return 'rgb(250, 184, 86)'
} else {
return 'rgb(253, 97, 97)'
}
}
return (
<>
<div style = {{
position : 'absolute',
left: `${left}px`,
fontFamily : 'Roboto',
fontWeight : 'bold',
fontSize : '20px',
height : "auto",
top: `${top}px`,
margin: "0p",
paddingLeft: "8px",
paddingRight: "8px",
backgroundColor: 'rgba(54, 54, 54, 0.384)',
pointerEvents: 'none',
}}>
<li style = {{ listStyleType : 'none', color : changeColorByMs()}}>{ping} ms</li>
<li style = {{ listStyleType : 'none', color :changeColorByFps()}}>{fps} fps</li>
</div>
</>
)
}
I am currently in the Canvas component so currently here I am using a useState, which will be used later to update the 'ServerInfos' component
const Canvas = () => {
const [statsData, setStatsData] = useState(null)
This is actualized in an animation function in which is running a 'requestAnimationFrame'
function update() {
movePlayer() //player movement function
setStatsData({ // the hook object that I am updating for my component
left : canvasRef.current.offsetLeft,
top : canvasRef.current.offsetTop,
ping : ping,
fps : fpsFunc()
})
requestAnimationFrame(update)
}
And here I return my block in which I update my component 'ServerInfos'
return (
<div ref={ref} tabIndex={-1} onKeyDown={handleKeyDown} onKeyUp={handleKeyUp} className={styles.canvas}>
<canvas ref={canvasRef}/>
{statsData ? <ServerInfos props = {{
left : statsData.left,
top : statsData.top,
ping : statsData.ping,
fps : statsData.fps,
}}/> : null }
<div ref={tchatRef} className={styles.personalTchat}>
<div ref={chatRef} className={styles.messages}>
</div>
<ul className={styles.chat}></ul>
<div className="input-group p-2">
<input ref={messageRef} id="message"
className="form-control form-control-lg"
type="text"
placeholder="Envoyer un message" autoComplete='off'/>
<div className="input-group-append">
<button ref={sendRef} className = {styles.escape}>
Envoyer
</button>
</div>
</div>
</div>
</div>
)
Indeed so far everything works correctly, the concern being that I use a function to move, and when I add this code below
setStatsData({ //the object hook I am updating for my component
left : canvasRef.current.offsetLeft,
top : canvasRef.current.offsetTop,
ping : ping,
fps : fpsFunc()
})
In my animation function, then my current component reloads at the speed of the requestAnimationFrame, which has the side effect I think of crippling my players' movement, thus preventing any possible movement action, none of my keys do is discoverable and detected in the movePlayer() function
function movePLayer() {
if (keys.z.pressed && lastKey.toLowerCase() === 'z') {
emitArray.z(socket)
ctxRef.current.translate(0, +speed)
} else if (keys.q.pressed && lastKey.toLowerCase() === 'q') {
ctxRef.current.translate(+speed, 0)
emitArray.q(socket)
} else if (keys.s.pressed && lastKey.toLowerCase() === 's') {
emitArray.s(socket)
ctxRef.current.translate(0, -speed)
} else if (keys.d.pressed && lastKey.toLowerCase() === 'd') {
emitArray.d(socket)
ctxRef.current.translate(-speed, 0)
}
}
on the other hand, the handle functions below detect my movements well:
const handleKeyUp = (e) => {
switch (e.key.toLowerCase()) {
case 'z':
keys.z.pressed = false
break
case 'q':
keys.q.pressed = false
break
case 's':
keys.s.pressed = false
break
case 'd':
keys.d.pressed = false
break
}
if(!e.shiftKey) {
emitArray = emitMoveSlow
speed = 3
}
}
const handleKeyDown = e => { // we detect the keys on the keyboard
switch (e.key.toLowerCase()) {
case 'z':
keys.z.pressed = true
lastKey = 'z'
break
case 'q':
keys.q.pressed = true
lastKey = 'q'
break
case 's':
keys.s.pressed = true
lastKey = 's'
break
case 'd':
keys.d.pressed = true
lastKey = 'd'
break
}
if(e.shiftKey) {
emitArray = emitMoveRun
speed = 5
}
}
Game link so you can see the playerMove issue: http://141.94.31.123:8000/