Archive for the ‘programacao’ Category

jaga e ludum dare 16

December 14th, 2009

bem o fim de semana foi bizzarro cheio novidades e aventuras, a mais legal eh um novo morador da casa esta chegando, o Neskau, um simpatico cachorrinho que vai morar conosco, por enquanto como esta desmamando, vem durante o dia e depois volta na mãe … otimo presente de natal para todos nós.
ld16 new player at home

outro ocorrido foi a participação no ludum dare 16, meio desastrosa porque não entreguei um jogo no fim do prazo, mas muito produtiva porque conclui a migracao inicial do framework que estou fazedo para o desktop. A versão inicial soh rodava no android agora tem a versão desktop também, as duas estão assim como direi em estágio alpha :) mas breve breve terei ao menos uma versão beta com documentação decente, vai esta lah em jaga.athanazio.com

ao menos os desenhos para o jogo ficaram bonitinhos hhhahahhah
ld16 npc list

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();
	}

}

android – mover bolinha

November 21st, 2009

android move ball

Na minha opinão o hello world para desenvolver jogos eh mover um desenho primitivo na tela junto com a informação de FPS (frames por segundo) até porque logo logo perguntamos : tah rodando a quantos FPS ? :) assim sendo já posso dizer que fiz o meu hello world para o android.

Alguns links que ajudaram bastante foram estes :

Uma apresentação da google sobre o desenvolvimento para de jogos para o Android
Writing-Real-Time-Games-for-Android

Os exemplos de cógigo citados na apresentação
C2B 2 GameView

Com certeza este exemplo que escrevi eh extremamente simples, mas exemplifica alguns elementos básicos :

  • main loop
  • chamada de update
  • atualização da area de vizualização
  • input do usuário

O ambiente que tenho eh o Eclipse com o plugin para desenvolvimento do android instalado, para os testes eu prefiro usar o telefone porque o emulador demora muito para inicializar :) e este exemplo tem basicamento 3 classes :

GameActivity – que eh a entrada da aplicação, nela eu solicito o uso fullscreen para o jogo, e determino que a visualização será realizada por uma instancia da classe GameView.

package com.athanazio.android.moveball2;

import android.app.Activity;
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);

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

	protected void onPause() {
		super.onPause();
		view.pause();
	}
}

GameView – nesta classe reside o loop principal do jogo que é iniciado no final do construtor, note que na verdade eh criado um Thread com baixa prioridade, que passará a realizar as atividades de atualização e principalmente executar o método postupdate() notficando a interface que pode ser exibida.

além do loop principal o input direcional é tratado pelo método onKeyDown() e o tocar na tela pelo método onTouchEvent()

package com.athanazio.android.moveball2;

import android.content.Context;
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 = "GAMEVIEW";

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

	private float x = 50;

	private float y = 50;

	private boolean running = true;

	FPSCounter fps;

	public GameView(Context context) {
		super(context);
		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 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");

		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;
		}
		return handled;
	}

	public boolean onTouchEvent(MotionEvent event) {
		x = event.getRawX();
		y = event.getRawY();
		Log.i(TAG, "on touch");

		return super.onTouchEvent(event);
	}

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

		cPaint.setColor(Color.BLUE);
		canvas.drawCircle(x, y, 15, cPaint);

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

	}

	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 pause() {
		running = false;
	}

}

FPSCounter – nesta classe é feita uma contagem de frames que o jogo consegue exibir por segundo, vi algumas implementações interessantes disto, mas acabei fazendo o mais simples e mais econômico, contar frames e ver se jah passou o tempo :) note que algumas variáveis eu criei fora dos métodos para evitar que o Garbage collector tivesse que trabalhar, querendo ou não isto economiza alguns milisegundos :)

package com.athanazio.android.moveball2;

import java.text.DecimalFormat;

import android.os.SystemClock;

public class FPSCounter {

	public static final DecimalFormat format = new DecimalFormat("###0.00");

	private float frames;
	private String fps;
	private long start;
	private long current;

	public FPSCounter() {
		start = SystemClock.uptimeMillis();
		frames = 0;
		fps = "???";
	}

	public void update() {
		frames ++;
		current = SystemClock.uptimeMillis();
		if( current - start > 1000 ){
			fps = format.format(frames);
			frames = 0;
			start = current;
		}
	}

	public String getFPS() {
		return fps;
	}
}

a propósito o fps esta em torno de 90 e poucos, vamos ver o que acontece quando tiver de desenhar uma imagem no fundo e varias outras na tela hehehehe.

android camera binarization

November 16th, 2009

image binarization screenshot

Olas,

Este eh o meu primeiro experimento de aplicação para o android, neste programa capturo a camera e gero uma versão binarizada (preto e branco) da imagem da camera usando o algorimo do otsu de binarização de imagens.

segue o link para o download da aplicação: www.athanazio.com/downloads/android/camera_binarization.apk

segue alguns exemplos do resultado da binarização

image_1257643961757 image_1257643961757_bin

image_1257649452570 image_1257649452570_bin

image_1257649828412 image_1257649828412_bin

image_1257711822305 image_1257711822305_bin

game framework para android

November 13th, 2009

apos uma pequena pesquisa, esbarrei com alguns frameworks para jogos para o android

estou explorando para servir de ideias para o framework de jogos que vou criar para o android !!! se preparem :P

unity3d passo 6 – tudo junto num jogo

September 30th, 2009

drop than all alpha1
Esta eh uma versao mais arrumada destas minhas investigacoes do Unity3D.

Alguns comentarios sobre o codigo abaixo que eh novinho em folha.

static var dead:int = 0;

function Awake () {
	dead = 0;
}

function OnCollisionEnter(collision : Collision) {

	if( collision.collider.name == "bottom" || collision.collider.tag == "enemy"){
		dead = 1;
		var message = GameObject.Find("end of level");
		var message2 = GameObject.Find("end of level2");
		message.guiText.text = "You failed.";
		message2.guiText.text = "Click to restart";
		audio.Play();
	}
}

function Update () {

	if( dead == 1 ){
		if (Input.GetButtonDown("Fire1")) {
			Application.LoadLevel (Application.loadedLevel);
		}
	}

}

Este codigo esta associado ao personagem que esta em movimento, ou seja se o danado colidir com o plano chamado “bottom” que esta abaixo das plataformas, ou com algum dos inimigos a variavel dead eh setada para 1, algumas mensagens sao exibidas e o som correspondente toca.

Quando estiver neste estado de “morto” (dead==1) o update deste mesmo script vai verificar se o click foi pressionado para ai entao recarregar a cena atual, detalhe que a funcao Awake garante que nao reiniciamos a cena com o personagem morto :) porque a variavel eh static e portanto o reload da cena nao apaga seu valor.

usei esta variavel em outros pontos do de outros scripts, como por exemplo para impedir que o tiro fosse disparado ou o personagem movimentado se estivesse no estado de morto, veja como foi usado

var speed:int = 10.0;

function FireRocket () {
	// dont fire if the char is dead
	if (restart_if_char_die.dead == 1) return;
	if( count_enemies.end_level == 1) return;

	var bullet = GameObject.CreatePrimitive(PrimitiveType.Sphere);
	bullet.tag = "bullet";
	bullet.AddComponent(Rigidbody);

	bullet.transform.position = transform.position;
	bullet.transform.rotation= transform.rotation;
	bullet.transform.localScale= transform.localScale;

    bullet.rigidbody.velocity = transform.forward * speed * -1;
	bullet.rigidbody.mass = 5;
	audio.Play();
}

function Update () {
    if (Input.GetButtonDown("Fire1")) {
        FireRocket();
    }
}

bom eh isto ae divirta-se jogando as caixinhas do alto, pena que elas nao gritam :)

unity3d passo 5 – quero te falar …

September 30th, 2009

Alem das coisas em 3D que giram explodem e coisa e tal precisamos de textos 2D pendurados em alguns lugares da tela, para isto adicionamos um GUIText, e o legal do GUIText eh o seu posicionamento na tela, que eh bem simples usando somente as coordenadas X e Y (2D pelamordeDEus) no intervalo de 0 a 1.

canto superior esquerdo : X=0 e Y=1
canto superior direito : X=0.9 e Y=1
canto inferior esquerdo : X=0 e Y=0.1
canto inferior direito : X=0.9 e Y=0.1

bons texto pra vc :)

unity3d passo 4 – quando as coisas se encontram

September 30th, 2009

Nada como controlar colisao para fazer as coisas acontecerem em um jogo, algumas referencias sao base para isto :

ScriptReference/Collision.html
a funcao OnCollisionEnter e os detalhes do objeto de colisao o Collider

para testar quero remover o cubo do jogo se ele colidir com o personagem, considerando que o nome do personagem eh char teriamos algo assim :

function OnCollisionEnter(collision : Collision) {

	if( collision.collider.name == "char" ){
		Destroy( gameObject );
	}
}

E este script deve ser adicionado ao prefab que dara origem a todos os cubos assim nao temos de recriar ou reassociar script a cada um dos elementos da tela.

Contagem de inimigos

Outra funcao importante eh contar itens na tela no caso quero contar quantos inimigos ainda estao na cena, o codigo usa o metodo Find da class GameObject e o metodo de FindGameObjectsWithTag ,

[/code]
function Update () {
var enemies = GameObject.FindGameObjectsWithTag ("enemy");
var counter = GameObject.Find("enemies counter");
counter.guiText.text = "enemies found : " + enemies.length;
}
[/code ]

Note que o "enemies counter" eh um GUIText que esta sendo usado para indicar quantos inimigos estao ativos na cena.

unity3d passo 3 – tiros e mais tiros !

September 30th, 2009

tank drop
jogue a versao atual ! tankdrop-20090929

link que salvou a noite :)
unity3d.com/support/documentation/ScriptReference/index.html

Varias novidades exploradas nesta versao

  • disparo de tiro
  • criacao de cena de menu princial
  • carga de objeto no formato 3ds
  • camera de ladinho
  • Uso de fontes TTF

vamos falar primeiro do disparo do tiro. A ideia inicial era de calcular para que direçao o tanque esta apontando e criar um novo objeto com um rigid body e em alta velocidade na mesma direcao do tanque. Era uma boa intencao mas as contas de determinar para que direcao ficaram um pouco chatinhas, dai tive a ideia de criar um subobjeto do tanque, que eh um quadradinho na posicao onde quero que saia o tiro e adicionei um script a este cubinho, algo assim

var speed = 150.0;

function FireRocket () {
	var bullet = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        bullet.AddComponent(Rigidbody);
	bullet.transform.position = transform.position;
	bullet.transform.rotation= transform.rotation;
	//bullet.transform.localScale= transform.localScale;
    bullet.rigidbody.velocity = transform.forward * speed * -1;
	bullet.rigidbody.mass = 3;
}

function Update () {
    if (Input.GetButtonDown("Fire1")) {
        FireRocket();
    }
}

um detalhe importante que demorei para acertar eh a rotacao do quadradinho de origem do tiro, acabei verificando que rotacionando Y em 270 fica na posicao certa do tiro. e Se for necessario redimensionar o projetil para o tamanho do quadrado por exemplo, basta descomentar o trecho “bullet.transform.localScale= transform.localScale;” que vai reproduzir a mesma escala aplicada ao quadrado para o projetil.

a massa do projetil eh interessante se vc deseja que o tiro vah arrastando coisas com controle fisico pelo caminho, faltou adicionar um som e umas particulas de fumaca na hora do tiro mas jah jah coloco isto :)

A novela do menu principal
para mim o mais dificil foi alinhar a camera com o cubo que resolvi colocar como fundo da tela principal, mas depois me manquei que bastava colocar todo mundo na origem, cubo e camera, e depois ir afastando a camera aos pouquinhos. Nem sei ainda se esta eh a melhor maneira, mas funcionou :)

O efeito de fazer o texto cair, fiz com a criacao de duas caixas, sendo a de cima com rigidbody e suspensa no ar, logo quando inicia a cena a caixa cai, criei um GUI Text como subobjeto da caixa que cai e pronto o texto cai acompanhando a caixa, e para que as caixas em questao nao tivessem nenhum tipo de rederizacao removi o componente Mesh Renderer de cada um.

e para realizar a transicao para a proxima cena, usei o seguinte script que anexei no GuiText “Play”

function Update () {
    if (Input.GetButtonDown("Fire1")) {
		Application.LoadLevel (1);
	}
}

Observe que o numero do level fica determinado na tela de configuracao do build “File / Build Settings”, e lembre-se de nunca ficar mexendo as cenas pelos diretorios :) fiz isto e deu uma baguncada boa nos build settings hehehe.

carga de objeto no formato 3ds
Foi muito sem graça hehehe baixei o arquivo do www.turbosquid.com/ (fica atento que se na hora da busca ordenar pelo menor preco tem varios modelos de graça) descompactei e arrastei sobre o projeto, e arrastei sobre a cena, mudei a escala e pronto todos felizes com o RV2 tank como subobjeto do meu “char”

camera de ladinho
A camera smooth follow nao servia para o que eu queria, o que eu precisava eh uma camera que acompanhasse o tanque mas q quando ele rodasse nao rodasse junto, ou seja uma smotth follow sem rotation :) dei uma canibalizada na smotth follow e sobrou isto aqui

var target : Transform;
var distance = 10.0;
var height = 5.0;

// Place the script in the Camera-Control group in the component menu
@script AddComponentMenu("Camera-Control/Smooth Follow - no rotation")

function LateUpdate () {
	if (!target)	return;

	wantedHeight = target.position.y + height;
	currentHeight = transform.position.y;
	currentHeight = Mathf.Lerp (currentHeight, wantedHeight, Time.deltaTime);

	transform.position = target.position;
	transform.position -= Vector3.forward * distance;

	transform.position.y = currentHeight;
	transform.LookAt (target);
}

O Legal das fontes eh lembrar de criar um objeto de fonte para cada tamanho que sera usado, tirando este detalhe eh bem transparente o uso facim facim, arrasta o arquivo da fonte para o projeto e pimba troca o tamanho e da apply que o unity gera a imagem da fonte no tamanho que eh necessario.

unity3d passo 2

September 25th, 2009

unity screenshot passo 2

Mais coisas interessantes no Unity3D, algumas teclas de atalho interessantes : a sequencia QWER muda a forma de manipulacao dos objetos, e de acordo com a forma que estiver selecionada, quando vc clica no fundo muda a forma como arrastar o mouse sobre a tela vai mudar a sua visualização da scene enquanto estiver trabalhando. isto me deu uma dor de cabeça de primeira heheheh como me achar com os oibjetos 3D :)

outra coisa nova descoberta, como debugar ! basta usar o objeto Debug :) facil facil.

Fiz um script para um elevador, funcionou como esperado veja soh como ficou o codigo :

// smaller value
var start:float;

//greater value
var end:float;
var speed: int = 15;
var direction: int = 1;
var sleep:float = 4000;
var elapsed:float = 0;

function Update () {

	var y = speed * Time.deltaTime * direction;

	// check if the limit is reach and inverse the direction
	if( elapsed <= 0 ){
		if( direction == 1 ){
			if( transform.position.y + y > end ){
				transform.position.y = end;
				elapsed = sleep;
				direction = -1;
			}else {
				transform.Translate(0 , y, 0 );
			}
		} else {
			if( transform.position.y + y < start ){
				transform.position.y = start;
				elapsed = sleep;
				direction = 1;
			}else {
				transform.Translate(0 , y, 0 );
			}
		}
	} else {
		elapsed = elapsed - Time.deltaTime;
	}

	Debug.Log(elapsed);
}

Este codigo eh arrastado sobre um gameObject que no caso eh um plano, e determino o Y inicial do objeto e o Y final, o tempo que o elevador fica parado em sleep, e a velocidade que vai se deslocar. fica assim na interface :
unity script details elevator

Outro aprendizado importante foi como criar materiais, usa Asset / Create / Material e pronto ! dai vc configura os detalhes do material e aplica o material sobre o objeto desejado.

o controle do personagem ainda esta engraçado heheheh tipo quando cai e vira de cabeça para baixo inverte tudo :) ainda estou pensando no que fazer, estou com as seguintes opções em mente :

  • Nao deixar o personagem virar
  • Controlar se ele virou e inverter a transformacao para refletir que esta virado
  • Mudar a forma de controlar para ficar parecido com um carro, usando as setas para controlar o volante, e acelerando com seta para cima

unity3d passo 1

September 22nd, 2009

movebox1
Esta eh a primeira aventura com o Unity3D, graças a um esperto tutorial do Erick consegui dar os primeiros passos no Unity3D !! o resultado pode ser encontrado aqui : move-box1

Quero registrar alguns passos importantes que aprendi :

1. O chao vira chao quando vc chama ele de chao :) hehehehe neste exemplo adicionei um cubo usando a opcao : ‘Game Object / Create Other / Cube’, fiz ele ficar mais larguinho para dar mais estabilidade ao movimento e adicionei o component de corpo rigido atraves de : ‘Component / Physics / Rigid Body’ pronto isto bastaria para todos serem felizes e o cubo nao passar do chao quando dah o play.

2. nao entendi ainda como usar um Shader para cada elemento heheheh quando mudo a cor do plano muda a cor da rampinha que fiz

3. adicionei um codigo javascript e arrastei sobre o cubo, pronto !! o metodo update implementado fica valendo para o objeto, e uma variavel que declarei no codigo : var speed:int ficou on inspector do objeto, simplim simplim

olha o codigo usado para o controle de teclado:

var speed: int;
function Update () {
    var x = Input.GetAxis("Horizontal") * speed * Time.deltaTime;
    var y = 0;
    var z = Input.GetAxis("Vertical") * speed * Time.deltaTime;
    transform.Translate(x , y, z );
}

4. e este links salvaram o dia
documentacao sobre o gameplay
documentacao sobre a fisica
documentacao sobre o input
post sobre movimentacao com teclas

por enquanto eh soh, depois tem mais

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