Exercício fácil: Usando Promises

Olá pessoal! Neste exercício iremos praticar um pouco o uso de promises. As promises vem do termo “promessa”, que representa um valor que pode estar disponível em algum momento no futuro, no presente, ou nunca estar disponível. Ele é um objeto utilizado em processamento assíncrono.

Caso você ainda não saiba o que são promises, verifique o link abaixo antes de prosseguir com o seu exercício:

Vamos ao exercício:

Primeiramente, crie um arquivo chamado scripts.js. Neste arquivo, iremos criar uma função de soma que precisará ter como resultado um número par. Para isso, você precisará criar os seguintes callbacks:

  • callbackSucesso() = trará uma mensagem de sucesso, dizendo que a operação foi concluída com sucesso e que o número somado é par.
  • callBackError() = trará uma mensagem de erro, dizendo que a operação falhou, trazendo um número impar (resultado da soma).

Tome como base o seguinte código:

function somar(){
    if (){
        callbackSucesso();
    } else {
        callbackError();
    }
}

function callbackSucesso(){

}

function callbackError(){
 
}

É muito importante a realização deste exercício para darmos continuidade!

Transformando o exercício em uma promise:

Utilize a função anterior para criar uma promise que tenha:

  • then: uma mensagem de sucesso, informando que a operação foi concluída com sucesso, dizendo se é par ou ímpar e trazendo o número;
  • catch: uma mensagem de erro, informando que a operação possui erro, dizendo se é par ou ímpar e trazendo o número.

Dica: Utilize uma promise com função (resolve, reject).

Observação: Conhecimentos aritméticos serão necessários para a realização deste exercício.

Use este arquivo js como referência:

function soma (){
    let p = new Promise() {        
        if (){
            resolve();
        } else {
            reject();
        }
    })
    
    p.then(() {
    }).catch(() {
    })
}

 

Resolução:

Segue abaixo o arquivo de solução para as respectivas fases do exercício

[download id=”3554″]

 

 

Utilizando o File System para leitura e criação de arquivos

O módulo File System do Node.js permite o trabalho com o sistema de arquivos do computador. Podemos incluir o File System no nosso arquivo js utilizando o método require:

let fs = require('fs');

Para que serve o módulo File System? O que podemos fazer com ele?

  • Ler arquivos
  • Criar arquivos
  • Atualizar arquivos
  • Deletar arquivos
  • Renomear arquivos

Para ler arquivos usando o file system:

Podemos utilizar o método fs.readFile() para ler arquivos salvos no computador. Por Exemplo, podemos ter o seguinte arquivo html (que esteja localizado na mesma pasta de execução do node):

<!DOCTYPE html>
<html lang="pt-br">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>readFile()</title>
</head>
<body>
    <h1>Cabeçalho da página</h1>
    <p>Parágrafo da página</p>
</body>
</html>

Após isso, criemos um arquivo javascript (node) para ler o nosso arquivo html e retornar o conteúdo:

// criando uma requisição http para criação do servidor
let http = require('http');

// criando uma requisição para o módulo filesystem
let fs = require('fs');

// criando um servidor funcionando na porta 8080
// e utilizando o fs.readFile para ler o arquivo html
http.createServer(function (req,res){
    fs.readFile('index.html', function(err, data){
        res.writeHead(200, {'Content-Type': 'text/html'});
        res.write(data);
        res.end();
    });
}).listen(8080);

A nossa saída deve ser assim:

E como podemos criar arquivos com o File System?

Podemos utilizar o módulo para criar novos arquivos utilizando os métodos:

  • fs.appendFile()
  • fs.open()
  • fs.writeFile()

O método fs.appendFile() anexa o conteúdo especificado a um arquivo. Se o arquivo não existir, ele será criado. Crie um novo arquivo chamado appendFile.js e faça o seguinte:

// Crie uma requisição para o módulo file system
let fs = require('fs');

// Utilize o appendFile() para criar um novo arquivo que será anexado à sua pasta node
// onde 'meuNovoArquivo.txt será o arquivo a ser criado
// 'Eu sou o novo conteudo é o conteúdo do arquivo txt

fs.appendFile('meuNovoArquivo.txt', 'Eu sou o novo conteudo', function (err){
    // Se ocorrer um erro, especifique
    if (err) throw err;
    // Senão, logue no console = salvo!
    console.log("salvo!")
})

Perceba que o arquivo foi criado na mesma pasta de origem:

Podemos também utilizar o método fs.open() para criar um arquivo vazio:

let fs = require('fs');

// 'w' significa 'write' = escrever
fs.open('meuNovoArquivo2.txt', 'w', function (err, file){
    if (err) throw err;
    console.log("Aberto!");
});

E teremos nosso arquivo criado:

E, finalmente, o método writeFile():

O método writeFile() substitui o arquivo e conteúdo especificados, se existirem. Se o arquivo não existir, ele será criado:

let fs = require('fs');

// Substituiremos o conteúdo em meuNovoArquivo2.txt pela frase
// 'Novo conteúdo!'
fs.writeFile('meuNovoArquivo2.txt', 'Novo conteúdo!', function (err){
    if (err) throw err;
    console.log('Salvo!')
})

E esse será o resultado:

Esses são os métodos de leitura e criação de arquivos utilizando o File System do NodeJS!

Gostou deste artigo? Acompanhe os próximos artigos e comente abaixo!

Novas funcionalidades DevTools

O Google Chrome fornece um conjunto robusto de ferramentas integradas diretamente no navegador, chamado afetivamente de DevTools do Chrome. Essas ferramentas são atualizadas o tempo todo pela equipe de desenvolvedores do Google Chrome; portanto, às vezes vale a pena procurar no site do DevTools para ver as novidades.

Alguns dos recursos menos conhecidos se enquadram na API do utilitário do console. Isso significa que eles estão disponíveis apenas para uso no console do Chrome. Você não pode usar esses recursos dos seus scripts.

  1. $ e $$

Esses dois caras são pseudônimos. Um único $ é um atalho para document.querySelector () e um duplo $$ é um atalho para document.querySelectorAll ().

Digamos que tenhamos um documento HTML simples parecido com este:

<div class="container">
    <div id="app">
        <div :class="{ ugly: isUgly }">{{ message }}</div>
        <h2 id="theCount">The count is: {{ count }}</h2>
        <button class="btn btn-primary" @click="increment">+</button>
        <button class="btn btn-primary" @click="decrement">-</button>
        <button class="btn btn-primary" @click="applyUgly">make ugly</button>
    </div>
</div>

E vamos especular ainda mais que queremos selecionar o primeiro botão deste documento, bem como uma coleção de todos os botões. Dê uma olhada neste:

O único $ retorna um elemento enquanto o $$ retorna a coleção.

Observe que, se você estiver usando uma biblioteca como o jQuery, que atribuirá outro valor a $, substituirá a funcionalidade interna.

  1. A função inspect()

Este pode ser usado em conjunto com o código anterior. Digamos que nosso documento HTML seja enorme e gostaríamos de selecionar um botão no HTML no console. Se inserirmos o seguinte:

Assim que pressionar enter, o DevTools passará da guia Console para a guia Elementos e destacará o elemento HTML que foi selecionado.

Também podemos usar o atalho $$ com inspect(). Ele exibirá uma lista de correspondências no console e podemos clicar em uma para ir para ela no DOM.

 

  1. key / values

Este é útil para ver rapidamente do que um objeto é composto. Digamos que temos o seguinte objeto simples.

let myObj = {
    first: 'alex',
    last: 'ritzcovan',
    state: 'ny'
}

 

Usando keys() e values(), podemos extrair exatamente isso ou podemos exibir as chaves e os valores chamando o objeto diretamente, como mostrado abaixo:

 

  1. Table

Por último, temos a função table(). Usando o mesmo objeto que usamos anteriormente, se o passarmos para table(), obtemos o seguinte no console.

Referência: https://medium.com/dailyjs/5-chrome-devtools-utilities-you-need-to-know-5bfe58c75773

Gostou? Comente abaixo!

Conheça o Callback Hell e como evitá-lo

Conheça o Callback Hell

JavaScript assíncrono, ou JavaScript que usa callbacks, é complicado de acertar intuitivamente. A causa do call-back hell é quando as pessoas escrevem JavaScript de uma maneira que ocorre a execução de cima para baixo, visualmente falando. Em algumas outras linguagens, como C, Python, existe a expectativa de que o que quer que aconteça na linha 1, tenha que terminar antes que o código da linha 2 execute, e assim por diante. Mas no JavaScript, isso funciona de uma maneira diferente.

O que são Callbacks?

São apenas o nome de uma convenção para o uso de funções JavaScript. Não existe nada chamado “callback” no JavaScript, sendo apenas uma convenção. Em vez de utilizar retorno imediato como a maioria das funções. As funções call-back demoram algum tempo para produzir resultados. A palavra “assincronismo”, conhecida no JavaScript como “async”, significa “demora algum tempo / acontece no futuro”.

Quando você chama uma função normal, pode usar seu valor de retorno:

let resultado = multiplicarDoisNumeros(5, 10);

console.log(resultado);

No entanto, funções assíncronas e que usam call-backs não retornam nada imediatamente:

let foto = downloadFoto('http://coolcats.com/cat.gif')

// foto é 'undefined'!

Nesse caso, o gif pode demorar muito para ser baixado e você não deseja que seu programa seja pausado enquanto aguarda a conclusão do download. Em vez disso, você armazena o código que deve ser executado logo após a conclusão do download em uma função. Este é o callback. Você executa a função downloadFoto e ele executará seu callback, quando o download estiver concluído e passará a foto (ou um erro se algo der errado).

downloadFoto('http://coolcats.com/cat.gif', lidarComFoto)

function lidarComFoto (error, foto) {
  if (error) console.error('Erro de Download!', error)
  else console.log('Download finished', foto)
}

console.log('Download iniciado')

Como podemos evitar o callback hell?

  1. Mantenha seu código limpo:

Callback hell geralmente é causado por más práticas de codificação. Escreva melhor o seu código e não passará trabalho.

let form = document.querySelector('form');
form.onsubmit = function formSubmit (submitEvent) {
    let name = document.querySelector('input').value;
    request({
        uri: "http://example.com/upload",
  body: name,
        method: "POST"
        }, function postResponse (err, response, body) {
        let statusMessage = document.querySelector('.status');
  if (err) return statusMessage.value = err;
  statusMessage.value = body;
    })
}

Nomear funções é uma prática benéfica e facilita a leitura do código.

Agora podemos mover as funções para o nível superior do nosso programa:

document.querySelector('form').onsubmit = formSubmit;

function formSubmit (submitEvent) {
  let name = document.querySelector('input').value;
  request({
    uri: "http://example.com/upload",
    body: name,
    method: "POST"
  }, postResponse)
}

function postResponse (err, response, body) {
  let statusMessage = document.querySelector('.status');
  if (err) return statusMessage.value = err;
  statusMessage.value = body
}
  1. Modularize:

Segundo Isaac Schlueter (do projeto Node.js): “Escreva pequenos módulos que cada um faz uma coisa e monte-os em outros módulos que fazem uma coisa maior. Você não terá um callback hell se não for lá”.

Criando um módulo, ficaria assim:

module.exports.submit = formSubmit

function formSubmit (submitEvent) {
  let name = document.querySelector('input').value;
  request({
    uri: "http://example.com/upload",
    body: name,
    method: "POST"
  }, postResponse)
}

function postResponse (err, response, body) {
  let statusMessage = document.querySelector('.status');
  if (err) return statusMessage.value = err;
  statusMessage.value = body;
}
  1. Lide com todos os erros:

Existem diferentes tipos de erros: de sintaxe, de runtime, erro de permissões, falha no disco rígido, entre outros. Ao lidar com callbacks, você, por definição, está lidando com tarefas despachadas, executa algo em segundo plano e, em seguida, conclui com êxito ou aborta devido a alguma falha. Podemos manipular isso deixando o primeiro argumento da função callback reservada ao erro.

function lidarComFoto (error, foto) {
  if (error) console.error('Erro de Download!', error)
  else console.log('Download finished', foto)
}

Dito isto, sempre lide com todos os erros e mantenha seu código simples e limpo.

Para maiores informações, acesse o site: http://callbackhell.com/

Referências: http://callbackhell.com/

O que são e como criar Promises:

Você sabe o que são promises?

Promises vem do termo “promessa”, que representa um valor que pode estar disponível em algum momento no futuro, no presente, ou nunca estar disponível. Ele é um objeto utilizado em processamento assíncrono. Um promise representa um proxy para um valor não necessariamente conhecido, permitindo uma associação de métodos de tratamento para eventos em uma ação assíncrona na hipótese de sucesso ou falha, permitindo que o método assíncrono retorne uma “promessa” ao valor em algum momento no futuro.

Quais são os estados de um promise?

  • pending (estado: pendente): O promise ainda não foi rejeitada, nem realizada. É o estado inicial;
  •  fulfilled (estado: realizado): O promise obteve sucesso na operação;
  • rejected (estado: rejeitado): O promise falhou na operação;
  • settled (estado: estabelecido): O promise foi estabelecido. Significa que o promise foi realizado ou rejeitado.

Sintaxe:

new Promise (/* executor */ function (resolve, reject) { … });

O executor é uma função que recebe os argumentos resolve e reject. O executor é chamado antes que o construtor de Promise retorne o objeto criado. As funções resolve e reject, quando chamadas, resolvem ou rejeitam (respectivamente) a promessa. Quando estiver concluído o trabalho assíncrono, o executor chama as funções resolve ou reject para definir o estado da promise.

Uma promise pode se tornar realizada ou rejeitada. Com a ocorrência de algum desses estados, o método them do Promise é chamado, e ele chama o método associado ao estado (resolved ou rejected).

O que é composição?

São métodos encadeados. Isso pode ocorrer com os métodos Promise.prototype.then e Promise.prototype.catch, já que ambos retornam promises que podem ser encadeadas.

Métodos:

  • Promise.all(lista): Retorna uma promise que é resolvida quando todas as promises no argumento forem resolvidas ou rejeitada quando uma das promises do argumento for rejeitada. É um método útil para agregar resultados de múltiplas promises.
  • Promise.race(lista): Retorna uma promise que resolve ou rejeita assim que uma das promises do argumento resolve ou rejeita.
  • Promise.reject(motivo): Retorna um promise que foi rejeitado por algum motivo.
  • Promise.resolve(valor): Retorna um promise que foi resolvido com dado valor. Se o valor for thenable (possuindo um método then), a promise retornada seguirá este metodo. Caso contrário, a promise será realizada com o valor.

Criando uma promise:

// Vejamos se a mãe está feliz. Utilize true para sim e false para não
let maeEstaFeliz = false;

// primeira promise que criaremos
let ganharTelefoneNovo = new Promise(
    (resolve, reject) => {
        if (maeEstaFeliz) {
            let telefone = {
                marca: 'iPhone',
                cor: 'Branco'
            };
            resolve(telefone);
        } else {
            let razao = new Error('Mãe não está feliz');
            reject(razao);
        }

    }
);

// Agora criaremos a segunda promise
async function mostrarTelefoneNovo(telefone) {
    return new Promise(
        (resolve, reject) => {
            var message = 'Hey cara, eu tenho um novo ' +
                telefone.marca + ' ' + telefone.cor;

            resolve(message);
        }
    );
};

// chamando nossa promise
async function perguntarParaMae() {
    try {
        console.log('Antes de perguntar para a mãe');

        let telefone = await ganharTelefoneNovo;
        let message = await mostrarTelefoneNovo(telefone);

        console.log(message);
        console.log('Depois de perguntar para a mãe');
    }
    catch (error) {
        console.log(error.message);
    }
}

(async () => {
    await perguntarParaMae();
})();

Gostou deste artigo? Comente abaixo!

Referências:

 

Como quebrar um vetor grande em vários menores

Neste artigo veremos duas funções que leem um vetor e devolvem um outro dividido em pedaços menores. O exemplo será bem simples pois a aplicação é a mesma para 5 o para 5 bilhões de registros. 

A primeira função será genérica e você provavelmente poderá utilizá-la em outras linguagens com pouca ou nenhuma adaptação. Já a segunda é utilizando mais das funções do JavaScript para reduzir o código

Em resumo queremos que um vetor linear seja quebrado em vários pequenos vetores. No meu caso, eu precisava que uma lista de contatos fosse quebrada em diversas listas menores para facilitar o controle e atualização das mesmas.

Iremos de algo assim:

let vetor = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];

Para algo assim:

let vetor = [[0, 1, 2], 
             [3, 4, 5], 
             [6, 7, 8], 
             [9, 10, 11], 
             [12, 13, 14], 
             [15, 16]];

Como podemos fazer isso? Bom, a primeira forma é a seguinte:

Algoritmo Genérico

  1. Criar a função e inicializar as variáveis. Observe que novoVetor é um vetor com um vetor vazio dentro dele.
    function converterVetor(vetor, tamanho) {
        let novoVetor = [[]];
        let novoIndice = 0;
        let novoIndiceSub = 0;
    }
  2. Criar um laço FOR para adicionar os elementos no novoVetor. Observe que:
    1. Precisamos de um IF para testar a hora de avançar de um sub-vetor para outro.
    2. Dentro deste IF é necessário criar um vetor em branco para que o Javascript saiba o tipo do dado.
    3. No final, você está adicionando o valor dentro de um vetor que está dentro de outro vetor, então é preciso usar [x][y] para adicionar na posição correta.
    for(let indice = 0; indice < vetor.length; indice++){
    
        if(indice % tamanho == 0 && indice != 0){
            novoIndice++;
            novoVetor[novoIndice] = [];
            novoIndiceSub = 0;
        }
    
        novoVetor[novoIndice][novoIndiceSub] = vetor[indice];
        novoIndiceSub++;
    }
  3. Por ultimo, basta retornar o resultado. Veja abaixo o código completo.
    function converterVetor(vetor, tamanho) {
        let novoVetor = [[]];
        let novoIndice = 0;
        let novoIndiceSub = 0;
    
    
        for (let indice = 0; indice < vetor.length; indice++) {
    
            if (indice % tamanho == 0 && indice != 0) {
                novoIndice++;
                novoVetor[novoIndice] = [];
                novoIndiceSub = 0;
            }
    
            novoVetor[novoIndice][novoIndiceSub] = vetor[indice];
            novoIndiceSub++;
        }
    
        return novoVetor;
    }

Usando mais recursos JavaScript

Agora vejamos a mesma função, mas usando mais recursos JavaScript para reduzir um pouco o trabalho.

  1. Iniciaremos de forma muito parecida, mas precisaremos de uma variável a menos
    function converterVetor2(vetor, tamanho) {
        let index = 0;
        let novoVetor = [];
    }
  2. Agora faremos o loop for, mas ao invés de percorremos o loop original de 1 em 1, percorreremos o tamanho que já queremos colocar no sub-vetor.
    1. Dentro do loop, usaremos a função slice() que nos retornará um pedaço do vetor. Sendo ele o tamanho exato do sub-vetor.
    2. Após, adicionamos o subVetor ao novo com o método push() que adiciona um elemento na ultima posição.
    for (index = 0; index < vetor.length; index += tamanho) {
        let subVetor = vetor.slice(index, index + tamanho);
        novoVetor.push(subVetor);
    }
  3. Pronto!! Basta retornar o objeto com o resultado. Segue abaixo o código completo.
    function converterVetor2(vetor, tamanho) {
        let index = 0;
        let novoVetor = [];
    
        for (index = 0; index < vetor.length; index += tamanho) {
            let subVetor = vetor.slice(index, index + tamanho);
            novoVetor.push(subVetor);
        }
    
        return novoVetor;
    }

Conclusão

Como você pode ver, o segundo formato é um pouco menos detalhado, mas utilizando os recursos do JavaScript é possível escrever menos código que ainda é fácil de entender. Por isso que, quando você estuda uma linguagem, é importante conhecer as funções nativas e formas mais inteligentes de trabalhar com seus objetos.

Phaser.js #7 – Criando jogo Final!

Estamos chegando ao final de nosso projeto com Phaser pessoal! Lembrando que vocês podem acessar o projeto original em inglês na documentação diretamente no site do Phaser (deixarei o link no final do post).

Pontuação

O que é um jogo sem uma pontuação, não é mesmo? Como saberemos quantas estrelas coletamos?

Para isso, precisamos criar um objeto de jogo de texto. Vamos criar duas variáveis para conter uma pontuação e o objeto de texto:

var score = 0;
var scoreText;

O scoreText será configurado na função create():

scoreText = this.add.text(16, 16, 'score: 0', { fontSize: '32px', fill: '#000' });

A coordenada que exibiremos o texto score: 0 é na 16×16. A fonte padrão de textos do Phaser é a Courier.

Agora, precisamos modificar a função collectStar para que, quando o player coletar uma estrela, o contador seja aumentado, adicionando o nosso score:

function collectStar (player, star)
{
    star.disableBody(true, true);

    score += 10;
    scoreText.setText('Score: ' + score);
}

Deste modo, cada vez que coletamos uma estrela, o nosso contador, que é a variável score, é incrementada em 10, ou seja, a cada estrela coletada, +10 pontos para você 🙂

Você pode verificar isso no seu arquivo part9.html!

Continue lendo “Phaser.js #7 – Criando jogo Final!”

Phaser.js #6 – Criando jogo Parte 5

E aí pessoal, dando sequência ao nosso tutorial de Phaser.js, iremos dar um propósito ao nosso jogo agora.

Já temos as plataformas, já temos a gravidade implantada, e já temos o nosso player com seus comandos especificados (andar para as laterais e pular para as plataformas). Agora, iremos inserir algumas estrelas no nosso cenário, para que o nosso player as colete. Para isso, criaremos um grupo chamado stars e o preencheremos dentro de nossa função create():

stars = this.physics.add.group({
    key: 'star',
    repeat: 11,
    setXY: { x: 12, y: 0, stepX: 70 }
});

stars.children.iterate(function (child) {

    child.setBounceY(Phaser.Math.FloatBetween(0.4, 0.8));

});

Este é um processo muito parecido como quando criamos nosso grupo de plataformas, mas como as estrelas precisam se mover e saltar, elas são um grupo dinâmico de física.

Ok, mas o que faremos agora?

Bom, primeiramente precisamos definir a chave de textura (key) para a nossa imagem. Mas o que isso significa?

Significa que todos os objetos filhos criados como resultado do objeto de configuração estrela receberão as texturas de estrela por padrão. 

Ok, já criamos uma estrela, e agora? Agora precisamos definir o repeat. O repeat é o valor de repetição das estrelas. Precisaremos de 12 estrelas saltitando pelo nosso mapa, então precisamos repeti-la 11 vezes.

Feito isso, usaremos o setXY para definir a posição das 12 estrelas criadas pelo nosso grupo star. cada estrela (child) será colocada começando em x:12 e y:0, e com um passo x de 70.

Mas o que isso significa?

Isso significa que a primeira estrela será posicionada em 12 x 0, a segunda terá 70 pixels em 82 x 0, o terceiro em 172 x 0, aumentando 70 pixels proporcionalmente para cada uma das 12 estrelas. Com o valor de 70 pixels, as estrelas vão se espalhar perfeitamente espaçadas na nossa viewport.

Mas e o que a última parte deste código faz?

Bem, esta parte do código itera entre todas as estrelas criadas pelo grupo e fornece a elas um valor aleatório entre 0,4 e 0,8 no eixo Y. O intervalo de rejeição é entre 0 e 1, sendo 0 sem rejeição e 1, rejeição completa. Como as estrelas iniciam sem gravidade, elas são puxadas para o solo, até que ocorra colisão com alguma plataforma.

Continue lendo “Phaser.js #6 – Criando jogo Parte 5”

Conheça o Meteor, um framework JavaScript.

O Meteor é um framework JavaScript completo para a criação de aplicativos Web e móveis moderno. Ele inclui um conjunto de tecnologias para a criação de aplicações reativar, uma ferramenta para construção, entre outros.

  • O Meteor permite o desenvolvimento JavaScript em ambientes de servidores de aplicativos, navegadores da web e dispositivos móveis;
  • Ele usa dados na conexão, ou seja, o servidor envia os dados, não HTML, e o cliente os processa;
  • Full Stack reactivity: Sua UI reflete perfeitamente o true world state com o mínimo de esforço de desenvolvimento.

Por onde começar?

O Meteor possui suporte para OS X, Windows e Linux.

No Linux e OSX, execute o seguinte comando:

curl https://install.meteor.com/ | sh

No Windows, primeiro instale o Chocolatey e, depois, use o seguinte comando no Prompt de Comando como Administrador:

choco install meteor

E agora?

Depois de instalado o Meteor, crie um projeto:

meteor create myapp

Depois de criado, execute-o localmente:

cd myapp
meteor npm install
meteor

Sua saída será algo como:

# Meteor server running on: http://localhost:3000/

O meteor já vem com o npm incluído, ou seja, você pode digitar meteor npm sem se preocupar se está instalado.

Agora, vamos criar um app simples:

Para criar um app, abra o seu terminal e escreva:

meteor create simples-todos

Isso vai criar uma nova pasta chamada simple-todos, com todos os arquivos que o aplicativo Meteor necessita:

client/main.js        # um arquivo de JavaScript carregado no cliente
client/main.html      # um documento HTML para definir seu templates[
client/main.css       # um arquivo CSS para definição de estilos
server/main.js        # um arquivo JS carregado no servidor
test/main.js          # um arquivo JS para testes
package.json          # um arquivo de controle para instalar pacotes npm
package-lock.json     # descreve a árvore de dependência npm
node_modules/         # pacotes instalados por nmp
.meteor/              # arquivos internos do Meteor
.gitignore            # um arquivo de controle para GIT

Para rodar o aplicativo criado:

cd simple-todos
meteor

Agora, abra o seu web browser e vá para http://localhost:3000 e veja o seu aplicativo rodando. Experimente colocar um <h1> dentro do seu client/main.html e veja a sua página ser atualizada com o novo conteúdo!

Você pode verificar a documentação original em inglês aqui: https://www.meteor.com/tutorials/blaze/creating-an-app

Gostou deste artigo? Comente abaixo!

Phaser.js #4 – Criando jogo Parte 3

Nosso jogo já está tomando forma, pessoal! Para continuarmos, recomendo a leitura da Parte 2 desta série de artigos!

Adicionando o jogador:

Já temos nossas plataformas, mas ninguém para percorrê-las. Temos que resolver isso neste momento.

Criaremos uma variável chamada player e adicionaremos o seguinte código à função create().

player = this.physics.add.sprite(100, 450, 'dude');

player.setBounce(0.2);
player.setCollideWorldBounds(true);

this.anims.create({
    key: 'left',
    frames: this.anims.generateFrameNumbers('dude', { start: 0, end: 3 }),
    frameRate: 10,
    repeat: -1
});

this.anims.create({
    key: 'turn',
    frames: [ { key: 'dude', frame: 4 } ],
    frameRate: 20
});

this.anims.create({
    key: 'right',
    frames: this.anims.generateFrameNumbers('dude', { start: 5, end: 8 }),
    frameRate: 10,
    repeat: -1
});

Você pode conferir isso no seu arquivo part5.html.

Há duas coisas acontecendo neste código: a criação de um Sprite de física e a criação das animações que ele irá usar.

Physics Sprite:

A primeira parte do código cria o sprite:

player = this.physics.add.sprite(100, 450, 'dude');

player.setBounce(0.2);
player.setCollideWorldBounds(true);

Isso cria um novo sprite chamado player, posicionado a 100×450 pixels da parte inferior do jogo. O sprite foi criado através da Physics Game Object Factory, ou seja, ele é um corpo de Física Dinâmica por padrão.

Depois de criar o sprite, ele recebe um valor de rejeição de 0,2. Mas o que isso significa?

Isso significa que, quando ele aterrissar de um salto, ele saltará levemente. O sprite é definido para colidir com os limites do jogo. Os limites, por padrão, estão do lado de fora da dimensão do jogo. Como o jogo foi definido em 800×600, o jogador não poderá avançar para fora desta área, impedindo o player de correr pelas bordas da tela ou pular pela parte superior.

Animando:

Se você olhar para a função preload, verá que o “dude” foi carregado como uma folha de sprites, não como uma imagem. Isso acontece porque ele possui vários quadros de animação.

Existem 9 quadros de animação dentro desta página de sprites: 4 para a esquerda, uma para a frente e 4 para a direita. O Phaser suporta sprites invertidos, para econimizar quadros de animação.

Definimos duas animações, “left” e “right”. Aqui está a animação “left”:

this.anims.create({
    key: 'left',: 'left',
    frames: this.anims.generateFrameNumbers('dude', {
        start: 0,
        end: 3
    }),
    frameRate: 10,
    repeat: -1
});

A animação “left” usa os frames 0, 1, 2 e 3 e é executada a 10 frames por segundo. O valor “repeat -1” informa que há repetição de animação.

Esse é o nosso ciclo de execução padrão e o repetimos para correr na direção oposta, usando a tecla “right” e a final para “turn”.

Velocidade do player:

O Phaser tem suporte para uma variedade de sistemas de física diferentes, cada um atuando em alguma cena do Phaser. Quando um Sprite de Física é criado, ele recebe uma propriedade body, que é uma referência ao seu corpo. Isso representa o sprite como um corpo físico no mecanismo de física do Phaser Arcade. O objeto body tem muitas propriedades e métodos. Por exemplo, para simular os efeitos da gravidade de um sprite, podemos adicionar o seguinte:

player.body.setGravityY(300);

Isso tornará o objeto mais pesado e mais rapidamente ele cairá. Verifique isso no seu código executando o part5.html, e verá que o player irá cair sem parar, ignorando completamente o terreno criado anteriormente:

Isso acontece pois ainda não estamos testando colisões entre o solo e o player. O Phaser já sabe que nosso solo e plataformas são corpos estáticos. Se tivéssemos os criado de forma dinâmica, o jogador entraria em contato com elas, pararia por um momento e o jogo colapsaria. Um sprite de solo dinâmico é um objeto físico em movimento e, quando o jogador o atinge, a força resultante da colisão também é aplicada ao solo, levando os dois corpos a trocarem suas velocidades, fazendo o solo começar a cair também. Para permitir a colisão com as plataformas, podemos criar um objeto Collider. Este objeto monitora dois objetos de física (que podem incluir grupos) e verifica as colisões ou sobreposições entre eles:

this.physics.add.collider(player, platforms);

Veja a mágica acontecer:

O Collider testa a colisão e realiza a separação entre dois objetos. Estamos fornecendo um sprite do player e o grupo de plataformar. Precisamos ter colisões com todas as plataformas, então precisamos fazer esta colisão com o grupo da plataforma. O resultado disso é uma plataforma firme que não entra em colapso.

Está gostando do jogo? Curtindo os seus resultados? Comente abaixo e aguarde o próximo artigo 🙂