sexta-feira, 31 de janeiro de 2014

OpenGL

Neste artigo vou apresentar um método simples de como criar aplicações 3D utilizando a linguagem de programação C# através de um controlo que encapsula as funções OpenGL para a plataforma .NET.
O controlo a utilizar responde pelo nome de SharpGL.

A versão atual do controlo inclui modelos de aplicações que podem ser instalados diretamente na versão 2010 do Visual C#, incluindo a versão Express.
Depois de instalado o SharpGL basta escolher o tipo de aplicação pretendida: Windows Forms ou WPF.


A partir daqui podemos gravar o projeto criado e abri-lo na versão 2012 do Visual Studio.

De seguida é possível exportar o projeto a partir do Visual Studio 2012 como um Template para que se possam criar mais projetos sem ser necessário voltar ao Visual C# 2010.


Esta opção abre um Wizard que passo a passo permite gerar o Template na Versão 2012 do Visual Studio.

O modelo agora criado apresenta código que permite gerar uma pirâmide 3D a rodar com cores diferentes entre os vertices.


O controlo gera automaticamente três métodos/funções:

  • openGLControl_OpenGLDraw
  • openGLControl_OpenGLInitialized
  • openGLControl_Resized


A função openGLControl_OpenGLInitialized é chamada uma vez quando o controlo é inicializado em conjunto com a janela da aplicação. Aqui devemos colocar o código que necessita de ser executado uma só vez como por exemplo a definição de valores iniciais de objetos a utilizar no programa.

A função openGLControl_Resized é chamada sempre que o controlo é redimensionado, por força da alteração do tamanho da janela ou da alteração da resolução do ecrã.

Por fim a função openGLControl_OpenGLDraw controla o evento de redesenhar o controlo, portanto a cena tridimensional. Será nesta função que vamos colocar o código que faz aparecer os objetos do nosso programa.

OpenGL

Hoje em dia os programas 3D utilizam um método de desenho baseado em Shaders. Neste artigo vamos abordar o chamado método imediato de desenho 3D, sem shaders, por ser mais simples de implementar.

Para começar vamos definir algumas classes que mais tarde vão facilitar o nosso trabalho, especialmente quando estivermos a conceber uma aplicação já com alguma dimensão.

Classe Ponto - esta classe vai permitir definir um ponto no espaço 3D. Define três floats que representam as coordenadas dos três eixos (X,Y,Z).
Classe Objeto - esta classe representa um objeto 3D, nomeadamente as caraterísticas base do objeto, a origem, a rotação, a cor, a largura (para desenhar em wireframe) e a transparência (alpha).
Classe Triangulo - esta classe, tal como o nome indica, representa um triângulo, derivando a partir da classe objeto só temos de definir os vertices do triangulo (três pontos).

Com estas três classes já podemos criar algumas imagens interessantes.

Desenhar

O processo de desenhar com o OpenGL implica diversas operações matemáticas, as principais implicam passar as coordenadas que definem o objeto para as coordenadas que o colocam numa determinada posição no espaço do mundo 3D. Estas operações são realizadas através de cálculos matriciais. Para que os cálculos realizados para colocar um modelo no espaço não influenciem os restantes o estado deve ser guardado antes de iniciar o processo de desenho do objeto. Para isso deve-se guardar a matriz do espaço 3D antes de desenhar e no final do processo tornar a repor a matriz original. As funçãos PushMatrix e PopMatrix são utilizadas para essas operações, devendo ocorrer entre elas as operações de desenho.

gl.PushMatrix();
//desenhar
gl.PopMatrix();

O objeto gl é uma referência para o controlo colocado no formulário, esta referência deve ser passada para todas as funções de desenho das classes referidas.
Assim a função de desenho em wireframe (esqueleto) do triângulo fica assim:

            //guardar o estado da matriz
            gl.PushMatrix();
            //desenhar
            gl.Translate(origem.getX(), origem.getY(), origem.getZ());
            gl.Rotate(rotacao.getX(), rotacao.getY(), rotacao.getZ());
            gl.Color(cor.getX(), cor.getY(), cor.getZ());
            gl.LineWidth(largura);
            //vertice 1 ao 2
            gl.Begin(OpenGL.GL_LINES);
                gl.Vertex(p1.getX(), p1.getY(), p1.getZ());
                gl.Vertex(p2.getX(), p2.getY(), p2.getZ());
            gl.End();
            //vertice 2 ao 3
            gl.Begin(OpenGL.GL_LINES);
                gl.Vertex(p2.getX(), p2.getY(), p2.getZ());
                gl.Vertex(p3.getX(), p3.getY(), p3.getZ());
            gl.End();
           //vertice 3 ao 1
            gl.Begin(OpenGL.GL_LINES);
                gl.Vertex(p3.getX(), p3.getY(), p3.getZ());
                gl.Vertex(p1.getX(), p1.getY(), p1.getZ());
            gl.End();
            //repor a matriz
            gl.PopMatrix();

Primeiro fazemos uma translação, que na prática significa mover o objeto para a sua origem, depois uma rotação, de seguida definimos a cor de desenho e a largura da linha a desenhar.
A função de desenho utilizada no OpenGL necessita de dois pontos, o inicial e final que no caso do nosso triângulo são os vértices.

Para que o código funcione a classe Ponto deve implementar três funções públicas que devolvem as coordenadas de cada eixo (getX, getY, getZ).

O resultado ainda não é espetacular mas é um bom começo:

No próximo artigo vamos passar para a fase em que o triângulo será desenhado com uma textura, para além de uma função para importar objetos 3D desenhados a partir do Blender.

O projeto pode ser picado aqui.

sábado, 14 de setembro de 2013

Let there be light - vamos fazer uma lanterna

Neste post vamos fazer um pequeno programa que permite utilizar o telefone Android como se de uma lanterna se tratasse.

O projeto é muito simples, vamos inserir um botão na interface para ligar e desligar a luz do flash que vamos utilizar para a iluminação.


Primeiro a interface, o código:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/relativeLayout1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <Button
        android:id="@+id/buttonFlashlight"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:text="Luz" />

</RelativeLayout>

Muito simples, só um botão, optei por inserir o texto diretamente na propriedade do botão uma vez que não vou reutilizar o texto nem pretendo traduzir a interface para outra língua.

Agora as permissões, para podermos ligar e desligar a luz do flash do telefone precisamos de autorização. Para isso adicionamos a seguinte linha ao manifesto da aplicação:

    <uses-permission android:name="android.permission.CAMERA" />

Para além disso devemos indicar que a aplicação requer a camera com a seguinte linha:

 <uses-feature android:name="android.hardware.camera" />

O manifesto completo fica assim:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="edu.pjcferreira.flashlight"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />

    <application
        android:debuggable="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name="edu.pjcferreira.flashlight.FlashLightActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Por fim o código, igualmente simples. Na função onCreate vamos associar um evento click ao botão para ligar e desligar a luz, mas a parte mais difícil não é essa, primeiro temos de verificar se o programa já está em execução e não está a ser retomado, para isso temos uma variável boolean que passa de false para true quando o programa já está em execução.

Caso seja a primeira vez verificamos se temos camera e em caso afirmativo capturamos o dispositivo para o nosso programa.

Dentro da função onClick ligamos e desligamos o flash através da função setFlashMode.

Aqui fica o código completo:

public class FlashLightActivity extends Activity {

//luz ligada
protected boolean isLighOn = false;
//camera
private Camera camera;
//botao da atividade
private Button button;
private boolean repete=false;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if(repete==false){
repete=true;
button = (Button) findViewById(R.id.buttonFlashlight);
 
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
 
Context context = this;
PackageManager pm = context.getPackageManager();
// if device support camera?
if (!pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
Log.e("err", "Dispositivo não tem camera!");
return;
}
camera = Camera.open();
final Parameters p = camera.getParameters();
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if (isLighOn) {
Log.i("info", "luz está desligada!");
p.setFlashMode(Parameters.FLASH_MODE_OFF);
camera.setParameters(p);
camera.stopPreview();
isLighOn = false;
} else {
Log.i("info", "luz está ligada!");
p.setFlashMode(Parameters.FLASH_MODE_TORCH);
camera.setParameters(p);
camera.startPreview();
isLighOn = true;
}
}
});
}
}
@Override
protected void onStop() {
super.onStop();

if (camera != null) {
camera.release();
}
}
}

Não esquecer a função onStop que liberta a camera quando o programa é fechado.

Para evitar problemas quando o telefone muda de posição a interface fica bloqueada em posição vertical.

O projeto pode ser retirado aqui.
A aplicação pronta a usar está aqui.

Espero que tenha gostado se sim passe pela nossa página web e do facebook.

sexta-feira, 10 de maio de 2013

Unity 3D - Jogo em Split Screen

Neste artigo vou criar um pequeno jogo para dois jogadores humanos em ecrã dividido utilizando o Unity 3D.

Para começar vou mostrar o resultado final.


Na parte de cima da imagem anterior temos a composição da cena e na parte de baixo a imagem que os jogadores vão ver quando jogarem.

Primeiro vamos preparar a cena e depois vamos ao código, assim adicione um plano para servir de chão e depois defina uma textura a aplicar.

Altere o tamanho do plano, nomeadamente a largura nos eixos x e z para acomodar os dois jogadores.

Agora que temos o campo de jogo vamos tratar dos jogadores, para isso adicione uma capsule.

Agora vamos posicionar esta capsula no lado esquerdo do ecrã.

De seguida vamos posicionar a camera que temos na cena atrás da capsula, assim:


Continuamos a preparar o jogador do lado esquerdo alterando a sua cor e definindo um ponto de disparo à sua frente, para isso vamos utilizar um ponto vazio.


O próximo passo é muito importante porque vai permitir organizar o nosso trabalho por isso muita atenção.

Primeiro alteramos o nome dos objetos para os podermos identificar mais facilmente, assim, Capsule passa a graficos, GameObject passa ponto_disparo e Main Camera a Camera_esquerda.

De seguida vamos criar um novo ponto vazio e arrastar para dentro desse ponto a capsula e o ponto de disparo. Agora mudamos o nome do novo ponto vazio para jogador. No final temos algo assim:

Agora a camera, vamos às propriedades e alteramos a largura para 0.5, o campo a alterar é o w (width). Assim ficamos com metade do ecrã preenchido com a imagem desta camera a outra metade vai ser preenchida com a outra.

Então para preencher a outra metade duplicamos a camera e alteramos o nome para camera_direita, de seguida arrastamos para a direita e rodamos a camera para mostrar o jogador a partir do outro lado do plano.
Agora basta alterar a posição da imagem para 0.5, a propriedade é X.


Agora já temos duas cameras vamos criar o código para os jogadores.

Crie um javascript com o nome jogador.js

Primeiro as variáveis, como vamos utilizar o mesmo código para os dois jogadores vamos criar variáveis para configurar as teclas que controlam os jogadores a partir do inspector.

public var tecla_esquerda : String = "z";
public var tecla_direita : String = "x";
public var tecla_dispara : String = "c";

As variáveis para associar ao jogador e a velocidade de movimento:
public var jogador : CharacterController;
public var velocidade : float = 0.5;

E algumas variáveis para o modelo da bola que vamos atirar:

public var modelo_bala : GameObject;

O ponto de disparo:
public var ponto_disparo : GameObject;

A força:
public var forca : float=200.0;
public var forcaTotal : float =0;
public var forcaMax : float= 1000;
public var barraForca : Texture;
public var posBarra : int=0;
private var temp : float;
public var boladas : float = 0;
public var posTexto : int=0;

A cor do nosso jogador, que também vamos atribuir à bola:
public var cor : Color = Color.red;

De seguida apresento a função que atualiza a interface, nós vamos mostrar duas informações ao utilizador: a força com que ele vai atirar a bola (esta força é controlada pelo tempo que fica a carregar na tecla de disparo) e quantas vezes já levou com a bola.

function OnGUI(){
    if(forcaTotal<0) temp = forcaTotal * (-1);
    else temp=forcaTotal;
   
    if(temp>0){
        GUI.DrawTexture(Rect(posBarra,10,temp/forcaMax*100,10),barraForca);
    }

    GUI.TextArea(Rect(posTexto,20,30,20),boladas.ToString());
}

 A função mais importante:
function Update () {

    if (Input.GetKey(tecla_esquerda)) jogador.transform.position.z +=(velocidade*Time.deltaTime);
    if (Input.GetKey(tecla_direita)) jogador.transform.position.z -=(velocidade*Time.deltaTime);
    if (Input.GetKey(tecla_dispara)){
        forcaTotal += (forca*Time.deltaTime);
    }
    if(Input.GetKeyUp(tecla_dispara)){
        var bala : GameObject;
        bala=Instantiate(modelo_bala,ponto_disparo.transform.position,this.transform.rotation);
        bala.gameObject.renderer.material.color = cor;
       
        bala.rigidbody.AddForce(Vector3(forcaTotal,0,0));
        forcaTotal=0;
    }
   
}

Nesta função controlamos a posição do jogador bem como a força a atribuir à bola quando a lançamos.

Agora vamos criar uma função que vai ser chamada sempre que a bola acertar no jogador:

function bolada(x : float){

    boladas += x;
   
}

Passamos à bola, para isso adicionamos uma esfera e associamos-lhe um rigidbody.

Agora criamos outro ficheiro javascript com o nome bola.js, neste colocamos o seguinte código:

var tempo : float =4.0;

function Start () {

    Destroy(this.gameObject,tempo);
}

function OnCollisionEnter(col:Collision){
    if(col.gameObject.tag=="Player"){
        col.gameObject.SendMessage("bolada",1.0,SendMessageOptions.DontRequireReceiver);
        Destroy(this.gameObject);
    }
}

A função start é utilizada para controlar o tempo que a bola vai viver, depois temos a função que deteta as colisões e chama a função para contar mais um tiro certeiro.

Agora associamos este código à esfera e criamos um prefab com a esfera, para isso basta arrastar da hierarchy para a pasta project. Depois apagamos da hierarchy a cópia uma vez que vamos criar cópias por código.

Também pode criar um material para definir as propriedades da bola.

Agora duplicamos o jogador e arrastamos para o outro lado do ecrã, isto já com o script jogador.js associado. De seguida configuramos o script através do inspector para podermos definir teclas diferentes para os dois jogadores.

O jogador da direita tem de ser rodado para ficar de frente para o outro jogador, para isso devemos rodar o ponto vazio criado.

Outro ponto importante é o código que deve ser associado ao elemento gráfico do jogador e não ao ponto vazio.

Para terminar de preparar os jogadores devemos definir a tag Player nos dois jogadores.

A velocidade e a força fica ao critério de cada um basta testar e afinar até atingir os valores desejados.

Os meus valores ficaram assim:



Antes de terminar podemos adicionar algumas luzes e definir alguns pormenores visuais como um rasto para as bolas ou sons.

O projeto pode ser retirado aqui.

sexta-feira, 26 de abril de 2013

Tem troco

Para hoje um pequeno programa que dá troco, bem dar não dá mas calcula o troco a dar em função das moedas disponíveis.

Neste projeto vamos utilizar o novo Visual Studio 2012.



Como era de se esperar vamos iniciar um projeto novo:


Agora adicionamos os seguintes elementos:
 - um botão para calcular as moedas a dar de troco
 - um botão para repor o número de moedas iniciais disponíveis
 - uma textbox para introduzir o valor a pagar
 - uma textbox para introduzir o valor entregue
 - umas labels para informar o utilizador do que deve introduzir e outra para mostrar o troco
 - por fim uma grelha para mostrar os valores das moedas e as quantidades disponíveis de cada uma.

A janela principal do programa fica assim:


Agora o código, primeiro o evento load do formulário, neste vamos definir os valores das moedas e as respetivas quantidades

Para guardar estes valores vamos necessitar de uma variável definida ao nível do formulário, logo abaixo da definição da class:

Public Class Form1
    Public moedas(0 To 7, 0 To 2) As Double


Assim no load fica:


        'valor das moedas
        moedas(0, 0) = 0.01
        moedas(1, 0) = 0.02
        moedas(2, 0) = 0.05
        moedas(3, 0) = 0.1
        moedas(4, 0) = 0.2
        moedas(5, 0) = 0.5
        moedas(6, 0) = 1
        moedas(7, 0) = 2
        'número de moedas
        moedas(0, 1) = 5
        moedas(1, 1) = 5
        moedas(2, 1) = 5
        moedas(3, 1) = 5
        moedas(4, 1) = 5
        moedas(5, 1) = 5
        moedas(6, 1) = 5
        moedas(7, 1) = 5
        'moedas dadas como troco
        moedas(0, 2) = 0
        moedas(1, 2) = 0
        moedas(2, 2) = 0
        moedas(3, 2) = 0
        moedas(4, 2) = 0
        moedas(5, 2) = 0
        moedas(6, 2) = 0
        moedas(7, 2) = 0

Como podemos verificar na matriz temos três colunas: a primeira para o valor facial das moedas, a segunda para a quantidade de moedas disponíveis e a terceira para a quantidade de moedas a dar de troco.

Precisamos, ainda, de uma função para atualizar a grelha:

    Sub grelha()
        Dim l, c As Integer

        If Me.DataGridView1.Rows.Count < moedas.Length / 3 Then

            For l = 0 To 7
                Me.DataGridView1.Rows.Add()
                For c = 0 To 2
                    Me.DataGridView1.Rows(l).Cells(c).Value = moedas(l, c)
                Next
            Next
        Else
            For l = 0 To 7
                For c = 0 To 2
                    Me.DataGridView1.Rows(l).Cells(c).Value = moedas(l, c)
                Next
            Next
        End If

    End Sub

Esta função começa por verificar se a grelha está ou não preenchida, se sim atualiza os valores senão adiciona linhas e atualiza os valores.
A função deve ser chamada no evento load, mesmo no final.


O botão para repor é muito simples:

    Sub repor()
        'número de moedas
        moedas(0, 1) = 5
        moedas(1, 1) = 5
        moedas(2, 1) = 5
        moedas(3, 1) = 5
        moedas(4, 1) = 5
        moedas(5, 1) = 5
        moedas(6, 1) = 5
        moedas(7, 1) = 5
        'moedas dadas como troco
        moedas(0, 2) = 0
        moedas(1, 2) = 0
        moedas(2, 2) = 0
        moedas(3, 2) = 0
        moedas(4, 2) = 0
        moedas(5, 2) = 0
        moedas(6, 2) = 0
        moedas(7, 2) = 0

        grelha()

    End Sub

Primeiro altera os valores disponíveis de cada tipo de moeda e por fim limpa os valores referentes às moedas retiradas como troco.

Agora o código do botão calcular:

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Dim v_pagar, v_entregue, v_troco, s_troco, m As Double

        If IsNumeric(TextBox1.Text) = False Then Exit Sub
        If IsNumeric(TextBox2.Text) = False Then Exit Sub

        Double.TryParse(TextBox1.Text, v_pagar)
        Double.TryParse(TextBox2.Text, v_entregue)
        v_troco = v_entregue - v_pagar
        v_troco = Math.Round(v_troco, 2)
        Me.Label3.Text = v_troco

        If Me.Label3.Text = "0" Then Exit Sub

        s_troco = 0
        m = 7
        Do While s_troco < v_troco And m >= 0
            If s_troco + moedas(m, 0) <= v_troco And moedas(m, 1) > 0 Then
                s_troco = s_troco + moedas(m, 0)
                moedas(m, 1) -= 1
                moedas(m, 2) += 1
            Else
                m -= 1
            End If
        Loop
        If s_troco < v_troco Then
            MessageBox.Show("Não existem moedas suficientes para processar o troco!")
        End If
        grelha()

    End Sub
Esta função começa por tentar retirar os valores das textboxes, depois calcula o valor do troco.
De seguida arredonda o troco só para duas casas decimais e se o troco foi diferente de 0 então vamos procurar moedas até atingir o valor do troco.
Para dar o troco começamos pelo fim da matriz à procura das moedas de maior valor até não termos mais moedas ou até satisfazermos o valor do troco.

E pronto, mais um projeto disponível aqui.


quinta-feira, 18 de abril de 2013

Atualizar uma página html com jquery

Neste post vamos implementar uma página web que atualiza o seu conteúdo sem ter de recarregar a página toda.

A estrutura básica da página tem as seguintes pastas:
\ajax - pasta com ficheiro php que pesquisa a base de dados e devolve o valor encontrado
\db - pasta com ficheiro php com instruções para ligação à base dados
\js - pasta com código javascript que utiliza a livraria JQuery para atualizar o ficheiro index.html com os dados devolvidos pelo ficheiro php que pesquisa a base de dados.

O resultado final será:



Se a página fosse construída somente com código html ao clicar no botão "Pesquisar" o browser seria redirecionado para outra página ou para a mesma mas fazendo um reload.

Para implementarmos a página sem reload utilizamos código que vai alterar o DOM da página com os dados recolhidos na base de dados.

Começamos pela página principal, index.html, com o seguinte código:


<!DOCTYPE html>
<html>
<head>
<title>AJAX Database</title>
</head>
<body>
Nome: <input type="text" id="name">
<input type="submit" id="name-submit" value="Pesquisar">
<div id="name-data"></div>
<script src="http://code.jquery.com/jquery-1.8.0.min.js"></script>
<script src="js/global.js"></script>
</body>
</html>


Neste código é importante recordar os nomes do botão (name-submit), o nome do campo de introdução de texto (name) e por fim o nome da div (name-data). Estes nomes são importantes porque vamos ter de nos referir a eles no código javascript.

Antes de continuarmos vamos criar a base de dados MySQL que vai conter o dados a apresentar.

Primeiro criar a base de dados com o seguinte comando:

create database ajaxdb;

Depois criar uma tabela com nome names, assim:

create table names(name_id int,name varchar(50),location varchar(50));

Agora que temos a base de dados podemos continuar.

Olhando para o código html apresentado encontramos uma referencia a um ficheiro global.js que se encontra na pasta js. Este ficheiro vai, utilizando javascript, implementar o método post através do controlo do clique com o rato no botão.

O código javascript tem uma particularidade com a qual estou pouco à vontade que são as funções callback anónimas, desde que comecei a ver código javascript com este tipo de funções fiquei espantado! Como é que alguém consegue perceber aquilo?! Assim vou apresentar duas versões do ficheiro global.js, uma sem funções anónimas muito mais fácil de entender e outra com as funções anónimas.

Ficheiro global.js, versão sem funções anónimas:


$('input#name-submit').on('click',f_click());

function f_click(){
var name = $('input#name').val();

if($.trim(name)!=''){
$.post('ajax/name.php',{name: name},f_recebe(data));
}
}

function f_recebe(data){
$('div#name-data').text(data);
}


A primeira linha associa a função f_click ao evento click do botão, ou seja, quando o utilizador clica no botão é chamada a dita função.

A função f_click começa por recolher o valor do campo de texto e guarda-o na variável name, como pretendemos que o valor esteja preenchido utilizamos a função trim para remover espaços em branco antes de verificar se está em branco.

Se tudo correu bem e existe um valor para pesquisar na base de dados utilizamos a função post para receber valores do servidor chamando uma página, neste caso a página name.php e passando o parâmetro name para a página. Definimos, ainda, uma função callback (f_recebe) para receber o resultado do servidor através do parâmetro data.

Dentro da função f_recebe colocamos o valor de data na div.

Antes de avançarmos para o PHP aqui fica o código da versão com funções callback anónimas:

$('input#name-submit').on('click',function(){
var name = $('input#name').val();

if($.trim(name)!=''){
$.post('ajax/name.php',{name: name},function(data){

$('div#name-data').text(data);
});
}
});



Agora o PHP, a página name.php, tem o seguinte código:

<?php
if(isset($_POST['name'])===true && empty($_POST['name'])===false){
require '../db/connect.php';

$query = mysql_query("
SELECT names.location
FROM names
WHERE names.name='".mysql_real_escape_string(trim($_POST['name']))."'
");
echo (mysql_num_rows($query)!==0) ? mysql_result($query,0,'location') : 'Nome não encontrado';
}
?>


Primeiro verificamos se o parâmetro name está preenchido, em caso afirmativo fazemos o require do ficheiro connect.php (ver código abaixo) e consultamos a base de dados com um select. O resultado da consulta é devolvido com a função echo.

O código do ficheiro connect.php é simples, estabelece a ligação à base de dados:

<?php
mysql_connect('localhost','utilizador','password');
mysql_select_db('ajaxdb');
?>

Assim temos uma página que consulta a base de dados e coloca o resultado dinamicamente na página sem recarregar a página, ao estilo gmail.




Fontes:
http://api.jquery.com/jQuery.post/
http://www.w3schools.com/jquery/jquery_syntax.asp
http://www.youtube.com/watch?v=Yb3c-HljFro

sábado, 13 de abril de 2013

Game of 15

Toda a gente conhece o jogo de puzzle em que existe um espaço livre para mover as peças para os lugares certos. Para quem não conhece pode sempre clicar aqui.

Imagem da wikipedia

Hoje vamos resolver o jogo em C.



Para começar utilizamos uma matriz 4x4 para o jogo.

int jogo[4][4];

Além desta matriz vamos definir outra para armazenar a solução do jogo.

int solucao[4][4];

Antes de mais nada criamos uma função para limpar e preparar a matriz de jogo e a matriz da solução:

//prepara a matriz do jogo
void limpar(void)
{
int l,c,conta=1;

    n_jogadas=0;
    for(l=0;l<4;l++){
        for(c=0;c<4;c++){
            jogo[l][c]=conta;
            solucao[l][c]=conta;
            conta++;
        }
    }
    jogo[3][3]=0;
    solucao[3][3]=0;
}

Também precisamos de uma função para mostrar o estado da matriz do jogo, assim:

//mostra a matriz do jogo
void mostrar(void)
{
int l,c;
    system("cls");
    for(l=0;l<4;l++){
        for(c=0;c<4;c++){
            if(jogo[l][c]>0){
                goto_xy(10+c*3,10+l*2);
                printf("%d",jogo[l][c]);
            }
        }
    }
}

Esta função utiliza a instrução goto_xy que não existe em C mas que está definida num header file que acompanha o código fonte do projeto.

Com as duas matrizes é fácil saber se o jogo foi resolvido, basta comparar as posições de uma matriz com a outra:

//terminou?!
int resolvido(void)
{
int l,c,r=1;
    for(l=0;l<4;l++){
        for(c=0;c<4;c++){
            if(solucao[l][c]!=jogo[l][c]) r=0;
        }
    }
    return r;
}

Como queremos que o computador resolva o jogo vamos utilizar uma tática simples, sempre que fizermos uma jogada guardamos o movimento realizado para mais tarde podermos reverter todos os movimentos até à posição inicial da matriz. Para isso vamos ter um vetor onde guardamos as jogadas e uma variável com o número de jogadas feitas.


int jogadas[100];
int n_jogadas;

Agora as funções que implementam as jogadas:


//move uma peça para a direita
void mover_direita(void)
{
int l,c;
int temp;

    pos_livre(c,l);
    if(coord_validas(c-1,l)==0) return;
    temp=jogo[l][c-1];
    jogo[l][c]=temp;
    jogo[l][c-1]=0;
    //guarda a jogada
    jogadas[n_jogadas]=DIREITA;
    n_jogadas++;
}
//move uma peça para a esquerda
void mover_esquerda(void)
{
int l,c;
int temp;

    pos_livre(c,l);
    if(coord_validas(c+1,l)==0) return;
    temp=jogo[l][c+1];
    jogo[l][c]=temp;
    jogo[l][c+1]=0;
    //guarda a jogada
    jogadas[n_jogadas]=ESQUERDA;
    n_jogadas++;
}
//move uma peça para cima
void mover_baixo(void)
{
int l,c;
int temp;

    pos_livre(c,l);
    if(coord_validas(c,l-1)==0) return;
    temp=jogo[l-1][c];
    jogo[l][c]=temp;
    jogo[l-1][c]=0;
    //guarda a jogada
    jogadas[n_jogadas]=BAIXO;
    n_jogadas++;
}
//move uma peça para baixo
void mover_cima(void)
{
int l,c;
int temp;

    pos_livre(c,l);
    if(coord_validas(c,l+1)==0) return;
    temp=jogo[l+1][c];
    jogo[l][c]=temp;
    jogo[l+1][c]=0;
    //guarda a jogada
    jogadas[n_jogadas]=CIMA;
    n_jogadas++;
}

Cada uma destas funções utiliza o seguinte algoritmo:
1. Descobrir as coordenadas do espaço livre na matriz (função pos_livre, apresentada a seguir)
2. Se as coordenadas do movimento não são válidas (função coord_validas, apresentada a seguir) não joga.
3. Guarda o número da peça a mover e troca com o 0 (zero) do espaço livre.
4. Guarda a jogada feita para mais tarde poder voltar atrás.
5. Adiciona um à variável n_jogadas.


//procura a posicao livre
void pos_livre(int &x,int &y)
{
int l,c;

    for(l=0;l<4;l++){
        for(c=0;c<4;c++){
            if(jogo[l][c]==0){
                x=c;
                y=l;
                return;
            }
        }
    }
}
//devolve 0 se as coordenadas estão fora da matriz
//devolve 1 se as coordenadas são válidas
int coord_validas(int x,int y)
{
    if(x<0 || y<0) return 0;
    if(x>3 || y>3) return 0;
    return 1;
}

Para terminar o programa faltam duas funções, uma para baralhar o puzzle e outra para resolver.
Aqui ficam:

//resolve o jogo
void resolver(void)
{
int n;

    for(n=n_jogadas-1;n>=0;n--){
        if(jogadas[n]==ESQUERDA) mover_direita();
        if(jogadas[n]==DIREITA) mover_esquerda();
        if(jogadas[n]==CIMA) mover_baixo();
        if(jogadas[n]==BAIXO) mover_cima();
        mostrar();
        Sleep(50);
    }
}
//baralha
void baralhar(void)
{
int movimento,temp,sorteia;
    srand(time(NULL));
    for(temp=0;temp<50;temp++){
        mostrar();
        Sleep(50);
        sorteia=rand()%4+1;
        switch(sorteia){
            case ESQUERDA :
                            mover_esquerda();
                            break;
            case DIREITA :
                            mover_direita();
                            break;
            case CIMA :
                            mover_cima();
                            break;
            case BAIXO :
                            mover_baixo();
                            break;
        }
    }
}

Esta versão da função baralhar mostra as jogadas ao mesmo tempo que baralha isso pode ser alterado removendo a linha que chama a função mostrar().

Agora para terminar de verdade aqui fica a função main:

int main(int argc,char *argv[])
{
char op;

    limpar();
    baralhar();
    while(1){
        mostrar();
        printf("\n\n\nOpcao (e,d,c,b,r):");
        scanf("%c",&op);
        if(op=='e') mover_esquerda();
        if(op=='d') mover_direita();
        if(op=='c') mover_cima();
        if(op=='b') mover_baixo();
        if(op=='r') resolver();
        if(resolvido()) break;
    }
    mostrar();
    system("pause");
    return 1;
}

Aqui chegados só falta jogar e quando não conseguir resolver o puzzle basta escolher r.

O código fonte.







sexta-feira, 8 de março de 2013

Arduino & Motor DC

Neste post vou apresentar um pequeno projeto com o Arduino, a ideia é simples, controlar um motor DC.





O projeto vai incluir um potenciómetro para regular a velocidade do motor.

O circuito é o apresentado a seguir, criado com o fritzing.

Como o motor consome mais energia do que o Arduino lhe pode fornecer vamos utilizar uma pilha de 9V só para o motor. O truque está no transistor IRF520 MOSFET que vai controlar a energia que o motor recebe, da pilha de 9V, em função do valor que o Arduino lhe vai enviar.

O transistor tem 3 pernas: a base, o coletor e o emissor. A base está ligada ao pino digital do Arduino, o coletor é ligado ao motor e o emissor é ligado no neutro. O transistor além de funcionar como interruptor, ligado e desligado o motor, vai funcionar como um acelerador pois quanto maior o valor da base maior a corrente que flui entre o emissor e o coletor.

Antes de definir a velocidade do motor o Arduino lê o valor do potenciómetro, ajusta a escala, no potenciómetro vai de 0 a 1023, para um valor entre 0 e 255 e depois envia esse valor para a porta onde a base do transistor está ligada.

A porta do potenciómetro é analógica o que permite ler valores entre 0 e 1023.

Por outro lado a porta do transistor é digital e a variação da velocidade é conseguida através da técnica PWM - Pulse With Modulation.

Por fim temos de ligar o Arduino à terra da pilha de 9V.

O código fica assim:
Primeiro as constantes e as variáveis

const int potPin=0;  //pino onde o potenciometro fica ligado
const int transistorPin=9;  //pino onde fica ligado o transistor
int potValue=0;  //valor lido do potenciometro

Depois a função setup (é executada uma vez quando o programa arranca)
void setup(){
  pinMode(transistorPin,OUTPUT);
  Serial.begin(9600);
}

Por fim o ciclo (Repetido eternamente)
void loop(){
  potValue=analogRead(potPin)/4;
  analogWrite(transistorPin,potValue);
  Serial.println(potValue);
}


Além do código que lê os valores do potenciómetro e escreve para a porta do transistor incluí código para debug, enviando os valores para o computador através do cabo USB.

E a magia acontece...

Mas, sim tem um mas, o motor só pode rodar numa direção.

É um projeto simples mas que pode ser reutilizado para energias maiores, dependendo dos valores que o transistor suportar.

Por segurança incluí um diodo para proteger o Arduino de eventuais descargas que o motor possa gerar quando pára.

Projeto para download.