Archive for the ‘java’ Category

ano de jogos e a vinda do jaga

December 10th, 2009

Ahhhh 2009 terminando, quanta coisa aconteceu !! minha investida no mercado de jogos esta crescendo, consegui fazer vários jogos este ano, vários mesmo !! dá uma olhada na lista : http://www.athanazio.com/jogos/ e nesta jornada usei diversas tecnologias diferentes: XNA, SDL, Lõve, Java, Unity3D delícia !! agora com a experiência que acumulei estou iniciando o desenvolvimento de um framework para jogos, onde o desenvolvimento será em Lua e o backend em Java.

A implementação da primeira versão de testes foi feita para o sistema operacional Android, e pretendo ter a versão para web pronta para o próximo Ludum Dare ! espera otimas novidades ! assim que tiver um release para download vai estar em jaga.athanazio.com

abs

android game – imagem e som

November 21st, 2009

android show image
Opa ! apos algumas idas e vindas no codigo, as coisas começam a se arrumar hehehehe, nesta versão já esta resolvida a exibição de imagem a partir do nome da imagem, e execução de som no formato ogg, tanto no loop como um som a partir de um evento do usuário.

Apesar da recomendação do SDK seja de acessar os arquivos de midia através do resource ID criado na classe R, eu estou construindo as classes usando o nome do resource para poder expandir a programação do jogo para uma lingaguem de script, e usar o java como uma camada de abstração do jogo.

Vamos ao codigo e alguns comentarios sobre cada um :

GameActivity - ganhou uma nova chamada para determinar que volume o jogo vai usar, setVolumeControlStream(AudioManager.STREAM_MUSIC) assim o jogo fica com o mesmo volume que estiver acertado para a musica, alem disto o metodo onDestroy() chama o novo metodo release() da view que vai se encarregar de liberar recursos e em especial mandar os audios se calarem :)

package com.athanazio.android.showimage;

import android.app.Activity;
import android.media.AudioManager;
import android.os.Bundle;
import android.view.Window;

public class GameActivity extends Activity {
	private GameView view;

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setVolumeControlStream(AudioManager.STREAM_MUSIC);

		view = new GameView(this, getResources());
		setContentView(view);
	}

	protected void onDestroy() {
		super.onDestroy();
		view.release();
	}

}

GameView – usa as classes Sprite e Audio para exibir imagens e tocar audio, poucas mudanças comparando com a versão anterior.

package com.athanazio.android.showimage;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;

public class GameView extends View implements Runnable {

	private static final String TAG = "GAME VIEW";

	private static final int INTERVAL = 10;
	private Paint cPaint;

	private boolean running = true;

	FPSCounter fps;

	private Sprite background;
	private Sprite cloud;

	private Audio soundtrack;
	private Audio touch;

	public GameView(Context context, Resources resources) {
		super(context);

		String packageName = getClass().getPackage().getName();

		background = new Sprite(resources, packageName, "background");
		cloud = new Sprite(resources, packageName, "cloud");
		cloud.setCenterAtMiddle();

		soundtrack = new Audio(resources, packageName, "soundtrack");
		touch = new Audio(resources, packageName, "cowbell");

		soundtrack.setLooping(true);
		soundtrack.play();

		cPaint = new Paint();
		setFocusable(true);
		setClickable(true);
		setLongClickable(true);

		fps = new FPSCounter();

		// Set the background
		this.setBackgroundColor(Color.WHITE);
		Log.i(TAG, "game view created");

		Thread monitorThread = new Thread(this);
		monitorThread.setPriority(Thread.MIN_PRIORITY);
		monitorThread.start();
	}

	public void draw(Canvas canvas) {
		super.draw(canvas);

		background.draw(canvas);
		cloud.draw(canvas);

		cPaint.setColor(Color.WHITE);
		canvas.drawText(fps.getFPS(), 20, 20, cPaint);
	}

	public boolean onKeyUp(int keyCode, KeyEvent event) {
		return super.onKeyUp(keyCode, event);
	}

	public boolean onKeyDown(int keyCode, KeyEvent event) {
		boolean handled = false;
		Log.i(TAG, "key down");
		float x = cloud.getX();
		float y = cloud.getY();

		if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
			y = y - 5;
			handled = true;
		} else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
			y = y + 5;
			handled = true;
		} else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
			x = x - 5;
			handled = true;
		} else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
			x = x + 5;
			handled = true;
		}

		cloud.move(x, y);
		return handled;
	}

	public boolean onTouchEvent(MotionEvent event) {
		cloud.setX(event.getRawX());
		cloud.setY(event.getRawY());
		Log.i(TAG, "on touch");

		touch.play();
		return super.onTouchEvent(event);
	}

	public void run() {
		while (running) {
			try {
				Thread.sleep(INTERVAL);
			} catch (InterruptedException e) {
				Log.e(TAG, "main loop finished");
			}
			update();
			postInvalidate();
		}
	}

	private void update() {
		fps.update();

	}

	public void release() {
		running = false;
		soundtrack.release();
		touch.release();
	}

}

Sprite – esta eh responsavel por exibir imagens na tela, uma atenção especial deve ser dada ao recurso de determinar o centro da imagem, isto eh muito util para responder eventos de mouse, e por exemplo posicionar a imagem centralizada onde o usuário clicou, o método setCenterAtMiddle() calcula a posição para desenhar baseado na largura e altura da imagem. e por default o centro da imagem eh no 0,0.

package com.athanazio.android.showimage;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.Log;

public class Sprite {

	private static final String TAG = "GAME SPRITE";
	private Bitmap bitmap;
	private float x;
	private float y;
	private float centerX;
	private float centerY;
	private float drawX;
	private float drawY;
	private Paint paint;

	public Sprite(Resources resources, String packageName, String name) {
		String logFileName = packageName + " " + name;
		Log.i(TAG, "loading image : " + logFileName);

		int id = resources.getIdentifier(name, "drawable", packageName);
		bitmap = BitmapFactory.decodeResource(resources, id);
		centerX = 0;
		centerY = 0;

		setX(0);
		setY(0);

		this.paint = new Paint();
	}

	public void draw(Canvas canvas) {
		canvas.drawBitmap(bitmap, drawX, drawY, paint);
	}

	public void move(float x, float y) {
		setX(this.x + x);
		setY(this.y + y);
	}

	public void setCenterAtMiddle(){
		centerX = bitmap.getWidth() / 2F;
		centerY = bitmap.getHeight() / 2F;
	}

	public float getX() {
		return x;
	}

	public void setX(float x) {
		this.x = x;
		drawX = this.x - centerX;
	}

	public float getY() {
		return y;
	}

	public void setY(float y) {
		this.y = y;
		drawY = this.y - centerY;
	}

}

Audio – esta classe esconde a criação de um MediaPlayer para cada som que se deseja tocar, imagino que o melhor cenário seria ter uma classe para som em loop que usaria um MediaPlayer, e outra classe para efeitos sonoros que tocaria no maximo N efeitos ao mesmo tempo, mantendo menos objetos MediaPlayer na memória.

Mas a implementação atual mantém um MediaPlayer para cada som, observar que o resource ID é recuperado pelo nome do arquivo usando o metodo resources.getIdentifier(name, “raw”, packageName) e a partir do resource ID podemos recuperar o AssetFileDescriptor com a chamada resources.openRawResourceFd(id), of file descriptor é usado para inicializar o MediaPlayer com os detalhes necessários a execução do som.

package com.athanazio.android.showimage;

import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.media.MediaPlayer;
import android.util.Log;

/**
 * Audio resources abstraction
 *
 * @author athanazio
 * @see "http://developer.android.com/intl/fr/guide/topics/media/index.html"
 * @see "http://developer.android.com/intl/fr/reference/android/media/MediaPlayer.html#Valid_and_Invalid_States"
 */
public class Audio {

	private static final String TAG = "GAME AUDIO";
	private MediaPlayer player;
	private boolean ready;
	private int id;
	private AssetFileDescriptor afd;

	/**
	 *
	 * @param resources
	 * @param context
	 * @param packageName
	 * @param name
	 *
	 */
	public Audio(Resources resources, String packageName, String name) {
		String logFileName = packageName + " " + name;
		Log.i(TAG, "loading audio : " + logFileName);

		ready = false;
		player = new MediaPlayer();

		try {
			this.id = resources.getIdentifier(name, "raw", packageName);
			this.afd = resources.openRawResourceFd(id);

			Log.i(TAG, "loading audio : " + logFileName + " id:" + id);

			player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
			player.setLooping(false);
			player.prepare();

			// reset the player after completion
			player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
				public void onCompletion(MediaPlayer mp) {
					try {
						player.reset();
						player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
						player.prepare();
					} catch (Exception e) {
						Log.e(TAG, "error resetting the media player");
						e.printStackTrace();
					}
				}
			});

			ready = true;

		} catch (Exception e) {
			Log.e(TAG, "ERROR loading audio : " + logFileName);
			e.printStackTrace();
		}
	}

	public void play() {
		if (ready) {
			player.start();
		} else {
			Log.i(TAG, "the player is not ready.");
		}
	}

	public void setLooping(boolean b) {
		player.setLooping(b);
	}

	public void release() {
		player.stop();
		player.release();
	}

}

glaucon e a caverna – jogo do ld15

September 13th, 2009

glaucon and the cave
ld15-athanazio-v2
Olas esta eh a segunda versao com algumas melhorias do jogo que fiz para a competicao de 48 Ludum Dare #15.

basta levar o Glaucon pela caverna, coletar os artefatos, evitar zumbis, e jogar tochas neles, tem 4 fases.

divirta-se !!

javafx os cabecudinhos preview 2009-03-18

March 19th, 2009

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

javafx cabecudinhos preview 2009-03-15

March 16th, 2009

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

javafx group dentro de group

March 14th, 2009

groupgroup
Quando criamos uma cena em Javafx, por vezes precisamos controlar grupos de componentes como um só, neste exemplo demonstro como adicionar dois grupos distintos em uma mesma cena, e fazendo com que uma fique invisivel enquanto a outra visivel. Neste exemplo são criados dois objetos Group que juntos compõe o content da Scene

import javafx.scene.Cursor;
import javafx.scene.effect.DropShadow;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.Scene;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;

/**
 * @author athanazio
 */

Stage {
    title: "Application title"
    width: 250
    height: 150
    scene: Scene {
        content: [
            Group{
                id: "me"
                content: [
                    Rectangle {
                        cursor: Cursor.HAND
                        x: 5
                        y: 25
                        width: 50
                        height: 30
                        arcWidth: 20
                        arcHeight: 20
                        fill: Color.BLACK
                        stroke: Color.BLACK
                        effect: DropShadow{
                            offsetX: 5
                            offsetY: 5
                            color: Color.BLACK
                        }
                    }
                    Text {
                        font: Font {
                            size: 16
                        }
                        x: 10,
                        y: 40
                        content: "one"
                        fill: Color.WHITE
                    }]
                onMouseClicked: function(e){
                    e.node.scene.lookup("myself").visible = true;
                    e.node.scene.lookup("me").visible = false;
                }
            }
            Group{
                visible: false
                id: "myself"
                content: [
                    Rectangle {
                        cursor: Cursor.HAND
                        x: 65
                        y: 25
                        width: 50
                        height: 30
                        arcWidth: 20
                        arcHeight: 20
                        fill: Color.BLACK
                        stroke: Color.BLACK
                        effect: DropShadow{
                            offsetX: 5
                            offsetY: 5
                            color: Color.BLACK
                        }
                    }
                    Text {
                        font: Font {
                            size: 16
                        }
                        x: 70,
                        y: 40
                        content: "two"
                        fill: Color.WHITE
                    }]
                onMouseClicked: function(e){
                    e.node.scene.lookup("me").visible = true;
                    e.node.scene.lookup("myself").visible = false;
            }
            }
        ]
    }
}

Note que a ideia eh de ter dois grupos, e neste exemplo dentro de cada um um retangulo e um texto, mas qualquer conjunto de Node poderia ser adicionado. veja no link abaixo a aplicação criada funcionando
groupgroup

javafx jogos dos cabecudinhos 2 na tela

March 10th, 2009

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

javafx processo de criação de interface

March 10th, 2009

Uma das coisas mais poderosas no JavaFx na minha opiniao eh a possibilidade concreta de dividir esforços da equipe de desenvolvimento e da equipe de design em paralelo.

o resumo eh o seguinte :
a equipe de programação inicia o processo de desenvolvimento com retangulos, ou desenhos conceituais simples que foram criados em SVG e exportados para o JavaFx, enquanto isto a equipe de design pode criar as ilustrações definitivas e quando estiverem prontas serem encaixadas no projeto, permitindo a programação inclusive manipular items das ilustracoes atraves do ID.

vamos mostrar um exemplo passo a passo

o primeiro passo temos a imagem desenhada no inkscape, que vamos assinalar um ID para uma parte da imagem

object-properties

na tela de propriedades adicionamos o nome do corpo do personagem

object-properties2

note que este nome sera usado respeitando maiusculas e minusculas, permitindo que seja manipulado atraves do codigo Javafx pelo desenvolvedor. Agora o próprio designer para testar seu trabalho e deixar pronto para ser usado pela equipe de programação converte seu arquivo SVG para o formato FXZ do JavaFx, e faz isto abrindo o arquivo com o SVG converter que vem no Production Suite.

 open-with-svg-converter

e executa a conversão do arquivo

convertit

Agora o arquivo jah pode ser usado dentro do NetBeans, que oferece uma opção para realizar o preview do arquivo gerado sem sair da ferramenta, veja na tela abaixo

details-of-the-node

Repare que quando clicamos no elemento do corpo do personagem, podemos ver diversas caracteristicas do mesmo, inclusive o ID e o tipo do objeto que eh um Rectangle

Repare que na classa GameScene são definidos objetos do tipo NodeFromFXZ que eh um wrapper para a carga automática de arquivos do tipo FXZ, facilitando o processo de carga para dentro da aplicação.

E um interessante trecho de código que deve ser destacado, é a parte onde transformamos a cor do corpo do personagem de acordo com o jogador, ou seja o jogador1 fica com azul e o 2 com vermelho, veja neste trecho.

        (player1.lookup("JFX:body") as Rectangle).fill = Color.BLUE;

veja o resultado como ficou !!
corpinhos-coloridos

javafx planejando gravidade …

March 6th, 2009

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 :)

javafx esta na área

December 4th, 2008

Opa o esperado JavaFx, esta na área ! é uma iniciativa da Sun de assumir o poder e necessidade do desenvolvimento de interfaces, uma linguagem de script com fortes influências do Java e Javascript.

veja mais em http://javafx.com/

para aqueles que gostam de ler a API, existe uma bem rica que fornece a base para iniciar a implementacao http://java.sun.com/javafx/1/docs/api/master-index.html

minha bola de cristal ve possibilidades otimas para o javafx !! =)

ant file para alterar a data de todos jsp

October 14th, 2008

Arre que raiva de usar usar arquivo de include no jsp … quando mudo o header o server nao saca que tem que dar reload nos arquivos, dai tem que ficar abrindo e salvando na mao cada um … dureza !! a menos que alguma atividade cerebral se acometa sobre o seu ser e resolva automatizar isto … bem alguma atividade crebral aconteceu e fiz um ant file para isto, compartilho aqui para meus colegas sofredores … =)

<project name=”i need a hug” default=”touch” basedir=”.”>

   <description>Touch all the JSP files</description>

    

  <target name=”touch” >

 <touch verbose=”yes”>

     <fileset dir=”web”>

      <include name=”**/*.jsp”/>

     </fileset>

 </touch>

  </target>

</project>

sioti eh legal

April 27th, 2008

arre !

eu e mais um grupo de loucos esta trabalhando em um projeto de jogo ! imagino que muita gente jah comecou projetos assim, mas espero que possamos nao soh comecar como tambem colocar no ar o projeto !! jah tem umas 3 semanas que comecamos a trabalhar e algumas coisas jah comecaram a criar vida, e jah comecaram a sair do papel !

para ver as novidades do que estamos fazendo visite www.sioti.com em breve a estoria do jogo vai estar lah disponivel bem como outras informacoes legais !

jah temos ateh um cubo andando no cenario !! huahuahuahua que tosqueira puro teste tecnico mesmo, mas se quizer ver esta online … http://www.youtube.com/watch?v=uOrRReoJIKw

e nesta empreitada, meus horarios livres sao para mergulhar no blender, jmonkey engine, pesquisar bichos, plantas, modelos 3d, estorias, roupas, armaduras, coordenar a galera, acordar uns e outros, sorrir junto, chorar junto, caminhar, caminhar, caminhar … vamos caminhando e quem sabe nesta jornada saimos com um jogo interessante para se jogar :)

o mais importante eh fazermos algo que seja divertido de fazer e divertido de jogar !!

e vamos caminhando

working with isometric maps

February 21st, 2008

Ok, I’m working on my own time to create a game, and exploring technical possibilities on this adventure !

In the beginning I was planning to do the map 2D plain, the coordinates 10,10 would be easy to calculate, was just a matter of multiply the x,y by the width and height of the small tile that would be in the screen.

isometric1.png

But nothing is simple ! My daughters are helping me on the discussions of the game, and also helped to create the map, thanks girls you are the best daughters !! The 8 years old one come with the great idea ! Hey dad, why don’t you make the game like the age of empires or warcraft III maps ? a little bit shifted back … Oh well that began all of this :)

Now I have a new map to work with

isometric2.png

And the nice problem of how to convert from a screen coordinate to the map coordinates ? remember that in this case the screen 0,0 is the top left point of the window.

Read more »

game protocols

January 21st, 2008

I’ve been thinking about games protocols… read some stuff about protocol hacking, bots, and many sorts of wierd stuff… But I began to as k myself if the usage of HTTP to send the data would be too slow, cause by using this, we could for example have a backend made in PHP, or Java or wherever language that fits better, and have all the benefits of an mature server solution as Http servers. Things like load balance and security are already tested and solved in the Http world, so why reinvent the wheel by creating custom protocols, and custom server implementations ?

I hope I can do some proof of concept on this, I’m planning to use Pulpcore as UI framework … lets see what happens :)