Portando o Web App Bubblewrap para o Google Android* e o Apple iOS* usando o PhoneGap*

O Bubblewrap é um jogo onde o usuário estoura bolhas de plástico. Este artigo descreve como portar o jogo original do Tizen, BubbleWrap usando o Adobe PhoneGap* para que ele rode no Google Android* e no Apple iOS*.

O código fonte deste exemplo pode ser encontrado aqui: https://github.com/gomobile/sample-bubblewrap.

Requisitos

  • Converter o jogo em um App Android e iOS usando o PhoneGap Build e as APIs Apache Cordova*.
  • Corrigir o app para que funcione bem nos navegadores dos dispositivos.
  • Mostrar as bolhas do mesmo tamanho em dispositivos diferentes, com o número de bolhas dependendo do tamanho da tela.

Estado Inicial

Para iniciar, fiz o download da aplicação de sua localidade original no Tizen e a testei em um navegador de um dispositivo móvel. Ela funcionou com a orientação em modo paisagem, mas quando o dispositivo foi rotacionado em 90 graus (modo retrato), o jogo ficou impossível de jogar. As capturas de tela abaixo mostram um exemplo do jogo em modo paisagem:  

e quando o dispositivo foi rotacionado em modo retrato:

Fiz o build deste app usando o PhoneGap Build e testei ele em diversos dispositivos. No Android 4 e no iOS 5.1, encontrei dois problemas: nenhum som e a página de licença do software não era mostrada. No Android 2.3, a situação era pior ainda, pois além dos problemas encontrados no Android 4, a aplicação não escalonava de forma adequada e não cabia na tela -- era impossível de jogar o jogo em um dispositivo com o Android 2.3.

Soluções do Port

APIs Cordova

Eu primeiro adicionei o suporte à API Cordova (anteriormente conhecida como PhoneGap) para reproduzir sons nos dispositivos:

document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
  init();
}

$(document).ready(function(){
  setTimeout(function(){
    init();
  },1000)

  window.onblur = function() {infocus = false;};
  window.onfocus = function() {infocus = true;};
};

A função do Cordova para carregar os arquivos de mídia:

function playMusic(soundPath){ 
  if (window.device)              // verificar se o Cordova/PhoneGap está sendo usado: 
  { 
    var path = getPhoneGapPath(); // caminho para o phonegap 
    path = path+soundPath;        // caminho para o arquivo de mídia 
    var media = new Media( path, mediaCallSuccess, mediaCallError ); 
    media.play(); 
  } 
  else{ 
    new Audio(path).play(); 
  } 
}; 

Eu também alterei o formato dos arquivos de som, de OGG para MP3 para poder suportar o iOS.

Carregamento da Licença

Fiz algumas alterações no processo de carregamento da licença. O app Bubblewrap original utiliza um frame para carregar o texto da licença do software, mas este método não é suportado pelo Cordova. Em vez dele, eu utilizei o seguinte código em dispositivos móveis:

if (window.device) {   // executando no PhoneGap
  var readRequest = new XMLHttpRequest();
  readRequest.open("GET", licFname);
  readRequest.onreadystatechange = function () {  // chamar quando o status for alterado
    if (readRequest.readyState == 4 && readRequest.status == 200) {
      var divLicense = document.getElementById("licensetext");
      divLicense.innerText = readRequest.responseText;
    }
  }
  readRequest.send();
}

Tamanhos das Imagens

Na aplicação original, todas as imagens estão especificadas em pixels. Por isso, eu decidi usar as funções de transformação do CSS scaletranslate para modificar os tamanhos das imagens em função do tamanho da tela. Depois de alguns testes, eu encontrei um problema no escalonamento de imagens do Android 2.3, que gerava um problema com esta estratégia: a função translate funcionava, mas a função scale era ignorada (http://code.google.com/p/android/issues/detail?id=12451). A solução encontrada foi alterar os tamanhos absolutos para percentuais relativos a X.

De acordo com os requisitos, o tamanho das bolhas deveriam parecer o mesmo em todos os dispositivos, o que significa que o número de bolhas exibidas na tela seria dinamicamente ajustado para caber no espaço disponível na tela. Para fazer isso, o tamanho do playview (o container das bolhas) é fixo e não muda, mesmo se a janela do navegador for redimensionada. Revisei os tamanhos no CSS, de pixels absolutos para a utilização de percentuais, mas setando o tamanho do playview em pixels absolutos, usando JavaScript, em função do tamanho da tela:

var screen_height = $(window).height();
var screen_width = $(window).width();
$('#playView').css('height', (screen_height*view_k) + 'px');
$('#playView').css('width', (screen_width*view_k) + 'px');

Agora que o tamanho do container do playview é conhecido, eu posso gerar as bolhas. Primeiro, o número de bolhas é calculado:

var x_bubbles = (width-width%bubble_size)/bubble_size;   // num de bolhas no eixo x
var y_bubbles = (height-height%bubble_size)/bubble_size; // num de bolhas no eixo y

onde width é o tamanho do bubblesheet (que é calculado em função do playview size) e bubble_size é uma constante. Então, uma lista de bolhas somadas aos espaços intermediários pode ser gerada e adicionada ao bubblesheet usando a função appendChild do JavaScript:

for(var i = 0; i<y_bubbles; i++){
  var hbox = document.createElement("div");
  hbox.className = "hbox";
  var bubblegap = document.createElement("div");
  if (i % 2 == 0) {
    bubblegap.className = "bubblegap-odd";
  }
  else {
    bubblegap.className = "bubblegap-even";
  }
  hbox.appendChild(bubblegap);
  for (var j=0; j<x_bubbles; j++){
    var bubble = document.createElement("div");
    bubble.className = "bubble";
    var bubbleOverlay = document.createElement("div");
    bubbleOverlay.className = "bubble-overlay";
    bubble.appendChild(bubbleOverlay);
    bubble.setAttribute('onclick',function(){popBubble()} );
    hbox.appendChild(bubble);
    if (j != (x_bubbles-1)){
       var bubblespace = document.createElement("div");
       bubblespace.className = "bubblespace";
       hbox.appendChild(bubblespace);
    }
  }
  sheet.appendChild(hbox);
}

Agora o aplicativo é redimensionado em função da tela sem ussar as funções scale translate, e pode ser carregado e ser executado com sucesso no Android 2.x, Android 4.x, dispositivos iOS e em navegadores de desktop.


Dispositivos Testados

  • HTC One V (Android 4.0.3)
  • Sony Xperia Go Smartphone (Android 2.3.7) 
  • Samsung Galaxy Tab 2 (7.0) (Android 4.0.3)
  • Apple iPad 2 (iOS 5.1.1)
  • Navegadores de Desktop: Google Chrome 21.0.1180.89, Safari 4.0.5
标签:
如需更全面地了解编译器优化,请参阅优化注意事项