Month: May 2020

Programação avançada – capitulo 8 – maquina de estados, exemplo3 (revisitado)

Revisitar o exercício acerca do uso de maquina de estados com a implementação de um jogo de 3×3, onde existem dois jogadores.

A máquina de estados:
é um padrão de programação;
serve para abordar problemas mais complexos;
vai ajudar no fluxo na evolução das aplicações (redirecciona para o estado que vai fazer um determinado processamento);
permite identificar os momentos importantes, na evolução da aplicação/jogo;

Definição dos estados:
está relacionada com a interacção do utilizador;
existem transições entre os estados;
as transições de entrada (métodos) e podem/devem ser condicionados pelo estado do jogo;
as transições de saída (métodos) e podem/devem ser condicionados pelo estado do jogo;
existem então acções do utilizador sobre o jogo, e estas acções resultam em métodos, para haver evolução no jogo;
(identificar as etapas do jogo, que vão ser implementadas, para resolver mini problemas, sub dividir para se simplificar o código que é implementado);

Os estados, são assim:
são representados através de classes;
existe uma classe base, da qual os estados vão derivar (polimorfismo), normalmente do IEstado (através do implements);
e devem ser implementados todos os métodos abstractos que estão definidos no IEstado (usando return para o new “estado”) ou então fica nele próprio (return this).

(2)O IEstado, serve então:
é uma interface, dos estados (e não uma classe);
serve para representar/declarar o que existe, acções possíveis e comuns em todos os estados (através de métodos);
esses métodos são do tipo da interface IEstado;
mas atenção que podem existir algumas acções que podem não ser usadas/implementadas em todos os estados (fica o return this, nas bases), mas têm que ser aqui colocadas, construindo implementações default;
assim sendo os IEstado representam as evoluções (transições) do nosso modelo.

(3)O EstadoAdapter, serve então para:
é uma classe intermédia/genérica que vai implementar os comportamentos default, sem qualquer actualização de estado, para evitar a programação destas acções em estados onde não fazem sentido (normalmente ficam no mesmo estado).
só depois e em cada um dos estados é que os vamos implementar, pois só se justifica no contexto desse estado haver uma evolução na maquina de estados, e é em cada um desses estados que fica implementado
esta classe implementa o IEstado (implements)
implementa todos os métodos abstractos / default (return this), isto é, não existe evolução de estado/fica no mesmo estado.
surge aqui também os testes da evolução, assim estes estados vão ter que ter acesso aos dados do jogo (JogoDados), construtor e get e set
esta classe deve ser public abstract, para não ser instanciada,
e o JogoDados fica protected, evitando fazer uso do método getJogo, e pelas derivadas acedo a esta instância

(4)E agora construir os estados, que são classes derivadas e:
são extends EstadoAdapter
por ser protected a base, esta derivada tem que ter o construtor correspondente (super)
implementar os métodos correspondentes às acções que fazem sentido, são as setas de saída;
os outros não fazem sentido num estado, ficam com o default do EstadoAdapter
os métodos implementados em cada um dos estados fazem então um return new estado, ou this se voltar ao mesmo, sendo que é implementada também a lógica de cada um dos métodos

Surge uma classe
surge então o inicio da máquina de estados, representando numa classe que inicia o primeiro estado por onde arranca (new..), e que vai permitir aceder (get) ou alterar o estado (set)
esta classe vai ter que satisfazer as ordens do utilizador, define os métodos que permitem alterar/mudança de estado (métodos de transição)

Na iteração com o utilizador (texto ou gráfica):
recebe a maquina de estados;
obtém permanente o estado em que se encontra a máquina de estados;
faz uso de instanceof dos estados para invocar a interface que deve surgir ao utilizador.

neste exemplo:
(1)o JogoMaqEstados, gestão/ver a evolução/mudança entre os estados (no diagrama ir de um estado para outro), conhece o estado atual, é a classe de interface entre o IU do utilizador e todas as classes internas (quer aquelas que representam os estados, quer os dados, que representam o jogo (tem assim informação sobre o jogo (JogoDados), e o estado em que estamos (IEstado));
o JogoMaqEstados tem ainda a interface para todos os outros estados, onde actualiza a situação do estado;
os estados, recebem a entidade jogo, como referência;
já a grelha, onde estão as peças, o jogador, este tipo de dados ficam em JogoDados;
JogoDados, representa assim o tabuleiro do jogo, onde se fazem todas as verificações;
Jogador, representada cada um dos jogos;
Peca, as peças do tabuleiro de jogo;
IEstado;
EstadoAdapter

(10) A interface (IU) também precisa de ir buscar coisas ao jogo, mas quem trata disso é o JogoMaqEstados

package me_jogopecasr;

import me_jogopecasr.iu.texto.IUtexto;
import me_jogopecasr.logica.JogoMaqEstados;

public class Me_jogoPecasR {

    public static void main(String[] args) {

        IUtexto iuTexto = new IUtexto(new JogoMaqEstados());
        iuTexto.corre();
    }
}
package me_jogopecasr.iu.texto;

import java.util.Scanner;
import me_jogopecasr.logica.JogoMaqEstados;
import me_jogopecasr.logica.estados.AguardaColocacao;
import me_jogopecasr.logica.estados.AguardaDevolucao;
import me_jogopecasr.logica.estados.AguardaInicio;
import me_jogopecasr.logica.estados.IEstado;

public class IUtexto {

    private JogoMaqEstados jogo;
    private boolean sair = false;

    public IUtexto(JogoMaqEstados jogo) {
       this.jogo = jogo;
    }

    void iuAguardaInicio() {

        if ((jogo.getJogador1() != null && jogo.getJogador1().isGanhou())) {
            System.out.println("\n" + jogo.getJogador1() + "\n" + jogo.grelhaToString());
        } else if (jogo.getJogador2() != null && jogo.getJogador2().isGanhou()) {
            System.out.println("\n" + jogo.getJogador2() + "\n" + jogo.grelhaToString());
        }
        System.out.println("\n=== AGUARDA INICIO ===\n"
                + (jogo.getJogador1() != null ? "" + jogo.getJogador1() : "")
                + (jogo.getJogador2() != null ? "" + jogo.getJogador2() : ""));
        while (true) {
            System.out.println("\n0 - Sair\n1 - Define nome de jogador\n2 - Comecar jogo");
            char c = ' ';
            Scanner sc = new Scanner(System.in);
            c = sc.next().charAt(0);
            if ((c == '0')) {
                sair = true;
                return;
            }
            if ((c == '1')) { //1 - Define nome de jogador
                System.out.println("Numero (1 ou 2)  e nome do jogador: ");
                while (!sc.hasNextInt());
                int num = sc.nextInt();
                System.out.println(" numero: " + num);
                String nome = sc.next();
                jogo.defineNomeJogador(num, nome);
                System.out.println(" nome: " + nome);
                return;
            }
            if ((c == '2')) { //2 - Comecar jogo
                System.out.println("Comecar jogo: ");
                jogo.comecarJogo();
                return;
            }
        }
    }

    void iuAguardaColocacao() {
        System.out.println("\n=== AGUARDA COLOCACAO === \n"
                + jogo.getJogador1()
                + jogo.getJogador2()
                + "\nJogador activo: " + jogo.getNomeJogadorActivo()
                + "\n" + jogo.grelhaToString());

        System.out.println("\n1 - Jogar : linha  coluna\n2 - Abandonar");
        char c = ' ';
        Scanner sc = new Scanner(System.in);
        c = sc.next().charAt(0);
        if ((c == '1')) {

            System.out.print(jogo.getNomeJogadorActivo() + ">");

            while (!sc.hasNextInt());
            int linha = sc.nextInt();

            while (!sc.hasNextInt());
            int coluna = sc.nextInt();
            jogo.jogar(jogo.getNumJogadorActivo(), linha, coluna);
        }
        if ((c == '2')) {
            jogo.abandonar(jogo.getNumJogadorActivo());
            return;
        }
   
    }

    void iuAguardaDevolucao() {
        System.out.println("\n=== AGUARDA DEVOLUCAO === \n"
                + jogo.getJogador1()
                + jogo.getJogador2()
                + "\nJogador activo: " + jogo.getNomeJogadorActivo()
                + "\n" + jogo.grelhaToString());

//        System.out.println("\nDevolver : linha  coluna\nAbandonar: -1");
         System.out.println("\n1 - Devolver : linha  coluna\n2 - Abandonar");
        char c = ' ';
        Scanner sc = new Scanner(System.in);
        c = sc.next().charAt(0);
        if ((c == '1')) {
        System.out.print(jogo.getNomeJogadorActivo() + ">");
        while (!sc.hasNextInt());
        int linha = sc.nextInt();
 
        while (!sc.hasNextInt());
        int coluna = sc.nextInt();
        jogo.devolver(jogo.getNumJogadorActivo(), linha, coluna);
        }
        if ((c == '2')) {
            jogo.abandonar(jogo.getNumJogadorActivo());
            return;
        }
   
    }

    public void corre() {

        while (!sair) {
            IEstado estado = jogo.getEstado();
            if (estado instanceof AguardaInicio) {
                iuAguardaInicio();
            } else if (estado instanceof AguardaColocacao) {
                iuAguardaColocacao();
            } else if (estado instanceof AguardaDevolucao) {
                iuAguardaDevolucao();
            }
        }

    }
}
package me_jogopecasr.logica;

public interface Constantes {
    int DIM = 3;
}
package me_jogopecasr.logica;

import java.util.ArrayList;
import java.util.List;


public class Jogador implements Constantes {

    private JogoDados jogo;
    private String nome;
    private List<Peca> mao = new ArrayList<Peca>();
    private boolean ganhou;

    public Jogador(String nome, JogoDados j) {
        this.nome = nome;
        this.jogo = j;
        ganhou = false;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getNome() {
        return nome;
    }

    public boolean isGanhou() {
        return ganhou;
    }

    public void setGanhou(boolean ganhou) {
        this.ganhou = ganhou;
    }

    public void recebePecas() {
        mao.clear();
        for (int i = 0; i < DIM; i++) {
            mao.add(new Peca(this));
        }
        ganhou = false;
    }
     public void recebePeca(Peca peca) {
            mao.add(peca);   
    }

    public boolean temPecas() {
        return mao.size() > 0;
    }

    public boolean jogar(int linha, int coluna) {
        if (mao.size() == 0) {
            return false;
        }
        Peca peca = mao.get(0);
        if (jogo.setPeca(peca, linha, coluna)) {
            // jogou
            mao.remove(0);
            if (jogo.ganhou(this)) {
                ganhou = true;
            }
            return true;
        }
        return false;
    }

    @Override
    public String toString() {
        return "Jogador " + nome + " mao=" + mao + (ganhou ? " == GANHOU ==" : "") + "\n";
    }

    public int getNumPecas() {
        return mao.size();
    }
}
package me_jogopecasr.logica;

import java.util.ArrayList;
import java.util.List;

public class JogoDados implements Constantes{
 
    private List<Jogador> jogadores = new ArrayList<Jogador>();

    private int numJogActivo;
    private Peca[][] grelha;
    

    public JogoDados() {
        
        jogadores.add(new Jogador("A", this));
        jogadores.add(new Jogador("B", this));
        grelha = new Peca[DIM][DIM];
    }

    public Jogador getJogadorActivo() {
        return jogadores.get(numJogActivo - 1);
    }
    public String getNomeJogadorActivo() {
        return jogadores.get(numJogActivo - 1).getNome();
    }

    public Jogador getJogadorNaoActivo() {
        if (numJogActivo == 1) {
            return jogadores.get(1);
        } else if (numJogActivo == 2) {
            return jogadores.get(0);
        }
        return null;
    }

    public int getNumJogadorActivo() {
        return numJogActivo;
    }

    public int getNumJogadorNaoActivo() {
        return (numJogActivo == 1? 1: 2);
    }

    public Jogador getJogador1() {
        return jogadores.get(0);
    }

    public Jogador getJogador2() {
        return jogadores.get(1);
    }

    


    public Peca getPeca(int linha, int coluna) {
        if (linha < 0 || linha >= DIM || coluna < 0 || coluna >= DIM) {
            return null;
        }
        if (grelha == null) {
            return null;
        }
        return grelha[linha][coluna];
    }

    public boolean setPeca(Peca peca, int linha, int coluna) {
        if (linha < 0 || linha >= DIM || coluna < 0 || coluna >= DIM) {
            return false;
        }
        if (grelha[linha][coluna] != null) {
            return false;
        }
        grelha[linha][coluna] = peca;
        return true;
    }

    public boolean retiraPeca(int linha, int coluna) {
        if (linha < 0 || linha >= DIM || coluna < 0 || coluna >= DIM) {
            return false;
        }
        if (grelha[linha][coluna] == null) {
            return false;
        }
        grelha[linha][coluna] = null;
        return true;
    }

    public void jogaOutro() {
        numJogActivo = numJogActivo == 1 ? 2 : 1;
    }

  
    public boolean inicializa() {

        grelha = new Peca[DIM][DIM];
        jogadores.get(0).recebePecas();
        jogadores.get(1).recebePecas();

        numJogActivo = 1;

        return true;
    }

    public boolean setNomeJogador(int num, String nome) {
        try{
            jogadores.get(num-1).setNome(nome);
            return true;
        }catch(IndexOutOfBoundsException e){
            return false;
        }
    }

    private boolean isEmDiagonalPrincipal(Jogador jogador) {
        for (int i = 0; i < DIM; i++) {
            if (grelha[i][i] == null || grelha[i][i].getJogador() != jogador) {
                return false;
            }
        }
        return true;
    }

    private boolean isEmDiagonalSecundaria(Jogador jogador) {
        for (int i = 0; i < DIM; i++) {
            if (grelha[i][DIM - 1 - i] == null || grelha[i][DIM - 1 - i].getJogador() != jogador) {
                return false;
            }
        }
        return true;
    }

    private boolean isEmDiagonal(Jogador jogador) {
        return isEmDiagonalPrincipal(jogador) || isEmDiagonalSecundaria(jogador);
    }

    private boolean isEmHorizontal(Jogador jogador, int linha) {
        for (Peca peca : grelha[linha]) {
            if (peca == null || peca.getJogador() != jogador) {
                return false;
            }
        }
        return true;
    }

    private boolean isEmVertical(Jogador jogador, int coluna) {
        for (int i = 0; i < grelha[coluna].length; i++) {
            Peca peca = grelha[i][coluna];
            if (peca == null || peca.getJogador() != jogador) {
                return false;
            }
        }
        return true;
    }

    private boolean isEmHorizontal(Jogador jogador) {
        for (int i = 0; i < DIM; i++) {
            if (isEmHorizontal(jogador, i)) {
                return true;
            }
        }
        return false;
    }

    private boolean isEmVertical(Jogador jogador) {
        for (int i = 0; i < DIM; i++) {
            if (isEmVertical(jogador, i)) {
                return true;
            }
        }
        return false;
    }

    public boolean ganhou(Jogador jogador) {

        return isEmHorizontal(jogador) || isEmDiagonal(jogador) || isEmVertical(jogador);
    }

      public boolean jogar(int numeroJogador, int linha, int coluna) {
        if (linha < 0 || linha >= DIM || coluna < 0 || coluna >= DIM) {
            return false;
        }
        if(numJogActivo != numeroJogador){
            return false;
        }
      
        Jogador j = getJogadorActivo();
        
        
        if(!j.jogar(linha, coluna)){
            return false;
        }
        return true;
    }
    
      public boolean devolver(int numeroJogador, int linha, int coluna) {
        if (linha < 0 || linha >= DIM || coluna < 0 || coluna >= DIM) {
            return false;
        }
        
        if(numJogActivo != numeroJogador){
            return false;
        }
       Peca peca = getPeca(linha, coluna);
        Jogador j = getJogadorActivo();
         if (peca == null || peca.getJogador() != j) {
            return false;
        }
        
        if(!retiraPeca(linha, coluna)){
            return false;
        }
        j.recebePeca(peca);
        return true;
    }
    
    public String grelhaToString() {
        String s = "";
        for (int i = 0; i < DIM; i++) {
            for (int j = 0; j < DIM; j++) {
                String casa;
                if (grelha[i][j] != null) {
                    casa = "" + grelha[i][j].getJogador().getNome().charAt(0);
                } else {
                    casa = " ";
                }
                s += "|\t" + casa + "\t";
            }
            s += "|\n";
        }
        return s;
    }

   
    public boolean acabou() {
        return ganhou(jogadores.get(0)) || ganhou(jogadores.get(1));

    }
    
}

package me_jogopecasr.logica;

import me_jogopecasr.logica.estados.AguardaInicio;
import me_jogopecasr.logica.estados.IEstado;

public class JogoMaqEstados {
    JogoDados jogo;
    IEstado estado;

    public JogoMaqEstados() {
        //1)
        this.jogo = new JogoDados();
        //7
        this.estado = new AguardaInicio(jogo);
    }

    public JogoDados getJogo() {
        return jogo;
    }

    public void setJogo(JogoDados jogo) {
        this.jogo = jogo;
    }

    public IEstado getEstado() {
        return estado;
    }

    public void setEstado(IEstado estado) {
        this.estado = estado;
    }

    //8 redirecionar, agulhar, as acções para os estados, o interface para todas as outras classes
    public void defineNomeJogador(int numeroJogador, String nome) {
        //8.1 a evolução do estado, retorna o estado seguinte
        estado = estado.defineNomeJogador(numeroJogador, nome); //ou usar o setEstado
    }

    public void comecarJogo() { //no infitivo
        estado = estado.comecaJogo();
    }

    public void jogar(int numeroJogador, int linha, int coluna) {
        estado = estado.joga(numeroJogador, linha, coluna);
    }

    public void devolver(int numeroJogador, int linha, int coluna) {
        estado = estado.devolve(numeroJogador, linha, coluna);
    }

    public void abandonar(int numeroJogador) {
        estado = estado.abandona(numeroJogador);
    }

    //9 redirencuionar para o modelo de dados
    public Jogador getJogador1() {
        return jogo.getJogador1();
    }

    public Jogador getJogador2() {
        return jogo.getJogador2();
    }

    //11 redirencuionar para o modelo de dados
    public String getNomeJogadorActivo() {
        return jogo.getNomeJogadorActivo();
    }

    public String grelhaToString() {
        return jogo.grelhaToString();
    }

    public int getNumJogadorActivo() {
        return jogo.getNumJogadorActivo();
    }

}

package me_jogopecasr.logica;

public class Peca {
    private Jogador jogador;

    public Peca(Jogador jogador) {
        this.jogador = jogador;
    }

    public Jogador getJogador() {
        return jogador;
    }

    public String toString(){
        return "" + jogador.getNome().charAt(0);
    }
}

package me_jogopecasr.logica.estados;

import me_jogopecasr.logica.JogoDados;
//5
public class AguardaColocacao extends EstadoAdapter{
    //6.2.3 ver se ele não colocou no mesmo local
    int l, c; 
    
    //5.1
    public AguardaColocacao(JogoDados jogo) {
        super(jogo);
        //6.2.5
        l = c-1;
    }
    //6.2.4
        public AguardaColocacao(JogoDados jogo, int l, int c) {
        super(jogo);
        this.l = l;
        this.c = c;
    }

    //5.2
    @Override
    public IEstado abandona(int numeroJogador) {
        //poderia ver qual é o jogador e atribuir a vitória ao outro
        return new AguardaInicio(jogo);
    }
    
    //5.3
    @Override
    public IEstado joga(int numeroJogador, int linha, int coluna) {
         //6.2.6, testar se é a mesma jogada
         if(linha == l && coluna == c){
             return this;
         }
        
        
        //5.3.1, vamos realizar o jogar
        if(!jogo.jogar(numeroJogador, linha, coluna)){
            return this;
        }
        
        //5.3.2, ver se ele ganhou
        if(jogo.getJogadorActivo().isGanhou()){
            return new AguardaInicio(jogo);
        }
        //5.3.3, mudar de jogador
        jogo.jogaOutro();
        
        //5.3.4, ver se tem peças 
         if(jogo.getJogadorActivo().isGanhou()){
            return new AguardaColocacao(jogo); //ou return this, fica no mesmo estado, e com l e c a -1
        }
         
         
         //5.3.5, 
         return new AguardaDevolucao(jogo);
    }
    
    
    
}


package me_jogopecasr.logica.estados;

import me_jogopecasr.logica.JogoDados;

//6
public class AguardaDevolucao extends EstadoAdapter {

    public AguardaDevolucao(JogoDados jogo) {
        super(jogo);
    }

    //6.1
    @Override
    public IEstado abandona(int numeroJogador) {
        return new AguardaInicio(jogo);
    }
    
    //6.2
    @Override
    public IEstado devolve(int numeroJogador, int linha, int coluna) {
        //6.2.1 adcionar a devolção
        if(jogo.devolver(numeroJogador, linha, coluna)){
            //o devolver já verifica
            return new AguardaColocacao(jogo, linha, coluna);  //6.2.7
        }
        //6.2.2 fica no mesmo estado
        return this;
    }
    
    
}

package me_jogopecasr.logica.estados;

import me_jogopecasr.logica.JogoDados;

public class AguardaInicio extends EstadoAdapter{
    //4) por ser protected a base, esta derivada tem que ter um construtor correspondente
    public AguardaInicio(JogoDados jogo) {
        super(jogo);
    }
    
    //4.2) implementar os métodos correspondentes às acções que fazem sentido, são as setas de saída

    @Override
    public IEstado defineNomeJogador(int numeroJogador, String nome) {
        //4.4
        jogo.setNomeJogador(numeroJogador, nome);
        //4.3
        return this;
    }

    @Override
    public IEstado comecaJogo() {
        //4.4 testes para começar um jogo
        if(jogo.getJogador1()== null || jogo.getJogador2() ==null){
        //fico no mesmo estado
        return this;
        }
        
        //12
        jogo.inicializa();
        return new AguardaColocacao(jogo);
    }
    
    
}

package me_jogopecasr.logica.estados;

    //3) existem acções que não fazem sent
import me_jogopecasr.logica.JogoDados;

public abstract class EstadoAdapter implements IEstado{
    //3.2) acesso aos jogos de dados
    //3.3) protected, evitando fazer uso do método getJogo, e pelas derivadas acedo a esta instancia
    protected JogoDados jogo;

    public EstadoAdapter(JogoDados jogo) {
        this.jogo = jogo;
    }

    public JogoDados getJogo() {
        return jogo;
    }

    public void setJogo(JogoDados jogo) {
        this.jogo = jogo;
    }
    
    
    //3.1)
    @Override
    public IEstado defineNomeJogador(int numeroJogador, String nome) {
        return this;
    }

    @Override
    public IEstado comecaJogo() {
        return this;
    }

    @Override
    public IEstado joga(int numeroJogador, int linha, int coluna) {
        return this;
    }

    @Override
    public IEstado devolve(int numeroJogador, int linha, int coluna) {
        return this;
    }

    @Override
    public IEstado abandona(int numeroJogador) {
        return this;
    }
    
}

package me_jogopecasr.logica.estados;

//2) definir todos os estados
public interface IEstado {
    IEstado defineNomeJogador(int numeroJogador, String nome);
    IEstado comecaJogo();
    IEstado joga(int numeroJogador, int linha, int coluna);
    IEstado devolve(int numeroJogador, int linha, int coluna);
    IEstado abandona(int numeroJogador);
}
Tags : , , ,

Humble RPG game development assets bundle: 2d art, music and sound effects (uma campanha)

Um conjunto de objetos para ajudar no desenvolvimento de videojogos do género RPG, da lista consta:
2D Characters Male
2D Hand Painted Mine Tileset
2D Hand Painted Snowland Tileset
58 Fantasy RPG Items
Souls RPG Graphics – Town Tileset
Souls RPG Graphics Tiles – Grasslands
Ancient Game SFX Pack
Clean City Game Assets
Cute RPG UI Kit
Dark RPG Chiptune Soundtrack Bundle
Dialogue Boxes
Dwarves vs Elves RPG Sprites
Elemental Magic Sound Effects Vol 1
Elemental Magic Sound Effects Vol 2
Fantasy Character Bundle
Fantasy RPG Items Vol 2
Farm & Fort Tileset & Icons
Forest Isometric Block Tileset
Frozen Village Isometric Block Tileset
Hand Painted Extra Objects Tileset
Human Fantasy Animated Pack
Interface SFX
Inventory Sounds Pack
Japanese Bar Interior Assets
Japanese City Game Assets
JRPG Character Pack
JRPG Music Pack
Lighthearted RPG Location Soundtrack Bundle
Lighthearted RPG Soundtrack Bundle
Medieval RPG UI Kit
MMORPG UI Kit
Monster Creature Animated Pack
Monster Creature Super Mix
Osaka City Game Assets
Pixel Art Beach Tile Set
Pixel Art Forest Road
Pixel Art Medieval Fantasy Characters
Pixel Art Medieval Interiors
Pixel Art Medieval UI Pack
Pixel Art Old Castle
Pixel Art Town
RPG Inventory – Fantasy Battles Axes
RPG Inventory – Fantasy Bows
RPG Inventory – Fantasy Daggers
RPG Inventory – Fantasy Potions
RPG Inventory – Fantasy Spears
RPG Inventory – Fantasy Swords
RPG Music Pack – Complete Collection
Side View Animated RPG Battlers
Souls RPG Graphics – Desert Tileset
Soul’s RPG Graphics – Sprites
Spells & Ability Icons
Survival Icons
Tyler Warren RPG Battlers Pixel Style
Warrior Adventure Game Characters

+infos(campanha): LINK

Tags : , , , , , ,

Humble Learning game coding and development bundle (uma campanha)

Está a decorrer uma campanha com referências a cursos para aprender a programar jogos e a desenvolver. Da campanha surge a lista de:
Applied Computer Vision with Unity and Azure
Battle Royale – Multiplayer Projects
Build a Micro-Strategy Game
Build an RPG Adventure in Phaser
C++ Programming for Beginners
Create a 2D RPG with Godot
Create Your First 3D Game with Unity
Develop a Puzzle Platformer Game
EasyAR and Marker-Based Apps for Beginners
Godot Game Development for Beginners
Humanoid Animation Tools for Beginners
Intro to Game Development with Unity
Intro to Multiplayer Game Development
Learn C++ by Making a Text-Based RPG
Player Authentication with Azure PlayFab
Python Programming by Making a Game
Real-time Strategy Project – Unit Movement
RPG – Multiplayer Projects
RPG Development with Phaser
The Complete Blender Course
The Complete Procedural Terrain Generation Course
Tile-Based Math Game Project
Turn-Based Game – Multiplayer Projects
Unity 2D Projects – Super Plumbers
Unity Cinemachine for Films and Games

+infos(a campanha): LINK

ps_ eu até achei interessante esta campanha por causa de alguns dos cursos que ele tem, contudo uma análise com mais critério apercebi-me que afinal estes cursos são cursos que fazem parte de um pack mais completo da malta da zenva.com nomeadamente do percurso Strategy Game Development Academy e que prefazem um total de 12 cursos online

Tags : , , , , ,

Oferta de trabalho

professores-adjuntos:
Instituição: Instituto Politécnico de Leiria – Escola Superior de Tecnologia e Gestão
Áreas: Jogos Digitais – Design Sonoro – LINK
Áreas: Jogos Digitais – Arte 2D – LINK
Áreas: Jogos Digitais – Ambientes Virtuais 3D – LINK

Tags :

Livros a ler/comprar.. prendas?

Eurogames: The Design, Culture and Play of Modern European Board Games, 2012, de Stewart Woods
+infos(na loja): LINK

It’s All a Game: The History of Board Games from Monopoly to Settlers of Catan, 2017,de Tristan Donovan
+infos(na loja): LINK

Game Design Workshop: A Playcentric Approach to Creating Innovative Games, Fourth Edition 4th Edition, 2018, de Tracy Fullerton
+infos(na loja): LINK

Rules of Play – Game Design Fundamentals, 2003, de K Salen
+infos(na loja): LINK

Tags : , ,

JavaFX, exercício 2

package javafx03;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx03.iu.gui.PaneOrganizer;

public class Javafx03 extends Application {

    public static void main(String[] args) {
        //redirecionar a execução para o método launch
        launch(args);
    }

    @Override
    public void init() throws Exception {
        //inicar qualquer coisa antes do start
        System.out.println("init");
        super.init();
    }

    //méotod obrigatório abstract do Application
    @Override
    public void start(Stage stage) throws Exception {
        System.out.println("start");
        //no palco vão ocorrer cenas
        PaneOrganizer po = new PaneOrganizer();
        Scene cena = new Scene(po, 600, 400);
        stage.setScene(cena);
        stage.setTitle("programação avançada!");
        stage.setMinWidth(300);
        stage.setMinHeight(200);
        stage.show();
    }

    @Override
    public void stop() throws Exception {
        System.out.println("stop");
        super.stop();
    }

}
package javafx03.iu.gui;

import javafx.event.EventHandler;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;

import javafx.scene.shape.Ellipse;
import javafx03.logica.Figura;

//pane, usa o espaço todo disponivel
public class PaneOrganizer extends Pane {

    //criar a figura
    Figura figura;
    Ellipse elipse;

    public PaneOrganizer() {
        this.figura = new Figura();
        figura.setPrimeiroPonto(0, 0);
        figura.setSegundoPonto(100, 50);
        figura.setRGB(0, 255, 0);

        criarLayout();
        registaListeners();
        atualizaFigura();
    }

    private void criarLayout() {
        //criar uma nova elipse
        /*
        elipse.setCenterX(200);
        elipse.setCenterY(100);
        elipse.setFill(Color.GREEN);
        elipse.setRadiusX(200); 
        elipse.setRadiusY(100);
         */
        //adicionar a elipse ao pane
        elipse = new Ellipse();
        this.getChildren().add(elipse);
    }

    private void registaListeners() {
        //podia ser feito numa classe à parte
        this.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent t) {
                figura.setPrimeiroPonto((int) t.getX(), (int) t.getY());
                figura.setSegundoPonto((int) t.getX(), (int) t.getY());
                figura.setRGB((int) (Math.random() * 256), (int) (Math.random() * 256), (int) (Math.random() * 256));
                atualizaFigura();
            }
        });
        //com lambda
        this.setOnMouseDragged((t) -> {
            figura.setSegundoPonto((int) t.getX(), (int) t.getY());
            atualizaFigura();
        });

//        this.setOnMouseReleased((t) -> {
//            figura.setSegundoPonto((int) t.getX(), (int) t.getY());
//            atualizaFigura();
//        });

    }

    private void atualizaFigura() {
        elipse.setFill(Color.rgb(figura.getR(), figura.getG(), figura.getB()));
        elipse.setCenterX((figura.getXi() + figura.getXf()) / 2);
        elipse.setCenterY((figura.getYi() + figura.getYf()) / 2);
        elipse.setRadiusX(figura.getAltura() / 2);
        elipse.setRadiusY(figura.getLargura() / 2);
    }
}
package javafx03.logica;

public class Figura {

    int xi, xf;
    int yi, yf;
    int r, g, b;

    public Figura() {

    }

    public int getXi() {
        return xi;
    }

    public int getXf() {
        return xf;
    }

    public int getYi() {
        return yi;
    }

    public int getYf() {
        return yf;
    }

    public int getR() {
        return r;
    }

    public int getG() {
        return g;
    }

    public int getB() {
        return b;
    }

    public void setRGB(int r, int g, int b) {
        this.r = r;
        this.g = g;
        this.b = b;
    }

    public void setPrimeiroPonto(int x, int y) {
        this.xi = x;
        this.yi = y;
    }

    public void setSegundoPonto(int x, int y) {
        this.xf = x;
        this.yf = y;
    }

    public int getLargura() {
        return Math.abs(xf - xi);
    }

    public int getAltura() {
        return Math.abs(xf - xi);
    }
}
Tags : ,

JavaFX, exercício 1

Uso de:

Com:

package javafx02;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx02.PaneOrganizer.PaneOrganizer;

public class JavaFx02 extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void init() throws Exception {
        super.init();
        System.out.println("onInit");
    }

    @Override
    public void start(Stage stage) throws Exception {
        System.out.println("onStart");
        PaneOrganizer brd = new PaneOrganizer();
         Scene scene = new Scene(brd, 600, 400);
        stage.setScene(scene);
        stage.setTitle("Programação avançada");
        stage.show();
    }

    @Override
    public void stop() throws Exception {
        super.stop();
        System.out.println("onStop");
    }
}
package javafx02.PaneOrganizer;

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;

public class PaneOrganizer extends BorderPane {

    Button btnVerde, btnAzul;
    Label lblVerde, lblAzul;
    int numerVerde, numeroAzul;

    public PaneOrganizer() {
        createPane();
        //registerListener1();
        //registerListener2();
        //registerListener3();
        //registerListener4();
        registerListener5();
        numerVerde=0;
        numeroAzul=0;
    }

    void createPane() {
        btnVerde = new Button("Green");
        btnVerde.setTextFill(Color.GREEN);
        btnAzul = new Button("Blue");
        btnAzul.setTextFill(Color.BLUE);
        //numeros dinamicos
        lblVerde = new Label("#Verde: 0");
        lblAzul = new Label("#Azul: 0");

        HBox hbox = new HBox();
        hbox.getChildren().addAll(btnVerde, btnAzul);
        hbox.setSpacing(25);
        hbox.setPadding(new Insets(10));
        hbox.setAlignment(Pos.CENTER);
        this.setTop(hbox);
        
        //numeros dinamicos
         HBox hboxlbl = new HBox();
        hboxlbl.getChildren().addAll(lblVerde, lblAzul);
        hboxlbl.setSpacing(25);
        hboxlbl.setPadding(new Insets(10));
        hboxlbl.setAlignment(Pos.CENTER);
        hboxlbl.setBackground(new Background(new BackgroundFill(Color.rgb(255, 255, 255), CornerRadii.EMPTY, Insets.EMPTY)));
        this.setBottom(hboxlbl);

        /*
        //outras coisas!
        Label l1 = new Label("Texto 1");
        l1.setFont(Font.font("Times New Roman", FontWeight.BOLD, FontPosture.ITALIC, 24));
        l1.setTextFill(Color.rgb(0, 255, 0));
        l1.setBackground(new Background(new BackgroundFill(Color.YELLOW, CornerRadii.EMPTY, Insets.EMPTY)));
        l1.setPadding(new Insets(10, 20, 30, 40));
        //brd.setTop(l1);

        Label l2 = new Label("Texto 2");
        l2.setTextFill(Color.rgb(0, 123, 123));

        HBox hbox = new HBox();
        hbox.getChildren().addAll(l1, l2);
        hbox.setStyle("-fx-background-color: #00ffff;"); //outra forma, css
        hbox.setPadding(new Insets(10));
        hbox.setAlignment(Pos.CENTER);
        hbox.setSpacing(25);
        this.setTop(hbox);

        //brd.setBottom(l2);
        BorderPane.setAlignment(l2, Pos.CENTER);
         */
    }

    //1ºalternativa, usando uma inner class
    void registerListener1() {
        btnVerde.setOnAction(new ProgBotaoVerde1()); //o que vai ser executado, um objecto do tipo!
        btnAzul.setOnAction(new ProgBotaoAzul1()); //o que vai ser executado, um objecto do tipo!
    }

    class ProgBotaoVerde1 implements EventHandler<ActionEvent> {

        @Override
        public void handle(ActionEvent t) {
            //quando o botão for clicado
            System.out.println("Oi botão verde - inner class");
            //aceder ao objecto de fora ou então criar uma varivel ou via construtor
            PaneOrganizer.this.setBackground(new Background(new BackgroundFill(Color.rgb(0, 255, 0), CornerRadii.EMPTY, Insets.EMPTY)));
        }

    }

    class ProgBotaoAzul1 implements EventHandler<ActionEvent> {

        @Override
        public void handle(ActionEvent t) {
            //quando o botão for clicado
            System.out.println("Oi botão azul - inner class");
            //aceder ao objecto de fora ou então criar uma varivel ou via construtor
            PaneOrganizer.this.setBackground(new Background(new BackgroundFill(Color.rgb(0, 0, 255), CornerRadii.EMPTY, Insets.EMPTY)));
        }
    }

    //2ºalternativa, usando uma classe inline
    void registerListener2() {
        btnVerde.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent t) {
                System.out.println("Oi botão azul - inline");
                PaneOrganizer.this.setBackground(new Background(new BackgroundFill(Color.rgb(0, 255, 0), CornerRadii.EMPTY, Insets.EMPTY)));
            }
        });
        btnAzul.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent t) {
                System.out.println("Oi botão azul - inline");
                PaneOrganizer.this.setBackground(new Background(new BackgroundFill(Color.rgb(0, 0, 255), CornerRadii.EMPTY, Insets.EMPTY)));
            }
        });
    }

    //3ºalternativa, usando uma classe inline
    void registerListener3() {
        btnVerde.setOnAction(new ProcessaBotao(Color.GREEN)); //o que vai ser executado, um objecto do tipo!
        btnAzul.setOnAction(new ProcessaBotao(Color.BLUE)); //o que vai ser executado, um objecto do tipo!
    }

    class ProcessaBotao implements EventHandler<ActionEvent> {
        Color cor;
        public ProcessaBotao(Color cor) {
            this.cor = cor;
        }
        @Override
        public void handle(ActionEvent t) {
            //quando o botão for clicado
            System.out.println("Oi botão azul - inner class");
            //aceder ao objecto de fora ou então criar uma varivel ou via construtor
            PaneOrganizer.this.setBackground(new Background(new BackgroundFill(cor, CornerRadii.EMPTY, Insets.EMPTY)));
        }
    }
    
    //4ºalternativa, usando lambda functions
    void registerListener4() {
    btnVerde.setOnAction(
            (t)->{
                PaneOrganizer.this.setBackground(
                        new Background(new BackgroundFill(Color.GREEN, CornerRadii.EMPTY, Insets.EMPTY)));
            });
   
    btnAzul.setOnAction(
            (t)->{
                PaneOrganizer.this.setBackground(
                        new Background(new BackgroundFill(Color.BLUE, CornerRadii.EMPTY, Insets.EMPTY)));
            });
    }
    
    //dinamicos
    void registerListener5() {
        btnVerde.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent t) {
                System.out.println("Oi botão azul - inline");
                PaneOrganizer.this.setBackground(new Background(new BackgroundFill(Color.rgb(0, 255, 0), CornerRadii.EMPTY, Insets.EMPTY)));
                numerVerde++;
                lblVerde.setText("#Verde: "+numerVerde);
            }
        });
        btnAzul.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent t) {
                System.out.println("Oi botão azul - inline");
                PaneOrganizer.this.setBackground(new Background(new BackgroundFill(Color.rgb(0, 0, 255), CornerRadii.EMPTY, Insets.EMPTY)));
                numeroAzul++;
                lblAzul.setText("#Azul: "+numeroAzul);
            }
        });
    }
}
Tags :

Programação avançada – capitulo 8 – maquina de estados, exemplo3

Exemplo de uma maquina de estado, usando como referência a implementação de um jogo de 3×3, onde existem dois jogadores.
O diagrama da maquina de estados dado:

Outra versão do diagrama da maquina de estados:

Em que ficou:

Com:

package me_jogopecas;

import me_jogopecas.iu.texto.IUTexto;
import me_jogopecas.logica.estados.JogoMaquinaEstados;

public class Me_jogoPecas {

    public static void main(String[] args) {
           IUTexto iuTexto = new IUTexto(new JogoMaquinaEstados());
           iuTexto.corre();
    }
    
}
package me_jogopecas.iu.texto;

import java.util.Scanner;
import me_jogopecas.logica.estados.*;

public class IUTexto {

    private JogoMaquinaEstados jogo;
    private boolean sair = false;

    public IUTexto(JogoMaquinaEstados jogo) {
        this.jogo = jogo;
    }

    void iuAguardaInicio() {

        if ((jogo.getJogador1() != null && jogo.getJogador1().isGanhou())) {
            System.out.println("\n" + jogo.getJogador1() + "\n" + jogo.grelhaToString());
        } else if (jogo.getJogador2() != null && jogo.getJogador2().isGanhou()) {
            System.out.println("\n" + jogo.getJogador2() + "\n" + jogo.grelhaToString());
        }
        System.out.println("\n=== AGUARDA INICIO ===\n"
                + (jogo.getJogador1() != null ? "" + jogo.getJogador1() : "")
                + (jogo.getJogador2() != null ? "" + jogo.getJogador2() : ""));
        while (true) {
            System.out.println("\n0 - Sair\n1 - Define nome de jogador\n2 - Comecar jogo\n3 - Ler jogo");
            char c = ' ';
            Scanner sc = new Scanner(System.in);
            c = sc.next().charAt(0);
            if ((c == '0')) {
                sair = true;
                return;
            }
            if ((c == '1')) { //1 - Define nome de jogador
                System.out.println("Numero (1 ou 2)  e nome do jogador: ");
                while (!sc.hasNextInt());
                int num = sc.nextInt();
                System.out.println(" numero: " + num);
                String nome = sc.next();
                jogo.defineNomeJogador(num, nome);
                System.out.println(" nome: " + nome);
                return;
            }
            if ((c == '2')) { //2 - Comecar jogo
                System.out.println("Comecar jogo: ");
                jogo.comecarJogo();
                return;
            }
            if ((c == '3')) { //3 - Ler o jogo
                System.out.println("Ler o  jogo: ");
                String ficheiroLer = sc.next();
               // jogo.ler(ficheiroLer);
                return;
            }
        }
    }

    void iuAguardaColocacao() {
        System.out.println("\n=== AGUARDA COLOCACAO === \n"
                + jogo.getJogador1()
                + jogo.getJogador2()
                + "\nJogador activo: " + jogo.getNomeJogadorActivo()
                + "\n" + jogo.grelhaToString());

        System.out.println("\n1 - Jogar : linha  coluna\n2 - Abandonar");
        char c = ' ';
        Scanner sc = new Scanner(System.in);
        c = sc.next().charAt(0);
        if ((c == '1')) {

            System.out.print(jogo.getNomeJogadorActivo() + ">");

            while (!sc.hasNextInt());
            int linha = sc.nextInt();

            while (!sc.hasNextInt());
            int coluna = sc.nextInt();
            jogo.jogar(jogo.getNumJogadorActivo(), linha, coluna);
        }
        if ((c == '2')) {
            System.out.println("Guardar o  jogo: ");
            String ficheiroGuardar = sc.next();
           // jogo.grava(ficheiroGuardar);
            jogo.abandonar(jogo.getNumJogadorActivo());
            return;
        }
    }

    void iuAguardaDevolucao() {
        System.out.println("\n=== AGUARDA DEVOLUCAO === \n"
                + jogo.getJogador1()
                + jogo.getJogador2()
                + "\nJogador activo: " + jogo.getNomeJogadorActivo()
                + "\n" + jogo.grelhaToString());

//        System.out.println("\nDevolver : linha  coluna\nAbandonar: -1");
        System.out.println("\n1 - Devolver : linha  coluna\n2 - Abandonar");
        char c = ' ';
        Scanner sc = new Scanner(System.in);
        c = sc.next().charAt(0);
        if ((c == '1')) {
            System.out.print(jogo.getNomeJogadorActivo() + ">");
            while (!sc.hasNextInt());
            int linha = sc.nextInt();

            while (!sc.hasNextInt());
            int coluna = sc.nextInt();
            jogo.devolver(jogo.getNumJogadorActivo(), linha, coluna);
        }
        if ((c == '2')) {
            jogo.abandonar(jogo.getNumJogadorActivo());
            return;
        }
    }

    public void corre() {

        while (!sair) {
            IEstado estado = jogo.getEstado();
            if (estado instanceof AguardaInicio) {
                iuAguardaInicio();
            } else if (estado instanceof AguardaColocacao) {
                iuAguardaColocacao();
            } else if (estado instanceof AguardaDevolucao) {
                iuAguardaDevolucao();
            }
        }

    }
}
package me_jogopecas.logica;

public interface Constantes {
    int DIM  =3;
}
package me_jogopecas.logica;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import static me_jogopecas.logica.Constantes.*;

public class Jogador implements Constantes, Serializable{

    private String nome;
    private JogoDados jogo;
    
    //lista de peças no inicio
    private List<Peca> mao = new ArrayList<Peca>(); 
    
    private boolean ganhou;

    public Jogador(String nome, JogoDados j) {
        this.nome = nome;
        this.jogo = j;
        ganhou = false;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public JogoDados getJogo() {
        return jogo;
    }

    public void setJogo(JogoDados jogo) {
        this.jogo = jogo;
    }

    public List<Peca> getMao() {
        return mao;
    }

    public void setMao(List<Peca> mao) {
        this.mao = mao;
    }

    public boolean isGanhou() {
        return ganhou;
    }

    public void setGanhou(boolean ganhou) {
        this.ganhou = ganhou;
    }

    //quando começar o jogo!
    public void recebePecas() {
        mao.clear();
        for (int i = 0; i < DIM; i++) { mao.add(new Peca(this)); } ganhou = false; } public int getNumPecas(){ return mao.size(); } //quando a peça é devolvida public void recebePeca(Peca peca) { mao.add(new Peca(this)); } public boolean temPecas() { return mao.size() > 0;
    }
    
    public boolean jogar(int linha, int coluna){
        if(mao.size()==0){
            return false;
        }
        //as peças são todas iguais
        Peca peca = mao.get(0);
        if(jogo.setPeca(peca, linha, coluna)){
            //jogou
            mao.remove(0);
            if(jogo.ganhou(this)){
                ganhou = true;
            }
            return true;
        }
        return false;
    }

    @Override
    public String toString() {
        return "Jogador " + nome + " mao=" + mao + (ganhou ? " == GANHOU ==" : "") + "\n" ;
    }   
}
package me_jogopecas.logica;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class JogoDados implements Constantes, Serializable  {

    private List<Jogador> jogadores = new ArrayList<Jogador>();

    private int numJoActivo;
    private Peca[][] grelha;

    public JogoDados() {
        jogadores.add(new Jogador("A", this));
        jogadores.add(new Jogador("B", this));
        grelha = new Peca[DIM][DIM];
    }

    public Jogador getJogadorActivo() {
        //considera-se que o jogador activo é 1 ou 2, daí o -1
        return jogadores.get(numJoActivo - 1);
    }

    public String getNomeJogadorActivo() {
        return jogadores.get(numJoActivo - 1).getNome();
    }

    public Jogador getJogadorNaoActivo() {
        if (numJoActivo == 1) {
            return jogadores.get(1);
        } else if (numJoActivo == 2) {
            return jogadores.get(0);
        }
        return null;
    }

    public int getNumJogadorActivo() {
        return numJoActivo;
    }

    public int getNumJogadorNaoActivo() {
        return (numJoActivo == 1 ? 1 : 2);
    }

    public Jogador getJogador1() {
        return jogadores.get(0);
    }

    public Jogador getJogador2() {
        return jogadores.get(1);
    }

    public Peca getPeca(int linha, int coluna) {
        if (linha < 0 || linha >= DIM || coluna < 0 || coluna >= DIM) {
            return null;
        }
        if (grelha == null) {
            return null;
        }
        return grelha[linha][coluna];
    }

    public boolean setPeca(Peca peca, int linha, int coluna) {
        if (linha < 0 || linha >= DIM || coluna < 0 || coluna >= DIM) {
            return false;
        }
        if (grelha[linha][coluna] != null) {
            return false;
        }
        grelha[linha][coluna] = peca;
        return true;
    }

    public boolean retiraPeca(int linha, int coluna) {
        if (linha < 0 || linha >= DIM || coluna < 0 || coluna >= DIM) {
            return false;
        }
        if (grelha[linha][coluna] == null) {
            return false;
        }
        grelha[linha][coluna] = null;
        return true;
    }

    public void jogaOutro() {
        numJoActivo = numJoActivo == 1 ? 2 : 1;
    }

    public boolean inicializa() {

        grelha = new Peca[DIM][DIM];
        jogadores.get(0).recebePecas();
        jogadores.get(1).recebePecas();

        numJoActivo = 1;

        return true;
    }

    public boolean setNomeJogador(int num, String nome) {
        //falta validar se o num é válido
        try {
            //tento aceder a um elemento do array que nao existe
            jogadores.get(num - 1).setNome(nome);
            return true;
        } catch (IndexOutOfBoundsException e) {
            return false;
        }
    }

    private boolean isEmDiagonalPrincipal(Jogador jogador) {
        for (int i = 0; i < DIM; i++) {
            if (grelha[i][i] == null || grelha[i][i].getJogador() != jogador) {
                return false;
            }
        }
        return true;
    }

    private boolean isEmDiagonalSecundaria(Jogador jogador) {
        for (int i = 0; i < DIM; i++) {
            if (grelha[i][DIM - 1 - i] == null || grelha[i][DIM - 1 - i].getJogador() != jogador) {
                return false;
            }
        }
        return true;
    }

    private boolean isEmDiagonal(Jogador jogador) {
        return isEmDiagonalPrincipal(jogador) || isEmDiagonalSecundaria(jogador);
    }

    private boolean isEmHorizontal(Jogador jogador, int linha) {
        for (Peca peca : grelha[linha]) {
            if (peca == null || peca.getJogador() != jogador) {
                return false;
            }
        }
        return true;
    }

    private boolean isEmVertical(Jogador jogador, int coluna) {
        for (int i = 0; i < grelha[coluna].length; i++) {
            Peca peca = grelha[i][coluna];
            if (peca == null || peca.getJogador() != jogador) {
                return false;
            }
        }
        return true;
    }

    private boolean isEmHorizontal(Jogador jogador) {
        for (int i = 0; i < DIM; i++) {
            if (isEmHorizontal(jogador, i)) {
                return true;
            }
        }
        return false;
    }

    private boolean isEmVertical(Jogador jogador) {
        for (int i = 0; i < DIM; i++) {
            if (isEmVertical(jogador, i)) {
                return true;
            }
        }
        return false;
    }

    public boolean ganhou(Jogador jogador) {
        return isEmHorizontal(jogador) || isEmDiagonal(jogador) || isEmVertical(jogador);
    }

    public boolean jogar(int numeroJogador, int linha, int coluna) {
        if (linha < 0 || linha >= DIM || coluna < 0 || coluna >= DIM) {
            return false;
        }
        if (numJoActivo != numeroJogador) {
            return false;
        }

        Jogador j = getJogadorActivo();

        if (!j.jogar(linha, coluna)) {
            return false;
        }
        return true;
    }

    public boolean devolver(int numeroJogador, int linha, int coluna) {
        if (linha < 0 || linha >= DIM || coluna < 0 || coluna >= DIM) {
            return false;
        }

        if (numJoActivo != numeroJogador) {
            return false;
        }
        Peca peca = getPeca(linha, coluna);
        Jogador j = getJogadorActivo();
        if (peca == null || peca.getJogador() != j) {
            return false;
        }

        if (!retiraPeca(linha, coluna)) {
            return false;
        }
        j.recebePeca(peca);
        return true;
    }

    public String grelhaToString() {
        String s = "";
        for (int i = 0; i < DIM; i++) {
            for (int j = 0; j < DIM; j++) {
                String casa;
                if (grelha[i][j] != null) {
                    casa = "" + grelha[i][j].getJogador().getNome().charAt(0);
                } else {
                    casa = " ";
                }
                s += "|\t" + casa + "\t";
            }
            s += "|\n";
        }
        return s;
    }

    public boolean acabou() {
        return ganhou(jogadores.get(0)) || ganhou(jogadores.get(1));
    }
}
package me_jogopecas.logica;

import java.io.Serializable;

public class Peca implements Serializable {
    private Jogador jogador;

    public Peca(Jogador jgd) {
        this.jogador = jgd;
    }

    public Jogador getJogador() {
        return jogador;
    }

    public void setJogador(Jogador jogador) {
        this.jogador = jogador;
    }

    @Override
    public String toString() {
        return "" + jogador.getNome().charAt(0);
    }
}
package me_jogopecas.logica.estados;

import me_jogopecas.logica.JogoDados;

public class AguardaColocacao extends EstadoAdapter {

    //para informação adicional
    int l, c;

    public AguardaColocacao(JogoDados jogodados) {
        super(jogodados);
        //para informação adicional
        l = c = -1; //se vier return this
    }

    //para informação adicional
    public AguardaColocacao(JogoDados jogo, int l, int c) {
        super(jogo);
        this.l = l;
        this.c = c;
    }

    //setas de saida
    @Override
    public IEstado abandona(int numeroJogador) {
        //podiamos atribuir a vitoria a um jogador, olhando para numeroJogador

        //voltamos ao inicio
        return new AguardaInicio(jogodados);
    }

    @Override
    public IEstado joga(int numeroJogador, int linha, int coluna) {
        //informação adicional
        if (linha == l && coluna == c) {
            return this;
        }

        //jogar normal, o jogar faz o teste se pode ou nao jogar
        jogodados.jogar(numeroJogador, linha, coluna);
        //verificar se o jogador activo
        if (jogodados.getJogadorActivo().isGanhou()) {
            return new AguardaInicio(jogodados);
        }
        jogodados.jogaOutro();
        //jogar a um jogador que não tem peças
        //jogar que nao tem pecas
        if (jogodados.getJogadorActivo().temPecas()) {
            //return this; //tb funciona
            //para informação adicional
            return new AguardaColocacao(jogodados);
        }
        return new AguardaDevolucao(jogodados);
    }
}
package me_jogopecas.logica.estados;

import me_jogopecas.logica.JogoDados;

public class AguardaDevolucao extends EstadoAdapter {

    public AguardaDevolucao(JogoDados jogodados) {
        super(jogodados);
    }

    @Override
    public IEstado abandona(int numeroJogador) {
        return new AguardaInicio(jogodados);
    }

    @Override
    public IEstado devolve(int numeroJogador, int linha, int coluna) {
        if (jogodados.devolver(numeroJogador, linha, coluna)) {
            //return new AguardaColocacao(jogodados);
            //informação adicional
            return new AguardaColocacao(jogodados, linha, coluna);
        }
        return this;
    }
}
package me_jogopecas.logica.estados;

import me_jogopecas.logica.JogoDados;

public class AguardaInicio extends EstadoAdapter {

    //construtor que redireciona para a classe base
    public AguardaInicio(JogoDados jogodados) {
        super(jogodados);
    }

    //setas de saida, os outros não fazem sentido
    @Override
    public IEstado defineNomeJogador(int numeroJogador, String nome) {
        //qual o novo estado depois de defineNomeJogador
        //agora vou atuar sobre o jogo
        jogodados.setNomeJogador(numeroJogador, nome);

        return this; //fico no mesmo estado
    }

    @Override
    public IEstado comecaJogo() {
        //testes para verificar se já tinhamos os dois jogadores
        if(jogodados.getJogador1()==null || jogodados.getJogador2()==null){
            return this;
        }
        jogodados.inicializa();
        return new AguardaColocacao(jogodados);
    }

}

package me_jogopecas.logica.estados;

import java.io.Serializable;
import me_jogopecas.logica.JogoDados;

//abstract para nao ser instanciada 
public abstract class EstadoAdapter implements IEstado, Serializable{
    
    
    JogoDados jogodados;//tem que ter acesso aos dados de jogo

    //podemos colocar como protected, para ser usado apenas nas classes derivadas
    public EstadoAdapter(JogoDados jogod) {
        this.jogodados = jogod;
    }

    public JogoDados getJogodados() {
        return jogodados;
    }

    public void setJogodados(JogoDados jogodados) {
        this.jogodados = jogodados;
    }

    @Override
    public IEstado defineNomeJogador(int numeroJogador, String nome) {
       return this;
    }

    @Override
    public IEstado comecaJogo() {
       return this;
    }

    @Override
    public IEstado joga(int numeroJogador, int linha, int coluna) {
        return this;
    }

    @Override
    public IEstado devolve(int numeroJogador, int linha, int coluna) {
        return this;
    }

    @Override
    public IEstado abandona(int numeroJogador) {
        return this;
    }
    //o interface precisa de ir buscar coisas para as mostrar
    
}

package me_jogopecas.logica.estados;

public interface IEstado {
    //definir todas as acções o jogo
    IEstado defineNomeJogador(int numeroJogador, String nome);
    IEstado comecaJogo();
    IEstado joga(int numeroJogador, int linha, int coluna);
    IEstado devolve(int numeroJogador, int linha, int coluna);
    IEstado abandona(int numeroJogador);
}

package me_jogopecas.logica.estados;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import me_jogopecas.logica.Jogador;
import me_jogopecas.logica.JogoDados;

public class JogoMaquinaEstados implements Serializable {

    //se JogoMaquinaEstados é Serializable as classes de base tb têm que ser
    JogoDados jogodados;
    IEstado estado;

    public JogoMaquinaEstados() {
        //criar o meu jogo
        this.jogodados = new JogoDados();
        //desenvolver, evoluir, programação dos estados (do diagrama)
        this.estado = new AguardaInicio(jogodados);
    }

    public IEstado getEstado() {
        return estado;
    }

    public void setEstado(IEstado estado) {
        this.estado = estado;
    }

    //implementar todos os estados, através desta maquina de estados
    //interface de todas as classes
    public void defineNomeJogador(int numeroJogador, String nome) {
        //estado seguinte vai ser do retornar..
        estado = estado.defineNomeJogador(numeroJogador, nome);
    }

    public void comecarJogo() {
        estado = estado.comecaJogo();
    }

    public void jogar(int numeroJogador, int linha, int coluna) {
        estado = estado.joga(numeroJogador, linha, coluna);
    }

    public void devolver(int numeroJogador, int linha, int coluna) {
        estado = estado.devolve(numeroJogador, linha, coluna);
    }

    public void abandonar(int numeroJogador) {
        estado = estado.abandona(numeroJogador);
    }

    //os métodos que surgem no IUTexto
    public Jogador getJogador1() {
        return jogodados.getJogador1();
    }

    public Jogador getJogador2() {
        return jogodados.getJogador2();
    }

    public String getNomeJogadorActivo() {
        return jogodados.getNomeJogadorActivo();
    }

    public int getNumJogadorActivo() {
        return jogodados.getNumJogadorActivo();
    }

    public String grelhaToString() {
        return jogodados.grelhaToString();
    }

    //ou em alternativa dava acesso ao jogodados
    public JogoDados getJogo() {
        return jogodados;
    }

    //gravação dos ficheiros
    public void grava(String filename) throws IOException {
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream(filename));
            oos.writeObject(this);
        } finally {
            if(oos != null)
            {
                oos.close();
            }
        }
    }
    public static JogoMaquinaEstados ler(String filename) throws IOException, ClassNotFoundException {
    ObjectInputStream oos = null;
        try {
            oos = new ObjectInputStream(new FileInputStream(filename));
            return (JogoMaquinaEstados) oos.readObject();
        } finally {
            if(oos != null)
            {
                oos.close();
            }
        }
    
    }
}

Tags : , ,

Programação avançada – capitulo 8 – maquina de estados, exemplo2

Exemplo de uma maquina de estado, simples, usando as referências a um mecanismo de um elevador com dois estados extra: erro e chaveManutencao

Em que ficou:

Com:

package me_me_elevador;

import me_me_elevador.IU.Texto.UsaElevador;
import me_me_elevador.logica.Elevador;

public class Me_ME_elevador {
    public static void main(String[] args) {
        Elevador e = new Elevador();
        UsaElevador usaE = new UsaElevador(e); //interface com o utilizador
        usaE.corre();
    }
}
package me_me_elevador.IU.Texto;

import me_me_elevador.logica.*;
import me_me_elevador.util.IUUtil;

public class UsaElevador {

    //o interface com o utilizador, com o nosso elevador.
    private Elevador elevador;
    private boolean sair = false;

    public UsaElevador(Elevador elevador) {
        this.elevador = elevador;
    }

    public void corre() {
        while (!sair) {
            //saber em que estado estou
            IEstado estado = elevador.getEstado();
            if (estado instanceof RC) {
                iuRC();
            } else if (estado instanceof Andar1) {
                iuAndar1();
            } else if (estado instanceof Andar2) {
                iuAndar2();
            } else if (estado instanceof Andar3) {
                iuAndar3();
            }else if (estado instanceof Manutencao) {
                iuManutencao();
            }
        }
    }
    
    
     private void iuManutencao() {
        int opcao = IUUtil.getOpcao("Em modo de manutenção", "Usar a chave", "Sair do elevador");
        switch (opcao) {
            case 0:
                elevador.chaveManutencao();
            case 1:
                sair = true;
                break;
        }
    }

    private void iuRC() {
        //opcoa 1
        //pedir ao utilizador: sair ou subir
        int opcao = IUUtil.getOpcao("Piso R/C", "Sair do prédio", "Subir", "Erro");
        switch (opcao) {
            case 0:
                sair = true;
                break;
            case 1:
                //fazer evoluir a maquina de estados
                elevador.sobe();
                break;
            case 2:
                elevador.erro();
                break;
        }
    }

    private void iuAndar1() {
        int opcao = IUUtil.getOpcao("Piso 1 andar", "Descer", "Subir", "Erro");
        switch (opcao) {
            case 0:
                //fazer evoluir a maquina de estados
                elevador.desce();
                break;
            case 1:
                //fazer evoluir a maquina de estados
                elevador.sobe();
                break;
            case 2:
                elevador.erro();
                break;
        }
    }

    private void iuAndar2() {
        int opcao = IUUtil.getOpcao("Piso 2 andar", "Descer", "Subir", "Erro");
        switch (opcao) {
            case 0:
                //fazer evoluir a maquina de estados
                elevador.desce();
                break;
            case 1:
                //fazer evoluir a maquina de estados
                elevador.sobe();
                break;
            case 2:
                elevador.erro();
                break;
        }
    }

    private void iuAndar3() {
        int opcao = IUUtil.getOpcao("Piso 3 andar", "Descer", "Erro");
        switch (opcao) {
            case 0:
                //fazer evoluir a maquina de estados
                elevador.desce();
                break;
            case 1:
                elevador.erro();
                break;
        }
    }
}
package me_me_elevador.logica;

public class Andar1 extends Piso {

    @Override
    public IEstado sobe() {
        //altero de estado
        return new Andar2();
    }

    @Override
    public IEstado desce() {
        //altero de estado
        return new RC();
    }
    
    //se fossem todos iguais podia ser implementado no Piso
    // com return this;
    @Override
    public IEstado erro() {
        return new Manutencao(this);
    }
}
package me_me_elevador.logica;

public class Andar2 extends Piso{

    @Override
    public IEstado sobe() {
        return new Andar3();
    }

    @Override
    public IEstado desce() {
        return new Andar1();
    }
    @Override
    public IEstado erro() {
                return new Manutencao(this);
    }
}
package me_me_elevador.logica;

public class Andar3 extends Piso{

    @Override
    public IEstado sobe() {
        //fico no mesmo estado
       return this;
    }

    @Override
    public IEstado desce() {
        //altero de estado
        return new Andar2();
    }
    @Override
    public IEstado erro() {
                return new Manutencao(this);
    }
}

package me_me_elevador.logica;

public class Elevador {
    IEstado estado;

    public Elevador() {
        estado = new RC();
    }

    public IEstado getEstado() {
        return estado;
    }
    public void setEstado(IEstado estado) {
        this.estado = estado;
    }
    public void sobe() {
        setEstado(estado.sobe());
    }

    public void desce() {
        setEstado(estado.desce());
    }
    
    public void erro(){
        setEstado(estado.erro());
    }
    
    public void chaveManutencao(){
        setEstado(estado.chaveManutencao());
    }
}

package me_me_elevador.logica;

public interface IEstado {
    IEstado sobe();
    IEstado desce();
    
    IEstado erro();
    IEstado chaveManutencao();
}

package me_me_elevador.logica;

public class Manutencao extends Piso{
    //vai recordar qual era o estado antes
    private IEstado anterior;

    public Manutencao(IEstado ant) {
        this.anterior = ant;
    }
    
    @Override
    public IEstado chaveManutencao() {
      return anterior;
    }   
}
package me_me_elevador.logica;

public abstract class Piso implements IEstado {
    @Override
    public IEstado sobe() {
        return this;
    }

    @Override
    public IEstado desce() {
        return this;
    }

    @Override
    public IEstado chaveManutencao() {
        return this;
    }

    @Override
    public IEstado erro() {
        return this;
    }
}
package me_me_elevador.logica;

public class RC extends Piso {

    @Override
    public IEstado sobe() {
        //altero de estado
        return new Andar1();
    }

    @Override
    public IEstado desce() {
        //fico no mesmo estado
        return this;
    }

    @Override
    public IEstado erro() {
        return new Manutencao(this);
    }
}

package me_me_elevador.util;

import java.util.Scanner;

public class IUUtil {
    public static int getOpcao(String question, String... options) {
        System.out.println(question);
        char[] ops = new char[options.length];
        for (int i = 0; i < options.length; i++) {
            char o = '\0';
            int c = 0;
            while (c < options[i].length()) {
                o = Character.toUpperCase(options[i].charAt(c));
                for (int j = 0; j < i; j++) {
                    if (ops[j] == o) {
                        o = '\0';
                        break;
                    }
                }
                if (o != '\0') {
                    break;
                }
                c++;
            }
            if (c >= options[i].length()) {
                return -1;
            }
            ops[i] = o;
            if (i > 0) {
                System.out.print(", ");
            }
            if (c > 0) {
                System.out.print(options[i].substring(0, c));
            }
            System.out.print("(" + ops[i] + ")" + options[i].substring(c + 1));
        }
        System.out.println();
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.print("Option: ");
            char o = Character.toUpperCase(sc.nextLine().charAt(0));
            for (int i = 0; i < ops.length; i++) {
                if (o == ops[i]) {
                    return i;
                }
            }
        }
    }
}

O erro e a chaveEmergencia são acções, sendo que o evento que surge é a Manutenção.

Tags : , ,

Programação avançada – capitulo 8 – maquina de estados, exemplo1

Exemplo de uma maquina de estado, simples, usando as referências a um mecanismo de um elevador

Em que ficou:

Com:

package me_me_elevador;

import me_me_elevador.IU.Texto.UsaElevador;
import me_me_elevador.logica.Elevador;

public class Me_ME_elevador {
    public static void main(String[] args) {
        Elevador e = new Elevador();
        UsaElevador usaE = new UsaElevador(e); //interface com o utilizador
        usaE.corre();
    }
}
package me_me_elevador.IU.Texto;

import me_me_elevador.logica.*;
import me_me_elevador.util.IUUtil;

public class UsaElevador {

    //o interface com o utilizador, com o nosso elevador.
    private Elevador elevador;
    private boolean sair = false;

    public UsaElevador(Elevador elevador) {
        this.elevador = elevador;
    }

    public void corre() {
        while (!sair) {
            //saber em que estado estou
            IEstado estado = elevador.getEstado();
            if (estado instanceof RC) {
                iuRC();
            } else if (estado instanceof Andar1) {
                iuAndar1();
            } else if (estado instanceof Andar2) {
                iuAndar2();
            } else if (estado instanceof Andar3) {
                iuAndar3();
            }
        }
    }

    private void iuRC() {
        //opcoa 1
        //pedir ao utilizador: sair ou subir
        int opcao = IUUtil.getOpcao("Piso R/C", "Ir embora", "Subir");
        switch (opcao) {
            case 0:
                sair = true;
                break;
            case 1:
                //fazer evoluir a maquina de estados
                elevador.sobe();
                break;
        }
    }

    private void iuAndar1() {
        int opcao = IUUtil.getOpcao("Piso 1 andar","Descer", "Subir");
        switch (opcao) {
            case 0:
                //fazer evoluir a maquina de estados
                elevador.desce();
                break;
            case 1:
                //fazer evoluir a maquina de estados
                elevador.sobe();
                break;
        }
    }

    private void iuAndar2() {
        int opcao = IUUtil.getOpcao("Piso 2 andar","Descer", "Subir");
        switch (opcao) {
            case 0:
                //fazer evoluir a maquina de estados
                elevador.desce();
                break;
            case 1:
                //fazer evoluir a maquina de estados
                elevador.sobe();
                break;
        }
    }

    private void iuAndar3() {
        int opcao = IUUtil.getOpcao("Piso 3 andar","Descer");
        switch (opcao) {
            case 0:
                //fazer evoluir a maquina de estados
                elevador.desce();
                break;
        }
    }
}
package me_me_elevador.logica;

public class Andar1 extends Piso{

    @Override
    public IEstado sobe() {
        //altero de estado
        return new Andar2();
    }

    @Override
    public IEstado desce() {
        //altero de estado
        return new RC();
    }
}
package me_me_elevador.logica;

public class Andar2 extends Piso{

    @Override
    public IEstado sobe() {
        return new Andar3();
    }

    @Override
    public IEstado desce() {
        return new Andar1();
    }
}
package me_me_elevador.logica;

public class Andar3 extends Piso{

    @Override
    public IEstado sobe() {
        //fico no mesmo estado
       return this;
    }

    @Override
    public IEstado desce() {
        //altero de estado
        return new Andar2();
    }
}
package me_me_elevador.logica;

public class Elevador {
//é a maquina de estados, que faz alterar os estados
    IEstado estado;

    public Elevador() {
        //o estado incial//arranque é então:
        estado = new RC();
    }

    public IEstado getEstado() {
        return estado;
    }

    public void setEstado(IEstado estado) {
        this.estado = estado;
    }

    //podia ter outras informações, como o numero de pessoas
    //as luzes que estão ou não ligadas..
    //métodos que dão origem à mudança de estado
    public void sobe() {
        setEstado(estado.sobe()); //versão1
        //this.estado = estado.sobe();  //versão2
    }

    public void desce() {
        setEstado(estado.desce()); //versão1
        //this.estado = estado.desce();  //versão2
    }
}
package me_me_elevador.logica;

public interface IEstado {
    //acções comuns a cada uma dos estados:RC,andar1,andar2...
    //interface geral
    IEstado sobe();
    IEstado desce();
}
package me_me_elevador.logica;

public abstract class Piso implements IEstado {
    //classe para implementação default, sem alterar o estado
    //serve para simplifcar todas as outras
    @Override
    public IEstado sobe() {
        return this;
    }

    @Override
    public IEstado desce() {
        return this;
    }
}
package me_me_elevador.logica;

public class RC extends Piso{

    @Override
    public IEstado sobe() {
        //altero de estado
        return new Andar1();
    }

    @Override
    public IEstado desce() {
        //fico no mesmo estado
        return this; 
    }
}
package me_me_elevador.util;

import java.util.Scanner;

public class IUUtil {
    // v1
      public static int getOpcao(String question, String... options) {
        System.out.println(question);
        char[] ops = new char[options.length];
        for (int i = 0; i < options.length; i++) {
            char o = '\0';
            int c = 0;
            while (c < options[i].length()) {
                o = Character.toUpperCase(options[i].charAt(c));
                for (int j = 0; j < i; j++) {
                    if (ops[j] == o) {
                        o = '\0';
                        break;
                    }
                }
                if (o != '\0') {
                    break;
                }
                c++;
            }
            if (c >= options[i].length()) {
                return -1;
            }
            ops[i] = o;
            if (i > 0) {
                System.out.print(", ");
            }
            if (c > 0) {
                System.out.print(options[i].substring(0, c));
            }
            System.out.print("(" + ops[i] + ")" + options[i].substring(c + 1));
        }
        System.out.println();
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.print("Option: ");
            char o = Character.toUpperCase(sc.nextLine().charAt(0));
            for (int i = 0; i < ops.length; i++) {
                if (o == ops[i]) {
                    return i;
                }
            }
        }
    }
}

No interface IEstado, são colocados todas as ações dos estados, mesmo que não façam sentido em alguns dos estados.
A class Piso, faz a implementação default de alguns dos estados para que não tenhamos que estar a repetir código nos diferentes estados.

Tags : , ,

JavaFX, construir aplicações com GUI em JAVA

Para começar a trabalhar com o JavaFX é necessário instalar na máquina:
https://openjfx.io/

que muito provavelmente vai redireccionar para o link:
https://gluonhq.com/products/javafx/

o download deve ser de:
openjfx-14.0.1_windows-x64_bin-sdk.zip

(ou então de uma versão LTS)

Em Windows depois é necessário descompactar o ZIP e copiar a pasta para:
\Program Files\Java

Antes de passar ao passo seguinte, recomendo que se instale a versão mais recente do Java, por exemplo a jdk-14.0.1_windows-x64_bin.exe e que desinstale todas as outras versões!!

Agora falta configurar o netbeans, v13:
criar uma nova biblioteca, tools->libraries
botão: new library
atribuir um nome, por exemplo JavaFX14
clicar em Add/JAR/Folder
e adicionar (seleccionar) todos os ficheiros jar da pasta: javafx-sdk-14.0.1\lib
voltar à janela principal do netbeans, e ir às propriedades do projeto
nas propriedades do projeto, escolher  a opção libraries e clicar em classpath e libraries
escolher a opção JavaFX14
e no separador Run adicionar ao modulepath adicionar a biblioteca JavaFX14
ainda nas propriedades e do lado esquerdo, escolher Run, VM options:
–module-path /Program Files/Java/javafx-sdk-14.0.1/lib –add-modules javafx.controls

e done!

(ou seguir isto https://openjfx.io/openjfx-docs/#IDE-NetBeans)

 
package javafx01;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class JavaFx01 extends Application {
    public static void main(String[] args) {
        //passamos os argumentos para o subsistema gráfico os parametros
        launch(args); 
    }

    @Override
    //quando começa a aplicação
    public void start(Stage stage) throws Exception{
        BorderPane bp = new BorderPane();
        Label label1 = new Label("programação avançada");
        Label label2 = new Label("outra label");
        bp.setBottom(label1);
        bp.setTop(label2);
        //criar a cena
        Scene scene = new Scene(bp,400,400); //raiz da cena, e dimensões
        //adicionar a cena ao palco
        stage.setScene(scene);
        stage.show();
    }
}

Stage -> a janela da aplicação
Scene -> representa os elementos que vão estar presentes num stage
Node -> componentes específicos, são os nodes, que podemos ter dentro de cada cena (Canvas, ImageView, MediaView, Shape, Shape3D, SwingNode, EventTarget, Styleable: button, checkbox, combobox, label, listview, progressbar, radiobutton textfield)

Acerca dos objectos Pane existem estas opções:

Para projectos futuros:
em libraries->separador compile-> class path: e seleccionar a biblioteca JavaFX14
separador run -> modulepath: e seleccionar a biblioteca JavaFX14
e no run -> VM options -> –add-modules javafx.controls

Tags : , ,

ukie, you-key, (UK Interactive Entertainment)

Mais um grupo relacionado com a industria dos videojogos, com algumas referências para investigação feita.. um grupo organizado no UK.

+infos(oficial): https://ukie.org.uk/

Tags : , , ,

European Games Developer Federation Ekonomisk Förening (EGDF)

Mais um grupo relacionado com a industria dos videojogos, não têm referências para investigação feita.. mais parece um aglomerado de empresas para obter uma força positiva para esta industria!

+infos(oficial): http://www.egdf.eu/

Tags :

Uma lista colaborativa acerca de ferramentas open-source #opensource

Tiny/weirdo game engines:

Game engines that let you make a full game, but often within a particular style, ethos, framework, or with other limitations. Generally quick to pick up and work with, made for accessibility.

  • Flickgame – A truly tiny engine, link frames to other frames. Share online or export. 
  • GB Studio – A drag and drop gameboy interface that lets you do some scripting. Export to html or an actual gameboy rom! 
  • Bitsy – Bitsy is a simple sprite-based editor that lets you build rooms & worlds. Walk around and talk to people and be somewhere. Has a strong community.
  • Borksy / Bitsy HD / bitsy hacks / bitsy mixer template – Hacks that extend the functionality of bitsy in various ways.
  • Flicksy – A tool for drawing and assembling graphical hypertext games – lets you import drawings!
  • Mosi – Similar to bitsy, but with more color & sound support, and more advanced scripting options.
  • Bravitzlana – A tool for making small interactive scenes (3d! kind of) that you can share with people.
  • PuzzleScript – An open source, HTML5 puzzle-game oriented editor.
  • Dungeonscript – Puzzlescript, but first person
  • RPG Paper Maker – An extremely cute jrpg-focused engine that lets you place flat sprites in a 3d world. (free, but $70 if you sell your game commercially)
  • Flatgames / Flatpack – Flatgames are as much a concept as engine (2d, a raw combination of movement, art and sound), but Flatpack bundles those ideas up into a tool that you can import into Unity or run on Android.
  • Tiny Game Maker – For small, one screen games without programming.
  • Kooltool – An experimental game making tool which has Kidpix vibes.
  • The Unfolding Game Engine – One to watch (in early access right now). A “paint a world” engine that lets you make your world while playing it. 2.5d. 
  • Multiverse – Not out yet – a storytelling and game making tools/game.
  • Bitmelo – A game editor and engine for making small pixel art games. In early access, exports to HTML5. 
  • Sok Worlds ($3) – A truly wild game/tool where you make and explore 3d collage worlds (images from the pixabay API, but there are over a million to choose from.).
  • Sok Stories ($3) – A drawing-based way to make and share games.
  • Playscii – Also an ascii art and animation program, but the game mode documented here: http://vectorpoem.com/playscii/howto_game.html 
  • Wick Editor – Also an animation program- a friendly flash-like for multimedia projects that allows interaction and game-like play. 
  • Unicorn Console – A “a quick and dirty engine … with a resolution of 400×240 pixels.”
  • Vipercard – An open source reimagining of 1987’s Hypercard.
  • Twine – An open-source tool for telling interactive, nonlinear stories. Has a big community and multiple versions and themes.
  • Choicescript  – Like Twine, but for more traditional CYOA gamebooks-with-stats. Tight community on the forums.
  • Tiny Choice – The tiniest of twine-likes, written in the browser.
  • Inform – A design system for interactive fiction which has been around for a while!
  • Ink – A narrative engine designed to slot into a game engine.
  • StudyCrafter – A scratch-like platform where you can play, share, and create interactive projects, on the browser or offline, and collect data from players. 
  • Inklewriter – The “baby” Ink, runs in browser and great for CYOA, same UI as Sorcery!
  • The Adliberum Engine – (Free but on Steam, early access) Make text adventures, muds and text-powered roleplaying games.
  • Yarn Spinner – The friendly tool for writing game dialogue. 
  • Cheap Bots Done Quick – A site where you can make a twitterbot today.

Indie/open source bigger game engines: 

Indie and open source game engines with more flexibility and power than the little engines above, and generally also another layer of complication. (Perhaps most useful for if you are concerned about free but closed-source engines like Unity.)

  • Superpowers – HTML5 2d + 3d engine, coding in Typescript.
  • HaxeFlixel – Cross-platform development, open source
  • Godot – Perhaps the most complete and well documented open source engine, for 2d and 3d.
  • Heaps – A free and open source cross platform graphics engine written in Haxe.
  • DOME – A framework for making 2D games using the Wren programming language.
  • luxe – In development: a 2d-focused engine, code in Wren.
  • LITIENGINE – A free and open source Java 2D Game Engine.
  • Starling – A Cross Platform Game Engine.
  • LÖVR – An open source framework for rapidly building VR experiences in Lua.
  • Ren’Py – Free, open source cross-platform Visual Novel development engine.
  • Adventure Game Studio – Free engine for making point & click adventure games.
  • Phaser.io – Desktop and mobile HTML5 game framework, using javascript.
  • Pixelbox.js – Combination editor and a simple JavaScript library.
  • Amulet – A free Lua-based audio/visual toolkit suitable for small games and experimentation, with online editor.

Fantasy consoles: 

A fantasy console is like a regular console (machine specs, dev tools, community), but without hardware. It is like an emulator for a machine that never existed. Generally, these are in the form of an application.

  • Pico8 ($15) – probably the most popular fantasy console for game dev, pico8 has harsh limitations but that are intentionally chosen. code is written in lua. export to standalone HTML+JS or PNG (fantasy cartridge, need pico8 to play)
  • Tic-80 – coding in lua and moonscript. export to html or .tic. 
  • Pixel Vision 8 (free, pro version is $30) – a no-console fantasy computer, navigate like the familiar icon-based desktops you know. 
  • LIKO-12 – Entirely open-source and free, written in Lua. The dev says: “Why did I develop this? Because I wanted to buy PICO-8 but that’s not possible without credit cards (no internet shopping in Syria)”
  • Pix64 – an extremely tiny fantasy console (64×64 px).
  • Homegirl Pro – A fantasy console with a very different vibe! This one dispenses of pixel nostalgia and is modeled after a Commodore Amiga. Coding in Lua. 
  • VectorBoy – Again, a fantasy console that breaks the mold – VectorBoy uses straight lines to emulate vector graphics.
  • VVpet – A fantasy console for LCD virtual pet games
  • Voxatron – ($20, come with Pico-8) Fantasy Console for voxel (3d pixel, kind of?) games. 
  • LowRes NX – BASIC programming on iOS, as well as desktops.
  • Pyxel – A retro game engine for Python
  • Zany80 – A fantasy console designed around the Z80 processor.
  • Riko4 – A Fantasy Console intended as a tool for pixel art game development.
  • ECoS – A modern fantasy console with Entity-Component-System modular architecture.
  • Nano JAMMER – A truly tiny console that runs in the browser and integrates into Google Drive. Code in the nano programming language. 
  • Rewtro – A wild little console that runs games encoded in a very small amount of data, meaning they can be printed as qr-codes.
  • Script-8 – A fantasy computer for making, sharing, and playing tiny retro-looking games. Free, browser-based, and open-source. Code in Javascript

Didn’t find what you were looking for? Just into fantasy consoles? More of them detailed here: https://github.com/paladin-t/fantasy 

Neat Unity extenders:

Tools or plug-ins that change the experience of using Unity.

  • Oikospiel-tools – Trigger-based tools for Unity for crafting games without programming.
  • Unity Bitmap Drawing – A library for adding real-time drawing to your Unity project.
  • Clayxels – Adds tiny voxels that seamlessly blend together like clay.
  • unity-wave-function-collapse – Bitmap & tilemap generation from a single example.
  • Tessera (5$)- 2d / 3d wave function collapse generation.
  • Borderless Unity Windows – A tiny tool for making Unity frameless apps from script.
  • First Person Drifter – The original drifting game controller. Download an updated package for Unity 2019 from me here
  • Unity Recorder – An editor-only tool that captures video and animation data during gameplay.
  • Bobbin – A small Unity editor tool that can automatically download and import anything with a URL into the project.
  • Meshedit ($35) – A Unity extension that lets you create and texture models from scratch.
  • Doodlestudio 95 ($45) – A FUN drawing and animation tool for Unity.
  • Raymarching Toolkit ($75) – A Unity add-on for editing raymarched scenes live.
  • Path CreatorPath creation asset for Unity game development
  • NaughtyAttributes – Create powerful inspectors without the need for custom editors.
  • UCLA Game Lab Mesh Creator – Extrudes 2D drawings into 3D objects.
  • Rhythm beat mapper ($45) – Synchronizes gameplay to music in your video game.
  • JPEG-MP4-Compression – recreates the effect of JPEG/MP4 compression as a PostProcessing Effect.

Godot Extenders:

Tools or plug-ins that change the experience of using Godot.

  • WAT – An automated testing framework for Godot built entirely within Godot itself

Maps, place, & levels:

Tools for making maps & levels – some of them simply visual, others generate data.

  • Tiled – The standard free, easy to use and flexible level editor.
  • OGMO – A free, open source, project oriented level editor. 
  • Tilesetter – Tileset designing made easy.
  • SPARTAN Procedural Tile Generator – A pixel art drawing and animation tool specialised in creating tiles and animated sprites for games.
  • Medieval Fantasy Town Generator – Generates a random medieval city layout of a requested size & can export to JSON.
  • City Viewer – The city viewer to see the above/other maps in 3d!
  • One Page Dungeon – A very simple one page dungeon generator.
  • Map Generator – A cellular automata tool for building custom maps, envisioned for use in tabletop roleplaying games.
  • Paper Dungeon Maker – A very little map generator with optional csv output.
  • RPG Map II – A tabletop oriented map editor with clean and simple design.
  • Snazzy Maps – Nice map stylings for Google Maps.
  • Google Earth Studio – Automate flying about the world.
  • Topo Topo – Get a little square of 3d elevation data, anywhere.
  • Nototo – Build and visualize all your notes, as a map
  • terrain.party – nice interface for getting terrain heightmaps anywhere in the world

+infos(fonte): http://everest-pipkin.com/teaching/tools.html

Tags : , ,

Chamada de trabalhos de videojogos :)

IndieCade’s 2020 flagship Festival is going virtual! As a distributed event, this new format will open new doors for opportunities, participation and access.

IndieCade Anywhere and Everywhere will be a multi-day distributed celebration of innovation and innovators, of fresh new games and their creators, of new connections and old, of coming together as a community and welcoming new voices, friends, partners, creators, supporters, and enthusiasts. As a virtual event, the event is more global than ever with game creators from more continents able to join us safely and without financial barriers. It is exciting.

This is a wonderful opportunity for your students to show their work. Submissions are now open through June 1st. As always, we invite all kinds of interactive works and are especially interested in students works, completed or in-progress. We also welcome faculty work!!! It is also important to us that there are no financial barriers and we are happy to work with each institution on a package deal or with individual students on financial aid options.

All submissions also include a long list of benefits for submitting, importantly including a pass for each active team member to participate in IndieCade Anywhere and Everywhere’s special developer sessions, show-and-tell, networking and more.

+infos(oficial): http://www.indiecade.com/submissions/

Tags : , ,

Programação avançada – capitulo 7

A classe Object:
esta é a classe das quais todas as outras classes derivam
tem métodos importantes:
public String toString()
que retorna uma string que descreve um objeto

public boolean equals(Objecto obj)
tem com objectivo fazer a comparação entre dois objectos, em termos de conteudos, sabendo que usando o == compara referências
e é necessário que ele esteja definido

package e23;

class Animal{
    private int peso;
    private String nome;

    Animal(int p, String s){
        this.peso = p;
        this.nome = s;
    }
    
    public boolean equals(Object ob){
        if(this == ob){
            return true;
        }
        if((ob == null) || (ob.getClass() != this.getClass())){
            return false;
        }
        
        // type casting of the argument
        Animal anim = (Animal)ob;
    
        return (this.peso == anim.peso && this.nome == anim.nome);
    }

}

public class e23 {

    public static void main(String args[]) {
        Animal a1 = new Animal(80, "pedro");
        Animal a2 = new Animal(55, "maria");
        Animal a3 = new Animal(80, "pedro");
        
        if(a1.equals(a3)){
            System.out.println("O método equals");
        }else{
            System.out.println("Não são iguais");
        }
    }
}

public int hashCode()
quando se define o método equals também se deve definir o método hashCode()
este método retorna um inteiro, que resulta da conversão do endereço interno do objecto

package e23;

import java.util.Objects;

class Animal {

    private int peso;
    private String nome;

    Animal(int p, String s) {
        this.peso = p;
        this.nome = s;
    }

    public boolean equals(Object ob) {
        if (this == ob) {
            return true;
        }
        if ((ob == null) || (ob.getClass() != this.getClass())) {
            return false;
        }

        // type casting of the argument
        Animal anim = (Animal) ob;

        return (this.peso == anim.peso && this.nome == anim.nome);
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 17 * hash + this.peso;
        hash = 17 * hash + Objects.hashCode(this.nome);
        return hash;
    }
}

public class e23 {

    public static void main(String args[]) {
        Animal a1 = new Animal(80, "pedro");
        Animal a2 = new Animal(55, "maria");
        Animal a3 = new Animal(80, "pedro");

        if (a1.equals(a3)) {
            System.out.println("O método equals");
        } else {
            System.out.println("Não são iguais");
        }
    }
}

Este método como outros podem ser inseridos de forma automática no netbeans, se dentro da classe e com o lado direito do reato se optar por inserir código (ALT+INSERT)

+infos(geeksforgeeks.org): LINK gostei da explicação

Tags : , , ,

Programação avançada – capitulo 6

O upcasting:
serve para realizar a conversão de tipo, de uma classe derivada para uma classe base
permite assim converter um tipo mais restrito num tipo mais alargado

O polimorfismo:
“O mecanismo de polimorfismo consiste na qualidade de poder decidir a operação que vai ser executada num dado instante , em função dos objetos específicos envolvidos na operação”

As classes abstractas:
um método é abstracto, se o seu prototípico for escrito precedido da palavra abstract
uma classe que tenha um método abstracto tem que ser declarada como abstracta
não se podem criar objectos em classes abstractas
uma classe pode ser abstracta, mesmo não tendo qualquer método abstracto (caso de uma classe derivada de uma abstracta)
uma classe derivada não é abstracta se tiver definidos todos os métodos da classe abstracta
uma classe derivada é abstracta se não tiver pelo menos um método da classe base

exemplo (especialização: do topo para a base, generalização: da base para o topo (sentido das setas)):

package e16;

abstract class Veiculo {
    abstract int calculaCarro();
    abstract int calculaAutocarro();
}

//errada esta classe Carro.. se é abstracta só deveria ter protótipos das funções
abstract class Carro extends Veiculo {
    private int km;
    private int custo = 5;

    public Carro(int k) {
        this.km = k;
    }
    int calculaCarro() {
        int valor = this.km * custo;
        return valor;
    }
    public String toString() {
        return "despesa do carro: " + calculaCarro();
    }
}

class Autocarro extends Veiculo {
    private int km;
    private int custo = 4;

    public Autocarro() { //importante - parte1
    }
    public Autocarro(int k) {
        this.km = k;
    }
    int calculaAutocarro() {
        int valor = this.km * custo;
        return valor;
    }
    int calculaCarro() {
        int valor = this.km * custo;
        return valor;
    }
    public String toString() {
        return "despesa do autocarro: " + calculaAutocarro();
    }
}

class MiniAutocarro extends Autocarro {
    private int km;
    private int custo = 1;

    public MiniAutocarro() { //importante - parte2
    }
    public MiniAutocarro(int k) {
        this.km = k;
    }
    int calculaMiniAutocarro() {
        int valor = this.km * custo;
        return valor;
    }
    public String toString() {
        return "despesa do mini-autocarro: " + calculaMiniAutocarro() + " , " + super.toString();
    }
}

public class e16 {

    public static void main(String args[]) {
        System.out.println("\n Classe abstracta:"); //sout+tab
        Veiculo v1;
        v1 = new Autocarro(100);
        System.out.println(v1.toString());
        Veiculo v2;
        v2 = new MiniAutocarro(200);
        System.out.println(v2.toString());
    }
}

As interfaces:
é outra forma de trabalhar com classes abstractas
a interface pode conter: constantes, ou métodos
para definir uma classe que tem um ou mais interfaces, faz-se uso da expressão implements
os membros variáveis são implicitamente: public, final ou static (e é redundante usar estas expressões)
os métodos são public (e é redundante indicar)
uma classe só deriva de outra classe, e pode ter vários interfaces
várias classes podem implementar um interface

package e17;

interface Livro {
    void oLivro(int paginas);
}

interface Comic {
    void acerca(int paginas);
}

class Policial implements Livro {
    public void oLivro(int p) {
        System.out.println("\nChamada com " + p + " no Policial");
    }
    void maisInformacao() {
        System.out.println("\nOutras informacações no Policial");
    }
}

class Marvel extends Policial implements Comic{
    public void acerca(int p){
        System.out.println("\nOutras informacações na Marvel: " +p);
    }
}

public class e17 {
    public static void main(String args[]) {
        Marvel v = new Marvel();
        v.acerca(2);
        v.maisInformacao();
        
        Policial p = new Policial();
        p.oLivro(10);
        p.maisInformacao();
    }
}

Podem existir referências para um interface, é usado o mecanismo de polimorfismo, e nele podem ser referidos objetos de uma classe que o implementem, e faz uso apenas dos métodos da classe declarados na interface
se uma classe for interface, e não forem definidos todos os métodos que são abstractos, essa classe passa a ser abstracta

package e18;

interface Jogos {
    void precoJogos(int preco);
    void qualidadeJogos(int qualidade);
}

class jogoTabuleiro implements Jogos {
    public void precoJogos(int p) {
        System.out.print("\njogo de tabueliro" + p);
    }
    public void qualidadeJogos(int q) {
        System.out.print("\njogo de tabueliro" + q);
    }
}

abstract class jogoDigital implements Jogos {
    void oJogoDigital(int j) {
        System.out.print("\njogo de tabueliro" + j);
    }
}

class jogoDigitialOficial extends jogoDigital {

    public void oJogoDigital() {
        System.out.print("\njogo digital");
    }

    public void precoJogos(int preco) {
    }; //obrgatorio
    public void qualidadeJogos(int qualidade) {
    } //obrgatorio
}

public class e18 {
    public static void main(String args[]) {
        jogoDigitialOficial jd = new jogoDigitialOficial();
        jd.oJogoDigital();
    }
}

Nas interfaces podem surgir os métodos default
O default define uma implementação por omissão desse métodos, para todas as classes que implementam o interface e que não definam a sua própria implementação
Um método defualt não pode ser abstract nem static

package e19;

interface jogosDigitais {

    void contaJogadores(int n);

    default void precoAtual(int preco) {
        int conta = preco * 2;
        contaJogadores(conta); //pode fazer uso de outros métodos da interface
    }
}

class RTS implements jogosDigitais {

    private int jogadores;

    public void contaJogadores(int ct) {
        this.jogadores = ct;
    }
    
    //redefinição do métdo default
    public void precoAtual(int p){
        contaJogadores(10);
    }
    

    public String toString() {
        return "resultado " + jogadores;
    }
}

public class e19 {
    public static void main(String args[]) {
        jogosDigitais jd1 = new RTS();
        jd1.precoAtual(4);
        System.out.print(jd1);
        jd1.toString(); //nao entendo porque este método não é reproduzido
    }
}

Nas interfaces podem surgir os métodos static
um método static numa interface tem que definir uma implementação
não existe overide nas classes que implementam uma interface com métodos static
o static pode ser usado na interface, para incluir métodos utilitários

package e20;

interface Quadro {

    void ilustrar(int il);

    static void calculo(int valor) {
        valor = valor * 1;
    }
}

class corRGB implements Quadro {

    private int corRGB = 123;

    corRGB() {
        this.corRGB = corRGB;
    }

    public void ilustrar(int i) {
        this.corRGB = i * i * i;
    }

    public String toString() {
        return "do quadro surge " + corRGB;
    }
}

public class e20 {

    public static void main(String args[]) {
        Quadro q1 = new corRGB();
        q1.ilustrar(20);
        System.out.print(q1);
    }
}

Nas interfaces podem surgir constantes que são utilizadas, como utilitárias nas classes derivadas

package e21;

interface valores {
    int EURO = 2;
    int DOLAR = 1;
}

class banco implements valores {

    private int contas;

    banco() {
        this.contas = EURO + DOLAR;
    }
    public String toString() {
        return "das contas surge " + contas;
    }
}

public class e21 {

    public static void main(String args[]) {
        banco b1 = new banco();
        System.out.print(b1);
        b1.toString(); // não é executada e não compreendo do porquê!
    }
}

E também uma interface pode derivar de outras interfaces:
a interface derivada que tenha constantes com o mesmo nome da interface herdada, a que é herdade não é “escondida”
a interface derivada herda todos os métodos abstract e default
a interface derivada não herda os métodos que forem static

package e22;

interface Mae {

    int valor = 10;
    int total = -10;

    static int fala() {
        return valor * 2;
    }

    default int comida() {
        return valor * 3;
    }

    abstract int correr();
}

interface Pai {

    int valor = 20;
    int total = -20;

    static int fala() {
        return valor * 2;
    }

    default int comida() {
        return valor * 3;
    }

    abstract int correr();
}

interface Filha extends Pai, Mae {

    int comida();
}

class Neto implements Filha {

    public int comida() {
        return Mae.valor + Pai.total;
    }

    public int correr() {
        return Mae.total + Pai.valor;
    }
}

public class e22 {

    public static void main(String args[]) {
        Filha f1 = new Neto();
        System.out.println("estatico " + f1.correr()); //20
        System.out.println("estatico " + f1.comida());//-10

    }
}

Como sempre gostei de gráficos aqui fica:

+infos(fonte dos gráficos): LINK

Tags : , , ,