Diario de un
programador. Día 179
Programando mi primer
videojuego en Small Basic. Parte 1
Por primera vez voy a hacer un juego completo, por lo tanto
fue todo un desafío conseguirlo. Este juego, se supone que fue uno de los
primeros (si no es que el primero) juegos de la historia. Se trata del juego
tic tac toe, también conocido como tres en raya o gato, como suelen llamarlo
por aquí donde yo vivo.
Aquí una imagen del juego:
El juego es para 2 jugadores. Al primer jugador le
corresponden las X mientras que al segundo jugador le corresponden los 0.
En un principio me pareció sencillo, me dije ¿Qué tan difícil
puede ser dibujar un par de rayas, unos círculos y unas equis y almacenarlas en
una matriz?, sin embargo la cosa se me complicó desde el principio, ya que tuve
que liarme en cómo hacer para que al primer clic saliera una equis, luego al
siguiente clic (turno del otro jugador) saliera un circulo, o que no se
permitiera hacer clic sobre una casilla que ya se encuentra ocupada, o cómo hacer para alinear las figuras (equis
y círculos) dentro de las casillas sin importar que el usuario haga clic en
cualquier parte de ESA casilla, o no permitir que se dibujen figuras fuera de
la matriz, o cómo hacer que el programa “entienda” que un jugador ha ganado y
cuando lo haga, trazar una línea sobre sus figuras, etc, etc, etc. Como se
podrán dar cuenta, son muchas las opciones que hay que tener en cuenta, pero
aún así fue muy motivante y emocionante ver cómo este pequeño proyecto iba
tomando forma.
EMPEZANDO DESDE CERO
Manos a la obra.
Lo primero que hice fue crear una subrutina a la cual llamé
“inicio”, esta me va a permitir iniciar y reiniciar el juego. Al momento, esta
es la única forma que conozco para volver a cargar o reiniciar una partida.
Esta subrutina contendrá los elementos iniciales del juego,
por lo tanto, dentro de ella se ubicarán las coordenadas de las líneas, los
colores, tamaños etc.
Voy a ir paso a paso así que este tutorial se podría extender
un poco, pero como es mi costumbre, prefiero hacerlo de esta forma y así no
dejar mayores dudas al respecto.
Entonces, de primera el código se vería de esta forma:
Sub inicio
GraphicsWindow.Width = 370
GraphicsWindow.Height = 300
GraphicsWindow.PenWidth = 2
GraphicsWindow.PenColor = "Green"
GraphicsWindow.CanResize = "no"
EndSub
inicio()
Como se puede ver, es una subrutina con elementos que ya se habían
visto antes. Se tiene una ventana con un tamaño de 370 x 300 pixeles. Luego con
PenWidth, se ajusta el grosor del lápiz a 2, a este lápiz se le asigna un color
verde “Green” (color que utilizaré para las líneas verticales y horizontales) y
posteriormente se desactiva el redimensionamiento de la ventana con CanResize =
“no”. Se da por finalizada esta subrutina con EndSub y posteriormente es
llamada con inicio() para poder ver que se obtiene. Al ejecutar el programa, se
debería ver algo así:
Lo siguiente que se debe agregar a esta subrutina son las líneas
verticales y horizontales donde irán ubicadas las figuras. Para ello utilicé el
siguiente código:
'lineas horizontales
GraphicsWindow.DrawLine(80,110,290,110)
GraphicsWindow.DrawLine(80,170,290,170)
'lineas verticales
GraphicsWindow.DrawLine(150,60,150,220)
GraphicsWindow.DrawLine(220,60,220,220)
Al ejecutar nuevamente el código, se puede apreciar la figura que
se creó.
Ya por último, voy a crear una matriz de 3 x 3 dentro de esta
subrutina, la cual me servirá para almacenar los valores que se vayan creando
al momento de ir jugando.
For fila = 1 To 3
For columna = 1 To 3
matriz[fila][columna] = 0
EndFor
EndFor
Esta
matriz la llené con ceros. Pudo haber sido cualquier otro valor, yo quise
llenarla con ceros simplemente para poder crearla.
A
modo de ayuda, también generé un
comentario de la matriz para después saber cual espacio corresponde
reemplazar posteriormente.
'Matriz de 3 x 3 de ceros
'X = 1
'O = 9
'1,1
1,2 1,3
'2,1
2,2 2,3
'3,1 3,2 3,3
Mi idea original era la siguiente: Crear una matriz de 3 x 3
y llenarla con ceros. Cuando una X seleccione una casilla,(por ejemplo la 2,2
de la matriz) el cero será cambiado por un 1. En cambio, si un círculo
seleccionaba una casilla, el cero será cambiado por un 9. ¿Por qué? Porque, al
llenar una fila, columna o diagonal con el número 1, ésta podría sumar 3, en
cambio, al llenar una columna, fila o diagonal con 9, ésta podría sumar 27. Entonces,
si el resultado de la suma de una fila, columna o diagonal entregaba un 3 o un
27, entonces habría un ganador. En un principio iba a escoger un 2 en vez del
9, pero rápidamente me di cuenta que no solamente sumando 1+1+1 daría un 3,
sino que también 2+1 daría 3, finalizando el juego en forma inesperada. Por la
misma situación tampoco podría escoger el 3... Así que sin pensarlo demasiado
escogí el 9 para no darme mayores complicaciones, pudo haber sido el 4, 5, 6
etc.
Sigamos...
Antes de realizar todos esos cálculos, necesitaba crear las
figuras. La idea era que al hacer un clic con el ratón en alguna parte del área
del juego, se dibujara una X. Posteriormente, al segundo clic (turno del
segundo jugador) se dibujara un O.
Así que vamos por parte. Lo primero es crear la X con un
clic.
Aquí se me complicó un poco, porque una X, consta de dos
líneas diagonales, que tenían que aparecer en el mismo lugar que apuntaba el
ratón.
Bueno, para empezar creé un evento para poder dibujar las
figuras.
GraphicsWindow.MouseDown = clicX
Este evento también lo incluí dentro de la subrutina “inicio”
Posteriormente hice la subrtutina que me permitiera dibujar
la X. Lo que hice fue lo siguiente: Como una X consta de dos diagonales y una
diagonal consta de 4 coordenadas(x1,y1, x2,y2), entonces necesitaba 8
coordenadas para dibujar la X.
Para que la cosa no se me complicara tanto fui paso a paso:
Primero voy a simplemente a dibujar una X en la esquina superior izquierda cada
vez que haga clic. Con el siguiente código debería ser suficiente:
Sub clicX
GraphicsWindow.PenColor = "Blue"
GraphicsWindow.DrawLine(0,0,30,30)
GraphicsWindow.DrawLine(0,30,30,0)
EndSub
Con esto, al momento de hacer clic, aparece una X en la
esquina superior izquierda.... Es un comienzo...
Dibujando la X parte 2
Ahora que ya se puede
dibujar la X, el siguiente paso sería lograr que la X apareciera en el mismo
lugar donde se hiciera clic. Para ello tuve que modificar un poco el código y
utilizar la propiedad MouseX y MouseY del objeto GraphicsWindow. Esta propiedad
permite obtener las coordenadas X e Y del mouse, perfecto para lo que tratamos
de hacer. Ahora, la siguiente pregunta
era como utilizar esa propiedad para dibujar la X. En primer lugar pensé: Para
realizar una X necesito 8 coordenadas (4 por cada diagonal)y la propiedad
MouseX y MouseY me entregan una coordenada cada uno (X e Y) ¿cómo hacerlo?,
bueno, en esta parte utilicé papel y lápiz (algo que utilizo muy a menudo para
resolver problemas así que lo recomiendo) y me puse a dibujar lo que quiero
conseguir. En esta parte voy a representar aquel dibujo que hice en papel, con
un dibujo que haré en paint.
Lo primero que pensé fue: "Bueno, con mouseX y mouseY
puedo conseguir una coordenada, supongamos que mi mouse se encuentra en la
posición x = 100 y en la posición y = 100."
"Entonces, si quisiera que se dibuje una diagonal de 30
pixeles justo en el centro de la flecha"
"A la posición X1 e Y1 debería restarle 15, para poder
calcular la posición inicial"
"Y a la posición X2 e Y2 debería sumarle 15, para poder
calcular la posición final"
Entonces, para cada
valor (x1,y1, x2,y2) debería crear una variable distinta y así poder guardar la
posición del mouse con los valores +15 o -15 según corresponda
Esto lo hice de la siguiente manera:
posX1 = GraphicsWindow.MouseX - 15
posY1 = GraphicsWindow.MouseY - 15
posX2 = GraphicsWindow.MouseX + 15
posY2 = GraphicsWindow.MouseY + 15
Ahora, solo queda asignar esas variables a la operación
DrawLine.
GraphicsWindow.DrawLine(posX1,posY1,posX2,posY2)
Entonces, ahora la subrutina se ve de esta forma:
Sub clicX
GraphicsWindow.PenColor = "Blue"
posX1 = GraphicsWindow.MouseX - 15
posY1 = GraphicsWindow.MouseY - 15
posX2 = GraphicsWindow.MouseX + 15
posY2 = GraphicsWindow.MouseY + 15
GraphicsWindow.DrawLine(posX1,posY1,posX2,posY2)
EndSub
Al ejecutar el
programa, se puede apreciar que realmente dibuja una línea diagonal en el mismo
lugar donde hacemos clic y además de que queda centrada respecto a la flecha
del mouse.
Muy bien, ahora
que podemos dibujar una diagonal. Agreguemos el código para poder dibujar la
otra diagonal y así formar la X. Esto quedaría de la siguiente forma:
posA1 = GraphicsWindow.MouseX + 15
posB1 = GraphicsWindow.MouseY - 15
posA2 = GraphicsWindow.MouseX - 15
posB2 = GraphicsWindow.MouseY + 15
Si agregamos esto
a la subrutina, entonces quedaría de la siguiente forma:
Sub clicX
GraphicsWindow.PenColor = "Blue"
posX1 = GraphicsWindow.MouseX - 15
posY1 = GraphicsWindow.MouseY - 15
posX2 = GraphicsWindow.MouseX + 15
posY2 = GraphicsWindow.MouseY + 15
posA1 =
GraphicsWindow.MouseX + 15
posB1 =
GraphicsWindow.MouseY - 15
posA2 =
GraphicsWindow.MouseX - 15
posB2 =
GraphicsWindow.MouseY + 15
GraphicsWindow.DrawLine(posX1,posY1,posX2,posY2)
GraphicsWindow.DrawLine(posA1,posB1,posA2,posB2)
EndSub
Al ejecutar el código podemos ver como se
dibuja nuestra X, quedando centrada con respecto al mouse.
Debido a lo extenso que resulta explicar este programa, tendré que dividirlo en varias partes, pero pronto subiré la segunda parte para así continuar con la construcción de este juego. Saludos
Gustavo J. Cerda Nilo
Julio 2016, Octubre 2016
¿PORQUE TANTA COSA?
ResponderEliminarnos estan trabando que tanto que hay que copiar a mano
pinshes inconsientes.
DE NADA
Eliminaryo no tengo futuro
ResponderEliminarya callense
ResponderEliminarJAAJAJAJA
ResponderEliminares muy buena el juego
ResponderEliminar