É grande com satisfação que posto este pequeno tutorial!
Tenho percebido, pelas estatísticas do blog, que o “Jogo da Memória em Java”, um de meus primeiros posts neste blog, é o tutorial mais acessado.
A grande maioria da galera que acessa este tutorial está buscando uma solução fácil para algum trabalho de faculdade, mas no fundo, este tutorial representou muito mais pra mim. Foi meu primeiro desafio pessoal em Java, algo que eu quis fazer para realmente me desafiar, e aprender a programar em Swing.
Agora, tenho o prazer de postar aqui o mesmo jogo, com algumas pequenas modificações funcionais, escrito na plataforma Pivot.
Sim! Apesar de ser escrito em Java, o Apache Pivot é uma plataforma RIA completa.
Não vou entrar em detalhes para explicar o código. Ao invés disso, vou disponibilizar aqui o código do jogo, e deixar o desafio de executar o jogo para aqueles que se interessarem em aprender mais sobre esta fascinante plataforma RIA.
Este jogo, apesar de pequeno, demonstra muitos dos recursos disponíveis no Pivot.
Visitem o site do projeto, e leiam os tutoriais http://pivot.apache.org/.
A versão 2.0 estará saindo em breve (tenho acompanhado a lista de desenvolvimento e de usuários, e recomendo).
Definição da interface através do arquivo memgame.wtkx:
<Window title="Pivot's Memory Game" maximized="true" xmlns:wtkx="http://pivot.apache.org/wtkx" xmlns:content="org.apache.pivot.wtk.content" xmlns="org.apache.pivot.wtk"> <content> <Border> <content> <GridPane columnCount="6" styles="{horizontalSpacing:1, verticalSpacing:1, showHorizontalGridLines:true, showVerticalGridLines:true}"> <rows> <GridPane.Row> <PushButton toggleButton="true" wtkx:id="1"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="2"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="3"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="4"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="5"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="6"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> </GridPane.Row> <GridPane.Row> <PushButton toggleButton="true" wtkx:id="7"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="8"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="9"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="10"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="11"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="12"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> </GridPane.Row> <GridPane.Row> <PushButton toggleButton="true" wtkx:id="13"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="14"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="15"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="16"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="17"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="18"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> </GridPane.Row> <GridPane.Row> <PushButton toggleButton="true" wtkx:id="19"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="20"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="21"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="22"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="23"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="24"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> </GridPane.Row> <GridPane.Row> <PushButton toggleButton="true" wtkx:id="25"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="26"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="27"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="28"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="29"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="30"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> </GridPane.Row> <GridPane.Row> <PushButton toggleButton="true" wtkx:id="31"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="32"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="33"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="34"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="35"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> <PushButton toggleButton="true" wtkx:id="36"> <buttonData> <content:ButtonData text=""/> </buttonData> </PushButton> </GridPane.Row> </rows> </GridPane> </content> </Border> </content> </Window>
Classe que manipula os componentes de tela:
package votti.pivot.memgame; import org.apache.pivot.collections.Map; import org.apache.pivot.wtk.Alert; import org.apache.pivot.wtk.Application; import org.apache.pivot.wtk.Button; import org.apache.pivot.wtk.ButtonPressListener; import org.apache.pivot.wtk.DesktopApplicationContext; import org.apache.pivot.wtk.Display; import org.apache.pivot.wtk.MessageType; import org.apache.pivot.wtk.PushButton; import org.apache.pivot.wtk.Window; import org.apache.pivot.wtkx.WTKXSerializer; import votti.pivot.memgame.component.MemGameButtonData; public class Main implements Application, ButtonPressListener { private String defaultImage = "img/default.gif"; private boolean firstClick = true; private boolean right = true; private PushButton buttonOne; private PushButton buttonTwo; private Button clickedButtonOne; private Button clickedButtonTwo; private Window window = null; private String[] images18; private String[] images36; private PushButton[] buttons; @Override public void startup(Display display, Map<String, String> properties) throws Exception { WTKXSerializer wtkxSerializer = new WTKXSerializer(); window = (Window) wtkxSerializer.readObject(this, "memgame.wtkx"); prepareImagesArray(); buttons = new PushButton[36]; for(int aux = 0; aux < 36; aux++){ buttons[aux] = (PushButton) wtkxSerializer.get(String.valueOf(aux+1)); buttons[aux].setButtonData(new MemGameButtonData(defaultImage, images36[aux])); buttons[aux].getButtonPressListeners().add(this); } window.open(display); window.setWidth(500); window.setHeight(520); } @Override public boolean shutdown(boolean optional) { if (window != null) { window.close(); } return false; } @Override public void suspend() { } @Override public void resume() { } public static void main(String[] args) { DesktopApplicationContext.main(Main.class, args); } private void prepareImagesArray(){ int posicaoNoArray, x, y; this.images18 = new String[18]; for ( x = 0; x < (18); x++ ){ this.images18[ x ] = new String("img/" + ( x + 1 ) + ".gif"); } this.images36 = new String[ (36) ]; for ( x = 0; x < 2; x++ ){ for ( y = 0; y < (18); y++ ){ do{ posicaoNoArray = ( int ) ( Math.random() * (36) ); }while( this.images36[ posicaoNoArray ] != null ); this.images36[ posicaoNoArray ] = images18[ y ]; } } } @Override public void buttonPressed(Button button) { if( firstClick ){ if ( !right ){ buttonOne = (PushButton) clickedButtonOne; buttonTwo = (PushButton) clickedButtonTwo; ((MemGameButtonData)buttonOne.getButtonData()).setDefaultURL(); ((MemGameButtonData)buttonTwo.getButtonData()).setDefaultURL(); window.repaint(); } clickedButtonOne = button; buttonOne = (PushButton) clickedButtonOne; ((MemGameButtonData)buttonOne.getButtonData()).setButtonURL(); firstClick = !firstClick; } else{ clickedButtonTwo = button; buttonTwo = (PushButton) clickedButtonTwo; if ( clickedButtonTwo == clickedButtonOne ){ right = false; Alert.alert(MessageType.WARNING, "Not permited action!", window); } else{ ((MemGameButtonData)buttonTwo.getButtonData()).setButtonURL(); if ( ((MemGameButtonData)buttonOne.getButtonData()).getButtonURL().equals( ((MemGameButtonData)buttonTwo.getButtonData()).getButtonURL())){ right = true; buttonOne.setEnabled( false ); buttonTwo.setEnabled( false ); } else{ right = false; } firstClick = !firstClick; } } } }