Ir para conteúdo

Programação De Jogos - As 3.0 - Carregando Imagens Corretamente..


Posts Recomendados

Fala ae galera! Voltando com +1 artigo, se der eu ainda faço outro de colisão em alguns dias... tópicos simples, mas que com certeza ajudarão muitos a iniciarem na área de jogos aí!

 

Vamos ao artigo, nesse aqui vou explicar como fazer com que você carregue todas imagens externas que precisa pro seu projeto, pra fazer seu mapa, mostrar seu personagem, inimigos e etc... de uma vez só e guardá-las num array, muitos jogos carregam essas imagens na demanda (quando precisam), o que faz que eles carreguem várias vezes os mesmos arquivos. Quando os arquivos são pequenos é quase imperceptível pra um humano, dependendo da velocidade da internet, claro... mas quando começam ficar maiores o jogo tá lá rodando... e você não vê nenhuma imagem, quando carrega a imagem você já tá na frente de um inimigo e puff, morreu!

 

Exemplo de funcionamento e download de todo o projeto no fim do artigo.

 

Vou utilizar as seguintes imagens que veio junto do meu windows por serem um tanto pesadas (500kb+ cada). Todas elas encontram-se em:

http://www.andersonferminiano.com/games/imageloader/images/

 

Então começamos a classe, crie seu *.fla e uma classe (*.as) nomeada ImageAutomaticLoader.

 

Importe no package as seguintes classes pra utilizarmos:

import flash.display.Loader;
import flash.net.URLRequest;
import flash.events.Event;
import flash.events.IEventDispatcher;
import flash.events.EventDispatcher;

 

Loader e URLRequest para carregarem as imagens, as outras 3 para manipularmos os eventos.

 

Seu código da classe deve estar assim:

package {

import flash.display.Loader;
import flash.net.URLRequest;
import flash.events.Event;
import flash.events.IEventDispatcher;
import flash.events.EventDispatcher;

public class ImageAutomaticLoader {

}

}		

 

Criamos nosso construtor que vai tratar de iniciar as variáveis comuns, o dispatcher pros eventos, o contador de imagens carregadas e os 2 arrays que vão ficar as imagens pra carregar/imagens já carregadas.

 

	public function ImageAutomaticLoader(){
		this.dispatcher = new EventDispatcher();
		this.loadedImages = new Array();
		this.toLoadImages = new Array();
		this.loadedImagesNum = 0;
	}

 

Um método pra inserir a imagem que o usuário deseja carregar no nosso array:

 

	public function addImageToLoad(image, id):void {
		this.toLoadImages.push(new Array(image, id));
	}

 

Perceba aqui nos parâmetros o ID, ele vai ser necessário pro usuário conseguir a imagem de volta depois que todas estiverem carregadas.

 

E mais outro método pra iniciar o carregamento:

 

	public function startLoading():void{
		for(var i=0;i<this.toLoadImages.length;i++){
			var imageLoader:Loader = new Loader();
			imageLoader.name = this.toLoadImages[i][1];
			imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, this.completeLoadingImage);

			var fileRequest:URLRequest = new URLRequest(this.toLoadImages[i][0]);
			imageLoader.load(fileRequest);

			this.totalKB += imageLoader.contentLoaderInfo.bytesTotal;
		}
	}

 

No método acima, perceba a propriedade name do imageLoader, nela colocamos o ID que a imagem recebe lá no método addImageToLoad, pra depois colocamos esse ID no array que carregou, e então o usuário conseguir utilizar a imagem depois de carregada sem problemas.

 

Nesse método também referenciamos outro no EVENT.Complete do loader, o método "completeLoadingImage", então vamos ver como ele é feito:

 

	public function completeLoadingImage(e):void{
		this.loadedImages[e.currentTarget.loader.name] = e.currentTarget.loader;
		this.loadedImagesNum++;
		this.dispatcher.dispatchEvent(new Event("imageLoaded"));

		if (this.toLoadImages.length == this.loadedImagesNum){
			this.dispatcher.dispatchEvent(new Event("loaderImagesLoaded"));
		}
	}

 

Primeiro pegamos ali o ID que agora está na propriedade name do loader, adicionamos então um elemento ao array de imagens carregadas com esse ID e sua respectiva imagem. Acrescentamos 1 no contador do loadedImages, disparamos um evento de que +1 uma imagem foi carregada - assim conseguimos manipular corretamente a classe quando estivermos utilizando. E também verifico se a quantidade de imagens pra carregar é igual a quantidade de imagens que já foram carregadas, se for, ele dispara outro evento pra dizer que acabou todas imagens de carregar...

 

Pra acabar a classe, coloquei alguns getters aqui:

 

		public function getLoadedImagesQuantity(){
		return this.loadedImagesNum;
	}

	public function getTotalImagesQuantity(){
		return this.toLoadImages.length;
	}

	public function getDispatcher(){
		return this.dispatcher;
	}

	public function getImage(imgid){
		return this.loadedImages[imgid];
	}		

 

getLoadedImagesQuantity retorna a quantidade de imagens carregadas.

toLoadImages retorna total de imagens que devem ser carregadas.

getDispatcher retorna o manipulador dos eventos disparados pela classe.

getImage(imgid) retorna a imagem do respectivo imgid para o usuário depois de carregado.

 

Ok, acabamos a classe... é uma classe bem simples, que não tem muito o que explicar mesmo. Outras coisas poderiam ser adicionadas ali pra garantir a integridade das imagens, como um evento pra quando desse erro em algum loader de alguma imagem.

 

Ela deve ter ficado assim:

package {

import flash.display.Loader;
import flash.net.URLRequest;
import flash.events.Event;
import flash.events.IEventDispatcher;
import flash.events.EventDispatcher;

public class ImageAutomaticLoader {


	public var loadedImages:Array;
	public var toLoadImages:Array;
	public var loadedImagesNum:Number;
	public var dispatcher:EventDispatcher;
	public var totalKB:Number;
	public var KBLoaded:Number;

	public function ImageAutomaticLoader(){
		this.dispatcher = new EventDispatcher();
		this.loadedImages = new Array();
		this.toLoadImages = new Array();
		this.loadedImagesNum = 0;
	}

	public function addImageToLoad(image, id):void {
		this.toLoadImages.push(new Array(image, id));
	}

	public function startLoading():void{
		for(var i=0;i<this.toLoadImages.length;i++){
			var imageLoader:Loader = new Loader();
			imageLoader.name = this.toLoadImages[i][1];
			imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, this.completeLoadingImage);

			var fileRequest:URLRequest = new URLRequest(this.toLoadImages[i][0]);
			imageLoader.load(fileRequest);

			this.totalKB += imageLoader.contentLoaderInfo.bytesTotal;
		}
	}

	public function completeLoadingImage(e):void{
		this.loadedImages[e.currentTarget.loader.name] = e.currentTarget.loader;
		this.loadedImagesNum++;
		this.dispatcher.dispatchEvent(new Event("imageLoaded"));

		if (this.toLoadImages.length == this.loadedImagesNum){
			this.dispatcher.dispatchEvent(new Event("loaderImagesLoaded"));
		}
	}

	public function getLoadedImagesQuantity(){
		return this.loadedImagesNum;
	}

	public function getTotalImagesQuantity(){
		return this.toLoadImages.length;
	}

	public function getDispatcher(){
		return this.dispatcher;
	}

	public function getImage(imgid){
		return this.loadedImages[imgid];
	}		

}

}

 

Beleza, salve e volte pro seu *.fla... Crie a estrutura da sua timeline como segue na imagem abaixo. No primeiro frame, crie um texto estático "Carregando...", e um texto dinâmico nomeado imagensCarregadas pra exibirmos o total de imagens carregadas.

 

loadingimages.png

 

Também adicione o seguinte código (comentado abaixo):

import ImageAutomaticLoader;
stop();

var loader:ImageAutomaticLoader = new ImageAutomaticLoader();
loader.addImageToLoad("images/Desert.jpg", "desertImage");
loader.addImageToLoad("images/Hydrangeas.jpg", "hydraImage");
loader.addImageToLoad("images/Tulips.jpg", "tulipImage");
loader.addImageToLoad("images/Penguins.jpg", "penguinImage");
loader.addImageToLoad("images/Koala.jpg", "koalaImage");
loader.startLoading();

loader.getDispatcher().addEventListener("loaderImagesLoaded", function(e:Event){
	gotoAndPlay(2);									   										   
});

imagensCarregadas.text = loader.getLoadedImagesQuantity()+"/"+loader.getTotalImagesQuantity()+" imagens carregadas";

loader.getDispatcher().addEventListener("imageLoaded", function(e:Event){
	imagensCarregadas.text = loader.getLoadedImagesQuantity()+"/"+loader.getTotalImagesQuantity()+" imagens carregadas";								   										   
});

 

Primeiro eu importei a classe que criamos, que deve estar na raiz do projeto, e então iniciei a classe, já colocando nela todas imagens que eu deveria carregar, seguindo os parâmetros de URL e path (caminho) da imagem. Comecei carregar no startLoading.

Depois eu fiz a manipulação dos 2 eventos que criamos, o primeiro que eu manipulei foi o loaderImagesLoaded que é chamado quando todas imagens foram carregadas, então eu vou pro próximo frame pra exibi-las no palco (veremos o código do próximo frame abaixo), e a outra eu atualizo o nosso simples preloader que exibe o total de imagens carregadas.

 

Segue o código do quinto frame:

stop();


var desert = loader.getImage("desertImage");
desert.x = 0;
desert.y = 0;

var hydra = loader.getImage("hydraImage");
hydra.x = 30;
hydra.y = 30;
hydra.alpha = .5;

var tulip = loader.getImage("tulipImage");
tulip.x = 60;
tulip.y = 60;
tulip.alpha = .5;

var penguin = loader.getImage("penguinImage");
penguin.x = 90;
penguin.y = 90;
penguin.alpha = .5;

var koala = loader.getImage("koalaImage");
koala.x = 120;
koala.y = 120;
koala.alpha = .5;

stage.addChild(desert);
stage.addChild(hydra);
stage.addChild(tulip);
stage.addChild(penguin);
stage.addChild(koala);

 

Única coisa que eu tenho pra comentar nesse código é o método getImage da loader, que à partir dos IDs dos elementos eu consigo agora a imagem deles, agora carregadas.

 

É isso, espero terem aprendido!

 

Exemplo de loader: http://www.andersonferminiano.com/games/imageloader/imageloader.swf

Download do projeto: http://www.andersonferminiano.com/games/imageloader.rar

×
×
  • Criar Novo...