Loop a sprite through an array of images to show walking, flying, etc.
It is nice to be able to change the images of the sprites as they move. This can be good for things like flapping wings, moving legs and arms, etc. It helps create a more convincing sense of animation.
In order to do this you can either:
- Use animated GIFs or PNGs
- Step through an array of images periodically
You can take advantage of .animate()
's start:
feature that allows you to call a function before the animation begins:
$( '#animateID' ).animate(
{ left: '-=50px' },
{ start: function () { // set the current sprites to looking up before the animation starts
self.currentSpritesArr = self.lookLeftArr;
},
duration: this.duration,
easing: 'linear' }
);
Then you can use window.setInterval
to periodically change
the image source to the next one in the array of sprite images.
(In this case, every 80 milliseconds...)
var imageLoop = setInterval(
function () {
ghost.changeSpriteImage();
}, 80
);
Source code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Image loops</title>
<!-- load jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script>
// ghost OBJECT
// ghost properties:
// ghost.element
// ghost.speed
// ghost.duration
//
// ghost.lookDownArr
// ghost.lookUpArr
// ghost.lookLeftArr
// ghost.lookRightArr
//
// ghost.currentSpritesArr
// ghost.currentSpriteIndex
//
// ghost methods
// ghost.setID()
// ghost.changeSpriteImage()
// ghost.goUp()
// ghost.goDown()
// ghost.goLeft()
// ghost.goRight()
//
var ghost = {
element: null, // the element to animate
speed: 300, // the distance to move with each animation
duration: 1000, // the amount of time to move with each animation
lookDownArr: [ // sprite links for looking down
"http://drapak.ca/cpg/img/pacman/pacmanGhostFlash0.png",
"http://drapak.ca/cpg/img/pacman/pacmanGhostFlash1.png",
"http://drapak.ca/cpg/img/pacman/pacmanGhostFlash2.png",
"http://drapak.ca/cpg/img/pacman/pacmanGhostFlash3.png",
],
lookUpArr: [ // sprite links looking up
"http://drapak.ca/cpg/img/pacman/pacmanInkyUp0.png",
"http://drapak.ca/cpg/img/pacman/pacmanInkyUp1.png"
],
lookLeftArr: [ // sprite links looking left
"http://drapak.ca/cpg/img/pacman/pacmanPinkyLeft0.png",
"http://drapak.ca/cpg/img/pacman/pacmanPinkyLeft1.png"
],
lookRightArr: [ // sprite links looking right
"http://drapak.ca/cpg/img/pacman/pacmanMoveRight2.png",
"http://drapak.ca/cpg/img/pacman/pacmanMoveRight1.png",
"http://drapak.ca/cpg/img/pacman/pacmanMoveRight0.png",
"http://drapak.ca/cpg/img/pacman/pacmanMoveRight1.png",
],
currentSpritesArr: null, // the current sprite array being used
currentSpriteIndex: 0, // stores the index of the current sprite...
// INIT: get the element containing the ghost
setID: function ( id ) {
this.elementID = id;
},
//PROCESS+OUTPUT: loop to the next sprite...
changeSpriteImage: function () {
var spriteArr = this.currentSpritesArr;
var maxIndex = spriteArr.length - 1; // record the maximum length of the current array of sprites
this.currentSpriteIndex = this.currentSpriteIndex + 1; // move on to the next sprite image
if ( maxIndex < this.currentSpriteIndex ) { // if the current sprite number is greater than the number in the array,
this.currentSpriteIndex = 0; // then start again at zero
}
document.getElementById( this.elementID ).src // change the element to the next image...
= spriteArr[ this.currentSpriteIndex ];
},
// OUTPUT: animate upwards
goUp: function () {
var self = this; // copy 'this' so it does not get lost when 'start:' is triggered
$( '#' + this.elementID ).animate(
{ top: '-=' + this.speed + 'px' },
{ start: function () { // set the current sprites to looking up before the animation starts
self.currentSpritesArr = self.lookUpArr;
},
duration: this.duration,
easing: 'linear' }
);
},
// OUTPUT: animate downwards
goDown: function () {
var self = this; // copy 'this' so it does not get lost when 'start:' is triggered
$( '#' + this.elementID ).animate(
{ top: '+=' + this.speed + 'px' },
{ start: function () { // set the current sprites to looking up before the animation starts
self.currentSpritesArr = self.lookDownArr;
},
duration: this.duration,
easing: 'linear' }
);
},
// OUTPUT: animate leftwards
goLeft: function () {
var self = this; // copy 'this' so it does not get lost when 'start:' is triggered
$( '#' + this.elementID ).animate(
{ left: '-=' + this.speed + 'px' },
{ start: function () { // set the current sprites to looking up before the animation starts
self.currentSpritesArr = self.lookLeftArr;
},
duration: this.duration,
easing: 'linear' }
);
},
// OUTPUT: animate rightwards
goRight: function () {
var self = this; // copy 'this' so it does not get lost when 'start:' is triggered
$( '#' + this.elementID ).animate(
{ left: '+=' + this.speed + 'px' },
{ start: function () { // set the current sprites to looking up before the animation starts
console.log('in goright begin' )
self.currentSpritesArr = self.lookRightArr;
},
duration: this.duration,
easing: 'linear' }
);
}
}
// this sets up the animation sprite looper
var imageLoop = setInterval(
function () {
ghost.changeSpriteImage();
}, 80
);
// set up a series of animations
// this is triggered when the page is finished loading and when the button is pressed
var mainProcedure = function () {
ghost.setID( 'animateID' ); // register the ID of the ghost object
ghost.goUp();
ghost.goLeft();
ghost.goDown();
ghost.goRight();
}
</script>
<style>
body {
background-color: darkBlue;
}
#animateID {
position: absolute;
opacity: 1;
width: 50px;
top: 400px;
left: 400px;
}
</style>
</head>
<body onload="mainProcedure();">
<img
id="animateID"
src="http://drapak.ca/cpg/img/pacman/pacmanInkyUp0.png" />
<p>
<button onclick="mainProcedure();">One more time!</button>
</p>
</body>
</html>