From the category archives:

Videojuegos

Juegos para el día de muertos (2009)

by Jorge Machin on October 30, 2009 · 0 comments

in Personal, Videojuegos

Este año, mucho trabajo y pocos juegos. Pero aún así siempre hay cinco minutos de vez en cuando para descansar y divertirse persiguiendo fantasmas, brujos y escapar del Lobo (¿?).


Ghostbusters
GhostbustersGhostbustersGhostbustersThe PathThe PathThe PathThe PathThe WitcherThe WitcherThe WitcherThe Witcher

Posts relacionados:

Juegos para el Día de Muertos (2008)
Juegos para el Día de Muertos (2007)

{ 0 comments }

En este post se va a tratar el movimiento de los jugadores usando BASIC para experimentar la velocidad y ver si se continua con este lenguaje o bien se hace la programación en ensamblador.

El programa en BASIC

Se corre el juego sin ningún problema en alta velocidad:

10 POKE 65495,0

Se inicializa la interfaz en serie, como se vio en el post anterior:

50 REM CONFIGURACION INICIAL DE LA CONEXION EN SERIE
60 POKE 65387,30
70 POKE 65386,11

Además programamos dos subrutinas para el envio y recepción de datos:

790 REM LECTURA DEL PUERTO SERIE
800 A=PEEK(65385)
810 B=A AND 8
820 IF B=0 THEN 800
830 D$=CHR$(PEEK(65384))
840 PRINT "RECIBE: " + D$
850 RETURN
860 REM ESCRITURA DEL PUERTO SERIE
870 A=PEEK(65385)
880 B=A AND 16
890 IF B=0 THEN 870
900 POKE 65384,ASC(A$)
910 PRINT "ENVIA: " + A$
920 RETURN

Para sincronizar el inicio de la comunicación entre las dos computadoras, cada una de ellas manda un mensaje con el caracter "N" y al mismo tiempo lo espera recibir. Esto nos permite correr el juego de manera asíncrona y no importa que computadora empiece primero:

40 CLS
80 REM MANDA LA SEÑAL DE SINCRONIZACION
90 A$="N":GOSUB 870
100 REM ESPERA LA SEÑAL DE SINCRONIZACION
110 GOSUB 800
120 IF D$<>"N" THEN 90

Como nuestro juego es "punto a punto" y cualquiera de las dos computadoras puede correr primero su programa; hacemos un sorteo para elegir que jugador va usar cada uno de ellos:

130 REM REALIZA EL SORTEO
140 A$=CHR$(RND(10)+47)
150 PRINT "RESULTADO: " + A$
155 REM ENVIA NUESTRO NUMERO ALEATORIO
160 GOSUB 870
165 REM ESPERA RECIBIR EL NUMERO ALEATORIO DE NUESTRO CONTRINCANTE
170 GOSUB 800
175 REM SI EMPATARON, VUELVE A HACER EL SORTEO
180 IF A$=D$ THEN 140

280 IF ( A$>D$) THEN 320
290 FX=0:FY=100
300 GX=0:GY=50
310 GOTO 340
320 FX=0:FY=50
330 GX=0:GY=100

Ahora nos vamos a ocupar de las animaciones de nuestros jugadores. Me basé en una técnica que aprendí del libro "Gráficos y sonidos para el Dragón" de K y S Brain ; Justamente cuando era niño. Consiste en primero dibujar a los jugadores y obtener una copia de la representación en memoria de sus movimientos por medio de la orden GET para después durante el juego copiar esa memoria durante el juego con la orden PUT.

El código que dibuja los movimientos de los jugadores y los guarda en memoria es el siguiente:

20 DIM F1(50):DIM F2(50):DIM F0(50)
30 DIM G1(50):DIM G2(50):DIM G0(50)

190 PMODE 3,1
200 SCREEN 1,0
210 PCLS 1
220 GOSUB 710
230 GET(10,0)-(26,15),F1,G
240 GET(10,20)-(26,35),G1,G
250 GET(30,0)-(46,15),F2,G
260 GET(30,20)-(46,35),G2,G

710 REM DIBUJA LOS MOVIMIENTOS DE LOS JUGADORES
720 FOR N=1 TO 40
730 READ X,Y:PSET(X+10,Y): PSET(X+10,Y+20,3)
740 NEXT N
750 FOR N=1 TO 48
760 READ X,Y:PSET(X+30,Y): PSET(X+30,Y+20,3)
770 NEXT N
780 RETURN

925 REM MOVIMIENTO CON PIERNAS JUNTAS
930 DATA 6,0,8,0,10,0
940 DATA 6,1,8,1,10,1
950 DATA 6,2,8,2,10,2
960 DATA 8,3
970 DATA 6,4,8,4,10,4
980 DATA 6,5,8,5,10,5
990 DATA 6,6,8,6,10,6,16,6
1000 DATA 6,7,8,7,10,7,7,12,7,14,7,16,7
1010 DATA 6,8,10,8
1020 DATA 6,9,10,9
1030 DATA 6,10,10,10
1040 DATA 6,11,8,11,10,11
1050 DATA 8,12
1060 DATA 8,13
1070 DATA 8,14
1080 DATA 8,15,10,15

1085 REM MOVIMIENTO CON PIERNAS SEPARADAS
1090 DATA 6,0,8,0,10,0
1100 DATA 6,1,8,1,10,1,16,1
1110 DATA 6,2,8,2,10,2,16,2
1120 DATA 8,3,14,3
1130 DATA 4,4,6,4,8,4,10,4,12,4
1140 DATA 2,5,6,5,10,5
1150 DATA 0,6,6,6,10,6
1160 DATA 2,7,6,7,10,7
1170 DATA 6,8,10,8
1180 DATA 6,9,8,9,10,9
1190 DATA 6,10,8,10,10,10
1200 DATA 6,11,8,11,10,11
1210 DATA 6,12,10,12
1220 DATA 4,13,12,13
1230 DATA 2,14,14,14
1240 DATA 2,15,4,15,14,15,16,15

grafysonidos
Con los libros de la clon Dragon,
aprendí muchas técnicas de programación

Ya con todas las inicializaciones, podemos dibujar la "cancha" y a los jugadores:

270 PCLS1
340 FOR LI=105 TO 110 STEP 5:LINE(0,LI)-(255,LI-50),PSET:NEXT LI
350 GET(FX,FY)-(FX+16,FY+15),F0,G
360 PUT(FX,FY)-(FX+16,FY+15),F1,OR
370 GET(GX,GY)-(GX+16,GY+15),G0,G
380 PUT(GX,GY)-(GX+16,GY+15),G1,OR

El movimiento del jugador local se a través del teclado:

390 A$=INKEY$
400 IF A$="" THEN 560
410 PUT(FX,FY)-(FX+16,FY+15),F0,PSET
420 IF A$="P" THEN FX=FX+16
430 IF A$="O" THEN FX=FX-16
440 IF A$="Q" THEN FY=FY-16
450 IF A$="A" THEN FY=FY+16

460 REM DIBUJAMOS LA NUEVA POSICION DEL JUGADOR LOCAL
470 GET(FX,FY)-(FX+16,FY+15),F0,G
480 PUT(FX,FY)-(FX+16,FY+15),F2,OR
490 PUT(FX,FY)-(FX+16,FY+15),F0,AND
500 PUT(FX,FY)-(FX+16,FY+15),F1,OR

Para simplificar la programación, en lugar de hacer un sistema de mensajes, simplemente se envia la tecla presionada al otro jugador:

455 GOSUB 870

Se revisa si el jugador remoto presionó alguna tecla y se procesa de la misma forma que para el jugador local:

560 GOSUB 790
610 PUT(GX,GY)-(GX+16,GY+15),G0,PSET
620 IF D$="P" THEN GX=GX+16
630 IF D$="O" THEN GX=GX-16
640 IF D$="Q" THEN GY=GY-16
650 IF D$="A" THEN GY=GY+16

655 REM DIBUJAMOS LA NUEVA POSICION DEL JUGADOR REMOTO
660 GET(GX,GY)-(GX+16,GY+15),G0,G
670 PUT(GX,GY)-(GX+16,GY+15),G2,OR
680 PUT(GX,GY)-(GX+16,GY+15),G0,AND
690 PUT(GX,GY)-(GX+16,GY+15),G1,OR

Finalmente, repetimos el ciclo:

700 GOTO 390

Conclusiones de esta parte

En el siguiente video, podemos apreciar el funcionamiento del programa:

Como podemos ver, aún para ser un programa en BASIC la velocidad es razonable; sobretodo para juegos de turno como los de cartas y ajedrez. En realidad la velocidad esta limitada por la velocidad de las instrucciones gráficas, por lo que un juego en baja resolución funcionaria muy rápido para juegos de acción. Si se va usar alta resolución para un juego de acción, lo conveniente es usar pocos efectos gráficos o bien programarlo en ensamblador.

Muchas Gracias a mi hermano por la interpretación de la música de fondo del video.

{ 0 comments }

Ahora que hemos comprobado el correcto funcionamiento de la Interface RS-232, el siguiente paso es establecer la comunicación entre las dos computadoras por medio del lenguaje BASIC.

La configuración de la interface RS-232 se hace a través de dos registros del circuito integrado 6551, los cuales son accesibles en las direcciones de memoria 65386 y 65387. El primero se conoce como el registro de control, el cual se utiliza para establecer la velocidad de transmisión en baudios, la fuente de frecuencia, el tamaño de la palabra y el número de bits de parada.

El segundo es el registro de comandos, que controlada diferentes modos y funciones como el modo de echo y comunicación con paridad.

controlregister
Tabla 1 Configuración del registro de control
según el manual del usuario

commandregister
Tabla 2 Configuración del registro de comando
según el manual del usuario

La programación de los registros se hace por medio de dos pokes:

5 REM ESTABLECEMOS EL REGISTRO DE CONTROL
10 POKE 65387,30
15 REM ESTABLECEMOS EL REGISTRO DE COMANDOS
20 POKE 65386,11

En este programa de prueba, guardamos si hay una tecla presionada para posteriormente mandarla:

30 I$=INKEY$

Para saber si hemos recibido información de la otra conexión, se debe consultar el registro de estado del circuito integrado 6551. Este es acceble desde la dirección de memoria 65385.

statusregister
Tabla 3 Configuración del registro de estado
según el manual del usuario

Si el bit 3 esta a uno, es que hay información por leer.

35 REM LEEMOS EL REGISTRO DE ESTADO
40 A=PEEK(65385)
50 B=A AND 8
60 IF B=0 THEN 90

La información en el registro de entrada la podemos recuperar leyendo la dirección de memoria 65384:

70 D=PEEK(65384)
80 PRINT CHR$(D)

Si presionó alguna tecla, la transmitiremos; de lo contrario regresaremos al inicio al ciclo. De manera similar, para transmitir consultamos el bit 4 del registro de estado para checar si podemos transmitir. Si es así, hacemos un poke a la dirección de memoria con el byte que deseamos enviar.

90 IF I$="" THEN 30
95 REM ESPERAMOS A QUE PODAMOS TRANSMITIR
100 A=PEEK(65385)
110 B=A AND 16
120 IF B=0 THEN 100
130 POKE 65384,ASC(I$)
140 GOTO 30

Una vez que emparejamos ambas computadoras y ejecutamos nuestro programa en BASIC, la tecla que apretamos en cada una de ellas se transmite a la otra.

Con esto, ya tenemos garantizado la mínima comunicación necesaria para programar nuestro juego.

{ 0 comments }

En 1987, cuando jugaba con mi computadora Color Computer de 8 bits, uno de mis tantos sueños era poder conectar dos computadoras y hacer un juego multiusuario. Cuando pude tener dos computadoras en mis manos, mi primer intento fue cruzando dos cables de la grabadora de cassettes. Y ... ¡Funcionó! Desafortunadamente, la comunicación como era de suponerse era muy lenta y no se podía hacer nada práctico :( . Por supuesto había otras maneras de hacerlo; como usando un modem o alguna interfaz en serie. Ambas inaccesibles para mí en esa época por presupuesto o falta de experiencia. Después cambié esas computadoras por una compatible con PC y ya no pude experimentar más.

Fue hasta 1990 que trabajando en la constructora tuve como tarea hacer una red ethernet, donde finalmente pude dar los primeros pasos para hacer mi sueño realidad. En 1994 jugué el juego de cartas del Windows for Worksgroups y por su puesto el fabuloso Doom en red. Aunque me frustré un poco con los ingenieros civiles que no querían jugar en serio y sólo me disparaban a mí en vez de atacar a los monstruos :P . En el año 2001, pude hacer mi primer juego multiusario usando Java.

Me pregunto si realmente hubiera podido hacerlo con mi querida Coco, si el tiempo y mi presupuesto hubiera estado de mi lado. En este y en varios de los siguientes posts voy a tratar de contestarme esta pregunta realizando un juego de fútbol soccer de dos jugadores. De antemano es posible porque ya otras personas vendían un juego de aviones en esos tiempos, pero no esta de más comprobarlo.

Con presupuesto y tecnología de mi lado

Ahora en el año de 2009, en el sitio www.coco3.com , Roger Taylor vende un cartucho que emula a la interfaz RS-232 que la Radio Shack vendía... ¡pero esta es inalámbrica por medio de la tecnología Bluetooth! ¡Nada de fabricar cables odiosos!

wireless
RS-232 Wireless de Roger Taylor

Para el proyecto, voy a necesitar dos de esos cartuchos y por su puesto dos Color Computers 2. Afortunadamente las computadoras las pude conseguir sin problemas en e-bay.

Probando la interfaz en serie

Antes de ponerse a programar, es necesario comprobar que el hardware está funcionando perfectamente y que se entiende como funciona. La documentación que proporciona Roger Taylor es muy completa y tiene especificado todo lo que se necesita para este proyecto.

Al ser bluetooth, lo primero que hice fue checar desde Linux si podía ver las dos interfases RS-232 (Una en cada Color Computer):

[renato@fedora ~]$ hcitool scan
Scanning ...
    XX:XX:XX:XX:XX:XX   C510a
    00:0C:84:00:85:19   eb101
    00:0C:84:00:87:9D   eb101

Con el nombre eb101 se puede ver claramente las dos interfaces y es de agradecerse que las direcciones MAC sean distintas por lo que no va haber ningún problema en identificar a cada dispositivo. Incluso podemos hacer pings a cada una de las interfaces:

l2ping 00:0C:84:00:87:9D ---> Cambiar la MAC de la Color Computer a la que se quiere uno conectar

Leyendo las especificaciones técnicas nos damos cuenta que el RS-232 utiliza un chip que está específicamente diseñado para servir a través de interfaces en serie, por lo que al utilizar además un chip 6551 como puente, se garantiza la compatibilidad con las aplicaciones existentes para el pak RS-232 de la Radio Shack. Solamente hay que tener en cuenta en las configuraciones que los parámetros por default son los siguientes:

Baud rate: 9600
Parity: none
Security: off
passkey: 0000

Se pueden mejores configuraciones, como velocidades de 115200 bps, pero creo que los valores por defectos son adecuados para el proyecto y así se simplifica las configuraciones.

El cartucho cuenta con una memoria con un programa desde donde se puede configurar la interface RS-232, además de un programa terminal con utilidades para transferir entre computadoras programas en BASIC y en lenguaje de máquina. Para acceder a ese programa se ejecuta:

exec &HC000

Probando la conexión con otra Color Computer

Desde ahi, se puede probar la comunicación entre las computadoras con tan sólo ajustar la velocidad a 9600 baudios y entrando al programa de terminal. Para hacer la conexión se utiliza el comando con con la dirección MAC de la interfaz de la otra Color Computer. A partir de ahí todo lo que se escriba en cualquiera de las dos computadoras, aparecerá en las dos terminales.

A continuación pongo un video de como fue la prueba con mis dos computadoras:

Antes de que me lo pregunten, la voz que utilizo en el video es sintética, como se acostumbra en YouTube :) .

Probando la conexión de una máquina Linux a una Color Computer

De igual manera se configura la interfaz en serie a 9600 baudios en la Color Computer y se coloca uno en la terminal. En la máquina Linux se corren los siguientes comandos:

rfcomm release all
rfcomm bind /dev/rfcomm0 00:0C:84:00:87:9D <--- Cambiar la dirección por la de la Color Computer

Ahorra corremos algún programa terminal en la linux como cu (instalar antes el paquete uucp):

cu -l /dev/rfcomm0

o bien el emulador de terminal VT100/ANSI screen:

screen /dev/rfcomm0

En ninguno de los dos es necesario configurar la interfaz en serie porque el protocolo spp lo negocia automáticamente.

Es probable que con comandos AT, nos podríamos conectar a un celular y utilizarlo como modem.

Probando la conexión de una Color Computer a una máquina Linux

1. Creamos un puerto en serie:

sdptool add --channel=3 SP

2. Nos ponemos a escuchar en ese puerto:

rfcomm listen rfcomm0 3

3. Nos vamos a la Color Computer y establecemos la conexión.

4. Si nos pide la llave en la máquina linux, le damos 0000, que es la llave por defecto.

5. Nos conectamos a la trerminal en la máquina usando cu o screen.

{ 4 comments }

A principios de 1989, en mi familia dejamos atrás las computadoras de 8 bits y cambiamos al mundo de los 16 bits con lo que fue nuestra primera PC: Una Tandy 1000 SL con un microprocesador 8086 a 8 Mhz. Originalmente, la compramos con 384 KB de memoria, una unidad de diskette de dos lados, doble densidad de 360 KB, sin disco duro, sin reloj y con un monitor monocromático verde. Por supuesto, el teclado en inglés.

La Tandy 1000 SL como se ve actualmente.
La Tandy 1000 SL como se ve actualmente. El mismo disco duro tenía la tarjeta controladora. La tarjeta para hacer respaldos. Así se ve por dentro.

De ahí, como buenos fanáticos de la electrónica, la modificamos bastante. Le aumentamos la memoria a 640KB, le cambiamos el microprocesador por el clon NEC V30 para que corríera de un 10 a 30% más rápido, le agregamos un disco duro de 20 mB y una tarjeta Central Point Option Board para poder respaldar programas protegidos de copia. Teníamos también una tarjeta para quemar memorias EPROM, un scanner de mano y para imprimir usabamos la impresora de matriz de puntos de mi vieja Color Computer 3. Después, con el tiempo, ya tuve un flamente monitor a color.

Lo que más me gustaba de esta máquina era que incluía un DAC de 8 Bits con un programa editor de sonido y otro para editar música colocando las notas en el pentragrama. Al usar ondas de 48Khz, la música capturada tenía buena calidad y los juegos como el Battle Chess y el Principe de Persia eran toda una experiencia para la época.

Con ella aprendí muchísimo: Pascal, Turbo Basic, dbase, ensamblador del 8086 y sus interrupciones, como funcionaban los programas residentes en memoria y los virus, hojas de cálculo, MathCAD, derive y una infinidad de programas.

Posteriormente compramos una Tandy 1000 TL/3 con un microprocesador 80286, 10 Mhz de velocidad y 728KB de RAM. No necesitabamos dos computadoras por lo que se la vendí a un tío, que este año al hacer limpieza, la donó a mi museo personal. ¡Muchas Gracias Don Pedro!

{ 4 comments }