Archive for the ‘Games’ Category

Papervision Tile [Player]

abril 8, 2009

Olá pessoal, para lhes ser sincero eu não pretendia fazer uma continuação tão cedo para o papervison tile, mas eu me empolguei muito ao escrever o tutorial anterior, e decidi criar uma continuação. Prestem atenção no flash a seguir.

ssemeny
Clique na imagem para visualizar a apresentação

Este foi o ultimo passo do nosso tutorial tile sytem, pois bem, a primeira meta do nosso tutorial papervision tile será replicar esta aplicação para o 3d. Agora veja como ficará o projeto final deste tutorial de hoje.

game
Clique na imagem pra visualizar a apresentação

Sobre:

Poderemos utilizar o mesmo arquivo fla que construímos no tutorial anterior, mas eu não irei utilizar o mesmo arquivo main, pois desta vez adicionaremos alguns conceitos de POO (Programação Orientada a Objetos) em nosso tutorial.

Nosso tutorial será constituído pelos seguintes arquivos:

  • ppv_tile.fla: Este arquivo não tem mistério nenhum, é o mesmo que utilizamos no tutorial anterior.
  • Tile3D.as: Este arquivo será a classe modelo para cada bloco, ele será responsável por desenhar o cubo, manipular as propriedades de coordenadas tile, ground e wall, que nos dirá se o tile desenhado permitir caminhar sobre ele e se ele funcionará como uma parede que impedirá a passagem quando o player estiver no mesmo nível.
  • Player.as: Esta classe além de desenhar nosso player no cenário e manipular coordenadas, ela também contará com o método de mover o player pelo cenário.
  • main.as: Nosso arquivo principal, será responsável por montar nosso ambiente 3d, adicionar o player no cenário e manipular o teclado para movimentar o player.

Obs: Não podemos esquecer-nos de referenciar a biblioteca do papervision.

Diretórios:

Neste tutorial utilizaremos o conceito de pacotes, e as classes não estarão no mesmo diretório que o arquivo fla, veja a imagem como será organizado nosso diretório.

dir

Como funcionará o código.

No nosso arquivo main.as criaremos 3 vetores, um para informar os materiais, outro para informar a altura que cada tile irá ficar e um terceiro que terá o mesmo comprimento dos outros, mas utilizaremos ele para armazenar objetos da classe Tile3D para podermos ter uma fácil manipulação de dados usando coordenadas tile.

Em nosso loop de criação de tiles instanciaremos cada posicionamento do veto tiles[i][j] pra se comportarem como um novo objeto do tipo Tile3D.

Nossa classe Tile3D será uma classe estendida da classe Cube do papervision, a diferença que nossa herança vai precisar de parâmetros adicionais como tamanho do cubo, posicionamento x,z,y no tile.

No decorrer do loop definiremos a propriedade wall e ground de acordo com os vetores especificadores de altura e material, utilizaremos os métodos da classe.

Ao termino do loop instanciaremos o objeto player do tipo Player

A classe Player receberá como parâmetros: o tamanho do tile, e posicionamento x,z e y como parâmetro opcional.

Para mover o player pelo cenário invocaremos o método move da classe Player, que recebe como parâmetros: direcionamento Z, direcionamento X e o vetor com os objetos de tile.

Lógica das classes Tile3D e Player:

Criar um cubo com os parâmetros passados pelo construtor de Tile3D e Player. Logo em seguida repassar os parâmetros para classe mãe Cubo. Não permitiremos o usuário alterar os atributos diretamente, pois para alterarmos precisaremos de uma validação, por isso estaremos utilizando os atributos do tipo privado, a validação será da seguinte maneira: O usuário informara qual será o tile que ele quer posicionar o cubo, o método automaticamente modificará o atributo que armazena o posicionamento no tile e calculará a posição física dele no plano 3d (x,z,y).

Lógica Get/Set:

Vamos supor que o atributo no qual armazenaremos o posicionamento do tileX esta definido como public. Ao fazermos “Player.tileX = 2;” modificaremos o nosso atributo para 2, mas com isso o nosso Player não se moveu para a posição 2. Este problema é solucionado utilizando a lógica get/set. Um método Get para recupera um valor (x = Player.tileX) e um método set para modifica um valor (Player.tileX = 2). Como não podemos ter atributos com o mesmo nome que os métodos utilizaremos “_nome” quando for atributo e “get nome ou set nome” para função.

private var _tileX:int;
private function gotoTile(n:int):Number{
    return _cubeW * n;
}
public function set tileX(n:int):void {
    _tileX = n;
    x = gotoTile(n);
}
public function get tileX():int {
    _tileX = Math.floor(x /_tileWidth);
    return _tileX;
}

Eu sei que a teoria pode estar meio confusa para alguns mas prometo que montarei um tutorial mais detalhado sobre Orientação a Objetos para vocês poderem refazerem este tutorial dizer. “Uhmmm então é isso.”

Move Player

Nosso método move na classe Player funcionará da seguinte forma, ele receberá parametros de adição para x,z e um vetor. se passarmos como parametro (0,1,vetor) estaremos informando que queremos que o player mova 0 na escala X e +1 na escala Z. Mas antes de mover verificamos se o bloco no qual nosso player está querendo se mover é permitido andar sobre ele (ground = true) e também se não existe um bloco do tipo parede atrapalhando (wall = false), só depois de verificarmos se é permitido andar que movimentamos nosso player.

        public function  move(dirx:int,dirz:int,arrayObj:Array):void {
            var nextTileX:Number = tileX + dirx;
            var nextTileZ:Number = tileZ + dirz;
            if (arrayObj[nextTileX][nextTileZ]!= "undefined" && !(arrayObj[nextTileX][nextTileZ].wall) && arrayObj[nextTileX][nextTileZ].ground){
                if ((dirx == 1) ||  (dirx == -1) || (dirz == 1) ||  (dirz == -1)) {
                    tileX = nextTileX;
                    tileZ = nextTileZ;
                }
            }
        }

Códigos:

Segue abaixo o código referente as arguivos: Tile3D.as, Player.as, main.as. Lembrando que o nome dos arquivos precisam ser exatamente estes respeitando letra maiuscula e minuscula, o mesmo vale para as pastas que os arquivo serão alocados.

  • Tile3D.as
package org.tile3d{
    import org.papervision3d.materials.utils.MaterialsList;
    import org.papervision3d.objects.primitives.Cube;
    public class Tile3D extends Cube {
        private var _wall:Boolean;
        private var _ground:Boolean = true;
        private var _tileX:int;
        private var _tileY:int;
        private var _tileZ:int;
        private var _cubeW:Number;
        public function Tile3D(matList:MaterialsList,_cubeW:Number=20,_tileX:Number=1,_tileZ:Number=1,_tileY:Number=1) {
            super(matList,_cubeW,_cubeW,_cubeW);
            this._cubeW = _cubeW;
            tileX = _tileX;
            tileZ = _tileZ;
            tileY = _tileY;
        }
        private function gotoTile(n:int):Number{
            return _cubeW * n;
        }
        //Get e Set: Modificando os valores dos atributos privados
        public function set tileX(n:int):void {
            _tileX = n;
            x = gotoTile(n);
        }
        public function get tileX():int {
            return _tileX;
        }
        public function set tileY(n:int):void {
            _tileY = n;
            y = gotoTile(n);
        }
        public function get tileY():int {
            return _tileY;
        }
        public function set tileZ(n:int):void {
            _tileZ = n;
            z = gotoTile(n);
        }
        public function get tileZ():int {
            return _tileZ;
        }
        //Permite que o objeto seja usada como chão
        public function set ground(valor:Boolean):void {
            _ground = valor;
        }
        public function get ground():Boolean {
            return _ground;
        }
        //Transforma o objeto em uma parede
        public function set wall(valor:Boolean):void {
            _wall = valor;
        }
        public function get wall():Boolean {
            return _wall;
        }
    }
}
  • Player.as
package  org{
    import org.papervision3d.objects.primitives.Cube;
    import org.papervision3d.materials.MovieAssetMaterial;
    import org.papervision3d.materials.utils.MaterialsList;
    public class Player extends Cube {
        private var _tileX:int;
        private var _tileY:int;
        private var _tileZ:int;
        private var _tileWidth:Number;
        private var matP:MovieAssetMaterial = new MovieAssetMaterial("playermat1");
        private var p:MaterialsList = new MaterialsList({all: matP});
        public function Player(_tileWidth:Number=20,_tileX:Number=1,_tileZ:Number=1,_tileY:Number=1) {
            super(p,15,15,15);
            this._tileWidth = _tileWidth;
            tileX = _tileX;
            tileZ = _tileZ;
            tileY = _tileY;
        }
        public function  move(dirx:int,dirz:int,arrayObj:Array):void {
            var nextTileX:Number = tileX + dirx;
            var nextTileZ:Number = tileZ + dirz;
            if (arrayObj[nextTileX][nextTileZ]!= "undefined" && !(arrayObj[nextTileX][nextTileZ].wall) && arrayObj[nextTileX][nextTileZ].ground){
                if ((dirx == 1) ||  (dirx == -1) || (dirz == 1) ||  (dirz == -1)) {
                    tileX = nextTileX;
                    tileZ = nextTileZ;
                }
            }
        }
        private function gotoTile(n:int):Number{
            return _tileWidth * n+(_tileWidth-15)/2;
        }
        //Get e Set: Modificando os valores dos atributos privados
        public function set tileX(n:int):void {
            _tileX = n;
            x = gotoTile(n);
        }
        public function get tileX():int {
            _tileX = Math.floor(x /_tileWidth);
            return _tileX;
        }
        public function set tileY(n:int):void {
            _tileY = n;
            y = gotoTile(n);
        }
        public function get tileY():int {
            _tileY = Math.floor(y/_tileWidth);
            return _tileY;
        }
        public function set tileZ(n:int):void {
            _tileZ = n;
            z = gotoTile(n);
        }
        public function get tileZ():int {
            _tileZ = Math.floor(z/_tileWidth);
            return _tileZ;
        }
    }
}
  • main.as
package  {
     //flash
    import flash.display.MovieClip;
    import flash.events.*;
    import org.tile3d.*;
    import org.Player;
    //Papervision
    import org.papervision3d.objects.primitives.Plane;
    import org.papervision3d.objects.primitives.Cube;
    import org.papervision3d.scenes.Scene3D;
    import org.papervision3d.render.BasicRenderEngine;
    import org.papervision3d.cameras.Camera3D;
    import org.papervision3d.view.Viewport3D;
    import org.papervision3d.materials.MovieAssetMaterial;
    import org.papervision3d.materials.utils.MaterialsList;
    public class main extends MovieClip {
        //papervision
        public var cena:Scene3D;
        public var viewport:Viewport3D;
        public var camera:Camera3D;
        public var renderer:BasicRenderEngine;
        public var centro:Plane;
        //material
        public var matGrass:MovieAssetMaterial = new MovieAssetMaterial("grass");
        public var matBase0:MovieAssetMaterial = new MovieAssetMaterial("base0");
        public var matBase1:MovieAssetMaterial = new MovieAssetMaterial("base1");
        public var matFlower:MovieAssetMaterial = new MovieAssetMaterial("flower");
        public var matWater:MovieAssetMaterial = new MovieAssetMaterial("water", true);
        public var w:MaterialsList = new MaterialsList(
        {front: matWater,
        back: matWater,
        left: matWater,
        right: matWater,
        top: matWater,
        bottom: matWater});
        public var g:MaterialsList = new MaterialsList(
        {front: matBase1,
        back: matBase1,
        left: matBase1,
        right: matBase1,
        top: matGrass,
        bottom: matBase1});
        public var f:MaterialsList = new MaterialsList(
        {front: matBase1,
        back: matBase1,
        left: matBase1,
        right: matBase1,
        top: matFlower,
        bottom: matBase1});
        public var b:MaterialsList = new MaterialsList(
        {all: matBase0});
        //tiles
        public var arrayTile:Array =[
        [w, w, w, w, w, w, w, w, w, w, w, w, w, w, w],
        [w, g, g, g, g, g, f, g, w, w, w, w, w, w, w],
        [w, g, g, f, g, g, g, g, g, w, g, g, f, w, w],
        [w, g, g, g, g, f, g, g, g, w, g, g, g, w, w],
        [w, w, g, g, g, g, g, g, g, f, f, g, g, w, w],
        [w, w, g, g, g, g, g, g, g, f, g, g, w, w, w],
        [w, g, g, g, g, g, g, g, g, g, g, w, w, w, w],
        [w, g, g, g, f, w, g, f, g, g, w, w, w, w, w],
        [w, w, g, g, w, w, g, g, g, w, w, w, w, w, w],
        [w, w, w, w, w, w, w, w, w, w, w, w, w, w, w]];
        public var arrayTileHeight:Array = [
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,1,0,0,0,0,0,0,0,0],
        [0,0,0,1,0,0,0,0,0,0,0,0,1,0,0],
        [0,0,0,0,0,1,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,1,1,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,1,0,0,1,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]];
        public var tiles:Array = [
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,1,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,1,0,0,0,0,0,1,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,1,0,0,0,0,0,1,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]];
        //Player
        public var player:Player;
        //Outros
        public var tileWidth:Number = 20;
        public function main () {
            Set ();
            Objetos ();
        }
        public function Set ():void {
            viewport = new Viewport3D(400,300,true,false,true,true);
            addChild (viewport);
            setChildIndex (viewport,1);
            cena = new Scene3D ;
            renderer = new BasicRenderEngine ;
            camera = new Camera3D ;
            camera.focus = 100;
            camera.zoom = 10;
            camera.x = 650;
            camera.z = 450;
            camera.y = 700;
        }
        public function Objetos () {
            for (var i = 0; i < arrayTile.length; i++) {
                for (var j = 0; j <  arrayTile[0].length; j++) {
                    //Criando blocos extras na altura 					
                    tiles[i][j] = new Tile3D(arrayTile[i][j],tileWidth,i,j,arrayTileHeight[i][j]); 					if (arrayTileHeight[i][j]>0) {
                    tiles[i][j].wall=true;
                    for (var k=0; k<arrayTileHeight[i][j];k++){
                        var tilesBlock=new Tile3D(b,tileWidth,i,j,k);
                        cena.addChild (tilesBlock);
                    }
                }
                if (arrayTile[i][j] == w){
                    tiles[i][j].ground=false;
                }
                //Criando bloco Tile
                cena.addChild (tiles[i][j]);
                }
            }
            //Player
            player = new Player(20,1,1);
            cena.addChild (player);
            stage.addEventListener (KeyboardEvent.KEY_UP, onKeyUpEvent,false,0,true);
            addEventListener (Event.ENTER_FRAME,Loop,false, 0, true);
        }
        public function Loop (e:Event):void {
            camera.lookAt (player);
            renderer.renderScene (cena,camera,viewport);
        }
        public function movePlayer(ob:Cube,dir:String,code:int) {
            if (code==37){
                player.move(0,-1,tiles);
            }else if (code==39){
                player.move(0,1,tiles);
            }else if (code==38){
                player.move(-1,0,tiles);
            }else if (code==40){
                player.move(1,0,tiles);
            }
        }
        public function onKeyUpEvent (event:KeyboardEvent ):void {
            var Code:Number=event.keyCode;
            if (Code==37 ||Code==38 ||Code==40 ||Code==39 ) {
                movePlayer (player,null,Code);
            }
        }
    }
}
Anúncios

Recapitulando

janeiro 30, 2009

Olá pessoal, Estou preparando uns tutoriais novos, alguns deles relacionados a papervision, provavelmente no meu próximo post já terá algo relacionado. Outra boa noticia é que o Rafael (Coisas Comuns 🙂) me disponibilizou um banco de dados no servidor dele para que eu possa salvar os recordes, com isso, farei um update nos jogos que já estão prontos e tentarei terminar os imcompletos.

Eis aqui parte do futuro

thumb_ppv

Essa é a primeira demo de um jogo que eu estou fazendo utilizando Papervision 3d e actionscript 3,  Para matar a curiosidade, no canto inferior dessa demo, tem uma formula matemática, essa formula também é conhecida como DPPR3 (distancia do ponto ao ponto em R3)  é com essa formula se faz a verificação de Hit nesse jogo. O jogo ainda esta na sua fase de aperfeiçoamento, ainda esta sujeito a alterações.

Para quem não parou para jogar os jogos prontos e testar as demos segue abaixo os links para vocês fazerem o test drive.

Jogos:

Clique nos Links ou nas imagens para jogar.

thmb_mariocard2 thumb_spaceinvaders

thumb_mariocard thumb_fire

thumb_ovada

thumb_sneak

Demos:

As Demos são componentes de futuros jogos. Não são jogos prontos, podemos dizer que são jogos incompletos.

isometria

False 3d

Agradeço a presença de vocês e voltem sempre.

Tile System [Enemy]

novembro 19, 2008

今日は皆-さん. Em fim dificuldade no nosso game, mas eu não estou falando de códigos avançados e complexos que vocês não entenderão, eu estou falando de inimigos. Como nosso grande amigos Ratysu (Dados Sujos) costumava dizer “A dificuldade valoriza o cumprimento da missão”. Pois bem um jogo com inimigos ganha muito mais emoção. E hoje daremos continuidade ao nosso tutorial tile system com a implementação de inimigos.

ssemeny

Clique aqui para jogar

Criando MovieClip Enemy:

Nosso movieclip enemy seguirá as mesmas proporções do player, com a diferença nos sprites e a propriedade linkage será definida como “Enemy”.

linkageenemy

Tipos de Inimigos:

Em nosso tutorial aprenderemos a montar 2 tipos de inimigos: os burros e os menos burros.

Burros: São aqueles inimigos que não se cansam de mover de um lado para o outro, anda anda anda , bate na parede, volta volta volta. Em nosso código chamaremos de inimigos tipo “Flip”.

Menos Burros: São aqueles inimigos que ao encostar em uma parede, escolhe uma direção aleatoriamente e segue ate o encontro da próxima parede. Chamaremos eles de tipo “Choose”.

Criando os objetos:

Nossos inimigos assim como criamos o jogador usaremos objetos com algumas propriedades pré definidas.

Enemy1 = {xtile:2, ytile:3, speed:2, enemy:true,  dirx:0, diry:-1, Type:"Flip"};
  • xtile,ytile (Number): Posição x e y inicial no tile system.
  • speed (Number): Velocidade do inimigo
  • enemy (Boolean): Esta propriedade especificara que o objeto é um inimigo, devemos implementar essa propriedade ao objeto Player também marcando como false.
  • dirx, diry (Number): Indica qual é a direção que nosso inimigo começará a percorrer. Seguindo as combinações:[1,0] direita, [-1,0] esquerda, [0,1] cima, [0,-1] baixo e [0,0] parado.
  • Type (“Choose” ou “Flip”): Indicará qual é o tipo do nosso inimigo

Junto com a criação dos objetos criaremos um vetor que armazenará todos os nosso objetos de inimigos. O código das declarações ficará mais ou menos assim:

char = {xtile:1,  ytile:1, speed:2, enemy:false};
Enemy1 = {xtile:2,  ytile:3, speed:2, enemy:true, dirx:0, diry:-1, Type:"Flip"};
Enemy2 = {xtile:6,  ytile:8, speed:2, enemy:true, dirx:-1, diry:0, Type:"Choose"};
Enemy3 = {xtile:2,  ytile:6, speed:2, enemy:true, dirx:0, diry:-1, Type:"Flip"};
arrayEnemy = [Enemy1, Enemy2, Enemy3];

Criando os MovieClips:

O processo de criação dos inimigos no field seguirá o mesmo padrão dos itens. Criaremos um loop que para cada índice fará referencia a um vetor para pegar as informações referentes as propriedades e logo em seguida substituirá o objeto do vetor pelo movieclip.

for (i = 0; i <  arrayEnemy.length; i++) {
  _root["Field"].attachMovie("Enemy","Enemy"  + i,5001 + i);
  _root["Field"]["Enemy"  + i]._x = arrayEnemy[i].xtile * TileP + 10;
  _root["Field"]["Enemy"  + i]._y = arrayEnemy[i].ytile * TileP + 10;
  _root["Field"]["Enemy"  + i].height = 7.5;
  _root["Field"]["Enemy"  + i].speed = arrayEnemy[i].speed;
  _root["Field"]["Enemy"  + i].enemy = arrayEnemy[i].enemy;
  _root["Field"]["Enemy"  + i].dirx = arrayEnemy[i].dirx;
  _root["Field"]["Enemy"  + i].diry = arrayEnemy[i].diry;
  _root["Field"]["Enemy"  + i].Type = arrayEnemy[i].Type;
  arrayEnemy[i] =  _root["Field"]["Enemy" + i];
}

Movendo os Inimigos:

O que difere os inimigos dos Playes? Ao meu ponto de vista o players você comanda e os inimigos andam sozinho. Vamos relembrar o funcionamento da estrutura de movimentação do Player.

Nos temos um loop que verifica quando pressionamos um botão. Depois se pressionarmos algo ele chama uma função passando os parâmetros da direção que o player vai ter que seguir. Na função armazenamos os valores de posicionamento em uma variável imagem fazemos cálculos com a velocidade, verificamos se depois do calculo se o tile no qual ele esta se dirigindo é walkable, senão deixamos o personagem parado.

Basicamente nosso inimigo também faz tudo isso com algumas mudanças, ao invés do jogador definir a direção com um botão, nosso inimigo já sabe qual é a direção que ele tem que seguir (dirx e diry), e ao invés dele ficar parado quando o destino não é permitido ele muda sua direção e segue o trajeto.

Pois bem no nosso loop criaremos um loop que percorrerá o vetor de inimigos e pedirá para todos andem suas respectivas direções, também aproveitaremos o loop para verificar se nosso player encostou em nosso inimigo, para o teste ficar perceptível colocaremos apenas para ele receber alpha 50 ao encostar. E na nossa função de movePlayer adicionaremos a verificação, se o objeto for encostar na parede ele criará uma variável wall e retornará true especificando o toque. Depois nós verificaremos. Se for um inimigo e encostou na parede mude de direção.

LoopFrame(){
   ..
 for (i in arrayEnemy) {
   movePlayer  (arrayEnemy[i],arrayEnemy[i].dirx,arrayEnemy[i].diry);
   if (arrayEnemy[i].hitTest  (Player)) {
     Player._alpha = 50;
   }
 }
 ..
..movePlayer (ob, dx, dy){
   ..
   if (_root["Field"][tileName].walk) {
     if ((dx == 1) or (dx == -1)) {
       ob._x += ob.speed * dx;
     }
   if ((dy == 1) or (dy == -1)) {
       ob._y += ob.speed * dy;
     }
   } else {
     hitwall = true;
   }
   ...

Nesta parte do código verificaremos se o inimigo é do tipo “Flip” ou “Choose”. Quando ele é Flip apenas multiplicamos as direções por -1 e quando for choose criamos um vetor com as 4 próximas possibilidades de movimento e usamos uma simples estrutura de random para escolher.

if (hitwall && ob.enemy) {
   if (ob.Type == "Flip")  {
     movePlayer (ob,dx * -1,dy *  -1);
     ob.dirx *= -1;
     ob.diry *= -1;
   } else if (ob.Type ==  "Choose") {
   var arraydir:Array = [[0, 1],  [1, 0], [0, -1], [-1, 0]];
   var rnddir = Math.round  (Math.random () * 4);
   movePlayer (ob,arraydir[rnddir][1],arraydir[rnddir][1]);
   ob.dirx = arraydir[rnddir][0];
   ob.diry = arraydir[rnddir][1];
   }
}

Código Final:

Agora vamos ver como ficou todo o código do na integra.

stop ();
arrayField = [[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
              [2, 0, 0, 0, 0, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2],
              [2, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 1, 2, 2],
              [2, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 2, 2],
              [2, 2, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 2, 2],
              [2, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 2, 2],
              [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2],
              [2, 0, 0, 0, 1, 2, 0, 1, 0, 0, 2, 2, 2, 2, 2],
              [2, 2, 0, 0, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 2],
              [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]];
itens = [[1, 2], [2, 8], [5, 6], [8, 7], [11, 4], [8, 4], [5, 1]];
var pontos:Number = 0;
_root.createEmptyMovieClip ("Field",1);
char = {xtile:1, ytile:1, speed:2, enemy:false};
Enemy1 = {xtile:2, ytile:3, speed:2, enemy:true, dirx:0,  diry:-1, Type:"Flip"};
Enemy2 = {xtile:6, ytile:8, speed:2, enemy:true, dirx:-1,  diry:0, Type:"Choose"};
Enemy3 = {xtile:2, ytile:6, speed:2, enemy:true, dirx:0,  diry:-1, Type:"Flip"};
arrayEnemy = [Enemy1, Enemy2, Enemy3];
Tile0 = {walk:true, frame:1};
Tile1 = {walk:false, frame:2};
Tile2 = {walk:false, frame:3};
TileP = 20;
indice = 0;
for (i = 0; i < arrayField[0].length; i++) {
  for (j = 0; j <  arrayField.length; j++) {
    indice += 1;
    newName =  "Tile_" + j + "_" + i;
    _root["Field"].attachMovie  ("Tile",newName,indice);
    _root["Field"][newName]._x = i * TileP;
    _root["Field"][newName]._y = j * TileP;
    _root["Field"][newName].walk = _root["Tile" + arrayField[j][i]].walk;
    _root["Field"][newName].gotoAndStop  (_root["Tile" + arrayField[j][i]].frame);
  }
}
for (i = 0; i < itens.length; i++) {
  var itemName =  "item_" + itens[i][1] + "_" + itens[i][0];
  _root["Field"].attachMovie  ("itens",itemName,i + 200);
  _root["Field"][itemName]._x  = itens[i][0] * TileP + 10;
  _root["Field"][itemName]._y  = itens[i][1] * TileP + 10;
}
_root["Field"].attachMovie  ("Player","Player",5000);
_root["Field"]["Player"]._x = char.xtile * TileP +  10;
_root["Field"]["Player"]._y = char.ytile * TileP +  10;
_root["Field"]["Player"].height = 7.5;
_root["Field"]["Player"].speed = char.speed;
_root["Field"]["Player"].enemy = char.enemy;
_root["Field"]["Player"].enemy = char.enemy;

for (i = 0; i < arrayEnemy.length; i++) {
  _root["Field"].attachMovie  ("Enemy","Enemy" + i,5001 + i);
  _root["Field"]["Enemy"  + i]._x = arrayEnemy[i].xtile * TileP + 10;
  _root["Field"]["Enemy"  + i]._y = arrayEnemy[i].ytile * TileP + 10;
  _root["Field"]["Enemy"  + i].height = 7.5;
  _root["Field"]["Enemy"  + i].speed = arrayEnemy[i].speed;
  _root["Field"]["Enemy"  + i].enemy = arrayEnemy[i].enemy;
  _root["Field"]["Enemy"  + i].dirx = arrayEnemy[i].dirx;
  _root["Field"]["Enemy"  + i].diry = arrayEnemy[i].diry;
  _root["Field"]["Enemy"  + i].Type = arrayEnemy[i].Type;
  arrayEnemy[i] =  _root["Field"]["Enemy" + i];
}

function loopFrame () {
  var Player =  _root["Field"]["Player"];
  if (Key.isDown  (Key.RIGHT)) {
    movePlayer  (Player,1,0);
  } else if  (Key.isDown (Key.LEFT)) {
    movePlayer  (Player,-1,0);
  } else if  (Key.isDown (Key.DOWN)) {
    movePlayer  (Player,0,1);
  } else if  (Key.isDown (Key.UP)) {
    movePlayer  (Player,0,-1);
  }
  for (i in itens)  {
    var  itemName = "item_" + itens[i][1] + "_" + itens[i][0];
    if  (_root["Field"][itemName].hitTest (Player)) {
      _root["Field"][itemName].removeMovieClip  ();
      pontos  += 100;
    }
  }
  for (i in  arrayEnemy) {
    movePlayer  (arrayEnemy[i],arrayEnemy[i].dirx,arrayEnemy[i].diry);
    if  (arrayEnemy[i].hitTest (Player)) {
      Player._alpha  = 50;
    }
  }
}
function movePlayer (ob, dx, dy) {
  var hitwall:Boolean  = false;
  ob.x = ob._x;
  ob.y = ob._y;
  ob.xtileIm =  Math.floor ((ob.x += ((ob.speed + ob.height) * dx)) / TileP);
  ob.ytileIm =  Math.floor ((ob.y += ((ob.speed + ob.height) * dy)) / TileP);
  var tileName:String  = "Tile_" + (ob.ytileIm) + "_" + (ob.xtileIm);
  if  (_root["Field"][tileName].walk) {
    if ((dx == 1) or  (dx == -1)) {
      ob._x  += ob.speed * dx;
    }
    if ((dy == 1) or  (dy == -1)) {
      ob._y  += ob.speed * dy;
    }
  } else {
    hitwall = true;
  }
  ob.xtile =  Math.floor (ob._x / TileP);
  ob.ytile =  Math.floor (ob._y / TileP);
  ob.xtileIm =  ob.xtile;
  ob.ytileIm =  ob.ytile;
  if (hitwall  && ob.enemy) {
    if (ob.Type ==  "Flip") {
      movePlayer  (ob,dx * -1,dy * -1);
      ob.dirx  *= -1;
      ob.diry  *= -1;
    } else if  (ob.Type == "Choose") {
      var  arraydir:Array = [[0, 1], [1, 0], [0, -1], [-1, 0]];
      var  rnddir = Math.round (Math.random () * 4);
      movePlayer  (ob,arraydir[rnddir][1],arraydir[rnddir][1]);
      ob.dirx  = arraydir[rnddir][0];
      ob.diry  = arraydir[rnddir][1];
    }
  }
}

Como vocês podem ver o código está bem rústico, quando eu tive a idéia de montar este tutorial era para seguir de maneira simples e pratica a criação de um jogo. Não me preocupei muito com modulação e estruturação. Por isso este será o tema do nosso próximo tutorial tile system. Vamos organizar este código e depois migrar para actionscript 3.0.até a próxima. Cya. また見てね.

SNEAK (Serpente)

novembro 6, 2008

今日は皆-さん. Dessa vez até eu me surpreendi, estava eu humildemente vendo o singelo comentário do nosso grande amigo Ratysu pedindo para que eu fizesse o jogo do tetris, foi quando eu pensei, tetris é um pouco complexo para mim, mas eu poderia tentar fazer o jogo da serpente (cobrinha para os intimos). Apesar dos códigos serem complexos eu tive um tempo livre no trabalho e consegui fazer o game em 3 dias.

Remake do grande glassico dos minis games

Clique aqui para jogar

  • Nome: Sneak
  • Ultima Atualização: 6 de Novembro de 2008.
  • Design: Ronaldo Santiago
  • Codificação: Ronaldo Santiago
  • Criação: Remaker
  • Gênero: Puzzle
  • Descrição: Clássico jogo da serpente.
  • Exigências: Suport ao Flash 8 ou superior.
  • Click Aqui para poder jogar

Este game eu fiz para ficar bem simples mesmo, já estou preparando uma versão mais elaborada deste game. Aguardem ^^

Para os leitores os tutoriais de criação de jogos, eu já estou preparando o post da continuação do Tile System e também de efeitos em actionsctip. Vlw pessoal até a próxima CYA. また見てね.

Mario Card 2

outubro 30, 2008

今日は皆-さん. Alguns devem estar se perguntando, por que o Ronaldo não postou nada falando sobre o aniversário do blog e o seu próprio aniversário, o motivo foi: falta de tempo T_T ultimamente tenho andado igual a Jack Bauer (Cloe estamos ficando sem tempo), trabalho, faculdade, curso, Bares (ninguém é de ferro^^), mas apesar do tempo escasso eu consegui uma brechinha na minha agenda para finalmente concluir um novo game. Conheçam agora o Mario Card 2.

Acho que nessa altura do campeonato vocês já devem ter percebido que eu adoro a serie de jogos Mario Bros, se eu não me engano a nintendo começou com um simples jogo de cartas e como o meu game Mario Card foi um sucesso achei que seria uma boa criar uma continuação^^.

  • Nome: Mario Card 2
  • Ultima Atualização: 18 de outubro de 2008.
  • Design: Ronaldo Santiago
  • Codificação: Ronaldo Santiago
  • Criação: Adaptação
  • Gênero: Puzzle
  • Descrição: Jogo de cartas onde seu objetivo é ir removendo todas as cartas iguais que estejam próximas.
  • Exigências: Suport ao Flash 8 ou superior.
  • Click Aqui para poder jogar

Diferente de sua versão anterior Mario Card 2 não é um jogo da memória, e sim um jogo tecnicamente infinito, seu principal objetivo e ir removendo os pares iguais que estejam adjacentes. Após clicar em uma carta você precisa clicar em uma carta que esteja exatamente do lado, não importando a direção: cima, baixo, frente, traz, diagonal o importante é clicar em uma carta que esteja do lado. Se você clicar em qualquer outra carta você estará cancelando a seleção.

Apesar do game estar 99% funcional, eu ainda estou trabalhando nele, em breve estarei fazendo o update deste game com sons e se possível um sistema de recordes. Enquanto o upgrade não chega peço lhes que degustem esse novo game.

Antes de se despedir deste post eu queria agradecer a um grande amigo Garu (vocalista da banda ctrl j ) que me ajudou a encontrar os bugs deste game no processo de criação, ao Phil por sempre que pode divulga meu blog e meus jogos (pode deixar que no próximo post terá imagem do cthulhu e em breve estarei te enviando o desenho do Dr.Orima) e a todos vocês por perderem seus tempos jogando meus simples e singelos jogos, pode deixar que em breve estarei postando mais. Vlw pessoal até a próxima CYA. また見てね.

Tile System [Itens]

setembro 5, 2008

今日は皆-さん Devota ao nosso tutorial system. Hoje nós implementaremos um sistema de itens muito simples. Um sistema de criar itens dentro do cenário tile, verificar se o player pegou o item e contagem simples de pontos. Vejam como ficará nosso arquivo.

Download

Como vocês podem ver, nosso cenário está um pouco diferente do que fizemos no tutorial passado, as mudanças no código são poucas o que deu o charme mesmo foi o gráfico que deu uma melhorada, se vocês baixarem o arquivo vejam o quão simples foi fazer essas mudanças^^

Mudando o código:

Tirando a Matriz que monta o cenário, nós adicionamos um contador para criar o depths de cada tile, fazendo com que o índice todos os depths de cenário fiquem entre 1 e 150, assim você vai se certificar e sempre vai criar um item na camada acima do cenário.

Outra mudança foi nos loops de construção do cenário, nos tutoriais anteriores nós usavamos cenrário quadrado. por isso podíamos usar uma variável limitadora do total para ambos os lados. agora vamos usar a largura do primeiro vetor que fica dentro de arrayField.

...
indice = 0;
for (i = 0; i < arrayField[0].length; i++) {
  for (j = 0; j < arrayField.length; j++) {
    indice += 1;
    newName = "Tile_" + j + "_" + i;
    _root["Field"].attachMovie("Tile",newName,indice);
...

Criando MovieClip Item:

Vamos usar como item uma estrela. Ela deverá ser criada no centro no movieclip e a propriedade linkage denominada “itens”

Array Itens:

Assim como no cenário montaremos um vetor para armazenar o posicionamento de cada item. E criaremos uma variável para armazenar os pontos.

itens = [[1, 2], [2, 8], [5, 6], [8, 7], [11, 4], [8, 4], [5, 1]];
var pontos:Number = 0;

Criaremos um loop que irá de 0 ao tamanho do vetor itens para ir criando cada item no cenário, lembrando que usaremos a mesma estrutura que usamos para criar o jogador no cenário (cordenadax* TileP + 10) e (cordenadax* TileP + 10);

for (i = 0; i < itens.length; i++) {
  var itemName = "item_" + itens[i][1] + "_" + itens[i][0];
  _root["Field"].attachMovie("itens",itemName,i + 200);
  _root["Field"][itemName]._x = itens[i][0] * TileP + 10;
  _root["Field"][itemName]._y = itens[i][1] * TileP + 10;
}

Player vs Itens:

Na função loop criaremos um loop for in em item, Assim a cada movimento do nosso player faremos uma consulta verificando se o nosso player encostou em algum item da tela. Se tiver encostado ele vai remover o item e adicionar um valor para pontos

for (i in itens) {
  var itemName = "item_" + itens[i][1] + "_" + itens[i][0];
  if (_root["Field"][itemName].hitTest(Player)) {
    _root["Field"][itemName].removeMovieClip();
    pontos += 100;
  }
}

Para cada i em itens ele vai construir uma variável com o nome do item correspondente no loop e verificar se encostou no player ou não.

Com isso nosso tutorial tile system item está pronto, agora vocês podem usar a imaginação da maneira que vocês quiserem para montar um joguinho simples de coleta de itens. No próximo tutorial, não tenho certeza ainda mas provavelmente aprenderemos a estruturar inimigos burros no nosso cenário^^ Bem pessoal espero que tenham gostado e até a próxima. CYA, また見てね.

1 de Maio – Descanso?

maio 1, 2008

A preguiça é a mãe de todos os vicíos…
Mas mãe é mãe e devemos respeita-la!!!!

今日は皆-さん. Hoje é um dia muito importante para quem não é vagabundo, o dia do trabalho, dia de você se estirar no sofá e não fazer nada que preste, para você que é vagabundo esteja feliz por que pode fazer isso todos os dias^^ de qualquer maneira aproveitem esse feriado. Feliz dia da Preguiça ou se preferirem Feliz dia do trabalho.

Bem pessoal nen todos usam o dia do trabalho para descansar, no meu caso estou aproveitando o tempo livre para implementar novas funções no meu jogo Demo e hoje postarei a demo atualizada com Inimigos.

Um grande poder exige uma grande responsabilidade, um Herói sempre precisa de um inimigo, Um jogo sem inimigos e como você tomar tequila sem limão e sal, tomar Yukault sem Vodka, Comer arroz sem feijão, tomar sopa sem sal e outras combinações. Por mais simples que um game seja exige Inimigos, para aumentar o campo de improbabilidade dos seus atos.

Clique aqui para testar a demo

Componente de Inimigos

Agora o game conta com 2 tipos de inimigos, podemos rotulalos como Inimigos burros e inimigos menos burros^^

  • Inimigos Burros: Se movem apenas para um lado e para outro, cima – baixo, baixo – cima, direita – esquerda, esquerada direita.
  • Inimigos Menos Burros: Se locomovem de uma parede a outra, quando ele alcança seu objetivo ele tem uma probabilidade de seguir outra direção.

O sistema vai contar com 3 niveis de dificuldade no momento. Onde o nível de dificuldade influencia diretamente na velocidade em que os inimigos se locomovem e a quantidade de inimigos na tela.

Modelo de Sistema

Algumas pequenas coisa do modelo final de sistema já está implementado na demo como por exemplo, ao iniciar um cenário o jogo automaticamente distribui os itens e inimigos aleatóriamente por entre o cenário. Mas o game contará com 2 modelos de sistema Alfabeto e Extra.

  • Alfabeto: Esse modelo funcionará de forma completamente randômica, todos os cenários serão letras, números, o nível de dificuldade, posição dos itens e inimigos, visual de tudo será feito de maneira randômica, resumindo as fazes nunca serão as mesmas^^
  • Extra: Esse modelo serão fases propostas, fases com posicionamento de tudo já predefinido, nível de dificuldade, quantidade de inimigos, posicionamento de itens, e o mais legal desse sistema é o seguinte, eu abrirei espaço para vocês montarem suas próprias fases criarei um editor de cenário aonde os usuários escolheria o tipo cenário, posição de tudo, visual de tudo.

Próximas Etapas

  • Implementar sistema de plano de fundo: para que você não esteja em um bloco e sua cabeça esta debaixo de um item que esta em um bloco acima^^
  • Criar Design: Essa etapa nem preciso explicar né
  • Cobrar 1 dólar para cada pessoa que queria jogar o game ops… err^^ por enquanto vamos pular essa etapa.

Bem espero que estejam gostando no nascimento desse novo game. agora aproveitem o feriado. Até mais, CYA, また見てね

The World Ends With You

abril 23, 2008

The World Ends With You

konnichiwa mina-san! Pela primeira vez desde que montei um blog que deveria ser de “GAMES” estou postando sobre um game que não é meu^^.

The World End With You trata-se do mais novo projeto da squareenix, Imagine que você acorda em uma bela manhã e descobre que se não cumprir missões você será apagado (literalmente) da face da terra. O ambiente do game é Shibuya a cidade da moda (Japão, Nihon para os intimos do idioma), e os vilões são Reapers e monstros tatuados^^, O sistema do game seREAPERS baseaia em combates no estilo Kingdom hearts advance com varios combos e você para fazer certas magias tem que desenhar pixações em seu nintendo DS (no seu mesmo pq eu ainda non tenho um T_T). Esse game provavelmente fará um grande sucesso com a massa, sk8tists, grafiteiros, otakus, sem contar a grande interação entre tekas que esse game terá. Se quizerem saber mais sobre esse incrivel game aqui vai o site oficial The World Ends With You

bem aqui vai algumas Screens do game (Eu roubei essas imagens do google imagens se essas imagens pertencia ao seu site espero que não fique chateado^^)

  • A INOVAÇÂO

A Squereenix nossa de cada dia armou um incrivel concurso juntamente com a comunidade deviantart, onde permitiam aos usuarios criarem herois, inimigos e monstros para serem usado como material de divulção para esse fabuloso game. Onde o ganhador ganharia a oportunidade de ter seu trabalho divulgado junto a comerciais desse game entre outras coisas. Apesar de ter tido acesso a essa inforção 1 dia antes de terminarem as inscrições para o concurso, eu consegui inscrever 2 desenhos meus para tentar o posto de heroi nesse game. Como o game se passa em Shibuya a cidade da moda os desenhistas tinham uma certa liberade para a criação. Deixa de papo e vou mostrar os desnhos que eu postei para concorrer.

Espero que a squereenix gostem seria maneiro ter meu auto retrato (Setzer Wolf) como personagem de um game (Apesar que eu ja fiz isso^^) bem pessoal até a proxima, CYA, Matamitene

Coisa Rápida..VRUUUMMM

abril 11, 2008

Konnichiwa mina san! Hoje eu logei rapidim só para cumprar a promessa de postar a atualizaçao da demo de corrida.

Antes nessa demo vinha 3 carros e você ficava desviando (desviando por capricho porque a batida não funcionava) toda vez que você passava um carro outro aparecia (Na verdade era o mesmo só que ele usava teleporte para frente para você passalo varias vezes) porém entre tudo todavia nessa nova atualização você só está competindo com um carro faça testes do tipo deixar ele te passar e tente rapassalo varias vezes, a ideia nessa nova vesão era testar posicionamento de inimigos para que no futuro teja uns 12 carros correndo^^ e nessa versão você ainda tem acesso a varias informações que pra vocês são inuteis mas pra mim ajuda pacas que é as posições X e Z dos carros. Caso vocês não esjam afim de testar essas demos eu recomendo vocês continuarem jogando Mario card^^ Até a proxima, Cya, Matamitene!

Retomando projetos.

abril 9, 2008

Konichiwa mina-san Devo lhes pedir desculpas por minha ausência no blog. Como eu já havia lhes dito antes estava passando por uma maratona de 240 capítulos em 19 dvds de One Piece.

One piece

One Piece é um anime muito bom de pirataria, com personagens carismáticos, historias dramáticas (até da vontade de chorar T_T), Combates Fodas(desculpe me a expessão), em fim é um excelente anime que eu recomendo, mas por causa dele eu fiquei um tempo numa rotina muito digamos preguiçosa. Acordar as 8 ir pro trabalho as 9, chegar em casa as 7, assistir one piece até meia noite e ir durmir sem mesmo tocar no PC. ^^ mas agora que eu já terminei a maratona vou poder voltar aos meus projetos.

Demo

Como eu havia mencionado eu tinha colocado pra funcionar o portal mas porem entre tudo todavia eu noob como eu sou esqueci o arquivo no trabalho e meio que tive que refazer uns códigos do zero, isso me impediu que eu começasse a trabalhar nos comandos de inimigos.

  • letra

    Planejado Objetivo: Bem eu já avia mencionado que não tinha noção qual seria o objetivo principal do game. Mas quando eu tava fazendo o sistema de fase eu tive uma idéia. Usarei sprites diferentes aleatórios para cada fase, por exemplo, você pode jogar a primeira fase em um cenário de neve, deserto, floresta, factory entre outros aleatórios, seu principal objetivo em cada fase é chegar ao certo numero de pontos e entra no warp portal que aparece ao concluir. Sendo que serão mais de 23 fases ^^ cada fase será uma letra diferente do alfabeto, e conforme você vai passando as fases vai habilitando personagens secretos. E pretendo colocar sistema de recordes (mas ainda eu tenho que estudar com calma e fazer uns testes para ver como funciona)

  • Adicionado Fases: Adicionei algumas fases demo para vocês poderem ter uma noção de como vai funcionar o game.
  • Adicionado Sistema de Portal: Agora o portal que aparece quando você pega os itens funciona.

carro

Recentemente andei mexendo naquela demo de corrida (Madrugas Race) que eu postei aqui a algum tempo mas meu problema ainda é fazer curvas via ActionScript por isso lançarei um game de corrida só com reta ^^ no grande estilo velozes e furiosos. pra semana eu tento colocar a nova atualização dessa demo. vlw pessoal e até a próxima (matamitene)