Creación de un juego 3-en-raya (tic-tac-toe, el gato) para dos jugadores locales, que permite la introducción de los nombres de los jugares y cuente con un historial de partidas jugadas.
Este video fue grabado en vivo del curso básico de desarrollo de aplicaciones Android el 2016. Algunas cosas pueden haber cambiado y/o desarrolladas de la forma más sencilla posible, aún así, es buena referencia para quienes que inician en Android y/o programación.
Aprenderás
- Crear tu primera aplicación Android en Android Studio
- Usar recursos Material Design, colores recomendados, etc.
- Crear un adaptador para un
RecyclerView
Colores
Colores para el texto
Colores usados en el vídeo:
<color name="colorPrimaryText">#DE000000</color>
<color name="colorSecondaryText">#8A000000</color>
<color name="colorDisabledText">#61000000</color>
<color name="colorPrimaryDarkText">#FFFFFF</color>
<color name="colorSecondaryDarkText">#B3FFFFFF</color>
<color name="colorDisabledDarkText">#80FFFFFF</color>
Colores del tema
Colores usados en el video:
<color name="colorPrimary">#00BCD4</color>
<color name="colorPrimaryDark">#0097A7</color>
<color name="colorAccent">#FFD740</color>
Dependencias
Minuto 0:52
Para usar componentes Material Design.
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:design:23.4.0'
compile 'com.android.support:cardview-v7:23.4.0'
compile 'com.android.support:recyclerview-v7:23.4.0'
Diseño
Minuto 1:05
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="tech.alvarez.tresenraya.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/jugador1EditText"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_weight="1"
android:hint="@string/jugador1" />
<EditText
android:id="@+id/jugador2EditText"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_weight="1"
android:hint="@string/jugador2" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal">
<Button
android:id="@+id/unoButton"
android:layout_width="80dp"
android:layout_height="80dp"
android:onClick="presionar1"
android:textSize="50sp" />
<Button
android:id="@+id/dosButton"
android:layout_width="80dp"
android:layout_height="80dp"
android:onClick="presionar2"
android:textSize="50sp" />
<Button
android:id="@+id/tresButton"
android:layout_width="80dp"
android:layout_height="80dp"
android:onClick="presionar3"
android:textSize="50sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal">
<Button
android:id="@+id/cuatroButton"
android:layout_width="80dp"
android:layout_height="80dp"
android:onClick="presionar4"
android:textSize="50sp" />
<Button
android:id="@+id/cincoButton"
android:layout_width="80dp"
android:layout_height="80dp"
android:onClick="presionar5"
android:textSize="50sp" />
<Button
android:id="@+id/seisButton"
android:layout_width="80dp"
android:layout_height="80dp"
android:onClick="presionar6"
android:textSize="50sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal">
<Button
android:id="@+id/sieteButton"
android:layout_width="80dp"
android:layout_height="80dp"
android:onClick="presionar7"
android:textSize="50sp" />
<Button
android:id="@+id/ochoButton"
android:layout_width="80dp"
android:layout_height="80dp"
android:onClick="presionar8"
android:textSize="50sp" />
<Button
android:id="@+id/nueveButton"
android:layout_width="80dp"
android:layout_height="80dp"
android:onClick="presionar9"
android:textSize="50sp" />
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/historialRecyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
Si bien se podría usar otros componentes como
GridView
en lugar de variosLinearLayout
s.
Activity
Minuto 5:09
Referencias
private EditText jugador1EdiText;
private EditText jugador2EdiText;
private Button unoButton;
private Button dosButton;
private Button tresButton;
private Button cuatroButton;
private Button cincoButton;
private Button seisButton;
private Button sieteButton;
private Button ochoButton;
private Button nueveButton;
private RecyclerView historialRecyclerView;
onCreate()
jugador1EdiText = (EditText) findViewById(R.id.jugador1EditText);
jugador2EdiText = (EditText) findViewById(R.id.jugador2EditText);
unoButton = (Button) findViewById(R.id.unoButton);
dosButton = (Button) findViewById(R.id.dosButton);
tresButton = (Button) findViewById(R.id.tresButton);
cuatroButton = (Button) findViewById(R.id.cuatroButton);
cincoButton = (Button) findViewById(R.id.cincoButton);
seisButton = (Button) findViewById(R.id.seisButton);
sieteButton = (Button) findViewById(R.id.sieteButton);
ochoButton = (Button) findViewById(R.id.ochoButton);
nueveButton = (Button) findViewById(R.id.nueveButton);
historialRecyclerView = (RecyclerView) findViewById(R.id.historialRecyclerView);
onClick para los botones
La acción para los botones se generan automáticamente presionando Alt+Enter
y escoger la generación del método.
Acciones
Minuto 8:21
Variable global para detectar si toca X
private boolean tocaX = true;
Método de un botón
if (unoButton.getText().toString().equals("")) {
if (tocaX) {
unoButton.setText("X");
} else {
unoButton.setText("O");
}
tocaX = !tocaX;
}
Método gano
Minuto 10:53
public boolean gano(String simbolo) {
boolean siHayGanador = false;
if (unoButton.getText().equals(simbolo) && dosButton.getText().equals(simbolo) && tresButton.getText().equals(simbolo)) {
siHayGanador = true;
}
if (unoButton.getText().equals(simbolo) && cuatroButton.getText().equals(simbolo) && sieteButton.getText().equals(simbolo)) {
siHayGanador = true;
}
if (unoButton.getText().equals(simbolo) && cincoButton.getText().equals(simbolo) && nueveButton.getText().equals(simbolo)) {
siHayGanador = true;
}
if (cuatroButton.getText().equals(simbolo) && cincoButton.getText().equals(simbolo) && seisButton.getText().equals(simbolo)) {
siHayGanador = true;
}
if (tresButton.getText().equals(simbolo) && seisButton.getText().equals(simbolo) && nueveButton.getText().equals(simbolo)) {
siHayGanador = true;
}
if (sieteButton.getText().equals(simbolo) && ochoButton.getText().equals(simbolo) && nueveButton.getText().equals(simbolo)) {
siHayGanador = true;
}
if (tresButton.getText().equals(simbolo) && cincoButton.getText().equals(simbolo) && sieteButton.getText().equals(simbolo)) {
siHayGanador = true;
}
if (dosButton.getText().equals(simbolo) && cincoButton.getText().equals(simbolo) && ochoButton.getText().equals(simbolo)) {
siHayGanador = true;
}
return siHayGanador;
}
Verificar si ganó
Minuto 13:30
Método verificarSiGano
public void verificarSiGano(String simbolo) {
if (gano(simbolo)) {
Toast.makeText(getApplicationContext(), "Gano " + simbolo + "!!!", Toast.LENGTH_SHORT).show();
String nombreJugador1 = jugador1EdiText.getText().toString();
String nombreJugador2 = jugador2EdiText.getText().toString();
int quienGano = 0;
if (simbolo == "X") {
quienGano = 1;
}
if (simbolo == "O") {
quienGano = 2;
}
Date fechaActual = Calendar.getInstance().getTime();
Partida partida = new Partida(nombreJugador1, nombreJugador2, quienGano, fechaActual);
partidasAdapter.add(partida);
limpiar();
}
}
Adapter
Minuto 14:52
Clase Partida
public class Partida {
private String nombreJugador1;
private String nombreJugador2;
private int quienGano;
private Date fecha;
// lo demás se genera con Android Studio
}
Adapter
public class PartidasAdapter extends RecyclerView.Adapter<PartidasAdapter.ViewHolder> {
private ArrayList<Partida> dataset;
public PartidasAdapter() {
dataset = new ArrayList<>();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_partida, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Partida partida = dataset.get(position);
if (partida.getQuienGano() == 1) {
holder.tituloTextView.setText(partida.getNombreJugador1());
} else {
holder.tituloTextView.setText(partida.getNombreJugador2());
}
holder.subtituloTextView.setText(darFormato(partida.getFecha()));
}
@Override
public int getItemCount() {
return dataset.size();
}
public static String darFormato(Date date) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("ddMMMyyyy hh:mm");
return simpleDateFormat.format(date).toUpperCase();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView tituloTextView;
TextView subtituloTextView;
public ViewHolder(View itemView) {
super(itemView);
tituloTextView = (TextView) itemView.findViewById(R.id.tituloTextView);
subtituloTextView = (TextView) itemView.findViewById(R.id.subtituloTextView);
}
}
public void add(Partida partida) {
dataset.add(partida);
notifyDataSetChanged();
}
public void clear() {
dataset.clear();
notifyDataSetChanged();
}
}
Diseño Item Partida
Minuto 16:10
item_partida.xml
Aún se deben adicionar los IDs.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="72dp"
android:orientation="horizontal"
android:paddingBottom="8dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="8dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:src="@mipmap/ic_launcher" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingLeft="32dp"
android:paddingRight="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textColor="@color/colorPrimaryText"
android:textSize="16sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textColor="@color/colorSecondaryText"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
Formato para fechas
Minuto 17:39
Obtener fecha actual
Date fechaActual = Calendar.getInstance().getTime();
Dar formato a una fecha
public static String darFormato(Date date) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("ddMMMyyyy hh:mm");
return simpleDateFormat.format(date).toUpperCase();
}
Limpiar
Minuto 19:52
Método limpiar
private void limpiar() {
unoButton.setText("");
dosButton.setText("");
tresButton.setText("");
cuatroButton.setText("");
cincoButton.setText("");
seisButton.setText("");
sieteButton.setText("");
ochoButton.setText("");
nueveButton.setText("");
}
También puede usarse
setText(null)
Código
Código completo de la aplicación: