Sprite Animation
Testing2
%%html
SPRITE
<body>
<div id="controls"> <!--basic radio buttons which can be used to check whether each individual animaiton works -->
</div>
<div>
<canvas id="spriteContainer"> <!-- Within the base div is a canvas. An HTML canvas is used only for graphics. It allows the user to access some basic functions related to the image created on the canvas (including animation) -->
<img id="robotSprite" src="/sharedGame/images/sprite1.png"> <!-- Change sprite here -->
</canvas>
</div>
</body>
<script>
const canvas = document.getElementById('spriteContainer');
const ctx = canvas.getContext('2d');
// start on page load
window.addEventListener('load', function () {
const SPRITE_WIDTH = 35; // matches sprite pixel width
const SPRITE_HEIGHT = 49; // matches sprite pixel height
const FRAME_LIMIT = 7; // matches number of frames per sprite row, this code assume each row is same
const SCALE_FACTOR = 2; // control size of sprite on canvas
canvas.width = SPRITE_WIDTH * SCALE_FACTOR;
canvas.height = SPRITE_HEIGHT * SCALE_FACTOR;
// a class to store the differences in the animations to make it clear what the animation changes are for
class AnimationType{
constructor(initFrameX = 0, maxFrame = FRAME_LIMIT, animationDelay = 75){
this.maxFrame = maxFrame;
this.initFrameX = initFrameX;
this.animationDelay = animationDelay;
}
}
class Robot {
constructor() {
this.image = document.getElementById("robotSprite");
this.x = 0;
this.y = 0;
this.minFrame = 0;
this.animationType = new AnimationType();
this.frameX = 0;
this.frameY = 0;
}
// draw Robot object
draw(context) {
context.drawImage(
this.image,
this.frameX * SPRITE_WIDTH,
this.frameY * SPRITE_HEIGHT,
SPRITE_WIDTH,
SPRITE_HEIGHT,
this.x,
this.y,
canvas.width,
canvas.height
);
}
// update frameX of object
update() {
// this sprite sheet uses a variable number of frames for different animations
if (this.frameX < this.animationType.maxFrame) {
this.frameX++;
} else {
// the start frame of the animations changes in this sprite sheet
this.frameX = this.animationType.initFrameX;
}
}
}
// Robot object
const robot = new Robot();
// Make the animations that deviate from the default use a class
// to make it more readible what the changes are doing
const jumpRightAnimation = new AnimationType(undefined, 7, undefined); // frames go from 0 to 7 but everything else is the same
const jumpLeftAnimation = new AnimationType(8, undefined, undefined); // frames go from 8 to 14 but everything else is the same
// update frameY of robot object, action from radio controls
document.addEventListener('keydown', function (event) {
const key = event.key.toLowerCase();
switch (key) {
case 'w':
robot.frameY = 2; // Walk Right
robot.animationType = new AnimationType();
break;
case 'a':
robot.frameY = 0; // Walk Left
robot.animationType = new AnimationType();
break;
case 'd':
robot.frameY = 1; // Jump Right
robot.animationType = jumpRightAnimation;
break;
case 's':
robot.frameY = 2; // Jump Left
robot.animationType = jumpLeftAnimation;
break;
default:
break;
}
});
// Animation recursive control function
function animate() {
// Clears the canvas to remove the previous frame.
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draws the current frame of the sprite.
robot.draw(ctx);
// Updates the `frameX` property to prepare for the next frame in the sprite sheet.
robot.update();
// Uses `requestAnimationFrame` to synchronize the animation loop with the display's refresh rate,
// ensuring smooth visuals.
requestAnimationFrame(function() {
setTimeout(animate, robot.animationType.animationDelay); // Adjust the delay (in milliseconds) to control the frame rate.
});
}
// run 1st animate
animate();
});
</script>
SPRITE