Tablero de 4 en raya

Creando mi primer “objeto” con Daniel Shiffman

Quiero aprender a crear mi primera clase objeto, me refiero a los objetos de la Programación Orientada a Objetos con la ayuda del tutorial “Objects” que Daniel Shiffman publica en Processing (puedes descargarte la traducción al final). Empezamos con un ser humano y un coche (los ejemplos que usa Shiffman) y cuando lo haya aplicado a mi objeto “Ficha” para el juego de 4 en ralla, al final conseguiré el “cortador de galletas”!! .

Convertir una ficha en un cortador de galletas

Teniendo un cortador de galletas puedes cortar todas las que quieras, dice, y en eso se parece a las clases: “Las propiedades de un objeto son las variables; y las cosas que un objeto puede hacer son las funciones. La programación orientada a objetos es la unión de todos los aspectos básicos de programación: los datos y funciones.”

¿Cuáles son las propiedades y las cosa que puede hacer una ficha en el juego de 4 en ralla?

Datos
(Propiedades de la ficha)
posición en x
posición en y
color

 

Funciones
(Cosas que puede hacer)
Salir: colocarse en la posición de inicio
Moverse en horizontal para elegir una columna
Lanzarse en caída a su posición final

Método Uno, Dos y Tres

Partiendo de este análisis, lo pasa a tres grupos: Datos (o variables globales), Setup() o configuración inicial, y draw() dibujar

Datos (Variables Globales)

Configuración setup();

Dibujar draw();

color de la ficha

Inicializar el color de la ficha

rellenar en color

posición inicial en x

posición final en x

Iniciallizar la posición de inicio (x e y)

mostrar la ficha en la posición de inicio

posición inicial en y

posisción final en y

Inicializar la posición final (x e y)

Mostrar la ficha en la columna elegida

ficha x movimiento horizontal

Inicializar el movimiento horizontal: elegir columna

Mostrar la ficha cayendo

ficha x movimiento vertical

Inicializar la caída

Mostrar la ficha en la posición final

La ficha es más complicada que el coche de Shiffman, ya que tiene dos movimientos: elegir la columna y caera hasta su posición (cuál sea ésta que dependerá de las demás fichas, pero por momento tengo suficiente con resolver este objeto, así que será la primera ficha.

En este punto el código quedaría algo así:

  color c;
  float xposIni;
  float xposFin;
  float yposIni;
  float yposFin;
  float mover; 

void setup(){
  size(500,500);
}

void draw(){
    background(0);
    elijeCol();
    caer();
    display();

 void elijeCol() {
    xposFin=xposIni + mover;
    if (xposFin > width) {
       xposFin = 0;
     }
    xposIni = xposFin;
 }

 void caer() {
    yposFin = yposIni + 8 * mover; 
    yposIni = yposFin;
 }

 void display() {
    fill(c);
    noStroke();
    rectMode(CORNER);
    rect ( xposIni,  yposIni,  50,  50);
 }
}

La programación orientada a objetos permite sacar todas las variables y funciones del programa principal y almacenarlas en el objeto ficha: en vez de tener todas las variables de posición, color etc, tendremos solo una: el objeto ficha.

Las clases: Una para todas y…

En la clase Ficha quedan contenidas todas las fichas. El código de una clase forma un bloque por sí mismo, por tanto se puede poner en cualquier sitio. Todas las clases deben incluir cuatro elementos: nombre, datos, constructor y métodos

  • El nombre de la clase se especifica: class NombreEnMayúsculas. {A partir de él todo el código va encerrado entre llaves }
  • Los datos de la clase, el conjunto de variables de instancia
  • El constructor es una función especial dentro de una clase que crea la instancia del objeto mismo. Sirve para dar las instrucciones sobre cómo configurar el objeto, y se utiliza siempre que se vaya acrear un muevo objeto de esa clase. Tiene el mismo nombre que la clase y se llama invocando al nuevo operador:
    Ficha miFicha = new Ficha ();
  • Los métodos: son las funciones que añadimos al objeto

Lo que conseguimos quedaría algo así:

 Ficha miFicha;  //declaramos el objeto

 void setup() {
    size(500,500);
    miFicha = new Ficha ();  //inicializamos el objeto
 }
 void draw() {
    background(0);
    ficha.elijeCol();   //llamamos a métodos en el objeto
    ficha.caer();
    ficha.display();
 }

Al declarar el objeto usamos el tipo de la clase (de la cuales una instancia). Los objetos son tipos de datos complejos -complex data types: almacenan múltiples piezas de información: datos y funcionalidad, en cambio, las variables primitivas sólo almacenan datos. Si olvidamos inicializar una variable primitiva, Processing le asigna un valor predeterminado. Pero si olvidamos inicializar un objeto, el resultado será “NullPointerException”. Nulo. Para llamar una función dentro de un objeto se usa la sintaxis de puntos:
variableName.objectFunction(Function Arguments).

El constructor con argumentos

¿Qué pasa si quiero dos instancias diferentes, una ficha azul, y otra roja, por ejemplo?

Habrá que incluir argumentos en la declaración del objeto:
miFichaRoja = new Ficha(color(255,0,0),0,0);
miFichaAzul = new Ficha(color(0,0,255),0,50);

Y habrá que incluir esos argumentos también en el constructor:

  Ficha(color tempC,float tempXpos,float tempYpos){
    c= tempC;
    xposIni = tempXpos;
    yposIni = tempYpos;
  }

Al final el código completo me quedó así::

//variables Globales//
boolean moverIzq;
boolean moverDcha;
boolean triger; 
int contador;
int col;
int n;
Ficha miFichaRoja;   //dos objetos del tipo Ficha
Ficha miFichaAzul;

void setup(){
  size(500,500);
  n = height/10;
  contador = 64;
  moverIzq = false;
  moverDcha = false;
  triger = false; 
  //inicialización de las dos fichas con argumentos que las distinguen
  miFichaRoja = new Ficha(color(255,0,0),0,0);
  miFichaAzul = new Ficha(color(0,0,255),0,50);
}
  
void draw(){
    background(0); stroke(255);
    noFill();
    rect(50,50,400,400);
    miFichaRoja.elijeCol();
    miFichaRoja.caer();
    miFichaRoja.display();
   // miFichaAzul.elijeCol();  //todavía no sé cómo usarlas
   // miFichaAzul.caer();
   // miFichaAzul.display();
    text("contador= " + contador, 400, 480);
}
      
//la clase Ficha
   
class Ficha{
  color c;
  float xposIni;
  float xposFin;
  float yposIni;
  float yposFin;
  float mover; 
  int cuentaCol;
  int cuentaRow;
  
  //Tenemos reescribir el constructor para que incorpore esos argumentos
  Ficha(color tempC,float tempXpos,float tempYpos){
    c= tempC;
    xposIni = tempXpos;
    yposIni = tempYpos;
  }
   
  void elijeCol(){
 
     if(moverDcha == true && xposIni  n){
        xposFin = xposIni - mover;
        if(xposFin == xposIni - mover){
          moverIzq = false;
          xposIni = xposFin;
          cuentaCol = cuentaCol - 1;
        }
      }
      fill(255);
      text("columnas= "+ cuentaCol, 20, 480);   
  }
   
  void caer(){
    
     if(triger == true){
       cuentaRow = 8;
       mover = n;       
       yposFin = yposIni + cuentaRow * mover; 
       if(yposFin == yposIni + cuentaRow *  mover){
         triger = false;
         yposIni = yposFin;
         if(yposIni > 0){
           text("siguiente", 320, 480);
         } 
       }
     }
     text("fila= "+cuentaRow,100,480); 
     if(contador < 64){
       text("index="+((cuentaRow-1)*8+(cuentaCol-1)),150,480);
     }
  }
   
  void display(){
     
     fill(c);
     noStroke();
     rectMode(CORNER);
     rect(xposIni, yposIni, 50, 50);
   }
}

//el ratón 
   
void mousePressed(){
     if (mousePressed && (mouseButton == LEFT)) {
       moverIzq = true;
     }
    if (mousePressed && (mouseButton == RIGHT)) {
       moverDcha=true;
     }
    if (mousePressed && (mouseButton == CENTER)) {
       triger = true;
       contador = contador - 1;
     }
}

 

Si quieres puedes bajarte la traducción del (pdf) pulsando aquí tutorial “objects” de Daniel Shiffman y aquí puedes ver y manejar el sketch con el ratón

Advertisements