Infelizmente não estou conseguindo identificar onde ocorre o erro, se alguém puder ajudar
o ERRO É unfortunately MyApplication has stopped
SEGUE O CÓDIGO
CLASSE MAIN
package br.com.forca.jogos.jogodaforca;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.util.Random;
//public class Main extends AppCompatActivity {
public class Main extends ActionBarActivity {
private Button btJogar;
private Button btPlay;
private EditText etLetra;
private ForcaView forcaView;
private ForcaController forcaController;
private String[] palavra = new String[] {"alura", "caelum"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btJogar = (Button) findViewById(R.id.btJogar);
btPlay = (Button) findViewById(R.id.btPlay);
etLetra = (EditText) findViewById(R.id.etLetra);
forcaView = (ForcaView) findViewById(R.id.fvJogo);
init();
}
private void init() {
btPlay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int qntItensNoArrayPalavras = palavra.length;
int qntItem = qntItensNoArrayPalavras;
/* nota: palavra.length
retorna a quantidade de itens no array, neste caso do "arry palavra"
*/
ForcaController forcaControle;
forcaControle = new ForcaController(palavra[new Random().nextInt(qntItem)]);
/* forcaControle é uma instancia de ForcaController()
sendo que é passado "palavra[new Random().nextInt(qntItem)]"
ou seja, ...
é passado uma palavra
que esta contida em nosso array de palava
esta que será passada, é definida a passagem de forma aleatória
*/
setForcaController(forcaControle);
forcaView.setForcaController(getForcaController());
etLetra.getText().clear();
etLetra.setEnabled(true);
btJogar.setEnabled(true);
btPlay.setEnabled(false);
}
});
btJogar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (etLetra.getText().toString().trim().length()==0) {
return;
} else {
getForcaController().Joga(etLetra.getText().toString().trim().charAt(0));
forcaView.invalidate(); /* faz com que a nossa forcaview seja REDEZENHADA */
etLetra.getText().clear();
if (getForcaController().isTerminou()) {
btJogar.setEnabled(false);
btPlay.setEnabled(true);
String mensagem = "Terminou o Jogo : ";
if (getForcaController().isMorreu()) {
mensagem = mensagem + " E você PERDEU!!!";
} else {
if (getForcaController().isGanhou()) {
mensagem = "Parabéns! você GANHOU a partida.";
}
}
Toast.makeText(getApplication(), mensagem, Toast.LENGTH_LONG);
}
}
}
});
}
public ForcaController getForcaController() {
return forcaController;
}
public void setForcaController(ForcaController forcaController) {
this.forcaController = forcaController;
}
}
CLASSE FORCA VIEW
package br.com.forca.jogos.jogodaforca;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
/**
* Created by fabio on 21/01/2016.
*/
public class ForcaView extends PlanoCartesianoView {
private enum Membro {braco, perna}
private enum Lado {direito, esquerdo}
private Path pathForca; // responsavel por desenhar TODAS AS FIGURAS GEOMETRICAS
private Paint paintForca;
private ForcaController forcaController;
public ForcaView(Context context) {
super(context);
}
public ForcaView(Context context, AttributeSet attrs, Canvas canvas) {
super(context, attrs);
setPathForca(new Path()); /* criando uma Instancia de Path() */
/* passando como parãmetro para o método setPathForca(new Path()) */
// onDraw(canvas);
}
private void plotaArmacaoDaForca() {
/* base da Forca, onde: x,y são as coordenadas informadas abaixo respectivamente */
getPathForca().moveTo(toPixel(1), toPixel(10));
getPathForca().lineTo(toPixel(3), toPixel(10));
//canvas.drawPath(getPathForca(), getPaintForca());
/* Lateral da Forca, onde: x,y são as coordenadas informadas abaixo respectivamente */
getPathForca().moveTo(toPixel(2), toPixel(10));
getPathForca().lineTo(toPixel(2), toPixel(1));
/* Barra Superior da Forca, onde: x,y são as coordenadas informadas abaixo respectivamente */
getPathForca().rLineTo(toPixel(5), 0); //getPathForca().moveTo(toPixel(2), toPixel(1));
//getPathForca().lineTo(toPixel(8), toPixel(1));
/* finalizando a ESTRUTURA DA FORCA */
getPathForca().rLineTo(0, toPixel(2));
}
private void plotaCabeca() {
/* constroi a CABEÇA do boneco da forca */
getPathForca().addCircle(toPixel(7), toPixel(3), toPixel(1), Path.Direction.CW);
}
private void plotaCorpo() {
/* constroi o CORPO */
getPathForca().moveTo(toPixel(7), toPixel(4));
getPathForca().lineTo(toPixel(7), toPixel(7));
}
private void plotaMembro(Membro membro, Lado lado) {
final int posicaoDoCorpo = 7; /* posição do corpo no Eixo X */
final int alturaDoBraco = 5; /* em relação ao corpo no Eixo Y */
final int alturaDaPerna = 7; /* em relação ao corpo no Eixo Y */
int alturaFinal;
if (membro == Membro.braco) {
getPathForca().moveTo(toPixel(posicaoDoCorpo), toPixel(alturaDoBraco));
alturaFinal = alturaDoBraco + 1;
} else {
getPathForca().moveTo(toPixel(posicaoDoCorpo), toPixel(alturaDaPerna));
alturaFinal = alturaDaPerna + 1;
}
if (lado == Lado.direito) {
getPathForca().lineTo(toPixel(posicaoDoCorpo + 1), toPixel(alturaFinal));
} else {
getPathForca().lineTo(toPixel(posicaoDoCorpo - 1), toPixel(alturaFinal));
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
plotaArmacaoDaForca();
plotaCabeca();
plotaCorpo();
plotaMembro(Membro.braco, Lado.direito);
plotaMembro(Membro.braco, Lado.esquerdo);
plotaMembro(Membro.perna, Lado.direito);
plotaMembro(Membro.perna, Lado.esquerdo);
drawLetrasCorretas(canvas);
plotaTracos();
/* executa o método "Canvas", ou seja pinta os desenhos */
canvas.drawPath(getPathForca(), getPaintForca());
}
public Path getPathForca() {
return pathForca;
}
public void setPathForca(Path pathForca) {
this.pathForca = pathForca;
}
public Paint getPaintForca() {
this.paintForca = new Paint(); /* 1a Etapa - Inicializa a variavel "paintForca" */
this.paintForca.setColor(Color.BLUE);
this.paintForca.setStyle(Paint.Style.STROKE);
this.paintForca.setStrokeWidth(8);
return this.paintForca;
}
private Paint getPaintTraco() {
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.FILL);
paint.setStrokeWidth(2);
paint.setTextSize(25);
return paint;
}
private void drawLetrasCorretas (Canvas canvas) {
int eixoX = toPixel(3);
getPathForca().moveTo(eixoX + 10, toPixel(10));
eixoX += 35;
if (getForcaController()==null) { return; }
int limiteLoop = getForcaController().getPalavraAteAgora().length() -1;
for (int i=0; i<= limiteLoop; i++) {
char c = getForcaController().getPalavraAteAgora().charAt(i);
int pontX = eixoX + ((toPixel(1) + 10) * i);
int pontY = toPixel(10) - 15;
//canvas.drawText(c+"", pontX, pontY, new Paint());
canvas.drawText(c+"", pontX, pontY, getPaintTraco());
}
}
private void plotaTracos() {
int eixoX = toPixel(3);
getPathForca().moveTo(eixoX+10, toPixel(10) );
if (getForcaController()==null) { return; }
int limiteLoop = getForcaController().getPalavraAteAgora().length() -1;
for (int i=0; i<= limiteLoop; i++) {
getPathForca().rMoveTo(10,0);
getPathForca().rLineTo(toPixel(1),0);
/*
char c = getForcaController().getPalavraAteAgora().charAt(i);
int pontX = eixoX + ((toPixel(1) + 10) * i);
int pontY = toPixel(10) - 15;
//canvas.drawText(c+"", pontX, pontY, new Paint());
canvas.drawText(c+"", pontX, pontY, getPaintTraco());
*/
}
}
public ForcaController getForcaController() {
return forcaController;
}
public void setForcaController(ForcaController forcaController) {
this.forcaController = forcaController;
}
}
CLASSE PlanoCartesianoView
package br.com.forca.jogos.jogodaforca;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by fabio on 21/01/2016.
*/
public class PlanoCartesianoView extends View {
/* GUARDA A REFERÊNCIA DO MENOR LADO DO DISPLAY,
SE O MENOR FOR O VERTICAL, então vai ATRIBUIR A INFORMAÇÃO DA VERTICAL
SE O MENOR LADO FOR O HORIZONTAL, então vai ATRIBUIR o valor correspondente HORIZONTAL
*/
private int menorLadoDisplay;
private int unidade; /* receberá o valor do lado do DISPLAY menor, dividido por 10 */
/* Unidade, porque estamos trabalhando com PROPORÇÕES esta é a ideia
ou seja, unidades proporcionais da tela, quando tentar desenhar.
*/
/* --------------------------------------------------- gets e Seters */
public int getUnidade() {
return unidade;
}
public void setUnidade(int unidade) {
this.unidade = unidade;
}
public int getMenorLadoDisplay() {
return menorLadoDisplay;
}
public void setMenorLadoDisplay(int menorLadoDisplay) {
this.menorLadoDisplay = menorLadoDisplay;
}
/* --------------------------------------------------- gets e Seters */
public PlanoCartesianoView(Context context) {
super(context);
}
public PlanoCartesianoView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int Largura = getWidth(); /* em relação ao DISPLAY */
int altura = getHeight(); // DO RESPECTIVO DISPOSITIVO
if (Largura < altura) {
setMenorLadoDisplay(Largura);
} else {
setMenorLadoDisplay(altura);
}
setUnidade(getMenorLadoDisplay() / 10);
drawPlanocartesiano(canvas);
}
public void drawPlanocartesiano(Canvas canvas){
Path path = new Path();
/* a ideia é definir
todos os caminhos que desejamos desenhar, uma LINHA, RETANGULO, UM CIRCULO
SEJA O QUE FOR... (TUDO QUE DESEJAMOS DESENHAR ESTARÁ NO "path"
*/
int max = toPixel(10);
for (int n=0;n<=10;n++){
//desenhando as LINHAS VERTICAIS
path.moveTo(toPixel(n),1);
path.lineTo(toPixel(n),max);
//desenhando as LINHAS HORIZONTAIS
path.moveTo(1,toPixel(n));
path.lineTo(max,toPixel(n));
}
Paint paint = new Paint();
paint.setAntiAlias(true); // determina a suavidade das linhas
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE); // sem preenchimento INTERNO (DO DEZENHO) apenas bordas
paint.setStrokeWidth(1); // a espesura fina das linhas...
canvas.drawPath(path, paint);
}
public int toPixel(int vlrPixelPoint) {
return vlrPixelPoint * getUnidade();
}
}
CLASSE ForcaController
package br.com.forca.jogos.jogodaforca;
import java.util.HashSet;
import java.util.Set;
/**
* Created by fabio on 24/01/2016.
*/
public class ForcaController {private String palavraParaAdivinhar; // palavra que deverá ser adivinhada
private Set<Character> letrasUsadas; // Lista de Letras Digitados sem caracteres repetidos
private int qntErros = -1;
public ForcaController(String palavra) {
this.letrasUsadas = new HashSet<Character>();
this.palavraParaAdivinhar = palavra;
}
public int getQntErros() {
return qntErros;
}
public void Joga(Character letra) {
/* caso o Set já contenha letra (já foi digitada anteriormente) sair da função */
if (letrasUsadas.contains(letra)) {
return;
} else {
letrasUsadas.add(letra);
if (palavraParaAdivinhar.contains(letra.toString())) {
return;
} else {
qntErros++;
}
}
}
public String getPalavraAteAgora() {
String visualizacao = "";
/* a ideia é constuir um Loop, que vai rodar em cima do array de caracteres
onde c corresponderá ao caracter corrente em relação a "palavraParaAdivinhar"
ou seja vai variar, conforme o loop, e a palavra toda será verificada letra a letra
*/
for (char c : palavraParaAdivinhar.toCharArray()) {
if (letrasUsadas.contains(c)) {// existe a correspondente Letra na palavra
visualizacao += c;
} else {
visualizacao += "";
}
/* ou seja, recebe o valor atualizando a posição conforme a palavra
sendo acertada, recebe "C" na corrente posição ou " "
quando a letra não existe na corrente posição.
*/
}
return visualizacao;
}
public boolean isMorreu() {
return (getQntErros()==5);
}
public boolean isGanhou() {
return (getPalavraAteAgora().contains(" "));
}
public boolean isTerminou() {
return (isGanhou() || isMorreu());
}
}
E O ARQUIVO XML