El juego del Pong para Excel en Visual Basic for Applications (VBA)
En esta entrada vamos a sumergirnos en un viaje fascinante a los orígenes del mundo de los videojuegos con el clásico Pong o Telepong. Desde los modestos inicios de «Tennis for Two» en 1958 hasta la explosión comercial de Pong en 1972. Descubriremos cómo este juego sencillo marcó el inicio de una revolución digital.
¿Te imaginaste alguna vez jugando al Pong (Ping – Pong) en Microsoft Excel? ¡Prepárate para un desafío divertido! Esta entrada no sólo explora la evolución del Telepong, sino que también te guía paso a paso para crear tu propio juego en Excel. Desde el movimiento de la pelota hasta el control de la raqueta, el código se revela con detalles jugosos.
¡Sumérgete en este blog lleno de nostalgia, curiosidades científicas y una experiencia práctica que te hará desear presionar esa tecla de Play!
Pong o Telepong: Un viaje a los orígenes de los videojuegos
En la era actual digital, con gráficos de alta definición y experiencias de juego inversivas, es fascinante retroceder en el tiempo y explorar los humildes comienzos de los videojuegos. Uno de los pioneros que marcó el inicio de esta revolución fue el clásico juego del Pong o telepong.
El Origen: El pong
El juego del Pong (o Tele-Pong) es un videojuego, simple pero adictivo, que forma parte de la primera generación de videoconsolas y videojuegos. Corría el año 1958 cuando William Higinbotham, un físico estadounidense creó un juego precursor en un osciloscopio llamado “Tennis for Two”. Este experimento sentó las bases para los videojuegos virtuales. Una década después Nolan Bushnell que trabajaba en la famosa empresa Atari, hizo del pong una realidad comercial, lanzándose al mercado el 29 de noviembre de 1972.
William Higinbotham
Nolan Bushnell
El “pong” es un juego basado en el deporte de mesa ping-pong. Normalmente el juego consiste en que dos jugadores hacen rebotar una pelota en una mesa empleado dos palas o raquetas. El telepong actualmente puede parecer simple, sin embargo, su gran éxito comercial estableció las bases de la industria millonaria de los videojuegos. Las primeras versiones del telepong estaban basadas en osciloscopios y una electrónica muy básica si se mira con la perspectiva de una persona del siglo XXI.
Evolución del juego del pong
La evolución: El telepong
Con el tiempo la tecnología avanzó y dio paso a nuevas experiencias de juego. El telepong surgió como una versión mejorada del pong, incorporando características innovadoras. Ahora los jugadores no sólo podían controlar las paletas, sino también participar en emocionantes competiciones en línea. El telepong trajo consigo una dimensión social al mundo de los videojuegos, allanando el camino para futuras innovaciones en la industria.
El pong con fines científicos
Este juego ha sido también empleado con fines científicos por parte de la empresa Neuralink de Elon Musk para probar con primates la transmisión de datos entre un cerebro y una computadora. Todo esto mediante implantes cerebrales sin necesidad de mover las extremidades.
La forma de hacerlo es increíblemente curiosa. Inicialmente los primates con implantes cerebrales aprenden a jugar mediante joysticks. Una vez el animal ya sabe jugar se les engaña. Es decir, se le da el mando como siempre, pero realmente controlan con el celebro las posiciones de la pala. El joystick se encuentra desconectado, aunque lo tengan en sus manos.
Experimentos realizados por Neuralink y con Primates usando el juego del pong
Según varios periódicos, algunos primates murieron a causa de complicaciones con los implantes. Parece ser que sufrieron infecciones, parálisis, pérdida de coordinación, equilibrio y depresión.
La intención última de la empresa Neuralink es desarrollar un dispositivo capaz de tratar pacientes que sufren discapacidades neurológicas. Este dispositivo está formado por una serie de cables y electrodos permitiendo la comunicación celebro – ordenador, el cual sería un aliado para personas inválidas con problemas de movilidad o enfermedades como la epilepsia. Otras propiedades que podría tener tal interfaz sería el acceso a la información del celebro e incremento de la memoria. En fin, un dispositivo que parece sacado de una novela de ciencia – ficción.
Ahora sí! El juego del Pong para Excel en Visual Basic for Applications (VBA)
Este juego se puede plantear y enfocar de diferentes maneras, con diferentes soluciones y se puede complicar tanto como uno desee. La solución no es única, por ejemplo, en el número de jugadores, pelotas, formas de puntuar, colores, etc. Yo he querido plantear el problema de la misma manera que aparece en el libro “Aprenda Visual Basic para Excel: Más de 100 ejercicios resueltos, macros y juegos, para desarrollar tus habilidades de programación”.
La manera en el libro enfoca el juego me parece muy intuitivo, didáctico y simple. De hecho, es un libro muy recomendable tanto por precio como por contenido. Para realizar el juego y con el objetivo de simplificar el problema, el autor reduce la complejidad de forma que, en vez de existir dos jugadores y dos palas, sólo se juega contra la máquina. Por lo que un jugador con una única pala competirá contra el ordenador. Luego, el usuario puede ampliar y complicar el código tanto como se desee.
Para ello primero se definen los límites del área de juego dónde rebotará la pelota. Luego, se creará la pelota desplazándose cada medio segundo. Del juego, se puede salir presionando la tecla escape “ESC”.
El campo, la pelota y la pala se crean empleando el método “shapes”. La pala, tendrá una velocidad de ascenso y descenso al pulsar las teclas de subir y bajar del teclado.
La pelota se desplaza en todas las direcciones, por lo que tendrá un movimiento vertical y horizontal a la vez. Esto fuerza a que la dirección y sentido del movimiento sea en diagonal. Al igual que los rebotes. El sentido del movimiento se invierte cuando la pelota toca la pala o llega a los límites del campo.
La representación del área de juego, la pelota y la pala es también muy sencilla. Unas barras verticales y horizontales realizadas con el método “shapes” de Excel permiten crear el área de juego y la pala. La pelota también se realiza con el mismo método. En la siguiente imagen se aprecia como se visualiza el juego:
Lo primero que se realizará, antes de empezar a programar el funcionamiento del propio código es escribir la siguiente instrucción:
Option Explicit
Con ello, evitaremos descuidarnos de no declarar alguna de las variables que intervienen en el juego. La anterior instrucción podría no estar. Sino estuviera no pasaría nada. Sin embargo, en caso de cualquier omisión en las constantes y variables podría dar lugar a errores.
A continuación, lo que nos interesa es controlar el juego. Para ello, al presionar una tecla debe suceder algo. Por ejemplo, al presionar un “escape” el juego debe pararse, o mediante las teclas de subir y bajar (flechas), se podrá controlar la raqueta.
Private Declare PtrSafe Function GetAsyncKeyState Lib "user32.dll" (ByVal vKey As Long) As Integer
La anterior instrucción se utiliza para declarar la función GetAsyncKeyState de la biblioteca user32.dll. Dicha función permite obtener el estado de una tecla específica. “PtrSafe” indica que la declaración es segura para plataformas de 64 bits. En este caso, la función devuelve un entero, lo que indica si la tecla está o no presionada. El tipo de teclas que podemos emplear son alfanuméricas, de función, teclas de flecha, de control y modificaciones entre otras.
Una vez hecho lo anterior hemos de definir todas las variables. Es decir, definimos como serán las cosas, que son y cómo deben ser. Por ejemplo, el área de juego (leftColumn, rightColumn, bottomColumn, topColumn, raqueta) y la pelota se definen como formas mediante “shapes”. Luego definimos los límites del campo (topLimit, bottomLimit, rightLimit y leftLimit). Luego la pelota debe ir a una velocidad determinada para que sea visible a los ojos, esto lo hacemos con unas variables adecuadas: XSpeed, YSpeed y velRaqueta. La velocidad requiere de la variable tiempo, la cual se controla con las siguientes: PauseTime, Start, Finish y TotalTime.
Una vez hemos declarado las variables necesarias y cómo se controlará el juego, lo primero que hay que pensar es qué sucede cuando iniciamos el juego. Lo normal es que el área de juego esté limpia y no quede nada de partidas anteriores. Para ello empleamos el siguiente bucle, el cuál elimina todas las “shapes”.
For Each shp In ActiveSheet.Shapes
shp.Delete
Next shp
Posteriormente reconstruiremos el área de juego dibujando nuevamente todos los límites del campo. Para ello emplearemos la siguiente instrucción el cual crea un objeto de forma rectangular en la hoja de cálculo activa (ActiveSheet).
Set leftColumn = ActiveSheet.Shapes.AddShape(msoShapeRectangle, 0, 0, 10, 210)
- Shapes.AddShapes: Este método se utiliza para agregar una forma a la hoja de cálculo, en este caso de forma rectangular.
- msoShapeRectangle: Es un tipo de autoforma que representa el tipo de forma que se va a agregar, en este caso, un rectángulo de coordenadas 0, 0, 10, 20, las cuales indican que dicho rectángulo se crea en la esquina superior izquierda de la hoja de cálculo con una anchura de 10 unidades y una altura de 210 unidades.
La misma metodología se emplea para crear todo el campo y la raqueta. Para la pelota empleamos un tipo de autoforma especial para dibujar una pelota: msoShapeOval.
Bien, hasta ahora hemos definido las formas, el área de juego, la pelota, raqueta, etc. Ahora hemos de dotar al juego de vida. Hemos de hacer que la pelota se mueva, rebote, y que la raqueta se desplace verticalmente. El juego se realiza en dos dimensiones, dentro de un bucle “Do While True” del que sólo se sale si se presiona la tecla “Escape”. Para ello vamos a definir un movimiento vertical y horizontal a la vez marcado por un tiempo que permita a la pelota ser observable.
Recordemos que en VBA el “Do While True” se utiliza para crear un bucle infinito que se ejecuta continuamente hasta que se alcanza una condición de salida deseada. Es imprescindible tener una forma para salir del código para evitar que éste se ejecute indefinidamente sin posibilidad de salir de forma rápida, sencilla y segura. Esta forma de salir es mediante un condicional que ejecuta la sentencia “exit do”. En nuestro caso, sólo si se pulsa la tecla ESC salimos se sale del juego.
- Mover la pelota horizontalmente y controlar el rebote de la pala: Desplaza la posición izquierda (“Left”) de la pelota (“ball”) sumando la velocidad horizontal (“Xspeed”). Si la posición izquierda supera un límite (“leftLimit”) o cae por debajo de otro límite (“rightLimit”), invierte la dirección multiplicando la velocidad por “-1”.
ball.Left = ball.Left + XSpeed
If ball.Left < leftLimit Then
XSpeed = XSpeed * -1
ElseIf(ball.Left + ball.Width - 5) > rightLimit or ball.Left > 175 _
And (ball.Top - 5) >= raqueta.Top And ball.Top <= (raqueta.Top + 50) Then
XSpeed = XSpeed * -1
End If
- Mover la pelota verticalmente y controlar el rebote vertical: Ajusta la posición superior (“Top”) de la pelota (“ball”) sumando la velocidad vertical (“YSpeed”). Si la posición superior es menor que un límite vertical (“topLimit”) o mayor que un límite inferior (“bottomLimit”) invierte la posición vertical.
ball.Top = ball.Top + YSpeed
If ball.Top < topLimit Then
YSpeed = YSpeed * -1
ElseIf (ball.Top + ball.Height - 5) > bottomLimit Then
YSpeed = YSpeed * -1
End If
- Parar un cierto tiempo para que la pelota vaya a una velocidad observable al ojo humano: Se define un tiempo de pausa (“pauseTime”) en segundos. Luego, establece el tiempo inicial (“Start”) empleando la función “timer”. Finalmente, se emplea un bucle “Do While”, junto con la función “Do events” para esperar hasta que el tiempo actual “timer” sea mayor que el tiempo inicial más la duración de la pausa (“PauseTime”). Al salir del bucle de pausa, registra el tiempo final (“Finish”) empleando la función “Timer”.
PauseTime = 0.1 'Establecer duración en términos de segundo
Start = Timer 'Establecer tiempo inicial
Do While Timer < Start + PauseTime
DoEvents 'Ir a otros procesos
Loop
Finish = Timer 'Tiempo fin
Este tiempo de parada es muy importante, sino la pelota se movería a “todo lo que dé el ordenador”. Es decir, las instrucciones el ordenador las lee de arriba hacia bajo, y lo hace muy rápido, según la velocidad de procesamiento del ordenador.
Puntuación
El tema de la puntuación también es importante. En libro antes comentado se plantea de una forma sencilla e intuitiva, pero repetimos que esto se puede complicar lo que uno quiera. De hecho, es un buen ejercicio para los que quieran aprender a programar o mejorar el juego.
La puntuación consiste en dar un punto cada vez que la pelota rebote en la raqueta. Para ello se necesita de una condición que verifique las posiciones de la pelota ball.Left y ball.Top con respecto al tamaño de la raqueta y su posición. El resultado de la puntuación se muestra en una celda “E1” de la hoja del juego.
If ball.Left > 175 And (ball.Top - 5) >= raqueta.Top And ball.Top <= (raqueta.Top + 50) Then
'Definimos el sistema de puntuación
Dim i As Integer
i = i + 1
Range("E1").Value = i
End If
En el “if” se verifica si la posición está más allá de cierto límite horizontal, y si la posición vertical de la pelota está dentro de los límites superior e inferior de la raqueta. Si esta condición es verdades incrementa una variable “i” y actualiza el valor en la celda “E1”.
Luego en la siguiente sección del código usamos la función GetAsyncKeyState para detectar si la flecha de “hacia arriba” (vbKeyUp) está siendo presionada. Si es así y la posición superior de la raqueta (raqueta.top) es mayor que 10 entonces decrementa la posición superior de la raqueta según la velocidad de ésta.
If GetAsyncKeyState(vbKeyUp) Then 'Con esta línea controlamos el subir y bajar de la pala
If raqueta.Top > 10 Then 'Con esta línea la raqueta no sale del área de juego
direcRaqueta = -1
raqueta.Top = raqueta.Top - velRaqueta
End If
End If
Finalmente, el juego termina con la posibilidad necesaria de terminar el juego al presionar la tecla escape:
If GetAsyncKeyState(vbKeyEscape) <> 0 Then
Exit Do
End If
Dicho todo lo anterior, podemos adjuntar todo el código completo:
Option Explicit
Private Declare PtrSafe Function GetAsyncKeyState Lib "user32.dll" (ByVal vKey As Long) As Integer
Sub pong()
'Definimos las formas como los márgenes del campo, pelota y palas
Dim ball As Shape
Dim leftColumn As Shape
Dim rightColumn As Shape
Dim bottomColumn As Shape
Dim topColumn As Shape
Dim raqueta As Shape
'Esta variable permite eliminar todas las formas anteriores
Dim shp As Shape
'Definimos los límites del campo
Dim topLimit As Integer
Dim bottomLimit As Integer
Dim rightLimit As Integer
Dim leftLimit As Integer
'Definimos la velocidad de pelota
Dim XSpeed As Integer
Dim YSpeed As Integer
Dim velRaqueta As Integer
'Definimos la velocidad de refresco para que sea visible a los ojos
Dim PauseTime, Start, Finish, TotalTime As Long
'Esta variable permite controlar la subida y bajada de la raqueta
Dim direcRaqueta As Integer
'Definimos la forma y velocidad de la raqueta
velRaqueta = 10
'Definimos los límites del campo
topLimit = 15
bottomLimit = 190
leftLimit = 15
rightLimit = 200
'Definimos la velocidad de la pelota
XSpeed = 5
YSpeed = 5
'Al comenzar el programa eliminar todas las posibles formas o shapes
For Each shp In ActiveSheet.Shapes
shp.Delete
Next shp
'Primero dibujamos el área de juego. Añadimos las columnas con el "shapes"
' Tenemos en cuenta que: Posición X, Posición Y, Ancho, alto
Set leftColumn = ActiveSheet.Shapes.AddShape(msoShapeRectangle, 0, 0, 10, 210)
leftColumn.Fill.ForeColor.RGB = RGB(192, 192, 192)
Set rightColumn = ActiveSheet.Shapes.AddShape(msoShapeRectangle, 210, 0, 10, 210)
rightColumn.Fill.ForeColor.RGB = RGB(192, 192, 192)
Set topColumn = ActiveSheet.Shapes.AddShape(msoShapeRectangle, 10, 0, 200, 10)
rightColumn.Fill.ForeColor.RGB = RGB(192, 192, 192)
Set bottomColumn = ActiveSheet.Shapes.AddShape(msoShapeRectangle, 10, 200, 200, 10)
rightColumn.Fill.ForeColor.RGB = RGB(192, 192, 192)
'Dibujamos la raqueta
Set raqueta = ActiveSheet.Shapes.AddShape(msoShapeRectangle, 200, 100, 10, 50)
rightColumn.Fill.ForeColor.RGB = RGB(192, 192, 192)
'Dibujamos la pelota: Posición inicial X, posición inicial Y, Largo, Ancho
Set ball = ActiveSheet.Shapes.AddShape(msoShapeOval, 10, 50, 20, 20)
ball.Fill.ForeColor.RGB = RGB(255, 255, 0)
'Hacer que la pelota se desplace
Do While True
'Mover la pelota horizontalmente y controlar rebote horizontal
ball.Left = ball.Left + XSpeed
If ball.Left < leftLimit Then
XSpeed = XSpeed * -1
ElseIf (ball.Left + ball.Width - 5) > rightLimit Or ball.Left > 175 _
And (ball.Top - 5) >= raqueta.Top And ball.Top <= (raqueta.Top + 50) Then
XSpeed = XSpeed * -1
End If
'Mover la pelota verticalmente y controlar rebote vertical
ball.Top = ball.Top + YSpeed
If ball.Top < topLimit Then
YSpeed = YSpeed * -1
ElseIf (ball.Top + ball.Height - 5) > bottomLimit Then
YSpeed = YSpeed * -1
End If
'Parar un cierto tiempo para que la pelota vaya a una velocidad observable a los ojos
PauseTime = 0.1 'Establecer duración en términos de segundo
Start = Timer 'Establecer tiempo inicial
Do While Timer < Start + PauseTime
DoEvents 'Ir a otros procesos
Loop
Finish = Timer 'Tiempo fin
'Puntuación
If ball.Left > 175 And (ball.Top - 5) >= raqueta.Top And ball.Top <= (raqueta.Top + 50) Then
'Definimos el sistema de puntuación
Dim i As Integer
i = i + 1
Range("E1").Value = i
End If
If GetAsyncKeyState(vbKeyUp) Then 'Con esta línea controlamos el subir y bajar de la pala
If raqueta.Top > 10 Then 'Con esta línea la raqueta no sale del área de juego
direcRaqueta = -1
raqueta.Top = raqueta.Top - velRaqueta
End If
End If
If GetAsyncKeyState(vbKeyDown) Then
If raqueta.Top < 150 Then 'Con esta línea la raqueta no sale del área de juego
direcRaqueta = 1
raqueta.Top = raqueta.Top + velRaqueta
End If
End If
'Al presionar escape salimos del juego.
If GetAsyncKeyState(vbKeyEscape) <> 0 Then
Exit Do
End If
Loop
End Sub
Legado y reflexiones
Pong y telepong son recordatorios atemporales de como la simplicidad puede ser la clave del éxito. Estos juegos sencillos, pero ingeniosos, allanaron el camino para la industria de los videojuegos tal y como la conocemos hoy. A través de su evolución desde las pantallas de los osciloscopios hasta las experiencias multijugadores en línea, han dejado un legado duradero. Estos juegos no sólo entretuvieron a millones de jóvenes y adultos, sino que también sentaron las bases para la rica y diversa industria de los videojuegos actuales.
Recomendamos que para aprender más sobre VBA y Excel lea cualquiera de los libros que recomendamos en la bibliografía tanto en Español como en Inglés.
Bibliografía
Origen de la información de blog «El juego del Pong para Excel en Visual Basic for Applications (VBA)»:
Otras consultas: