24

Criando Aplicações Móveis com Corona - O Livro

by Luiz Jr 19. outubro 2012 21:06

Criando Aplicações Móveis com Corona

Comprem com o botão na barra lateral do blog! O site de compras é o PagSeguro do UOL, e minha empresa é a Busca Acelerada Ltda.

Depois de algum tempo sem postar nada sobre meu framework multiplataforma favorito: Corona SDK, eis que volto com uma grande notícia pro pessoal que curte fazer apps e games pra smartphones e tablets: acaba de sair do forno a versão em Português do livro "Criando Aplicações Móveis com Corona" de meu amigo o Dr. Brian G. Burton, que é professor do curso de games mobile na faculdade de Abilene, no Texas. O livro é gigantesco, com cerca de 400 páginas e cobre praticamente todas as APIs do Corona, com muitas ilustrações e exemplos de projetos, incluindo várias aplicações e dois games completos, um scrolling shooter (os clássicos jogos de navezinha, tipo G-Darius) e um tower defense (tipo Plants vs Zombies).

O quê? Você não sabe o que é Corona SDK? Criado pela CoronaLabs (antiga Ansca Mobile), ele é um framework de desenvolvimento para smartphones e tablets que lhe permite desenvolver para iOS e Android (entre outras plataformas) de uma vez só, sem ter de transcrever código. Ou seja, você cria seu game ou app usando a linguagem Lua, nativa da plataforma, e gera os arquivos para publicação na Google Play Store e Apple App Store de uma vez só! Imagina o tempo que isto não vai te poupar em sua jornada rumo ao próximo Angry Birds...

A Tradução

A tradução e adaptação do livro, que originalmente se chamava "Beginning Mobile App Development With Corona", foi feita por mim durante o ano de 2012 e gostaria de ficar sabendo de quaisquer erros de Português ou de digitação que vocês encontrarem durante a leitura. Por enquanto o livro encontra-se à venda somente em formato digital, uma vez que custa uma grana preta fazer a versão impressa do mesmo sob o risco de não conseguirmos vender tudo. Para saber tudo o que tem no livro e principalmente para comprá-lo, acessem o blog oficial do livro em http://www.burtonsmediagroup.com/books/criando-aplicacoes-moveis-com-corona

Suporte e Dicas

Continuarei criando posts sobre Corona aqui no blog esporadicamente (como sempre fiz), mas com certeza o conteúdo do livro não será divulgado nos posts (afinal deu muito trabalho traduzir tudo e tenho respeito pelo meu trabalho e do autor). Além disso, todos os desenvolvedores que adquirirem o livro pelo referido site (ou seja, que comprem ele) terão suporte meu e do Dr. Burton por e-mail, ganharão sem custo as versões mais atualizadas do livro que saem esporadicamente e terão acesso a mais alguns materiais traduzidos que devem sair em breve. Mas somente para quem comprá-lo.

Tags: , , , , , , ,

Android | Corona SDK | Dica | iOS | Livros | Lua | Mobile | Projetos | Treinamentos

4

Relançamento do Busca Acelerada

by Luiz Jr 9. agosto 2012 20:50

Busca Acelerada

Boa noite pessoal. Hoje o post na verdade é um jabá descarado de um antigo projeto que só agora foi voltar ao ar: o Busca Acelerada (http://www.buscaacelerada.com.br).

Se eu tivesse que resumir do que se trata o site eu diria que é "O Google dos carros.". Ok, é uma analogia meio pretensiosa mas é basicamente isso mesmo. A ideia é que as pessoas não tenham mais que entrar em diversos sites de anúncios de carros para encontrar o veículo que procuram. Você entra no Busca Acelerada, digita os termos que definem o carro que busca (marca, modelo, etc) e o Busca Acelerada lhe traz o resultado de dezenas de sites de classificados, em milésimos de segundo e com possibilidades de filtrar os resultados, ordenar, etc.

Por enquanto o projeto está em testes (beta) e somente está englobando os cerca de 5700 anúncios de veículos da cidade de Gravataí-RS (a minha). Ainda assim, eu gostaria que acessassem e dessem um feedback, seja aqui pelo blog, pela página do facebook (http://www.facebook.com/BuscaAcelerada). Em breve estarei, em conjunto de meus sócios Lucas Pfeiffer e Adriano Costa, expandindo o sistema para todo RS e posteriormente para todo Brasil. Então mesmo que não seja Gravataiense como eu, me ajude a construir a melhor ferramenta de busca de veículos do país.

Valeu!

Tags: , ,

ASP.NET | Projetos | Web

17

Sunset Riders Lite com Corona SDK - First Step

by Luiz Jr 21. junho 2012 23:08

Depois de muito tempo sem postar sobre Corona SDK, o nosso framework favorito para desenvolvimento de jogos móveis multi-plataforma, eis que eu volto à ativa no desenvolvimento mobile de games com um clássico dos clássicos: Sunset Riders. Ok, eu já vinha desenvolvendo ele em posts anteriores, mas agora é pra valer. Atendendo a inúmeros pedidos o post de hoje inclui uma série de conceitos importantíssimos: botões, splash screen, tela de seleção de personagens, multimídia, sprites e por aí vai. Como o código é um pouco extenso, me aterei em comentar as etapas mais importantes. Use o link no final do post para baixar o projeto completo e até mesmo o executável para Android caso queira testar em um dispositivo de verdade.

Splash Screen do Sunset Riders Lite

Splash Screen

As splash screens são as clássicas telas de abertura do jogo, onde geralmente temos uma imagem e um menu opcional. No nosso caso, será apenas uma imagem estática do jogo original que achei na Internet, que quando tocada, se fecha, exibindo a tela anterior da pilha de execução. Para esta tela criei um arquivo chamado splashscreen.lua que eu apenas invoco usando require no main.lua.

 

module(..., package.seeall);

local tela = display.newImageRect( "image/splash-screen.jpg",display.contentWidth,display.contentHeight);
 tela:translate(240,160);

 function dismiss(event)
	tela:removeSelf();
 end

 tela:addEventListener("tap", dismiss);

Note que a imagem foi colocada dentro de uma pasta image dentro da pasta do projeto. Encontrará todas as imagens utilizadas neste post nos fontes do projeto.

Seleção de Personagem

Seleção de Personagens

Embora nos exemplos anteriores tenhamos apenas oferecido o Cormano como única opção de cowboy, sabemos que ele não é unanimidade entre os gamers mundo afora. Eu particularmente gostava de jogar com o Bob e suas espingardas, enquanto meus amigos curtiam o xerife Billy. Como segundo passo, criaremos uma tela de seleção de personagem. Seguindo as boas práticas de programação Lua criaremos um arquivo Lua para cada tela, assim como fizemos com a Splash Screen, então, crie um playerselect.lua e coloque lá o código abaixo:

module(..., package.seeall);

local selected = "steve";
local player;

function getSelected()
	return selected;
end

function isVisible()
	return player.isVisible;
end

local callbackFunction;
function callback(listener)
	callbackFunction = listener;
end

function configuraTela()
	player = display.newImageRect( "image/select-"..selected..".png", display.contentWidth, display.contentHeight);
	player:translate(240,180);
	player:addEventListener("tap", selectPlayer);
end

function selectPlayer( event )
   if(selected == "steve") then
	   if(event.x >= 1 and event.x <= 114) then--steve
			player.isVisible = false;
		elseif (event.x >= 151 and event.x <= 207) then--billy
			selected = "billy";
		elseif (event.x >= 271 and event.x <= 327) then--bob
			selected = "bob";
		elseif (event.x >= 391 and event.x <= 448) then--cormano
			selected = "cormano";
	   end
	elseif (selected == "billy") then
		if(event.x >= 30 and event.x <= 87) then--steve
			selected = "steve";
		elseif (event.x >= 119 and event.x <= 234) then--billy
			player.isVisible = false;
		elseif (event.x >= 271 and event.x <= 327) then--bob
			selected = "bob";
		elseif (event.x >= 391 and event.x <= 448) then--cormano
			selected = "cormano";
	   end
	elseif (selected == "bob") then
		if(event.x >= 30 and event.x <= 87) then--steve
			selected = "steve";
		elseif (event.x >= 150 and event.x <= 207) then--billy
			selected = "billy";
		elseif (event.x >= 240 and event.x <= 355) then--bob
			player.isVisible = false;
		elseif (event.x >= 391 and event.x <= 448) then--cormano
			selected = "cormano";
	   end
	elseif (selected == "cormano") then
		if(event.x >= 30 and event.x <= 87) then--steve
			selected = "steve";
		elseif (event.x >= 150 and event.x <= 207) then--billy
			selected = "billy";
		elseif (event.x >= 269 and event.x <= 328) then--bob
			selected = "bob";
		elseif (event.x >= 358 and event.x <= 476) then--cormano
			player.isVisible = false;
	   end
	end

	player:removeSelf();
	if(player.isVisible == true) then
		configuraTela();
	else callbackFunction();
	end
end

Uma breve explicação quanto a este código pode ser resumida no seguinte: para cada estado possível da tela, e são 4 (um para cada personagem) temos uma imagem diferente com o personagem realçado, ou seja, removemos a imagem anterior e carregamos a nova imagem na tela, dando a impressão de seleção de personagem, assim como no jogo original. Ao ser tocada a primeira vez, a tela realça o personagem e guarda seu nome na variável selected, no segundo toque no mesmo personagem, a tela é dispensada para que exiba o item anterior na pilha gráfica do Corona. As funções deste arquivo servem para expor alguns valores para os demais arquivos do projeto (principalmente o main.lua), como por exemplo, para o main.lua saber quem foi o personagem escolhido.

Estrutura de pastas do projeto

Orientação à Objetos

Lua não é orientado à objetos. É uma linguagem simples de scripting que é perfeita para criação de lógica de jogos. Entretanto, quando se programa a anos como eu e sabe-se que bons projetos não vão longe sem um mínimo de arquitetura e por isso você já deve ter notado que estou estruturando melhor os arquivos deste projeto em pastas, arquivos, etc. Desta forma, um conceito importantíssimo para criação de bons projetos são os conceitos de orientação à objetos que entre uma de suas premissas está o fato de que não se deve repetir código. Mas se todos personagens pulam, correm e param, como que não repetiremos esse código? A idéia é simples, vamos criar um arquivo chamado character.lua e nele vamos colocar tudo o que é comum aos personagens, como segue:

-- Arquivo contendo toda a lógica comum a todos os personagens
module(..., package.seeall);

local velocidade = 500;
local started = false;

function getVelocidade()
	return velocidade;
end

function start()
	started = true;
end

--carregando as variáveis e constantes
local relincho = audio.loadSound("audio/relincho.wav");
local trote = audio.loadSound("audio/galope.wav");
local canalTrote;
local cavaloY = 225;
local cavaloX = display.contentWidth / 4;
local escala = 1.2;

local galopandoSheet;
local galopandoSpriteSet;
local galopandoStance;

local jumpingSheet;
local jumpingSpriteSet;
local jumpingStance;

local parado;

function parar()
	audio.pause(canalTrote);

	parado.x = galopandoStance.x;
	parado.y = galopandoStance.y;

	parado.isVisible = true;
	galopandoStance.isVisible = false;
	jumpingStance.isVisible = false;
end

function galopandoConfig(nomeChar,spriteWidth,spriteHeight,spritesNumber)
	galopandoSheet = sprite.newSpriteSheet( "image/"..nomeChar..".png", spriteWidth,spriteHeight );

	galopandoSpriteSet = sprite.newSpriteSet(galopandoSheet, 1, spritesNumber);
	sprite.add( galopandoSpriteSet, nomeChar, 1, spritesNumber, velocidade, 0 );-- roda 5 frames/velocidade

	galopandoStance = sprite.newSprite( galopandoSpriteSet );
	galopandoStance.x = cavaloX + 40;
	galopandoStance.y = cavaloY;
	galopandoStance.xScale = escala;
	galopandoStance.yScale = escala;
	galopandoStance.isVisible = false;

	galopandoStance:addEventListener("tap", parar);
end

function jumpingConfig(nomeChar,spriteWidth, spriteHeight, spritesNumber)
	jumpingSheet = sprite.newSpriteSheet( "image/"..nomeChar.."-jump.png", spriteWidth, spriteHeight )

	jumpingSpriteSet = sprite.newSpriteSet(jumpingSheet, 1, spritesNumber)
	sprite.add( jumpingSpriteSet, nomeChar.."-jumping", 1, spritesNumber, 500, 1 ) -- play 3 frames every 500 ms

	jumpingStance = sprite.newSprite( jumpingSpriteSet )
	jumpingStance.x = cavaloX + 40
	jumpingStance.y = cavaloY;
	jumpingStance.xScale = escala;
	jumpingStance.yScale = escala;
	jumpingStance.isVisible = false;

	jumpingStance:addEventListener("sprite", fimPulo);
end

function paradoConfig(nomeChar)
	parado = display.newImage( "image/"..nomeChar.."-parado.png" )
	parado:setReferencePoint( display.CenterLeftReferencePoint )
	parado.x = cavaloX;
	parado.y = cavaloY;
	parado.xScale = escala;
	parado.yScale = escala;
	parado.isVisible = true;

	parado:addEventListener("tap", galopar);
end

function isParado()
	return parado.isVisible;
end

function galopar(nomeChar)
	if(started == true) then
		audio.play(relincho);
		canalTrote = audio.play(trote, {loops=-1});
		parado.isVisible = false;
		jumpingStance.isVisible = false;
		galopandoStance.isVisible = true;
		galopandoStance:prepare(nomeChar);
		galopandoStance:play();
	end
end

function pulo(nomeChar)
	if (parado.isVisible == false) then
		audio.play(relincho);
		galopandoStance.isVisible = false;

		jumpingStance.x = galopandoStance.x;
		jumpingStance.y = galopandoStance.y;

		jumpingStance.isVisible = true;
		jumpingStance:prepare(nomeChar.."-jumping")
		jumpingStance:play()
	end
end

function fimPulo(event)
	if (event.phase == "end") then
		parado.isVisible = false;
		galopandoStance.isVisible = true;
		jumpingStance:pause();
		jumpingStance.isVisible = false;
	end
end

function onMove(event)

	if (parado.isVisible == false) then
		local joyX = event.joyX
		local joyY = event.joyY

		if(joyX ~= false and joyY ~= false) then
			if(joyX > 0) then
				if(galopandoStance.x < display.contentWidth - 55) then
					galopandoStance.x = galopandoStance.x + 5;
				end
			else
				if(galopandoStance.x > 30) then
					galopandoStance.x = galopandoStance.x - 5;
				end
			end

			if(joyY > 0) then
				if(galopandoStance.y < 250) then
					galopandoStance.y = galopandoStance.y + 5;
				end
			else
				if(galopandoStance.y > 180) then
					galopandoStance.y = galopandoStance.y - 5;
				end
			end
		end
	end
end

Note que este arquivo carrega os sprites de maneira dinâmica, conforme o nome que for passado por parâmetro. Isso porque cada personagem terá suas próprias sprites, ou seja, só o que muda entre os personagens é seu nome (as spritesheets possuem os nomes dos personagens) e a largura e altura das sprites. O resto é exatamente igual. A função onMove será usada para manipularmos o personagem através do joystick que adicionaremos mais para frente na aplicação. Por ora, deixem-na quieta.Note também a forma como estamos carregando os áudios, de dentro de uma pasta audio, com a API audio (pois a API media foi descontinuada) e que não usamos mais os MIDs que usamos nos exemplos anteriores. A nova APi de áudio usa OpenAL e não suporta mais MID. Uma boa alternativa é WAV e incluí nos fontes do projeto os arquivos de áudio para que possa tê-los em seu projeto também.

A ideia é que todos os personagens vão carregar esta biblioteca em uma variável e chamar suas funções para carregar as sprites e poder correr, pular, etc, como veremos a seguir para o personagem Billy:

Billy Galopando

-- Arquivo contendo toda a lógica do personagem Billy
module(..., package.seeall);
local char = require("character");
local nomeChar = "billy";

function getVelocidade()
	return char.getVelocidade();
end

function start()
	char.start();
end

char.galopandoConfig(nomeChar, 96,80,5)
char.jumpingConfig(nomeChar,80,97,3);
char.paradoConfig(nomeChar);

function isParado()
	return char.isParado();
end

function galopar()
	char.galopar(nomeChar);
end

function parar()
	char.parar();
end

function pulo()
	char.pulo(nomeChar);
end

function onMove(event)
	char.onMove(event);
end

Note a simplicidade de criar um novo personagem usando esta arquitetura de software simplíssima baseada em Orientação à Objetos, ao criarmos o personagen Steve:

Steve galopando

-- Arquivo contendo toda a lógica do personagem Steve
module(..., package.seeall);
local char = require("character");
local nomeChar = "steve";

function getVelocidade()
	return char.getVelocidade();
end

function start()
	char.start();
end

char.galopandoConfig(nomeChar, 96,79,5)
char.jumpingConfig(nomeChar,80,95,3);
char.paradoConfig(nomeChar);

function isParado()
	return char.isParado();
end

function galopar()
	char.galopar(nomeChar);
end

function parar()
	char.parar();
end

function pulo()
	char.pulo(nomeChar);
end

function onMove(event)
	char.onMove(event);
end

Não postarei o código dos demais personagens pois acredito que sejam capazes de deduzir por vocês mesmos. Note que o que fizemos foi criar uma espécie de herança da orientação à objetos de uma forma tosca mas que funciona.

Agora que temos todos os personagens criados, vamos criar novamente o plano de fundo de nossa aplicação que conta com trilha sonora, trilhos de trem e uma bela paisagem do oeste selvagem!

Sunset Riders Lite com Cenário, Joystick e Botões

Cenário, Joystick e Botões

Já havíamos criado o cenário em posts anteriores e mesmo com essa nova abordagem mais arquitetural, o código ainda se parece com o código antigo. As imagens ainda são as mesmas de antes, mas agora temos algumas adicionais que nos levam a estudar duas bibliotecas antes: ui.lua e joystick.lua.

A biblioteca ui.lua lhe permite criar botões de forma muito mais fácil e é largamente utilizado em projetos Lua. O projeto inclui uma versão desta biblioteca, a última na época deste tutorial (1.6) e seu uso neste game é para criar dois botões, o de pular (que dispara a função de salto do personagem) e o de atirar, que ainda não tem utilidade mas que no futuro irá disparar projéteis com as armas dos personagens.

 

local ui = require("ui");
function jumpButtonEvent(event) personagem.pulo(); end function shotButtonEvent(event) print("shot"); end function configuraButtons() jumpButton = ui.newButton{ default = "image/jump-button.png", over = "image/jump-button-over.png", onRelease = jumpButtonEvent, x = display.contentWidth - 50, y = display.contentHeight - 75 }; shotButton = ui.newButton{ default = "image/shot-button.png", over = "image/shot-button-over.png", onRelease = shotButtonEvent, x = display.contentWidth - 50, y = display.contentHeight - 150 }; end

Este código deve ir no main.lua, que é um arquivo tão extenso que não incluirei aqui. Apenas pegue os fontes deste projeto e busque este trecho de código para saber onde colocar o seu. Note que as imagens para os botões são duas: a normal e a de botão pressionado. Além disso, os botões disparam uma função quando selecionados, funções estas definidas nas linhas anteriores ao carregamento dos mesmos. Note também que na função de pulo mandamos uma variável personagem pular, sem nem mesmo saber qual personagem que estamos jogando, o que é indiferente para nós. Em orientação à objetos poderíamos dizer que emulamos uma interface.

 

Outra biblioteca importante que usaremos hoje é a biblioteca joystick.lua (a versão 1 se encontra no projeto), que cria um direcional analógico assim como o visto em controles de Nintendo 64 e Playstation. Esse joystick usa duas imagens existentes em nossa pasta de imagens e dispara o evento onMove presente na biblioteca character.lua. Isso porque independente de personagem, ele se moverá da mesma forma, não é mesmo? Para usar o joystick.lua, use o seguinte código:

 

local joystickClass = require( "joystick" );
function configuraJoystick() joystick = joystickClass.newJoystick{ outerImage = "", outerRadius = 60, outerAlpha = 0, innerImage = "image/joystickInner.png", innerRadius = "", innerAlpha = 1, backgroundImage = "image/joystickDial.png", background_x = 0, background_y = 0, backgroundAlpha = 1, position_x = 0, position_y = baseline - 100, ghost = 0, joystickAlpha = 0.4, joystickFade = true, joystickFadeDelay = 2000, onMove = personagem.onMove } end

 

Olhando este código não é muito difícil de imaginar para que servem as propriedades que configuramos, sendo que as principais delas são as imagens que formam o joystick e a função que vai ser executada toda vez que o joystick for utilizado (neste caso, a onMove do personagem).

Mas voltando a ponto que havíamos parado no último tutorial, o plano de fundo é extremamente simples de implementar novamente, bastando carregar os trilhos duas vezes, adicionar música e os demais elementos, incluindo o próprio personagem. Muita atenção à ordem dos elementos no main.lua pois eles são colocados no display na ordem em que são instanciados. Ou seja, o que você quiser que sua aplicação exiba primeiro deve estar no final do arquivo (como a splashscreen e a selectplayer, por exemplo). Tendo isso em mente, o código para o cenário do jogo com os elementos juntos fica assim:

 

-- Arquivo contendo toda a lógica da aplicação Sunset Riders Lite
display.setStatusBar(display.HiddenStatusBar);
system.activate( "multitouch" );

local playerSelect = require("playerselect");
local joystickClass = require( "joystick" );
local ui = require("ui");
require "sprite";

 

Primeiro escondemos a barra de status, carregamos a tela de seleção d epersonagem 9que ainda não é exibida pois exige a chamada de uma função para tanto. Ativamos multitouch em nossa aplicação pois possuímos um joystick e botões, esperando que os usuários jogarão com as duas mãos sobre o dispositivo (impossível de testar no simulador), carregamos as bibliotecas ui e sprite, necessárias mais para frente. Continuando:

 

--variáveis e constantes
local started = false;
local baseline = 280;
local escalaTrilhos = 1.3;
local trilhosY = baseline - 115;
local textoX = 150;
local textoY = baseline - 175;
local velocidadeFundo = 0.2;--quanto maior mais rápido
local milhas = 0;--número de milhas percorridas pelo cowboy
local percurso = 10;--milhas até a cidade
local victoryMusic = audio.loadSound("audio/victory.wav");
local backMusic = audio.loadSound("audio/sunset-riders-bonus-stage.wav");
local backChannel;
local jumpButton, shotButton;
local tPrevious = system.getTimer()

 

Algumas variáveis e constantes para definir a linha base de onde o personagem inicia o jogo, a escala dos trilhos, a posição XY dos textos, trilhos, a velocidade do fundo, o número de milhas percorridas pelo cowboy (sim, um dia a fase irá acabar) o tamanho do percurso em milhas, a música de vitória, a música de fundo, o canal da música de fundo (para poder desligá-la depois), os dois botões e o tempo atual do sistema, para sincronizar as atualizações dos trilhos. Mais código:

 

-- Trilhos
-- O dobro de trilhos para fazer a animação
-- Quando um dos trilhos termina, aparece o outro
function montaTrilhos(x)
	local rails = display.newImage( "image/trilhos.jpg" )
	rails:setReferencePoint( display.CenterLeftReferencePoint )
	rails.y = trilhosY;
	rails.x = x;
	rails.xScale = escalaTrilhos;
	rails.yScale = escalaTrilhos;
	return rails;
end

local trilhos = montaTrilhos(0);
local trilhos2 = montaTrilhos(trilhos.contentWidth);

 

Aqui montamos os trilhos d emaneira bem simples, assim como havíamos construído antes. A diferença é a função que evita repetição de código.

 

--função para configurar um novo texto a ser exibido
function montaTexto(texto)
	local rotulo = display.newImage( "image/"..texto..".png" );
	rotulo:setReferencePoint( display.CenterLeftReferencePoint )
	rotulo.x = textoX;
	rotulo.y = textoY;
	rotulo.isVisible = false;
	return rotulo;
end

local textoStart = montaTexto("start");
textoStart.isVisible = true;
local textoHurry = montaTexto("hurry");
local textoVictory = montaTexto("victory");

 

Aqui temos uma função para montar os textos que usaremos na aplicação. Use esta função para exibir quaisquer textos no formato padrão do nosso jogo, basta ter as imagens corretas n pata de imagens do projeto. Agora vamos mover os elementos:

 

local personagem;

-- movendo os elementos
local function move(event)
	if(started == true and personagem.isParado() == false) then
		local tDelta = event.time - tPrevious;
		tPrevious = event.time;

		local xOffset = ( velocidadeFundo * tDelta )

		trilhos.x = trilhos.x - xOffset;
		trilhos2.x = trilhos2.x - xOffset;

		if (trilhos.x + trilhos.contentWidth) < 0 then
			milhas = milhas + 1;
			trilhos:translate(trilhos.contentWidth * 2, 0)
		end

		if (trilhos2.x + trilhos2.contentWidth) < 0 then
			milhas = milhas + 1;
			trilhos2:translate( trilhos2.contentWidth * 2, 0)
		end

		if(milhas >= percurso) then
			started = false;
			--jogo terminou
			personagem.parar();
			milhas = 0;
			textoVictory.isVisible = true;
			audio.pause();
			audio.play(victoryMusic);
		end
	end
end

--joystick
--botões

 

Este código é chamado a cada atualização de tela do dispositivo e redesenha o cenário conforme o tempo do sistema. Além disso, conta quantas vezes o cenário já foi desenhado por completo para contar as milhas do projeto e dizer se o cowboy já chegou no final do projeto ou não, neste caso tocando uma música de vitória. No último comentário é onde deve ser colocado o código do joystick, sem o comando require que já foi chamado antes no início do arquivo. Onde diz botões, deve ser colocado o código dos botões sem o comando require. Vamos ao último trecho de código do main.lua:

 

--função de início
local function start()
	if(playerSelect.isVisible() == false) then

		personagem = require (playerSelect.getSelected());
		configuraJoystick();
		configuraButtons();

		backChannel = audio.play(backMusic, { loops=-1 });
		started = true;
		textoStart.isVisible = false;
		personagem.start();
	end
end

playerSelect.callback(start);
Runtime:addEventListener( "enterFrame", move );
playerSelect.configuraTela();
local splashScreen = require("splashscreen");

Este trecho define a função de início de jogo, define a função de callback da tela de seleção de personagem (uma função de callback é uma função que será executada quando a tela de seleção de personagem for fechada) e o gatilho para o evento enterFrame, que é chamado uma vez para cada refresh da tela (o que depende do framerate do dispositivo, que pode variar de 30 a 60fps). E por fim, configura a tela de seleção de personagem (desenha) e carrega a splash screen (desenha-a também). Note que as primeiras telas do jogo são as últimas a serem desenhadas.

Os arquivos build.settings e config.lua ainda são os mesmos do último projeto de exemplo e não serão repetidos. Pronto, nosso jogo está pronto para ser executado e até mesmo ter uma versão compilada para ser instalado em um dispositivo de verdade. Incluí no final deste post os arquivos do projeto completo e o arquivo APK para instalação no Android.

Sunset Riders Lite 0.1 lançado!

Conclusões e Futuro

Espero que tenham gostado deste post que ficou muito extenso pois acabei me empolgando no desenvolvimento do game ao longo da semana e me esqueci de ir fazendo este post aos poucos ou até mesmo em pedaços, explicando cada uma das etapas em detalhes. De qualquer forma acredito que servirá para saciar a vontade do pessoal que queria ver coisas como botões, joysticks e a continuidade do jogo, que na verdade meio que começou a ser desenvolvido de verdade agora.

Para o futuro penso em adicionarmos uma barra de progresso enquanto o jogo está sendo inicializado, uma animaçãozinha de abertura, alguns efeitos sonoros adicionais, tiros e alguns obstáculos a serem saltados pelos personagens para dar algum sentido à fase. Então até o próximo post!

Quer saber tudo sobre Corona SDK? Compre já o meu livro!

Sunset Riders Lite 0.1.apk.zip (8,12 mb)

SunsetRiders-4.zip (6,13 mb)

Tags: , , , , ,

Android | Corona SDK | Lua | Mobile | Projetos

0

Ciclo de palestras na FAQI e demais projetos

by Luiz Jr 23. novembro 2011 19:55

Nesta segunda e terça-feira tive a oportunidade de conhecer a FAQI de Porto Alegre, graças ao contato do Prof. João Moreira, coordenador do curso de Análise e Desenvolvimento de Sistemas da instituição. Nos conhecemos na minha última visita à FAQI Gravataí, onde palestrei sobre Cloud Computing, palestra esta que eu e meu colega da RedeHost, Cristiano, temos ministrado em mais de uma dezena de instituições pelo Rio Grande do Sul afora. Desta vez não foi diferente, nossa presença na instituição foi para estreitar ainda mais os laços entre RedeHost e FAQI, enquanto empregadores e educadores.

Eu apresentando a RedeHost pro pessoal

Com esta palestra, provavelmente terá encerrado minha participação em eventos acadêmicos este ano, uma vez que estamos chegando em dezembro, e com ele, o recesso das instituições de ensino. Não que isto signifique o encerramento de minhas atividades relacionadas à ensino, já estão engatilhados novos cursos de desenvolvimento, em cima de plataformas mais tradicionais, como o curso recém organizado de C# Nível 2 que deve estreiar na Facensa no verão e principalmente, minhas estréia como ministrante de cursos em cima de mobilidade, com plataformas como Android, Windows Phone 7 e iOS (bom, quem acompanha o blog sabe do que estou falando!). Embora oficialmente eu não tenha fechado com nenhuma instituição (estou no aguardo de algumas confirmações), considero que 2012 será um grande ano para meus estudos nestas plataformas e que conseguirei alguns bons contratos enquanto instrutor.

2ª dia de palestra na FAQI

E por fim, hoje estive conversando com o Prof. Heitor Boeira, coordenador do curso de Análise e Desenvolvimento de Sistemas da FAQI Gravataí, para montarmos a agenda de cursos de extensão de 2012, desta vez focados em Linux e Virtualização, com os instrutores e colegas Diego Voltz e Cristiano Diedrich. Em contrapartida, a FAQI finalmente fechou conosco o tão aguardado convênio educacional, onde colaboradores da RedeHost terão desconto nos cursos de gradução e pós-graduação na instituição. Com isso, nossos profissionais terão mais um benefício oferecido pela empresa e mais uma motivação para estudarem. Outras parcerias estão em vias de serem fechadas, mas é cedo para comentar ainda...

Hoje o post foi curto, nada de tutorial ou algo do gênero, apenas o uso deste espaço para divulgar meu trabalho. Tenha uma boa semana!

Tags: ,

Blog | Cloud | Eventos | Experiências | Me | Projetos

0

Últimas palestras realizadas

by Luiz Jr 29. outubro 2011 21:25

Pra não perder tempo escrevendo quase todo dia sobre uma palestra nova, resolvi postar várias de uma vez só. Os últimos meses tem sido tranquilos com relação à cursos de extensão, mas tumultuados quando o assunto são palestras. Eu e meu colega Cristiano Diedrich estivemos visitando algumas instituições e palestrando sobre um dos assuntos em que a RedeHost é referência nacional: Cloud Computing. Além disso, também estivemos falando sobre carreiras em TI e inclusive fomos entrevistados para um importante jornal regional, aqui de Gravataí que tem me dado uma certa notoriedade na região, hehehehe.

Cloud Computing na Ulbra Canoas

Ciclo de Palestras nos campi da Ulbra

Nenhuma parceria educacional nos rendeu tanto espaço no meio acadêmico quanto com a Universidade Luterana do Brasil. Depois de nossa passagem pela instituição lecionando cursos de ASP.NET e Linux, tivemos diversas outras visitas, não apenas na Ulbra de Canoas, mas nas unidades de Cachoeira do Sul (no centro do estado) e recentemente na unidade de Guaíba. Ajudando a promover o nome da empresa e dividir um pouco de nossa expertise em Cloud Computing e virtualização, tivemos o prazer de palestrar para mais de 150 alunos de cursos superiores de TI, somente nestas ocasiões. E a parceria com essa que é uma das maiores redes de universidades do Brasil ainda vai render muitos frutos em breve, pois já somos figuras confirmadas na próxima edição do Seminfo, que deve ocorrer na Ulbra de Torres no verão próximo. Pois é, além de patrocinadores pretendemos ministrar palestras e mini-cursos no evento, e infelizmente terei de passar um final de semana na praia por conta da empresa...

Aproveito o post para agredecer mais uma vez ao prof. Anderson Yanzer, coordenador da área de informática do campus Canoas, ao prof. Maurício Escobar, pelo constante suporte nos cursos de extensão que ministramos por lá, ao prof. Rodrigo Keller, coordenador de Cachoeira do Sul, pela hospitalidade sem igual e ao prof. César Loureiro, pelo convite que nos levou até a Ulbra de Guaíba. Contem comigo pro que precisarem!

Carreira em TI no Dom Feliciano

Palestras sobre carreira no Dom Feliciano

Mas voltando à nossa terra natal (da RedeHost, eu sou de Porto Alegre, hehehehe) fomos convidados a conversar com as turmas de 3º ano do Ensino Médio e do curso Técnico em Informática da escola Dom Feliciano em Gravataí. Por aqui a conversa foi diferente, tratamos de um assunto muito importante pra gurizada que está na época mais confusa da vida: a adolescência. Eu e o Cristiano pudemos dividir nossas experiências com carreiras de TI, mais especificamente nas áreas de desenvolvimento (eu) e Infraestrutura (ele). Falamos de tendências de mercado, exigências, remuneração, perspectiva, e acredito que tenhamos motivado muitos alunos a ingressarem na área ou continuarem com sua opção. Essa é a idéia, fomentar o desenvolvimento tecnológico da região nessa garotada para colher os frutos no futuro.

Não apenas a palestra, iremos lecionar dois novos cursos na instituição: Linux e Virtualização. Sim, os mesmos que foram lecionados em nossa outra parceira, facensa, em julho. Uma vez que paramos por enquanto com a contratação de aprendizes de programação, por ora não ministrarei novamente o curso básico de ASP.NET nesta instituição. Mas quem sabe no ano que vem? Destaco também nossa aparição no jornal Correio de Gravataí, onde tiraram algumas fotos nossas e fui entrevistado por um repórter local. Pena que não mencionaram o nome da RedeHost na reportagem, afinal, o projeto é uma parceria bilateral, e não apenas uma idéia da escola...Quem quiser dar uma conferida na reportagem, é só acessar a edição online do jornal (http://www.bancadigital.com.br/cg/cgravatai/reader2/), na edição do dia 27/10/11 na página 7. Sim aquele cara fazendo uma pose estranha sou eu...Nunca saio direito nessas fotos...

FAQI - Palestra de Cloud COmputing

Onde tudo começou: FAQI!

No dia 21 deste mês fez um ano que pus em prática meu ambicioso projeto de levar o nome da RedeHost às principais instituições da região metropolitana de Porto Alegre, visando promover a marca, capacitar e captar talentos. Principalmente em Gravataí, região onde a empresa está instalada, não queria mais perder bons profissionais para empresas de fora da região e montei um plano agressivo de expansão do setor através de palestras e cursos nas tecnologias que utilizamos. No dia 21 de outubro de 2011, eu e nosso CEO, Flávio Cardoso, estivemos visitando a Faculdade de Tecnologia de Gravataí, mais conhecida como FAQI, palestrando sobre nossa empresa e as oportunidades em aberto na mesma. Também falamos do curso pioneiro na cidade, de desenvolvimento web com ASP.NET e SQL Server, ministrado por mim nas tardes de sábado do mesmo ano. Ou seja, faz um ano que dei o primeiro passo com o projeto e tenho o orgulho de admitir que foi um sucesso. Não só nosso nome está na boca de centenas (talvez já estejamos na casa dos milhares) de alunos de instrução técnico-superior no estado e qual melhor resultado senão o crecsimento do nosso setor em módicos 100%? Quando comecei com o projeto, tínhamos 12 profissionais, hoje temos 24 desenvolvedores em diferentes níveis de instrução. Ok, nem todos vieram diretamente dos cursos, mas muitos vieram de forma indireta como publicidade espontânea (o famoso "boca-a-boca") e uns poucos caíram de pára-qeudas. Poucos mesmo.

Pois bem, comemorando um ano do projeto, voltei à instituição que primeiro nos abriu as portas e palestrei sobre Cloud Computing, desta vez sozinho (o Cristiano estava ao mesmo tempo palestrando no Instituto Federal de Ciência e Tecnologia do RS, em porto Alegre, graças à indicação da Ulbra Canoas). A palestra foi um sucesso mais uma vez, estando com a sala cheia de alunos. O êxito foi tão positivo que recebi alguns currículos no dia seguinte, um convite para palestrar sobre o mesmo tema na FAQI de Porto Alegre e pasmem, em breve fecharemos um convênio com a instituição para fornecer descontos aos colaboradores da RedeHost que estudam ou pretendem estudar na instituição. É mole?

Curso de Corona SDK saindo do forno!

Conclusões

O ano não terminou ainda e muitas novidades ainda vem por aí. Em breve aplicarei prova de seleção na Facensa, para o novíssimo curso "Desenvolvimento Web com ASP.NET + SQL Server - Módulo II" que deve sair em janeiro. Também estou acertando com a mesma instituição, desta vez por conta própria, enquanto profissional liberal, um novo curso que montei voltado ao desenvolvimento mobile: "Desenvolvimento de games para Android e iOS" onde ensinarei como utilizar Lua e Corona SDK para desenvolvimento mobile multiplataforma. Até onde sei, somente um outro lugar no Brasil realizou um curso desses e ando conversando com Carlos Icaza, co-fundador da Ansca Mobile para me tornar uma referência no assunto no Brasil em breve.

Também será retomada em breve as negociações para a RedeHost ministrar o curso de Linux e o de Virtualização na FAQI em breve. Qual não foi minha surpresa quando descobri que o atual coordenador do curso superior da FAQI é meu ex-professor e empresário prof. Heitor Boeira. Uma vez que ambos se conhecem e sabem da seriedade do trabalho um do outro, acredito que a parceria RedeHost/FAQI trará muitos frutos em breve e crescerá exponencialmente neste ano que virá.

Pra encerrar o post, nesta próxima semana receberemos a visita de dois ilustres professores de instituições parceiras: o prof. Roberto Litel, do Alcides Maya e o prof. Arno Oelrich, do Pastor Dohms. A idéia é estreitar os laços com estas instituições, para dessa vez, tentar conseguir reforços para nosso setor de infraestrutura. Quaisquer novidades que eu achar pertinentes, eu coloco no próximo post sobre minhas aventuras na RedeHost. Até lá!

Tags: , ,

Cloud | Eventos | Experiências | Mercado | Projetos | Treinamentos

Powered by BlogEngine.NET 1.6.1.0
Design por Laptop Geek, adaptado por onesoft e personalizado por mim.