terça-feira, 29 de maio de 2012

Review: Games antigos 1. Descent

Olá pessoal.

Bem vindos à série de reviews de games antigos.
Aqui eu vou abordar um pouco da história de cada game, época e melhoramentos.

O primeiro game que vou comentar é um dos melhores e mais inovadores que eu já conheci que é o DESCENT.

Não tem nada a ver com pornografia. 'Descent' significa descida.

Experiência pessoal:

O jogo surgiu em 17 de março de 1995 para pc. Na época, poucas pessoas tinham pc. E felizmente eu consegui um 486 dx4 100Mhz com 512 mega de HD e 8 de ram!

Era uma senhora máquina. E ainda veio com Kit multimídia e alguns jogos no kit, Full Throttle, Cyberia e inclusive o Descent. Ele foi o último jogo que eu instalei, pois não botei fé por causa do nome...

Porém, quando descobri o visual do jogo, a possibilidade de rodopiar em 360 graus e todos os inimigos eram em 3d... NOSSA!

Eu não conseguia mais parar de jogar. Era um DOOM de nave!!!

Descent demanda muito do senso de orientação do jogador, já que toda a movimentação é livre e sem gravidade.

O visual do jogo era bastante empolgante para a época e ainda vinha com possibilidade de usar o óculos 3d.

Os puzzles eram relativamente simples, mas a tensão durante as partidas compensavam.

As músicas tinham um tom sinistro e envolvente. A mais legal era a do nível 12.


História:

Tudo começa com um executivo da empresa PTMC(Post Terram Minerals Corporation) chamado Dravis que para lidar com uma infestação de vírus nos robôs mineradores, contrata um mercenário, no jogo é chamado de 'Material defender' ou 'Vertigo-1' para lidar com a situação.

O jogo segue pelo Sistema Solar através da Lua até Mercúrio acabando em Charon, lua de Plutão.

Após a eliminação dos robôs infectados, Dravis impede que Material Defender retornasse à Terra, pois sua nave poderia estar infectada. E também o informa que perdera o contato com as instalações do interior do espaço.

Material Defender segue então para essas instalações dando início à sequência (Descent 2).

Plataformas:

Pc e Mac em 1995, Linux, Playstation em 1997, Wii em 2012.

Melhoramentos:

Com a liberação do código fonte das duas primeiras versões em 1997 e 1999, programadores entusiastas começaram a fazer algumas modificações.

Tanto Descent 1 quanto 2 possuem a mesma engine gráfica, fazendo com que os melhoramentos produzidos fossem compatíveis e usados para ambos.

Foram criados novos níveis para jogar solo e multiplayer e até mesmo retexturização do ambiente.

Um dos programas de modificação mais utilizados é o D2X-XL, que tem versões para Windows, Linux e Mac.

É possível encontrar esses melhoramentos no site do Descent2.de (www.descent.de).




Instalando o D2X-XL:

Primeiro você tem que ter a cópia do jogo original. Você consegue uma por R$ 12,00 aqui http://www.gog.com/en/gamecard/descent_1_descent_2.

No site http://www.descent2.de/ entre em D2X-XL e baixe a última versão para seu sistema.
Para Windows, o pacote é um autoextractive rar.

É só extrair numa pasta ex: \d2.

Dentro temos os executáveis apenas, o jogo, não está instalado de fato.
Instale normalmente o jogo e depois  vamos copiar os arquivos nas pastas conforme abaixo:
  • \d2\config\ coloque os arquivos *.cfg e *.ini;
  • \d2\data\ arquivos *.pig, descent.hog, descent.msn descent2.hog, descent2.msn, *.256;
  • \d2\demos\ arquivos *.dem;
  • \d2\missions\ coloque todos os arquivos das missões, *.hog, *.msn, *.mn2;
  • \d2\files\missions\single é uma pasta especial para guardar as missões solo;
  • \d2\models\ arquivos de modelos 3d, *.oof e *.tga;
  • \d2\movies\ arquivos *.mvl;
  • \d2\profiles\ arquivos *.plr;
  • \d2\savegames\ arquivos *.sg?;
  • \d2\screenshots\ arquivos *.tga;
  • \d2\temp\ arquivos temporários.

Feito isso é só executar o d2x-xl.exe e sair pilotando freneticamente!
Bom jogo!

segunda-feira, 14 de maio de 2012

Javascript uma implementação do padrão observer


Já ouviu falar de design patterns?
Conhece o padrão observer?
 Leia:
 http://www.dofactory.com/Patterns/PatternObserver.aspx ,
 http://en.wikipedia.org/wiki/Observer_pattern

Muitas vezes precisamos recorrer aos design patterns para resolver alguns problemas
comuns do nosso dia a dia.

Existem muitos tipos de implementações desses designs e muitas vezes, alguns não
se adequam às necessidades reais.

Temos que ter em mente o seguinte:
1 compreender o problema;
2 entender o design pattern;
3 entender como o padrão resolverá o problema.

Vamos ver uma implementação do padrão Observer em javascript.


/** ----------------------------------------------------------------------------
 * Implementacao de um observer (singleton)
 * Ex:
 *      var a = {}, b={}, c={}, obs=Observer.getInstance();
 *      obs.addObserver('notifyA',a,function(target){console.log(target)})
 *      obs.addObserver('notifyB',b,function(target){console.log(target)})
 *      obs.addObserver('notifyC',c,function(target){console.log(target)})
 *
 *      obs.notifyAll();       // notifica todos
 *      obs.notify('notifyB'); // notifica os objetos que possuem o evento 'notifyB'
 *      obs.notifyObj(c);      // notifica um objeto especifico
 *
 * @return {*}
 * @constructor
 */
function Observer(){
    var slf=Observer;
    // singleton pattern
    if(slf.instance) return slf.instance;
    slf.instance=this;
    var _observers={},
        _getSizeOfObservers=function(){return Object.keys(_observers).length;};
    /**
     * Adiciona um observer para um objeto passado.
     * @param {String} name   Nome do evento
     * @param {Object} obj    Objeto que observara o evento
     * @param {Function} func Callback do evento
     */
    this.addObserver=function(name, obj, func){
        if(name && typeof(obj) == "object" && typeof(func)=="function" ){
            if(!obj.gid) obj.gid=Object.gid();
            name='%ev-'+name+'%id-'+obj.gid+'%len-'+_getSizeOfObservers();
            _observers[name]={obj:obj,func:func};
        }
    };
    /**
     * Remove um observer
     * @param {String} name Nome do evento
     * @param {Object} obj  Objeto que esta na lista de observers
     */
    this.removeObserver=function(name,obj){
        if(name && typeof(obj) == "object" ){
            if(!obj.gid) return;
            name='%ev-'+name+'%id-'+obj.gid;
            for(var i in _observers){
                if(i.indexOf(name)>-1)   delete _observers[i];
            }
        }
    };
    /**
     * Notifica todos os elementos que estao na lista de _observers
     */
    this.notifyAll=function(){
        for(var i in _observers)
            if(_observers[i].func) _observers[i].func(_observers[i].obj);
    };
    /**
     * Notifica um objeto especifico
     * @param {Object} obj
     */
    this.notifyObj=function(obj){
        for(var i in _observers)
            if(_observers[i].obj && _observers[i].obj.gid == obj.gid)
                _observers[i].func(_observers[i].obj);
    };
    /**
     * Notifica os objetos que aguardam um evento qualquer
     * @param {String} name Nome do evento
     */
    this.notify=function(name){
        for(var i in _observers)
            if(i.indexOf(name)>-1 && _observers[i].obj)
                _observers[i].func(_observers[i].obj);
    };
}
    /**
     * Retorna a instancia (singleton)
     * @return {Observer}
     */
    Observer.getInstance=function(){
        if(this.instance) return this.instance;
        return new Observer();
    };


Note que é uma simples implementação onde o subject é inserido em uma lista
de observers no objeto Observer, mas que serve muito bem ao propósito.

Mas não segue o padrão apresentado!
Não mesmo, mas temos todos os elementos envolvidos agindo e reagindo conforme
esperado no padrão.

terça-feira, 8 de maio de 2012

jQuery. Extendendo position e offset para trazer right e bottom

Fala nerdaiada.
Tá precisando calcular o bottom e o right de um elemento?

Deixa isso pronto num arquivo js uai!

Vamos criar uma nova função no jQuery pra 'extender' as funções position e offset para que retornem esses valores.

Bem.
Pra extender o jquery, podemos fazer de várias maneiras.
Abaixo nós temos um exemplo de como fazer isso:

(function($){
/**
* Função que retorna o objeto posição com novos atributos.
* @return {Object} p Objeto com as opções top, left, right, bottom.
*/
$.fn.extPosition=function(){
var p=$(this).position(arguments);
if(('left' in p) && ('top' in p))
p=$.extend({},p,{
right:p.left+$(this).width(),
bottom:p.top+$(this).height()});
return p;
};

/**
* Função que retorna o objeto posição 'offset' com novos atributos.
* @return {Object} p Objeto com as opções top, left, right, bottom.
*/
$.fn.extOffset=function(){
var p=$(this).offset(arguments);
if(('left' in p) && ('top' in p))
p=$.extend({},p,{
right:p.left+$(this).width(),
bottom:p.top+$(this).height()});
return p;
};

})(jQuery);

Explicação?! 'Pô! Tô perdido!!!'
'$' é o objeto que contém toda a jQuery. (To errado?!)
'$.fn' é o objeto que contém a maioria das funções que serão usadas pelos elementos da página!
Então...

É só criar a função $.fn.minhaFuncao=function(){};

Outra forma: $.extend($.fn,{minhaFuncao:function(){}});

Quer saber mais?
http://docs.jquery.com/Main_Page

quinta-feira, 2 de fevereiro de 2012

Criar diretórios a partir de uma lista num arquivo no linux/cygwin

Como criar vários diretórios de uma lista de nomes num arquivo txt com apenas uma linha:

Crie um arquivo txt ou use algum com o conteúdo com um nome tipo dirs.txt:


Arquivo << dirs.txt >>


dir-1
dir-2
dir-3

Depois é só usar o comando:

Código


for i in `echo dirs.txt`; do mkdir `echo $i|sed "s/[\r\n\0]//g"` ; done

Pronto...
Os nomes do arquivo viraram diretórios no seu hd.