sábado, 15 de octubre de 2016

Capítulo 77. Programando mi primer video juego en Small Basic Parte 3

Continuación del capítulo anterior...

Para ubicar el centro de la casilla, simplemente dividí a la mitad la distancia entre un rango y otro. O sea, entre 80 y 150 nos separan 70 pixeles... y la mitad es 35 y así empecé a jugar con los valores.
Lo siguiente a realizar, es hallar los rangos para todas las demás casillas conjuntamente con su centro.
Una vez finalizado, esto debería quedar más o menos así:

Sub FiguraX
  GraphicsWindow.PenColor = "Blue"
  gmX = GraphicsWindow.MouseX
  gmY = GraphicsWindow.MouseY
 
  'ubicacion 1,1
  If gmX >= 85 And gmX <= 145 And gmY >= 65 And gmY <= 105 Then
      GraphicsWindow.DrawLine(100,70,130,100)
      GraphicsWindow.DrawLine(100,100,130,70)
  EndIf
 'ubicacion 1,2
  If gmX >= 155 And gmX <= 215 And gmY >= 65 And gmY <= 105 Then
      GraphicsWindow.DrawLine(170,70,200,100)
      GraphicsWindow.DrawLine(170,100,200,70)
  EndIf
 
  'ubicacion 1,3
  If gmX >= 225 And gmX <= 285 And gmY >= 65 And gmY <= 105 Then
      GraphicsWindow.DrawLine(240,70,270,100)
      GraphicsWindow.DrawLine(240,100,270,70)
  EndIf
 
  'ubicacion 2,1
  If gmX >= 85 And gmX <= 145 And gmY >= 115 And gmY <= 165 Then
      GraphicsWindow.DrawLine(100,125,130,155)
      GraphicsWindow.DrawLine(100,155,130,125)
  EndIf 
 
  'ubicacion 2,2
  If gmX >= 155 And gmX <= 215 And gmY >= 115 And gmY <= 165 Then
      GraphicsWindow.DrawLine(170,125,200,155)
      GraphicsWindow.DrawLine(170,155,200,125)
  EndIf

  'ubicacion 2,3
  If gmX >= 225 And gmX <= 285 And gmY >= 115 And gmY <= 165 Then
      GraphicsWindow.DrawLine(240,125,270,155)
      GraphicsWindow.DrawLine(240,155,270,125)
  EndIf
 
  'ubicacion 3,1
  If gmX >= 85 And gmX <= 145 And gmY >= 175 And gmY <= 215 Then
      GraphicsWindow.DrawLine(100,180,130,210)
      GraphicsWindow.DrawLine(100,210,130,180)
  EndIf
 
  'ubicacion 3,2
  If gmX >= 155 And gmX <= 215 And gmY >= 175 And gmY <= 215 Then
      GraphicsWindow.DrawLine(170,180,200,210)
      GraphicsWindow.DrawLine(170,210,200,180)
  EndIf 
 
  'ubicacion 3,3
  If gmX >= 225 And gmX <= 285 And gmY >= 175 And gmY <= 215 Then
      GraphicsWindow.DrawLine(240,180,270,210)
      GraphicsWindow.DrawLine(240,210,270,180)
  EndIf     
EndSub


Si se ejecuta el programa, se podrá ver que todas las X funcionan solamente dentro del rango establecido, además de quedar centradas (o casi, pero al menos se ven ordenadas).


Ahora hacer lo mismo con las figuras O
Para ello, también es necesario modificar la subrutina figuraO, tal como se hizo con la subrutina figuraX.
Entonces, esto debería quedar más o menos así:

Sub FiguraO
 GraphicsWindow.PenColor  = "Red"
  gwX = GraphicsWindow.MouseX
  gwY = GraphicsWindow.MouseY

  'ubicacion 1,1
  If gwX >= 85 And gwX <= 145 And gwY >= 65 And gwY <= 105 Then
      GraphicsWindow.DrawEllipse(100,70,30,30)
  EndIf
 
  'ubicacion 1,2
  If gwX >= 155 And gwX <= 215 And gwY >= 65 And gwY <= 105 Then
      GraphicsWindow.DrawEllipse(170,70,30,30)
  EndIf
 
  'ubicacion 1,3
  If gwX >= 225 And gwX <= 285 And gwY >= 65 And gwY <= 105 Then
      GraphicsWindow.DrawEllipse(240,70,30,30)
  EndIf
 
  'ubicacion 2,1
  If gwX >= 85 And gwX <= 145 And gwY >= 115 And gwY <= 165 Then
      GraphicsWindow.DrawEllipse(100,125,30,30)
  EndIf
 
  'ubicacion 2,2
  If gwX >= 155 And gwX <= 215 And gwY >= 115 And gwY <= 165 Then
      GraphicsWindow.DrawEllipse(170,125,30,30)
  EndIf
 
  'ubicacion 2,3
  If gwX >= 225 And gwX <= 285 And gwY >= 115 And gwY <= 165 Then
      GraphicsWindow.DrawEllipse(240,125,30,30)
  EndIf
 
  'ubicacion 3,1
  If gwX >= 85 And gwX <= 145 And gwY >= 175 And gwY <= 215 Then
      GraphicsWindow.DrawEllipse(100,180,30,30)
  EndIf
 
  'ubicacion 3,2
  If gwX >= 155 And gwX <= 215 And gwY >= 175 And gwY <= 215 Then
      GraphicsWindow.DrawEllipse(170,180,30,30)
  EndIf
 
  'ubicacion 3,3
  If gwX >= 225 And gwX <= 285 And gwY >= 175 And gwY <= 215 Then
      GraphicsWindow.DrawEllipse(240,180,30,30)
  EndIf
EndSub

Al ejecutar el código podemos comprobar que tanto las figuras X como las figuras O se dibujan dentro del área de juego


Al parecer está bien, pero existen varios problemas. El primero, es que nada impide que una casilla pueda volver a ser seleccionada o sobre escrita.


El otro error que encontré rápidamente es que si se hace clic fuera del área de juego, la variable “interruptor” cambiaba de valor, ocasionando que un jugador se saltara o perdiera su turno


Para solucionar el primer error y de paso el segundo, lo que se me ocurre es crear algún tipo de “marca” o registro cuando una casilla sea seleccionada. Así, si el jugador intenta seleccionar una casilla que ya se encuentra ocupada o “marcada”, no se imprima ninguna figura. Para esto, voy a ocupar la matriz de 3 x 3, que había creado al principio
  'Matriz de 3 x 3 de ceros
  'X = 1
  'O = 9

  '11  12   13
  '21  22   23
  '31  32   33

  For fila = 1 To 3
    For columna = 1 To 3
      matriz[fila][columna] = 0
    EndFor
  EndFor

Para crear la marca o registro, hay que añadir la siguiente condición:

  If gmX >= 85 And gmX <= 145 And gmY >= 65 And gmY <= 105 Then
    If matriz[1][1] = 0 Then
      GraphicsWindow.DrawLine(100,70,130,100)
      GraphicsWindow.DrawLine(100,100,130,70)
      matriz[1][1] = 1
    EndIf
  EndIf

Esta condición nos dice que si una casilla tiene un valor de cero, entonces está disponible y se puede dibujar una figura. Luego se cambia el valor por 1 para así hacerla inaccesible. De esta forma las figuras no se dibujarán una sobre otra. Lo que hay que hacer ahora es repetir el proceso con todas las demás, o sea, rellenar de condiciones tanto la subrutina figuraX, como la subrutina figuraO. Recordar que en la subrutina figuraO, la matriz debe ser cambiada por un 9, siguiendo el esquema anterior:
  'Matriz de 3 x 3 de ceros
  'X = 1
  'O = 9

  '11  12   13
  '21  22   23
  '31  32   33

Una vez finalizado el proceso, esto se debería ver más o menos así:

Sub FiguraX
  GraphicsWindow.PenColor = "Blue"
  gmX = GraphicsWindow.MouseX
  gmY = GraphicsWindow.MouseY
 
  'ubicacion 1,1
  If gmX >= 85 And gmX <= 145 And gmY >= 65 And gmY <= 105 Then
    If matriz[1][1] = 0 Then
      GraphicsWindow.DrawLine(100,70,130,100)
      GraphicsWindow.DrawLine(100,100,130,70)
      matriz[1][1] = 1
    EndIf
  EndIf
 'ubicacion 1,2
 If gmX >= 155 And gmX <= 215 And gmY >= 65 And gmY <= 105 Then
   If matriz[1][2] = 0 Then
      GraphicsWindow.DrawLine(170,70,200,100)
      GraphicsWindow.DrawLine(170,100,200,70)
      matriz[1][2] = 1
      EndIf
  EndIf
 
  'ubicacion 1,3
  If gmX >= 225 And gmX <= 285 And gmY >= 65 And gmY <= 105 Then
    If matriz[1][3] = 0 Then
      GraphicsWindow.DrawLine(240,70,270,100)
      GraphicsWindow.DrawLine(240,100,270,70)
      matriz[1][3] = 1
      EndIf
  EndIf
 
  'ubicacion 2,1
  If gmX >= 85 And gmX <= 145 And gmY >= 115 And gmY <= 165 Then
    If matriz[2][1] = 0 Then
      GraphicsWindow.DrawLine(100,125,130,155)
      GraphicsWindow.DrawLine(100,155,130,125)
      matriz[2][1] = 1
      EndIf
  EndIf 
 
  'ubicacion 2,2
  If gmX >= 155 And gmX <= 215 And gmY >= 115 And gmY <= 165 Then
    If matriz[2][2] = 0 Then
      GraphicsWindow.DrawLine(170,125,200,155)
      GraphicsWindow.DrawLine(170,155,200,125)
      matriz[2][2] = 1
      EndIf
  EndIf

  'ubicacion 2,3
  If gmX >= 225 And gmX <= 285 And gmY >= 115 And gmY <= 165 Then
    If matriz[2][3] = 0 Then
      GraphicsWindow.DrawLine(240,125,270,155)
      GraphicsWindow.DrawLine(240,155,270,125)
      matriz[2][3] = 1
      EndIf
  EndIf
 
  'ubicacion 3,1
  If gmX >= 85 And gmX <= 145 And gmY >= 175 And gmY <= 215 Then
    If matriz[3][1] = 0 Then
      GraphicsWindow.DrawLine(100,180,130,210)
      GraphicsWindow.DrawLine(100,210,130,180)
      matriz[3][1] = 1
      EndIf
  EndIf
 
  'ubicacion 3,2
  If gmX >= 155 And gmX <= 215 And gmY >= 175 And gmY <= 215 Then
    If matriz[3][2] = 0 Then
      GraphicsWindow.DrawLine(170,180,200,210)
      GraphicsWindow.DrawLine(170,210,200,180)
      matriz[3][2] = 1
      EndIf
  EndIf 
 
  'ubicacion 3,3
  If gmX >= 225 And gmX <= 285 And gmY >= 175 And gmY <= 215 Then
    If matriz[3][3] = 0 Then
      GraphicsWindow.DrawLine(240,180,270,210)
      GraphicsWindow.DrawLine(240,210,270,180)
      matriz[3][3] = 1
      EndIf
  EndIf     
EndSub

Sub FiguraO
 GraphicsWindow.PenColor  = "Red"
  gwX = GraphicsWindow.MouseX
  gwY = GraphicsWindow.MouseY

  'ubicacion 1,1
  If gwX >= 85 And gwX <= 145 And gwY >= 65 And gwY <= 105 Then
    If matriz[1][1] = 0 Then
      GraphicsWindow.DrawEllipse(100,70,30,30)
      matriz[1][1] = 9
    EndIf
  EndIf
 
  'ubicacion 1,2
  If gwX >= 155 And gwX <= 215 And gwY >= 65 And gwY <= 105 Then
    If matriz[1][2] = 0 Then
      GraphicsWindow.DrawEllipse(170,70,30,30)
      matriz[1][2] = 9
    EndIf
  EndIf
 
  'ubicacion 1,3
  If gwX >= 225 And gwX <= 285 And gwY >= 65 And gwY <= 105 Then
    If matriz[1][3] = 0 Then
      GraphicsWindow.DrawEllipse(240,70,30,30)
      matriz[1][3] = 9
    EndIf
  EndIf
 
  'ubicacion 2,1
  If gwX >= 85 And gwX <= 145 And gwY >= 115 And gwY <= 165 Then
    If matriz[2][1] = 0 Then
      GraphicsWindow.DrawEllipse(100,125,30,30)
      matriz[2][1] = 9
    EndIf
  EndIf
 
  'ubicacion 2,2
  If gwX >= 155 And gwX <= 215 And gwY >= 115 And gwY <= 165 Then
    If matriz[2][2] = 0 Then
      GraphicsWindow.DrawEllipse(170,125,30,30)
      matriz[2][2] = 9
    EndIf
  EndIf
 
  'ubicacion 2,3
  If gwX >= 225 And gwX <= 285 And gwY >= 115 And gwY <= 165 Then
    If matriz[2][3] = 0 Then
      GraphicsWindow.DrawEllipse(240,125,30,30)
      matriz[2][3] = 9
    EndIf
  EndIf
 
  'ubicacion 3,1
  If gwX >= 85 And gwX <= 145 And gwY >= 175 And gwY <= 215 Then
    If matriz[3][1] = 0 Then
      GraphicsWindow.DrawEllipse(100,180,30,30)
      matriz[3][1] = 9
    EndIf
  EndIf
 
  'ubicacion 3,2
  If gwX >= 155 And gwX <= 215 And gwY >= 175 And gwY <= 215 Then
    If matriz[3][2] = 0 Then
      GraphicsWindow.DrawEllipse(170,180,30,30)
      matriz[3][2] = 9
    EndIf
  EndIf
 
  'ubicacion 3,3
  If gwX >= 225 And gwX <= 285 And gwY >= 175 And gwY <= 215 Then
    If matriz[3][3] = 0 Then
      GraphicsWindow.DrawEllipse(240,180,30,30)
      matriz[3][3] = 9
    EndIf
  EndIf
EndSub

Al ejecutar el programa se puede apreciar de que las figuras ya no se dibujan unas sobre otras. Con esto solucionamos el primer problema. Ahora el segundo problema era que la variable “interruptor” se seguía actualizando incluso al hacer clic fuera del área de juego. Como solución se me ocurrió crear una subrutina que mantuviese la variable “interruptor” y llamarla desde la subrutina figuraX o figuraO, de esta forma, solo se actualizará si una figura es generada. Entonces, creamos la subrutina a la cual llamaré “inter”

Sub inter
  interruptor = interruptor + 1
EndSub

Se hace presente que debido a que se trabajará la variable interruptor desde una subrutina independiente, hay que borrar la variable interruptor que se encuentra en la subrutina clicX, ya que no la vamos a ocupar.


Ahora, lo que queda entonces es llamar desde las subrutinas figuraX y figuraO a la subrutina inter, para que actualice su valor

  'ubicacion 1,1
  If gmX >= 85 And gmX <= 145 And gmY >= 65 And gmY <= 105 Then
    If matriz[1][1] = 0 Then
      GraphicsWindow.DrawLine(100,70,130,100)
      GraphicsWindow.DrawLine(100,100,130,70)
      matriz[1][1] = 1
      inter()
    EndIf
  EndIf

Y hacer lo mismo con todas las demás
Al ejecutar el programa se puede comprobar que aunque se haga clic fuera del área de juego, no se actualiza la variable interruptor, salvo que se dibuje una figura, que es lo que queremos conseguir y además no se dibujan unas sobre otras. Hemos corregido ambos errores y estamos cerca de finalizar el juego. De hecho, ya está en una etapa más o menos jugable, debido a que cada jugador puede ocupar su turno como corresponde e ir llenando casillas hasta que uno de los dos gane. 
Esto es todo por ahora. En el próximo tutorial se continuará con la construcción de este juego, ya está casi terminado, solamente falta crear el código para determinar un ganador, otro para reiniciar el juego y añadirle algo de sonido.

Gustavo J. Cerda Nilo
Julio 2016, Octubre 2016


1 comentario:

  1. Por favor necesito armar un ajedrez con filas y columnas.alguien que me de ideas..gracias

    ResponderEliminar

C++ El apuntador This

El apuntador This En C++, cada objeto tiene acceso a su propia dirección a través de un puntero o apuntador denominado This. Lo...