Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Nemici, effetti sonori e spari

Implementare diversi oggetti a partire dal GameObject di base, creando proiettili e nemici. Aggiungere al game engine la gestione di effetti sonori.
Implementare diversi oggetti a partire dal GameObject di base, creando proiettili e nemici. Aggiungere al game engine la gestione di effetti sonori.
Link copiato negli appunti

In questa lezione vediamo come implemenrtare un semplice nemico volante che alla collisione con un blocco cambi direzione. Poi ci dedicheremo alli effetti sonori e alla gestione degli spari.

Creare un GameObj per i nemici

Iniziamo con i nemici caricando come al solito lo sprite animato:

this.sprUmbrella = rh.LoadSprite("img/umbrella.png",4);

Definiamo poi l'oggetto Umbrella, che colpisce e ferisce il Player quando entra in collisione con esso:

function Umbrella(x,y) { 
	GameObj.call(this, x, y);
	// imposta lo sprite e l'evento draw
	this.SetSprite(game.sprUmbrella);
	this.hSpeed = 1;
	this.life = 5;
	this.animSpeed = 0.25;
	this.bbox = new BoundingBox(this.x, this.y, this.sprite.w, this.sprite.height);
	this.Update = function() {
		// se collide con un blocco, cambia direzione
		if(this.GetCollision(game.blocks, this.hSpeed/2, 0)) {
			this.hSpeed = - this.hSpeed;
		}
		this.x += this.hSpeed;
		this.bbox.Move(this.x, this.y);
		// se il player non è in status "colpito/invulnerabile"
		if(!game.player.hit) {
			// se entra in collisione con il Player
			if(this.bbox.Collides(game.player.bbox)) {
				// colpisci il player
				game.player.Hit();
			}
		}
	}
	// inserisco l'istanza nell'array dei nemici
	game.enemies.push(this);
	//quando viene distrutto, cancella dall'array dei nemici
	this.OnDestroy = function() {
		game.enemies.splice(game.enemies.indexOf(this), 1);
	}
}
//eredita da GameObj
Inherit(Umbrella);

Aggiungiamo l'array enemies in ResetLevel:

this.ResetLevel = function() {
	// ...
	this.enemies = [];
}

Nella mappa che abbiamo importato, ci sono già alcuni oggetti, possiamo caricarli aggiungendo a LoadLevel il seguente codice, appena sotto il caricamento delle collisioni:

// dati sui blocchi di collisione
// ...
// dati sugli oggetti
var objects = levels[lev][3];
for(var i = 0; i < objects.length; i++){
	var object = null;
	var x = objects[i][0]*this.cellSize;
	var y = objects[i][1]*this.cellSize;
	switch(objects[i][2]) {
		case "umbrella":
			new Umbrella(x, y);
			break;
	}
}

Avviare Sound Effects

Definiamo la funzione AudioPlay in Utils.js, aggiungendo il seguente codice, che ci permetterà di avviare un suono più volte facendolo ripartire dall'inizio (dall'istante zero).

function AudioPlay(source) {
	// se il browser è internet explorer
	if(window.ActiveXObject != undefined) {
		source.pause();
		source.currentTime = 0;
	} else {
		source.load();
	}
	// avvia il suono
	source.play();
}

Purtroppo ci sono tantissime incongruenze tra i vari browser e l'istruzione currentTime = 0 non funziona ovunque come dovrebbe, perciò bisogna usare la funzione load() che inizializza nuovamente il suono dalla cache, facendolo ripartire dall'inizio.

Questo non sarà necessario su Internet Explorer, che almeno stavolta è uno dei pochi che funziona come dovrebbe.

Proiettili

Per rendere il gioco più vivo, diamo al nostro personaggio la possibilità di sparare. Come al solito carichiamo gli sprite necessari:

this.sprBullet = rh.LoadSprite("img/bullet.png",1);
this.sprBulletHit = rh.LoadSprite("img/bullethit.png",3);

Creiamo quindi l' oggetto Bullet, che rappresenterà la pallottola.

function Bullet(x,y,hspeed) {
	//constructor di GameObj
	GameObj.call(this, x, y);
	//imposta sprite e metodo Draw
	this.SetSprite(game.sprBullet);
	this.hSpeed = hspeed;
	//centra l'offset dello sprite
	this.OffsetCenter();
	//crea il bounding box
	this.bbox = new BoundingBox(x-this.xOffset, y-this.yOffset, this.sprite.w, this.sprite.height);
	this.Update = function() {
		// se collide con un blocco, si distrugge
		if(this.GetCollision(game.blocks, this.hSpeed/2, 0)) {
			this.Destroy();
		}
		//se collide con un nemico, gli riduce la vita
		//e il proiettile viene distrutto
		if(inst = this.GetCollision(game.enemies, this.hSpeed/2, 0)) {
			inst.life--;
			this.Destroy();
		}
		this.x += this.hSpeed;
		this.bbox.Move(this.x-game.sprBullet.width/2, this.y-game.sprBullet.height/2);
		//se il proiettile esce dalla visuale, viene distrutto
		if(this.x < 0 || this.x > game.AreaW * game.cellSize) {
			this.Destroy();
		}
	}
	//quando viene distrutto
	this.OnDestroy = function() { 
		//viene cancellato dall'array bullets
		game.bullets.splice(game.bullets.indexOf(this), 1);
		//crea una piccola esplosione
		new BulletExplosion(this.x, this.y);
	}
	game.bullets.push(this);
}
//eredita da GameObj
Inherit(Bullet);

Inizializziamo l'array bullets all'interno di ResetLevel

//...
this.bullets = [];
//...

Definiamo anche BulletExplosion, una semplice animazione che avviene quando il proiettile si distrugge:

function BulletExplosion(x,y) {
	//constructor
	GameObj.call(this, x, y);
	//avvia un suono
	AudioPlay(game.sndHit);
	//imposta sprite e funzione di draw
	this.SetSprite(game.sprBulletHit);
	//imposta l'offset al centro
	this.OffsetCenter();
	//velocità di animazione
	this.animSpeed = 0.25;
	//distruggi al termine dell'animazione
	this.OnAnimationEnd = function(){
		this.Destroy();
	}
}
//eredita da gameobject
Inherit(BulletExplosion);

Prima di andare avanti, dobbiamo caricare un paio di suoni, tra cui sndHit, utilizzato nel codice precedente:

this.sndHit = rh.LoadSound("audio/hit",["ogg", "mp3"]);
this.sndHit.volume = 0.03;
this.sndShot = rh.LoadSound("audio/shot",["ogg", "mp3"]);
this.sndShot.volume = 0.03;

Possiamo quindi far sparare il nostro player quando viene premuto il tasto X. In fondo al metodo Update del Player, aggiungiamo un po' di codice:

// ...
//se è possibile sparare
if(this.canShot){
	if(Inputs.GetKeyPress("X")) {  
		var bullet = new Bullet(this.x + 10*this.scaling, this.y-this.height/2, this.scaling * 8);
		//avvia il suono di sparo
		AudioPlay(game.sndShot);
		//imposta una pausa di qualche frazione di secondo,
		//prima di poter sparare un altro colpo
		this.canShot = false;
		this.shotTime = 10;
	}
} else {
	//timer di attesa per sparare il prossimo colpo
	this.shotTime --;
	if(this.shotTime <= 0){
		this.canShot = true;
	} 
	//cambia sprite in base allo status corrente
	//se salta, imposta lo sprite di sparo durante il salto
	//se è fermo, imposta lo sprite fermo in modalità sparo
	//ecc..
	switch(this.sprite){
		case game.sprPlayerRun:
			this.sprite = game.sprPlayerIdleShot;
			this.curFrame = 0;
			break;
		case game.sprPlayerIdle:
			this.sprite = game.sprPlayerIdleShot;
			this.curFrame = 0;
			break;
		case game.sprPlayerFall:
			this.sprite = game.sprPlayerFallShot;
			break;
		case game.sprPlayerJump:
			this.sprite = game.sprPlayerJumpShot;
			break;
	}
}

Ti consigliamo anche