Come creare un animazione in JavaScript (7) - immagini
Finora negli esempi ( Come creare un animazione in JavaScript), ho gestito solo forme grafiche, adesso vediamo come inserire nell'animazone delle immagini.
Per gestire l'animazione delle immagini, per prima cosa aggiungo il nuovo oggetto:
In questo caso non devo gestire in modo specifico l'aggiornamento delle coordinate o le collisioni in quanto posso assimilarli a dei rettangoli. Però devo gestire come viene disegnata l'immagine sul canvas modificando il metodo draw:
Ultimo passo, gestire il caricamento delle immagini modificando il metodo createSprites:
l'ultima istruzione, loadResources(), serve per caricare le immagini..
Essendo il caricamento delle immagini asincrono, prima cerco quali sprite sono di tipo image e ricavo il totale. Successivamente invoco il caricamento (loadImage) e al completamento diminuisco il contatore del totale delle immagini. Quando il totale è zero ho tutte le immagini caricate e posso invocare l'animazione (animationLoop):
a questo punto il metodo init diventa:
Il risultato è l'animazione a inizio pagina.
L'esempio completo è scaricabile da qui sgart-animation-2017.zip.
Vedi anche:
Usa i tasti cursore per muovere il quadrato bianco e i tasti WDSA per muovere il cerchio viola. Usa il mouse per muovere i 5 cerchi verdi.
Per gestire l'animazione delle immagini, per prima cosa aggiungo il nuovo oggetto:
JavaScript
//tipi di sprite gestiti (uso gli interi perchè sono più efficenti)
const SpriteType = {
...
IMAGE: 4
};
function SpriteImage(x, y, src, deltaX, deltaY) {
this.type = SpriteType.IMAGE;
this.x = x; // x e y sempre riferiti al centro dell'oggetto
this.y = y;
this.w = 0;
this.h = 0;
this.src = src;
this.image = null;
this.deltaX = deltaX == null ? 0 : deltaX;
this.deltaY = deltaY == null ? 0 : deltaY;
this.animationType = (this.deltaX !== 0 || this.deltaY !== 0) ? AnimationType.LINEAR : AnimationType.NONE;
this.alpha = 1;
this.animationType = AnimationType.LINEAR;
}
JavaScript
function draw() {
arena.sprites.forEach(sprite => {
ctx.globalAlpha = sprite.alpha;
let x = 0;
let y = 0;
switch (sprite.type) {
...
case SpriteType.IMAGE:
x = sprite.x - sprite.w / 2;
y = sprite.y - sprite.h / 2;
ctx.drawImage(sprite.image, x, y);
break;
...
}
});
}
JavaScript
function createSprites() {
...
//array con le immagini da caricare casualmente
const images = ['fantasmino.png', 'blue.png', 'pacman.png'];
//aggiungo sprite casuali
for (var i = 0; i < 40; i++) {
...
if (t < .4) {
const circle = new SpriteCircle(x, y, w2, null, color, deltaX, deltaY);
circle.alpha = alpha;
arena.addSprite(circle);
} else if (t < .6) {
const src = images[Math.random() * images.length | 0];
const image = new SpriteImage(x, y, src, deltaX, deltaY);
image.alpha = alpha;
arena.addSprite(image);
} else {
const rect = new SpriteRect(x, y, w2 * 2, h2 * 2, null, color, deltaX, deltaY);
rect.alpha = alpha;
arena.addSprite(rect);
}
}
..
// mi assicuro che vengano caricate le immagini
loadResources();
}
Essendo il caricamento delle immagini asincrono, prima cerco quali sprite sono di tipo image e ricavo il totale. Successivamente invoco il caricamento (loadImage) e al completamento diminuisco il contatore del totale delle immagini. Quando il totale è zero ho tutte le immagini caricate e posso invocare l'animazione (animationLoop):
JavaScript
function loadImage(sprite, handleComplete) {
sprite.image = new Image();
sprite.image.onload = function () {
sprite.w = sprite.image.width;
sprite.h = sprite.image.height;
if (typeof handleComplete === 'function')
handleComplete();
};
sprite.image.src = sprite.src;
}
function loadResources() {
const resourcesToLoad = [];
//cerco le risorse da caricare
arena.sprites.forEach(sprite => {
if (sprite.type === SpriteType.IMAGE) {
resourcesToLoad.push(sprite);
}
});
// le carico
let i = resourcesToLoad.length;
if (i === 0) {
animationLoop();
} else {
resourcesToLoad.forEach(sprite => {
new loadImage(sprite, function(){
i--;
if (i <= 0) {
//attendo il caricamento di tutte le immagini
animationLoop();
}
});
});
}
}
JavaScript
function init() {
createSprites();
}
init();
L'esempio completo è scaricabile da qui sgart-animation-2017.zip.
Vedi anche:
- Come creare un animazione in JavaScript
- Come creare un animazione in JavaScript (2)
- Come creare un animazione in JavaScript (3)
- Come creare un animazione in JavaScript (4) - collisioni
- Come creare un animazione in JavaScript (5) - tastiera
- Come creare un animazione in JavaScript (6) - mouse
- Come creare un animazione in JavaScript (7) - immagini