/*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Copyright 2015 Jose A. Gonzalez Cervera
Copyright 2015 Juan A. Fernández Sánchez
*/
package butterflydevs.brainstudio;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Intent;
import android.graphics.Color;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.facebook.AppEventsLogger;
import com.github.premnirmal.textcounter.CounterView;
import com.github.premnirmal.textcounter.Formatter;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import butterflydevs.brainstudio.extras.Dialogos.DialogoSalidaJuegos;
import butterflydevs.brainstudio.extras.Jugada;
import butterflydevs.brainstudio.extras.MySQLiteHelper;
import butterflydevs.brainstudio.extras.matrixHelper;
import butterflydevs.brainstudio.extras.utilidades;
/**
* Puede funcionar de dos maneras, tendrems que elegir una:
* A: el vector crece indefinidamente mientras el jugador pueda ser capaz de seguirlo. Calcular aquí el porcentaje de juego superado
* es entonces imposible porque el juego no tiene fin.
* B: el vector tiene un tamaño definido, como 30 elementos, así dependiendo cuantos elementos haya sido cacaz de recordar el jugador
* podremos calcular el porcenjate pasado del juego.
*
* En principio vamos a optar por la opción B.
*
*/
public class Juego3niveln extends ActionBarActivity {
//Botones del juego
static Boton []botones;
//Colores base
static String[] coloresBase;
//Colores enfasis
static String[] coloresEnfasis;
//Variables necesarias para construir el grid de forma dinámica:
//Para referenciar el layout grande donde van todos los layout que componen las filas
private LinearLayout layoutGridBotones;
//Filas del grid de botones:
private LinearLayout[] filasLinearLayout; //Cada fila de botones es un linearLayout
private int numFilas;
private int numColumnas;
private int tamButtons;
private int maxRandom;
private Button buttonBack, buttonHelp;
private int pos=0;
Thread background;
Animation animacion;
List<Integer> secuencia = new ArrayList();
List<Integer> secuenciaJugador = new ArrayList();
private CounterView counterView;
private int puntos=0;
private int level;
public Juego3niveln(){
}
public void inicializarHebra(){
// new prueba().execute();
background = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1500);
for (int i = 0; i <= secuencia.size(); i++) {
Message message = handler.obtainMessage();
message.what = 1;
// Thread.sleep(1000);
handler.sendMessage(message);
Thread.sleep(600);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg){
//Recibimos un mensaje desde la hebra del tiempo:
// System.out.println("yeah"+msg.what);
secuencia();
}
};
//SEcuencia tiene que recorrer toda la secuencia de botones sin tener nada más a su disposicion que una llamada.
public void secuencia(){
if(pos!=secuencia.size()) {
//botones[pos].setBackgroundColor(Color.YELLOW);
coloreaElegido( secuencia.get(pos) );
pos++;
//Al final se apagan todos los botones.
}else{
resetearBotones();
}
}
public void coloreaElegido(int elegido){
for(int i=0; i<botones.length; i++)
if(i==elegido) {
botones[i].boton.setBackgroundColor(botones[i].colorEnfasis);
botones[i].boton.startAnimation(animacion);
}
// else
// botones[i].setBackgroundColor(Color.DKGRAY);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_juego3niveln);
//Con esta orden conseguimos hacer que no se muestre la ActionBar.
getSupportActionBar().hide();
//Con esta hacemos que la barra de estado del teléfono no se vea y la actividad sea a pantalla completa.
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
//1º Asociación de los elementos del layout a variables para su contol.
asociarElementosVista();
//Cargar los colores que vamos a usar:
coloresBase = getResources().getStringArray(R.array.colores_base);
coloresEnfasis = getResources().getStringArray(R.array.colores_enfasis);
//2º Obtenemos los datos que se le pasa a la actividad.
Intent intent=getIntent();
//Obtenemos la información del intent que nos evía la actividad que nos crea.
level=intent.getIntExtra("nivel",0);
System.out.println("recibiod de la actividad llamante: "+level);
// 2.1 Ajustamos el nivel mediante la modificación de algunas variables que luego serviarán para la configuración del resto.
ajustarNivel(level);
//3º Configuramos los listener de los botones estáticos del layout:
buttonBack.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
//Creamos el Intent
Intent intent = new Intent(Juego3niveln.this, Juego3.class);
//Iniciamos la nueva actividad
startActivity(intent);
}
}
);
buttonHelp.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
//Creamos el Intent
Intent intent = new Intent(Juego3niveln.this, Help.class);
Bundle bundle = new Bundle();
bundle.putString("Zona_llamada","Juego");
bundle.putInt("Numero_zona", 3);
//Introducimos la informacion en el intent para enviarsela a la actívity.
intent.putExtras(bundle);
startActivityForResult(intent, 1);
}
}
);
//4º Cargamos las animaciones
animacion = AnimationUtils.loadAnimation(this, R.anim.animacionboton_juego_memo);
animacion.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
// System.out.println("La animación empieza");
}
@Override
public void onAnimationEnd(Animation animation) {
resetearBotones();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
utilidades.cargarColorFondo(this);
}
public void resetearBotones(){
for(int i=0; i<botones.length; i++)
botones[i].boton.setBackgroundColor(botones[i].color);
}
/**
* Función de ajuste de nivel del juego. Es la más importante pués según configure las variables se configurará después
* el aspecto y jugabilidad de todas los grids que se vayan creando. Tambien afecta a la fomra en la que se calcula
* el porcentaje completado del juego.
* @param level
*/
public void ajustarNivel(int level){
//1º Ajuste de las variables:
//Ajustes para el nivel 1
if(level==1){
Toast.makeText(this, "Level1", Toast.LENGTH_SHORT).show();
//1º Establecemos el tamaño del grid:
numFilas=2;
numColumnas=1;
//2º Establecemos el tamaño de los botones:
tamButtons=300;
maxRandom=numFilas*numColumnas;
}else
//Ajustes para el nivel 2
if(level==2){
Toast.makeText(this, "Level2", Toast.LENGTH_SHORT).show();
numFilas=2;
numColumnas=2;
tamButtons=200;
maxRandom=numFilas*numColumnas;
}else
//Ajustes para el nivel 3
if(level==3){
Toast.makeText(this, "Level3", Toast.LENGTH_SHORT).show();
numFilas=3;
numColumnas=2;
tamButtons=150;
maxRandom=numFilas*numColumnas;
}
//2º Inicialización de los elementos:
//2.1 BOTONES
//Inicializamos el vector de botones a un número de botones determinado dependiendo del nivel en el que estemos.
botones = new Boton[numFilas * numColumnas];
//Inicializamos los botones
for (int i = 0; i < botones.length; i++) {
//Inicializamos los objetos.
botones[i] = new Boton();
//Inicializamos cada uno de los elementos del vector
botones[i].boton = new Button(this);
//Establecemos parametros de layout a cada uno:
botones[i].boton.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(tamButtons, tamButtons);
params.setMargins(20, 20, 5, 5);
botones[i].boton.setLayoutParams(params);
// botones[i].boton.setBackgroundColor(getResources().getColor(Color.parseColor(coloresBase[i])));
//Inicializamos los colores de los botones:
//Ahora mismo solo para dos botones:
botones[i].color=Color.parseColor(coloresBase[i]);
botones[i].colorEnfasis=Color.parseColor(coloresEnfasis[i]);
botones[i].boton.setBackgroundColor(botones[i].color);
}
//Asociamos a cada boton un listener.
for (int i = 0; i<botones.length; i++) {
System.out.println("Boton: " + i);
botones[i].boton.setOnClickListener(new MyListener(i));
}
//2.2 LAYOUTS
//Inicializamos el vector de filas (vector de layouts)
filasLinearLayout = new LinearLayout[numFilas];
//Inicializamos los LinearLayout (filas)
for (int i = 0; i < numFilas; i++) {
filasLinearLayout[i] = new LinearLayout(this);
filasLinearLayout[i].setOrientation(LinearLayout.HORIZONTAL);
filasLinearLayout[i].setGravity(Gravity.CENTER);
}
//Añadimos todos los layout de filas al layout principal
for (int i = 0; i < numFilas; i++)
layoutGridBotones.addView(filasLinearLayout[i]);
//3º Asociación de los elementos:
//Añadimos los botones a los layouts.
int numBoton = 0;
for (int i = 0; i < numFilas; i++) //i sera el numero de fila
for (int j = 0; j < numColumnas; j++) {
filasLinearLayout[i].addView(botones[numBoton].boton);
numBoton++;
}
}
@Override
protected void onStart(){
super.onStart();
System.out.println("random entre 0 y "+(maxRandom-1));
//Añadimos el primer elemento:
secuencia.add(randInt(0,maxRandom-1));
//Mostramos la secuencia por consola:
for(int a: secuencia)
System.out.print(a+" ");
System.out.println(" ");
//Inicializamos la hebra:
inicializarHebra();
//Arrancamos la hebra:
background.start();
}
public void asociarElementosVista(){
System.out.println("Asociando elementos de la vista");
//Los botones del menu inferior
buttonBack = (Button) findViewById(R.id.botonBack);
buttonHelp = (Button) findViewById(R.id.botonHelp);
//Asociamos el layout principal
layoutGridBotones = (LinearLayout) findViewById(R.id.gridBotones);
//Le especificamos una horientación
layoutGridBotones.setOrientation(LinearLayout.VERTICAL);
//CounterView es el texto de puntos que va aumentando
counterView=(CounterView)findViewById(R.id.counter);
counterView.setAutoFormat(false);
counterView.setFormatter(new Formatter() {
@Override
public String format(String prefix, String suffix, float value) {
return prefix + NumberFormat.getNumberInstance(Locale.US).format(value) + suffix;
}
});
counterView.setAutoStart(false);
counterView.setStartValue(0);
counterView.setEndValue(0);
counterView.setIncrement(1f); // the amount the number increments at each time interval
counterView.setTimeInterval(2); // the time interval (ms) at which the text changes
counterView.setPrefix("");
counterView.setSuffix("");
counterView.start();
}
public boolean secuenciaCorrecta(){
boolean salida=true;
//Imprimimos la secuencia del juego:
System.out.println("Secuencia del juego:");
for(int a: secuencia)
System.out.print(a + " ");
System.out.println("");
//Imprimimos la secuencia del juego:
System.out.println("Secuencia del usuario:");
for(int a: secuenciaJugador)
System.out.print(a+" ");
System.out.println("");
for(int i=0; i<secuenciaJugador.size(); i++) {
if (secuenciaJugador.get(i) != secuencia.get(i))
return false;
}
if(secuenciaJugador.size()==secuencia.size()) {
avance();
//Reiniciamos la secuencia del Jugador
secuenciaJugador.clear();
//Acemos que vibre:
Vibrator v = (Vibrator) getSystemService(getApplicationContext().VIBRATOR_SERVICE);
counterView.setStartValue(puntos);
puntos=secuencia.size()*level*10;
counterView.setPrefix("");
counterView.setSuffix("");
counterView.setEndValue(puntos);
counterView.start();
// Vibrar durante 3 segundos
v.vibrate(200);
}
return salida;
}
public void avance(){
System.out.println("Avance");
secuencia.add(randInt(0,maxRandom-1));
reiniciaSecuencia();
}
public static int randInt(int min, int max) {
// NOTE: Usually this should be a field rather than a method
// variable so that it is not re-seeded every call.
Random rand = new Random();
// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
public void finPartida(){
//Informamos de ello:
DialogoSalidaJuegos dialogoFinJuego = new DialogoSalidaJuegos();
dialogoFinJuego.setComportamientoBoton(DialogoSalidaJuegos.ComportamientoBoton.SALIR);
dialogoFinJuego.setNivel(3);
dialogoFinJuego.setDatos(" Oups! ",secuencia, secuenciaJugador, calculaPorcentaje(), puntos);
//Mostramos el diálogo
dialogoFinJuego.show(getFragmentManager(), "");
//Grabar datos de partida!
MySQLiteHelper db = new MySQLiteHelper(this);
db.addJugada(new Jugada(puntos, calculaPorcentaje()), level, 3);
}
public int calculaPorcentaje(){
int resultado=0;
if(level==1){
//Una regla de tres simple
resultado=(int)(100*secuencia.size())/20;
}
if(level==2){
//Una regla de tres simple
resultado=(int)(100*secuencia.size())/40;
}
if(level==3){
//Una regla de tres simple
resultado=(int)(100*secuencia.size())/60;
}
return resultado;
}
/**
* Función que informa que has concluido el juego.
*/
public void finJuego(){
//Informamos de ello:
DialogoSalidaJuegos dialogoFinJuego = new DialogoSalidaJuegos();
dialogoFinJuego.setComportamientoBoton(DialogoSalidaJuegos.ComportamientoBoton.SALIR);
dialogoFinJuego.setNivel(3);
dialogoFinJuego.setDatos(" ¡ FIN ! ",secuencia, secuenciaJugador, calculaPorcentaje(), puntos);
//Mostramos el diálogo
dialogoFinJuego.show(getFragmentManager(), "");
//Grabar datos de partida!
MySQLiteHelper db = new MySQLiteHelper(this);
db.addJugada(new Jugada(puntos, calculaPorcentaje()), level, 3);
}
public void reiniciaSecuencia(){
pos = 0;
background = null;
inicializarHebra();
background.start();
}
/**
* Clase propia boton.
* Simplifica la abstracción del concepto de boton junto a sus colores.
*/
class Boton{
public Button boton;
public int color;
public int colorEnfasis;
};
class MyListener implements Button.OnClickListener {
private int numBoton;
public MyListener(int numBoton) {
this.numBoton = numBoton;
}
@Override
public void onClick(View v) {
botones[numBoton].boton.setBackgroundColor(botones[numBoton].colorEnfasis);
botones[numBoton].boton.startAnimation(animacion);
secuenciaJugador.add(numBoton);
if(secuenciaCorrecta())
System.out.println("Correcto");
else
finPartida();
}
}
@Override
protected void onPause() {
super.onPause();
// Logs 'app deactivate' App Event.
AppEventsLogger.deactivateApp(this);
}
}