javafx para criar jogos 1/3

On April 15, 2009, in trecos, by athanazio
4

Segue a parte 1/3 do video da apresentacao no Riojug
em abril de 2009 sobre a criacao de jogos usando JavaFX


JavaFX para criação de Jogos 1/3 from Hamilton Lima on Vimeo.

Tagged with:
 

javafx os cabecudinhos preview 2009-03-18

On March 19, 2009, in games, java, programacao, by athanazio
0

mosquito-killers

Temos grandes novidades neste preview:

  • Uma interface para entrar com nome dos usuarios que estão jogando
  • a tela de como jogar
  • o envio da pontuação para o servidor

Ufa … os novos graficos ainda nao estao lah, mas estao no forno !!

este eh o link para os arquivos do preview
http://svn.vacavitoria.com/cabecudinhos_1/cabecudinhos_1/preview/2009-03-18/

e este eh o video

Tagged with:
 

javafx cabecudinhos preview 2009-03-15

On March 16, 2009, in games, java, programacao, by athanazio
0

cabecudinhos-preview-2009-03-15
Olas ! estamos quase terminando o jogo dos cabecudinhos, episodio I o ataque dos mosquitos ! as partes graficas estao saindo do forno, valeu Mariana !! as coisas estao se encaixando, e em breve vai rolar o envio de pontuacao para o servidor.

Coisas novas bem legais estao neste preview :

  • feedback do tempo para a criacao do novo mosquito e tempo que o item vai ficar sem gerar mosquito
  • efeito quando os personagens sao atingidos pelo mosquito
  • contagem dos pontos

baixe o arquivo de webstart da implementacao atual
cabecudinhos_episodio_um.jnlp

curta o video do preview

e aproveite a moleza do codigo fonte disponivel no subversion :P

Tagged with:
 

javafx jogos dos cabecudinhos 2 na tela

On March 10, 2009, in java, programacao, by athanazio
0

Opa Opa ! grande passo no jogo dos cabeçudinhos ! agora estão os dois na tela, e com movimentos independentes, um pequeno passo para os cabeçudos um grande passo para a vaca vitoria !! huauhahuahu
dois-personagens-na-tela

veja o video

Tagged with:
 

javafx personagem que salta nas plataformas

On March 8, 2009, in games, by athanazio
7

Uia ! implementei meus rabiscos de gravidade e não eh q funcionou !! hehehe

como tinha dito em javafx-planejando-gravidade são 3 classes envolvidas:

  • GravityManager – fazo update() a cada tick do jogo
  • Force – aplica mudança de posição aos nodes
  • GNode – associa Node a Force.

Para os catucadores de plantão segue o endereço do subversion
http://svn.vacavitoria.com/cabecudinhos_1/cabecudinhos_1/

E alguns fragmentos do codigo
esta eh a Scene em que usei a GravityManager

public class GameScene extends Scene, Updatable{
    ...
    public var gravityManager: GravityManager;

    // set the need info for the Scene work
    public function setup(){
        gameSoundtrack.play();

        background =
        lookup(BACKGROUND_ID) as NodeFromFXZ;
        player1 =
        lookup(PLAYER1_ID) as MovableChar;
        player1.background = background;
        player1.requestFocus();

        gravityManager = GravityManager{
            gravity: 5
            content: [
                GNode{
                    node: bind player1
                }
            ]
        }

    }

    public override function update(){
        gravityManager.update();
    }

    override var content = [
        NodeFromFXZ{
            id: bind BACKGROUND_ID
            source: "{__DIR__}media/background.fxz"
        }

        MovableChar{
            id : bind PLAYER1_ID
            source: "{__DIR__}media/boy.fxz"
            x: 50
            y: 450
            speed: 3
            colision: ["casa1", "casa2", "casa3","casa4", "casa5", "casa6", "casa7", "casa8",
             "caixa1", "caixa2", "caixa3","caixa4", "caixa5", "caixa6",
            "caixa7", "caixa7b", "caixa8", "caixa8b",
            "left", "right", "bottom","top", "plataforma1"]

            onMouseClicked: function(e){
            }

            onKeyReleasedDelegate: function(current:MovableChar, key: KeyCode){
               if( key == KeyCode.VK_SPACE and current.hasColision){
                   fire.play();
                   gravityManager.addForce( current.id, Force {
                        y: -22;
                   });
                }
            }

            onUpdate: function(current:MovableChar){
                current.checkIfScrollBackground();

            }
        }
    ]
}

Segue o codigo das classes para o controle da gravidade

GravityManager

public class GravityManager extends Updatable{

    public var gravity: Integer;
    public var content: GNode[];

    public function addForce(id:String, force: Force){
        for( gNode in content){
            if( gNode.node.id.equals(id) )  {
                insert force into gNode.forces;
            }
        }
    }

    public override function update(){

        // iterate over all gnodes
        for( gNode in content){
            var x: Integer = 0;
            var y: Integer = gravity;

            // iterate over all Force from the GNode
            for( force in gNode.forces){
                x = x + force.x as Integer;
                y = y + force.y as Integer;

                force.applyGravity(gravity);
                if( force.isDisposable()){
                    delete force from gNode.forces;
                }
            }

            // try to move the Node with the increase of x and y
            gNode.node.moveX(x);
            gNode.node.moveY(y);
        }
    }
}

Force.fx

public class Force {

    public var x: Number;
    public var y: Number;
    public var percentGravity: Number = 0.15;

    // reduce the x and y value with the gravity
    public function applyGravity(gravity:Integer){
        if( x < 0 ){
            x = x + (gravity * percentGravity);

            if( x > 0 ){
                x = 0;
            }
        }

        if( y < 0 ){
            y = y + (gravity * percentGravity);
            if( y > 0 ){
                y = 0;
            }
        }
    }

    public function isDisposable():Boolean{
        return x == 0 and y == 0;
    }

}

GNode

public class GNode {

    public var node: MovableChar;
    public var forces: Force[];

}

E finalmente o video com o resultado saltitante :)

Tagged with:
 

site brazuca de jogos

On March 7, 2009, in games, by athanazio
0

mor legal este site http://www.umpi.com.br/index.html

Tagged with:
 

javafx planejando gravidade …

On March 6, 2009, in games, java, programacao, by athanazio
1

Nesta jornada de explorar JavaFx, e na migração do jogo que fizemos no evento do global game jam 2009, estou agora implementando a gravidade para o side scrolling.

Ou seja preciso de um mecanismo para manter os personagens no chão … e que possam dar uns pulinhos, e que não seja soh para cima possam ser pulinhos para os lados, vejam os rascunho que fiz no ônibus.

gravity-manager

A idéia é simples, uma classe para gerenciar a gravidade contendo as lista de plataformas onde será necessário verificar a colisão, para segurar o personagem, uma lista de GNodes que vao ter uma lista de forças que vao incidir sobre e o Node propriamente dito.

cada item que vai representar um Força vai possuir x, y percentual de gravidade que sera aplicado, uma funcao applyGravity(g) e outra para ver se pode remover o objeto da lista, isDisposable()

a logica do update do gravity manager eh :

  • calcular para cada GNode e para cada Força contida o deslocamento x e y do node
  • chamar para cada força o metodo applyGravity()
  • remover cada força que retornar true do isDisposable()

bem este é o plano, vamos ver se funciona :)

Tagged with:
 

artigo da veja sobre jogos no Brasil

On March 6, 2009, in games, by athanazio
0

Opa a veja deu um espaço interessante para a divulgação dos jogos no Brasil !
http://veja.abril.com.br/040309/p_100.shtml

Fala taikodon o RPG espacial, e do lançamento do Zeebo o novo console brasileiro.

Tagged with:
 

vote no tinysoldiers !

On February 3, 2009, in trecos, by athanazio
0

Baixe o jogo, comente no forum, de sua opinião !!

e vote com a sua opiniao tambem no site do globalgamejam

http://globalgamejam.org/games/tiny-soldiers-rise-mosquitos

Tagged with:
 

c# xna lendo mapas

On January 15, 2009, in games, programacao, by athanazio
0

Pelo que estou estudando, entendi que ateh consigo ler arquivos externos ao programa usando a classe StreamReader, mas quando o build do projeto for feito vai ter dependência que o arquivo exista fora do executável e não tenho a menor idéia de como referenciar o sistema de arquivo do Xbox por exemplo.

Assim sendo tem a tal da pasta content no projeto do jogo, dando add em itens nesta pasta, eles podem ser carregados pelo ContentManager !! mor legal.

No meu caso preciso carregar arquivos de mapa que gerei que contém um monte de zeros e uns, algo do tipo :

111111111111111111111111111111
100000000001100000000000000001
101111111111101111111111111101
101111111111101111111111111101
100000000001100001100001100001
101111111101111101101101101111
101111111101111101101101101111
100000001101100001101101100001

entaum seguindo alguns tutoriais, entendi que precisava escrever um contentimporter, para que o xna soubesse como transformar meu belo arquivo em objetos usaveis.

segui o tutorial e criei um Content PipeLine Extension Library dentro da mesma solution do jogo

e criei a classe MapFilesImporter

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline.Processors;

using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler;
using Microsoft.Xna.Framework.Content;

using System.IO;

namespace MapFilesContentPipeLine
{
[ContentImporter(".maze", DisplayName = "Map Files - ChikenMaze")]
public class MapFilesImporter : ContentImporter
{

public override Boolean[,] Import(string filename,
ContentImporterContext context)
{
FileStream stream = File.OpenRead(filename);
StreamReader reader = new StreamReader(stream);
List> buffer = new List>();

string line = reader.ReadLine();
while (line != null)
{

List bufferLine = new List();
foreach (char one in line)
{
bufferLine.Add(one == ’1′ ? true : false);
}
buffer.Add(bufferLine);
line = reader.ReadLine();
}

Boolean[,] result = new Boolean[buffer.Count, buffer[0].Count];
int row = 0;
int col = 0;

// copy data to the matrix
foreach (List onelist in buffer)
{
foreach (Boolean spot in onelist)
{
result[row, col] = spot;
col++;
}
row++;
col = 0;
}

return result;
}

}
}

Lembrando é claro de fazer referência ao projeto to content pipeline tanto no projeto do jogo, quanto nas referências da pasta content, isto me rendeu um tempão para perceber … hehehehe

dai tive a surpresa legal …
Error 1 Building content threw RankException: Cannot serialize multidimensional arrays.
po custava saber serializar arrays multidimensionais ?? =)

bem vou ter que mudar um pouco a estratégia de carregar os mapas, jah vi que vou precisar de um tipo de dados mais simplim que um array multidimensional de booleanos, pow mais simples que isso !! hehehehe, vou criar algo do tipo MapDefinition com as strings das linhas e um método para transformar na famigerada matriz de booleanos.

então refiz a classe de importar o formato de arquivo que tenho, novinha em folha !
comparando com a anterior, nesta mudei o display name para poder verificar se estava usando a nova implementação (danado desconfiado huahuahuuah) e passei a retornar List para os intimos conhecida como lista de tamanho variável de string.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline.Processors;

using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler;
using Microsoft.Xna.Framework.Content;

using System.IO;

namespace MapFilesContentPipeLine
{
[ContentImporter(".maze", DisplayName = "Map Files - ChikenMaze (List)")]
public class MapFilesImporter : ContentImporter>
{

public override List Import(string filename,
ContentImporterContext context)
{
FileStream stream = File.OpenRead(filename);
StreamReader reader = new StreamReader(stream);
List buffer = new List();

string line = reader.ReadLine();
while (line != null)
{
buffer.Add(line);
line = reader.ReadLine();
}

return buffer;
}

}
}

com esta novidade precisei alterar um pouco a classe que gerencia os mapas para poder converter de List para Boolean[,] olha como ficou o trecho que carrega o mapa e o conversor de um tipo para o outro.

public Map getMap(int level)
{
// ok ok in one line would be cooler =)
// Boolean[,] map = ListString2MatrixBoolean(scene.game.Content.Load>(getMapName(level)));
//
// but this way we can read easily at 4:30AM
//
string filename = getMapName(level);
List buffer = scene.game.Content.Load>(filename);
Boolean[,] map = ListString2MatrixBoolean(buffer);
return new Map(this.scene, map);
}

public Boolean[,] ListString2MatrixBoolean(List list)
{
Boolean[,] result = new Boolean[list.Count, list[0].Length];
int row = 0;
int col = 0;

foreach (string line in list) {
foreach (char one in line)
{
result[row, col] = (one == ’1′ ? true : false);
col++;
}
row++;
col = 0;
}

return result;
}

ultimo comentario para os desesperados que leram até o final, uma pena que minha mãe não programa em c# !! ela estaria lendo tudinho !! huahuahuhua

quando fizer referência ao arquivo a ser carregado nao inclua a extensão, eu estava buscando por maze_10_10.maze e recebendo o erro de “file not found”, resolvi fazer do mesmo jeito que estava fazendo com os arquivos de imagens e todos ficaram felizes, basta uasr o nome sem extensão.

olha que bela imagem da galinha andando num mapa carregado do arquivo !!

link para os tutoriais

Custom Content Importer with XNA 2.0
http://www.ziggyware.com/readarticle.php?article_id=166

Using a Custom Importer or Content Processor
http://msdn.microsoft.com/en-us/library/bb447743(XNAGameStudio.20).aspx

Tagged with:
 

este post eh continuação de

http://www.athanazio.com/2009/01/11/c-criando-um-labirinto-v1/

Fazer as conexões entre os elementos do labirinto foi uma coisa interessante, porque eu preciso de uma representação onde cada posição, seja parede ou celula vazia tenha a mesma largura para representar isto para cada item do labirinto criei uma matriz 3×3 onde a posição do centro representa a celula em si e as posições ao redor são as possiveis conexões com as proximas células, veja o desenho abaixo

o centro do quadro eh a celula atual sendo processada, e as caixa ao redor sao os possiveis vizinhos, note que para cara vizinho existe uma combinacao de modificadores para x e y, por exemplo o vizinho ao norte é 0 e -1 o do leste 1 e 0 e assim por diante.

alem disto para conectar ao vizinho armazenei tambem que coordenada na matriz de conexões é necessário atualizar para realizar a conexão, por exemplo para o norte a conexão é feita em 1,2 da matriz de conexões.

a matriz com estas definições está na classe de geração do maze

int[,] SearchNeighBorNumbers = { { 0, -1, 1, 2 }, { 1, 0, 0, 1 }, { 0, 1, 1, 0 }, { -1, 0, 2, 1 } };

desta forma preciso sortear somente que linha desta matriz vou usar para manipular o vizinho, e assim realizo as conexões. Antes que eu me esqueça ! além de mudar a matriz de conexões do vizinho é necessário fazer o mesmo na célula corrente e para encontrar a célula correta basta usar o mesmo deslocamento usado para encontrar o vizinho, dentro da matriz de conexões da celula atual, a partir da posicao 1,1 conforme este treco abaixo

current.conections[
1 + SearchNeighBorNumbers[neighborRow, NEIGHBOR_X],
1 + SearchNeighBorNumbers[neighborRow, NEIGHBOR_Y]] = OPEN;

algumas referencias para labirintos

tutorial sobre a geração do labirinto
http://www.mazeworks.com/mazegen/mazetut/index.htm

mais comentarios sobre o algoritmo
http://en.wikipedia.org/wiki/Maze#Generating_mazes

uma visao mais detalhada do Deep-first
http://en.wikipedia.org/wiki/Depth-first_search

Tagged with:
 

c# criando um labirinto v1

On January 11, 2009, in games, programacao, by athanazio
1

Para o jogo que estou criando preciso de uns labirintos e como não achei algo que pudesse gerar para um arquivo texto, estou implementando o meu mesmo, com algumas leituras vi que o algoritmo mais fácil para este caso seria a através de uma pilha assim eu garanto que percorri todos os elementos do labirinto.

o algortimo consiste em escolher uma posicao aleatoria, e buscar os vizinhos nao visitados ao redor, encontrando um abre caminho ateh ele e empilha o mesmo, e vai fazendo isto até que não existam vizinhos não visitados, assim vai desempilhando para voltar no caminho e tentando achar vizinhos não visitados no caminho de volta.
Assim percorremos todo o mapa mas ainda ficam uns becos sem saída, como pode ver marcado neste desenho que fiz quando estava testando manualmente o algoritmo

o teste foi de 5×5 e marquei com bolinhas abobora os becos sem saída, na próxima versão do algoritmo vou guardar os becos sem saída e conectar com algum vizinho =) eh melhor fazzer andar em círculos do que encontrar um beco em saída, hehehe

Seguem os códigos fonte, do gerador e do programa que esta gravando num arquivo texto o maze gerado, que por sinal esta com algum problema ainda …

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace MazeGenerator
{
class Program
{
static void Main(string[] args)
{
MazeGen mazeGen = new MazeGen();
MazeGen.MazeCell[,] maze = mazeGen.generateMaze(5,5);

string fileName = “c:/work/maze” + DateTime.Now.ToBinary() + “.txt”;
FileStream stream = File.Open(fileName, FileMode.OpenOrCreate);
StreamWriter writer = new StreamWriter(stream);

for (int n = 0; n < maze.GetLength(0); n++)
{
for (int conn = 0; conn < 3; conn++)
{
for (int m = 0; m < maze.GetLength(1); m++)
{
writer.Write(maze[n, m].conections[conn, 0] == MazeGen.OPEN ? "_" : "*");
writer.Write(maze[n, m].conections[conn, 1] == MazeGen.OPEN ? "_" : "*");
writer.Write(maze[n, m].conections[conn, 2] == MazeGen.OPEN ? "_" : "*");
}
writer.WriteLine();
}
}
writer.Close();
}
}
}

MazeGen,cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace MazeGenerator
{
public class MazeGen
{
public const Boolean DEBUG = true;
public const int CLOSED = 0;
public const int OPEN = 1;

public const int NEIGHBOR_X = 0;
public const int NEIGHBOR_Y = 1;
public const int NEIGHBOR_CONNECTION_2OPEN_X = 2;
public const int NEIGHBOR_CONNECTION_2OPEN_Y = 3;
public const int POSSIBLE_NEIGHBORS = 4;

public static Random random = new Random();

public class MazeCell
{
public MazeCell(int X, int Y)
{
this.X = X;
this.Y = Y;
this.Visited = false;
}

public Boolean Visited = false;
public int X;
public int Y;
// north, east, south, west
public byte[,] conections = { { CLOSED, CLOSED, CLOSED },
{ CLOSED, OPEN, CLOSED },
{ CLOSED, CLOSED, CLOSED } };

public override string ToString()
{
string buffer = "";
foreach( byte one in conections){
buffer += one.ToString();
}

return X + "," + Y + " [" + buffer +"] ";
}
}

// used to random the neighbor cell
// { increment of X, increment of Y, connection to open in the neighbor }
int[,] SearchNeighBorNumbers = { { 0, -1, 1, 2 }, { 1, 0, 0, 1 }, { 0, 1, 1, 0 }, { -1, 0, 2, 1 } };

public MazeCell[,] generateMaze(int rows, int cols)
{

// fill the matrix
MazeCell[,] result = new MazeCell[rows, cols];
for (int n = 0; n < result.GetLength(0); n++)
{
for (int m = 0; m < result.GetLength(1); m++)
{
result[n, m] = new MazeCell(n, m);
}
}

int visited = 1;
int total = rows * cols;

Stack path = new Stack();

int x = random.Next(1, rows - 1);
int y = random.Next(1, cols - 1);

result[x, y].Visited = true;

path.Push(result[x, y]);
MazeCell current = result[x, y];

while (visited < total)
{
// try the unvisited neighbors
int neighborRow = random.Next(0, 3);
MazeCell neighbor = nextRandomUnvisited(result, current, neighborRow);

int tries = 1;
while (tries < POSSIBLE_NEIGHBORS && neighbor == null)
{
neighborRow ++;
if( neighborRow >= POSSIBLE_NEIGHBORS ){
neighborRow = 0;
}
neighbor = nextRandomUnvisited(result, current, neighborRow);
tries ++;
}

if (neighbor == null)
{
current = (MazeCell)path.Pop();
}
else
{
current.conections[
1 + SearchNeighBorNumbers[neighborRow, NEIGHBOR_X],
1 + SearchNeighBorNumbers[neighborRow, NEIGHBOR_Y]] = OPEN;

neighbor.Visited = true;
neighbor.conections[
SearchNeighBorNumbers[neighborRow, NEIGHBOR_CONNECTION_2OPEN_X],
SearchNeighBorNumbers[neighborRow, NEIGHBOR_CONNECTION_2OPEN_Y]] = OPEN;

if (DEBUG){Console.WriteLine(“from {0} to {1}”, current, neighbor);}

path.Push(neighbor);
current = neighbor;
visited++;
}
}

return result;
}

public MazeCell nextRandomUnvisited(MazeCell[,] result, MazeCell current, int neighborRow)
{

int testX = current.X + SearchNeighBorNumbers[neighborRow, NEIGHBOR_X];
int testY = current.Y + SearchNeighBorNumbers[neighborRow, NEIGHBOR_Y];

// check if neighbor exists
// if not will try again
if (testX >= 0 && testX < result.GetLength(0) && testY >= 0 && testY < result.GetLength(1))
{

if (!result[testX, testY].Visited)
{
return result[testX, testY];
}
}

return null;
}

}
}

Tagged with:
 

c# xna criação de cenas e scroll de mapa

On January 11, 2009, in games, programacao, by athanazio
1

Uai ! em ateh map scroll hehehe, bem parte das minhas reflexões sobre a forma de implementar o jogo estão se materalizando, criei o conceito de cena, contendo o gerenciador de eventos e deslocamento da tela para permitir o scroll da tela de fundo.

o primeiro detalhe eh a classe Scene em si

using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace ChickenMaze
{
public abstract class Scene
{
public Game game;
public EventManager eventManager;
public int X;
public int Y;

public Scene(Game game, EventManager eventManager)
{
this.game= game;
this.eventManager= eventManager;
this.X = 0;
this.Y = 0;
}

public abstract void Initialize();
public abstract void LoadContent();
public abstract void Draw(GameTime gameTime, SpriteBatch spriteBatch);

}
}

que em alguns aspectos tentei manter o design semelhante a classe Game, com excessão do método Draw que adicionei o objeto spriteBatch sendo passado como parâmetro para evitar esta complexidade na cena atual, assim na classe Game principal do jogo um objeto scene é criado, e ao executar initialize, loadcontent e draw os respectivos metodos da Scene corrente serão chamados.

Esta abaixo eh a SceneMainMaze que determina os detalhes especificos do jogo, como sprite que vai ser usado como personagem, mapa e tratadores de eventos, note que a implementação dos eventos fica separada deste código.

using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace ChickenMaze
{
class SceneMainMaze : Scene
{
Sprite chicken;
Map map;

public SceneMainMaze(Game game, EventManager eventManager)
: base(game, eventManager)
{

}

public override void Initialize(){

map = new Map(this);
chicken = new Sprite(“chicken”, this);
chicken.Position = map.GetFirstFreeSpot();
chicken.SetMap(map);

eventManager.addHandler(new EventCantMoveHere(this));
eventManager.addHandler(new EventKeyboardLeft(this, chicken, map));
eventManager.addHandler(new EventKeyboardRight(this, chicken, map));
eventManager.addHandler(new EventKeyboardUp(this, chicken, map));
eventManager.addHandler(new EventKeyboardDown(this, chicken, map));
eventManager.addHandler(new EventNeedScrollMap(this, chicken, map ));
}

public override void LoadContent()
{
chicken.LoadContent(game.Content);
map.LoadContent(game.Content);
}

public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
{
Color color = new Color(0, 136, 0);
game.GraphicsDevice.Clear(color);

map.Draw(spriteBatch);
chicken.Draw(spriteBatch);
}
}
}

Então o trecho abaixo mostra como os eventos são registrados para que ao serem disparados, o tipo de evento é testado e em seguida o métido run() dos eventos é executado

eventManager.addHandler(new EventKeyboardDown(this, chicken, map));
eventManager.addHandler(new EventNeedScrollMap(this, chicken, map ));

O código abaixo é o tratador de eventos para quando o scroll de mapa eh necessário

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace ChickenMaze
{
class EventNeedScrollMap: EventHandler
{
protected Sprite sprite;
protected Map map;

protected int HorizontalBorderLimit;
protected int VerticalBorderLimit;

const byte BORDER_DIVISION_INDEX = 4;

public EventNeedScrollMap(Scene scene, Sprite sprite, Map map)
: base(EventHandler.EventType.SPRITE_MOVED, scene)
{
this.sprite = sprite;
this.map = map;

HorizontalBorderLimit = scene.game.GraphicsDevice.Viewport.Width / BORDER_DIVISION_INDEX;
VerticalBorderLimit = scene.game.GraphicsDevice.Viewport.Height / BORDER_DIVISION_INDEX;
}

///

/// if the sprite is close to the border of the viewport,
/// for each direction of the movement change the viewport
/// of the GraphicsDevice
///

/// public override void run(Object source) {

int SceneShift = sprite.speed;
int x = (int)sprite.Position.X – scene.X;
int y = (int)sprite.Position.Y – scene.Y;

// into left limit
if (x < scene.game.GraphicsDevice.Viewport.X + HorizontalBorderLimit)
{
if (scene.X - SceneShift > 0)
{
scene.X -= SceneShift;
}
}

// into right limit
if (x > scene.game.GraphicsDevice.Viewport.X
+ scene.game.GraphicsDevice.Viewport.Width – HorizontalBorderLimit)
{
scene.X += SceneShift;
}

// into top limit
if (y < scene.game.GraphicsDevice.Viewport.Y + VerticalBorderLimit)
{
if (scene.Y - SceneShift > 0)
{
scene.Y -= SceneShift;
}
}

// into bottom limit
if (y > scene.game.GraphicsDevice.Viewport.Y
+ scene.game.GraphicsDevice.Viewport.Height – VerticalBorderLimit)
{
scene.Y += SceneShift;
}

}

}
}

Desta maneira tratadores de evento podem ser facilmente reaproveitados entre jogos, e inclusive escrever código para realizar testes destes tratadores.

os próximos passos são :

  • carregar o mapa de uma arquivo
  • determinar que a galinha chegou no fim do mapa e criar evento para isto
  • adicionar sons
  • adicionar timer na tela
  • adicionar os marcadores de labirinto com ovos (1 ovo a cada 10 segundos com duração de 60 segundos cada)
  • adciionar cena de tela inicial
  • adicionar cena de pontuação
Tagged with:
 

xna uma lista de tutoriais

On January 11, 2009, in games, programacao, by athanazio
0
Tagged with:
 

sons gratuitos e experimentais

On January 11, 2009, in games, by athanazio
0

muito show este site de efetios sonoros, tem uns experimentais muito legais
http://www.freesound.org
Este devo usar no jogo da galinha
http://www.freesound.org/samplesViewSingle.php?id=49805

Tagged with: