[ad_1]
The level of a operate handed to requestAnimationFrame
which then passes itself again to requestAnimationFrame
at its finish is to not be a setup-function. It’s a drawing-function which will get referred to as again and again by the browser’s rendering engine.
I feel what it’s alleged to do in your code instance is to organize the canvas for first rendering and schedule the animations for all of the objects by calling their animateObjectImage
capabilities which then all create an interval. This is one thing you solely must do as soon as, not again and again. And you need not name it through requestAnimationFrame
. So each cases of the road window.requestAnimationFrame(setup)
make no sense. Just name the setup technique as soon as once you begin the sport.
Then there’s the issue that you’ve your calls to context.drawImage
not through the requestAnimationFrame
operate however as a part of the setInterval
operate. That’s not how you’re alleged to do it! All drawing ought to occur throughout requestAnimationFrame
, so the net browser can correctly combine the rendering into its personal rendering loop. Functions scheduled through setInterval
get executed every time, so that they shouldn’t comprise any canvas drawing.
Now you may marvel: “But I do not know the way typically the browser calls requestAnimationFrame. How am I alleged to correctly time my animations with that operate?”
The reply is to separate logic from drawing! A precept that ought to be obeyed in any well-designed recreation structure.
- Have the setInterval operate set which body is the at the moment displayed body for that object.
- Have the requestAnimationFrame draw no matter is the at the moment displayed body for the item.
You can try this by breaking the animateObjectImage
technique of your genericObject
operate pseudo-class into two separate strategies setup
and draw
. The setup technique does initialization and schedules the logic (however not the drawing!) and the draw technique attracts no matter state the logic has set.
operate genericObject(objectSpriteSheet, xPosition, yPosition){
this.objectImage = (operate (){
let newImageObject = new Image()
newImageObject.src = objectSpriteSheet
return (newImageObject)
})()
// setup operate
this.setup = operate(objectImage, frameRate){
let setIntervalTime = 1000 / frameRate;
let currentFrame = 1;
let totalSprites = 8;
let spriteHeight = objectImage.top;
let spriteWidth = objectImage.width / totalSprites;
setInterval(operate(){
currentFrame = (currentFrame + 1) % totalSprites;
currentFrame++;
}, setIntervalTime)
}
// draw operate
this.draw = operate() {
let screenX = currentFrame * spriteWidth;
context.drawImage(objectImage, screenX, 0, spriteWidth, spriteHeight, xPosition, yPosition, spriteWidth, spriteHeight);
}
}
Then in the principle program, you’ve each a setup technique and a draw technique. The setup technique begins the animation loop of the draw technique:
operate setup() {
objectsArray.forEach((factor) => {
factor.setup(factor.objectImage, 9)
})
window.requestAnimationFrame(draw)
}
operate draw() {
context.clearRect(0, 0, canvas.width, canvas.top)
objectsArray.forEach((factor) => {
factor.draw()
})
window.requestAnimationFrame(draw)
}
And then you definately initialize your recreation by calling the setup technique when the web page has loaded:
window.onload = operate(){
/* ...all the opposite initializations... */
setup();
}
By the way in which, there’s one other downside right here that you do not wait with drawing till all of the sprites have loaded. But that is one other downside for one more query.
[ad_2]