Configuración global
Define la resolución del área de dibujo virtual. El escalado al display es automático y siempre pixel-perfect sin interpolación.
- <ancho> <alto>
- Dimensiones en píxeles. Default: 256×240. Resoluciones históricas válidas: 256×192 (MSX), 256×224 (NES/SNES), 256×240 (NES), 320×200 (DOS VGA), 320×240 (GBA), 640×480 (VGA).
- COLORES <n>
- Profundidad de color: 16 (default) o 256.
PANTALLA 320 200 COLORES 256
Selecciona la paleta de 16 colores activa. Default: retro. Todos los nombres de color del lenguaje hacen referencia a la paleta activa.
- retro
- Colores VGA estándar en inglés: black, white, red, lime, blue, yellow, cyan, magenta, silver, gray, maroon, olive, green, purple, teal, navy.
- moderna
- Colores en español: negro, blanco, rojo, verde, azul, amarillo, cian, magenta, gris, naranja, violeta, marrón, rosa, lima, celeste, dorado.
COLOR cyan ' color de la paleta retro
Nota histórica: En v1.0 la paleta predeterminada era moderna. Cambió a retro en v1.1 para reforzar la estética de 8 bits del proyecto.
Define la cantidad de canales de audio disponibles para síntesis. Default: 4 (simula hardware de 8 bits). MODO 8 simula hardware de 16 bits.
Velocidad musical en beats por minuto. Afecta la duración de todas las figuras musicales. Default: 120.
Duración de una negra (ne) = 60000 ÷ BPM milisegundos. A 120 BPM, una negra dura 500ms.
Velocidad de animación de sprites en fotogramas por segundo. Default: 60. No afecta el game loop principal, que siempre apunta a 60fps.
Variables y arreglos
Declara una variable global. Las variables deben declararse antes de usarse. Todas las variables son globales — accesibles desde cualquier parte del programa incluyendo subprogramas.
- ENTERO
- Número sin parte decimal. Ejemplo: 42, -7, 0.
- FLOTANTE
- Número con parte decimal. Ejemplo: 3.14, -0.5.
- TEXTO
- Cadena de caracteres entre comillas dobles.
- BOOLEANO
- Solo puede ser VERDADERO o FALSO.
DECLARAR nombre COMO TEXTO
DECLARAR activo COMO BOOLEANO
x = 128
nombre = "jugador"
activo = VERDADERO
Case-insensitive: xJugador y xjugador son la misma variable. Los nombres de variable no pueden ser palabras clave del lenguaje.
Declara un arreglo unidimensional de n elementos del tipo indicado. El índice es base 1 (el primer elemento es [1]). El tamaño es fijo.
inventario[1] = "llave"
inventario[2] = "linterna"
' Recorrer con PARA
PARA i DE 1 A 6
IMPRIMIR inventario[i]
FIN PARA
Operadores
Operadores aritméticos. El operador + también concatena cadenas de texto.
- ^
- Potencia.
4 ^ 2 = 16 - \
- Raíz. El primer operando es el índice.
2 \ 9 = 3(raíz cuadrada de 9).3 \ 27 = 3(raíz cúbica de 27). - MOD
- Resto de la división entera.
10 MOD 3 = 1 - DIV
- Cociente entero.
10 DIV 3 = 3
potencia = 2 ^ 8 ' = 256
raiz = 2 \ 144 ' = 12
saludo = "Hola" + ", mundo" ' concatenación
Operadores lógicos. Solo funcionan como operadores en MAYÚSCULAS. En minúsculas (and, or, not) son identificadores válidos para variables.
' el jugador sobrevive
FIN SI
SI NOT COLISIONA(jugador) ENTONCES
x = x + velocidad
FIN SI
Precedencia completa (de menor a mayor): OR · XOR → AND → NOT → = <> < > <= >= COLISIONA → + - → * / MOD DIV → ^ \ → - (unario).
Condicional SI
Ejecuta un bloque si la condición es verdadera. OTRO SI encadena condiciones adicionales. SI NO es el bloque por defecto (else). Todos son opcionales excepto SI y FIN SI.
HACER game_over
OTRO SI vida < 25 ENTONCES
HACER advertencia_critica
OTRO SI vida < 50 ENTONCES
HACER advertencia
SI NO
HACER estado_normal
FIN SI
Selección SEGUN
Evalúa una expresión y ejecuta el bloque CASO cuyo valor coincida. CASO OTRO es el bloque por defecto. Alternativa más legible a cadenas de OTRO SI.
CASO "norte": HACER ir_norte
CASO "sur": HACER ir_sur
CASO "este": HACER ir_este
CASO "oeste": HACER ir_oeste
CASO OTRO: HACER detenerse
FIN SEGUN
Ciclos
Repite el bloque mientras la condición sea verdadera. La condición se evalúa antes de cada iteración — si es falsa desde el inicio, el bloque no ejecuta.
LEER save linea
TEXTO 10 y linea
y = y + 12
FIN MIENTRAS
Repite el bloque hasta que la condición sea verdadera. La condición se evalúa al final — ejecuta al menos una vez. Forma más común del game loop.
LIMPIAR
HACER actualizar_juego
HACER dibujar_todo
ESPERAR 16
HASTA TECLADO(TECLA_ESCAPE)
Ciclo con contador. ENPASOSDE es opcional y por defecto vale 1. Puede usarse con paso negativo para contar hacia atrás.
PARA i DE 0 A 15
COLOR HSL(i * 22, 100, 50)
RECTANGULO i*16 0 16 240 RELLENO
FIN PARA
' Contar hacia atrás
PARA i DE 10 A 1 ENPASOSDE -1
TEXTO 120 112 TEXTO(i)
ESPERAR 1000
FIN PARA
- ESCAPAR
- Interrumpe inmediatamente el ciclo en ejecución y pasa al código siguiente.
- ESPERAR <ms>
- Pausa la ejecución durante <ms> milisegundos. Cede el control al game loop.
ESPERAR 0cede sin esperar. - FINALIZAR
- Termina el programa y muestra el overlay FIN en el Player.
- PAUSAR
- Suspende el programa hasta REANUDAR o hasta que el usuario presione START.
- REANUDAR
- Reanuda si el programa estaba suspendido con PAUSAR.
Subprogramas
DEFINIR nombra un bloque de código reutilizable. HACER lo invoca. Los subprogramas no reciben parámetros ni devuelven valores — operan sobre variables globales. Deben definirse antes de ser invocados.
DECLARAR sy COMO ENTERO
DECLARAR sr COMO ENTERO
DEFINIR dibujar_estrella
POLIGONO sx sy sr 5 RELLENO
FIN DEFINIR
sx = 64 sy = 80 sr = 30
HACER dibujar_estrella
sx = 192 sy = 80 sr = 25
HACER dibujar_estrella
Imprimir para depurar: IMPRIMIR <expr> escribe en la consola del Player sin afectar el canvas. Acepta múltiples expresiones separadas por espacio.
Color
Establece los colores del estado de dibujo. COLOR solo establece trazo y relleno al mismo color. Las variantes permiten controles separados.
COLOR TRAZO white RELLENO blue ' trazo blanco, relleno azul
COLOR FONDO black ' fondo negro para LIMPIAR
Genera un color por modelo HSL. Se usa donde se espera un nombre de color.
- hue
- Matiz en el círculo cromático: 0-360. 0=rojo, 120=verde, 240=azul.
- saturación
- Viveza del color: 0 (gris) a 100 (vivo).
- luminosidad
- Claridad: 0 (negro) a 100 (blanco). 50 es el color puro.
COLOR HSL(hue, 30, 28) ' paredes
COLOR HSL(hue, 25, 14) ' piso
' Color que gira con un ángulo
COLOR HSL(angulo, 100, 60)
Grosor del trazo en píxeles. Afecta al borde de todas las figuras. Default: 1.
Geometría y dibujo
Rellena toda la pantalla con el COLOR FONDO actual. Llamar al inicio de cada frame para borrar el frame anterior.
Dibuja un punto de 1×1 píxel en las coordenadas indicadas con el COLOR TRAZO actual.
Dibuja líneas contiguas entre los pares de coordenadas. CERRAR cierra la figura uniendo el último punto con el primero. RELLENO pinta el interior.
LINEA 128 20 60 180 196 180 CERRAR RELLENO
Dibuja un círculo con centro en (x, y) y el radio indicado.
CIRCULO 128 112 60 RELLENO
Dibuja un rectángulo desde (x, y) con el ancho y alto dados. El orden de los parámetros es ancho antes que alto.
Parámetros en ese orden: x, y, ancho, alto. Invertirlos hace que las barras horizontales aparezcan verticales.
Dibuja un polígono regular inscrito en un círculo de radio dado, con el número de lados indicado. Ejemplo: 5 lados = pentágono, 6 = hexágono.
- TRIANGULO <x1> <y1> <x2> <y2> <x3> <y3>
- Por tres vértices arbitrarios.
- TRIANGULO EQUILATERO <x> <y> <lado>
- Equilátero desde el vértice superior.
- TRIANGULO ISOSCELES <x> <y> <lado> <ángulo>
- Isósceles con ángulo de apertura en grados.
- TRIANGULO ESCALENO <x> <y> <l1> <l2> <ángulo>
- Escaleno con dos lados y el ángulo entre ellos.
Todas las variantes aceptan RELLENO como modificador opcional al final.
Flood fill desde el punto dado. Rellena todos los píxeles contiguos del mismo color con el COLOR RELLENO actual. Usa algoritmo por scanline sobre ImageData.
Texto en canvas
Dibuja texto en el canvas con la fuente Press Start 2P. El argumento texto puede ser una expresión de cadena. SOMBREADO pinta el fondo con COLOR RELLENO para mejorar la legibilidad.
TEXTO 10 10 "PUNTAJE:"
TEXTO 90 10 TEXTO(puntos)
TEXTO 10 200 "Nombre: " + nombreJugador SOMBREADO
Renderiza texto con markdown extendido (negrita, cursiva, color, encabezados, etc.). El parámetro alto es opcional: si se indica, nada se dibuja más allá de y+alto.
- ancho
- Ancho máximo en píxeles para el word-wrap automático.
- alto
- Altura máxima en píxeles. Útil para áreas de texto de tamaño fijo.
TEXTO_MD 8 182 240 mensaje 56 ' limitado a 56px de alto
Función que retorna la altura en píxeles que ocuparía el texto con el ancho dado, sin dibujarlo. Útil para calcular posiciones antes de renderizar.
' Centrar verticalmente
y = (240 - alto) / 2
TEXTO_MD 8 y 240 mensaje
Sprites
Define un tipo de sprite. Con imagen es estático. Sin imagen acepta animaciones. Un sprite define el tipo; las instancias son las copias activas en pantalla.
Hace visible una instancia del sprite, opcionalmente en las coordenadas indicadas. La instancia es un número entero positivo que identifica la copia.
MOSTRAR enemigo 2 EN 240 50
MOSTRAR enemigo 3 EN 160 80
Mueve la instancia. Con HITBOX mueve solo la caja de colisión, dejando el visual en su posición. Permite hitboxes más precisas que el bounding box de la imagen.
- ROTAR [HITBOX] <sprite> <inst> A <grados>
- Rota la instancia. HITBOX: solo la caja de colisión.
- ESCALAR [HITBOX] <sprite> <inst> A <factor>
- Escala la instancia. 1.0 es tamaño original.
- VOLTEAR <sprite> <inst> HORIZONTAL | VERTICAL
- Espeja la instancia.
Animaciones
Define una animación asociada a un sprite con los fotogramas indicados. El sprite debe haberse creado sin imagen.
Reproduce la animación. BUCLE la repite indefinidamente. POR n la reproduce n veces.
- PAUSAR
- Congela la animación en el fotograma actual.
- DETENER
- Detiene y vuelve al fotograma 1.
Audio — archivos externos
Define un efecto de sonido (SFX) o música de fondo (BGM) desde un archivo externo (MP3, OGG, WAV). La carga es asíncrona.
- VOLUMEN <v>
- 0-100. Aliases: silencio=0, bajo=25, medio=50, alto=75, maximo=100.
- PANEO <p>
- -50 a 50. Aliases: izquierda=-50, centro=0, derecha=50.
Audio — síntesis por pistas
Define una pista musical por síntesis. Dentro del bloque se usan NOTA, TONO, SILENCIO y DINAMICA.
DINAMICA mf
NOTA Do4:ne Re4:ne Mi4:ne Fa4:ne
SILENCIO co
NOTA Sol4:bl
FIN PISTA
REPRODUCIR melodia BUCLE
Duración = 60000 ÷ BPM ms para la negra. Agregar punto multiplica por 1.5.
- cu · re · bl · ne · co · sc · fu · sf
- Cuadrada (8 negras) · Redonda (4) · Blanca (2) · Negra (1) · Corchea (½) · Semicorchea (¼) · Fusa (⅛) · Semifusa (1/16). Punto:
ne.= negra + corchea.
Capas y scroll
Carga una imagen en la capa con el factor de scroll. Las capas 0-2 son fondos con parallax (se mueven más lento). La capa 3 es la principal. La capa 4 es frontal (se mueve con la 3). La capa 5 es el HUD (estática).
Mueve la capa principal. Direcciones: izquierda, derecha, arriba, abajo. También acepta el nombre de una RUTA definida.
Define una ruta de scroll compleja basada en una figura geométrica. Permite scrolling circular, espiral u otras trayectorias.
Motor de tiles
Carga una imagen y la divide en celdas de tw×th píxeles. Los IDs de tile son base 1 (el tile en col=1, fila=1 es ID 1).
Crea una grilla de cols×filas en la capa indicada. Default: capa 3. El tilemap se pre-renderiza en un OffscreenCanvas y solo se redibujan los tiles modificados.
Coloca el tile con el ID indicado en la posición col, fila (base 1). RIGIDO activa una hitbox automática compatible con el motor de física.
Función que devuelve VERDADERO si la hitbox de la instancia de sprite colisiona con algún tile RIGIDO activo.
Física
Define la aceleración gravitacional global en píxeles por segundo al cuadrado. Default: 500. Valores típicos: 400-1000.
Activa o desactiva la física sobre una instancia de sprite. La física requiere tiles RIGIDO para resolución de colisiones.
Define la velocidad de la instancia en píxeles por segundo. vx positivo = derecha, vy positivo = abajo.
Negativos explícitos: usar paréntesis para valores negativos directos: VELOCIDAD jugador 1 A 100 (-200). Sin paréntesis, el parser interpreta 100 -200 como la resta 100−200.
Añade un impulso instantáneo a la velocidad actual. Ideal para saltos.
SI TECLADO("Z") AND EN_SUELO(jugador 1) ENTONCES
IMPULSO jugador 1 A 0 (-400)
FIN SI
- EN_SUELO()
- Devuelve VERDADERO si la instancia está apoyada sobre un tile RIGIDO.
- VEL_X() / VEL_Y()
- Devuelven la velocidad horizontal y vertical actual en px/s.
Archivos y datos
Abre un archivo. LECTURA usa fetch() desde el servidor. ESCRITURA usa localStorage (el archivo existe en el browser del usuario). ANEXAR agrega al final del archivo existente.
Asincrónico: ABRIR suspende la ejecución hasta que el archivo esté disponible. El game loop sigue dibujando frames durante la espera.
- LEER
- Lee la siguiente línea del archivo en la variable.
- ESCRIBIR
- Escribe una línea en el archivo.
- CERRAR
- Cierra el archivo. Si era ESCRITURA, persiste los cambios.
- FIN_ARCHIVO(<archivo>)
- VERDADERO si no quedan más líneas por leer.
Carga y parsea un archivo .qdat (formato declarativo de secciones y claves). El archivo se almacena en memoria bajo el nombre indicado.
nombre = LEER_DATO(mundo sala_1 nombre)
n = LEER_DATO(mundo sala_1 n) ' conexión norte
Formato .qdat: secciones con [nombre], claves con clave = valor, comentarios con #. Valores multilínea con """...""".
Teclado
Devuelve VERDADERO mientras la tecla está presionada. La forma con + verifica que todas las teclas estén presionadas simultáneamente (combo AND).
SI TECLADO("W") ENTONCES y = y - 3 FIN SI
SI TECLADO("Z") ENTONCES HACER saltar FIN SI
Teclas de letra/número: usar el carácter entre comillas: TECLADO("W"), TECLADO("5"). Teclas especiales (constantes): FLECHA_ARRIBA · FLECHA_ABAJO · FLECHA_IZQUIERDA · FLECHA_DERECHA · BARRA_ESPACIADORA · TECLA_ESCAPE · TECLA_ENTER · TECLA_TAB · BLOQ_MAYUS · SHIFT_IZQUIERDO · SHIFT_DERECHO · CTRL_IZQUIERDO · ALT_IZQUIERDO · TECLA_F1…F12 · TECLA_INICIO · TECLA_FIN · BACKSPACE · TECLA_INSERTAR · TECLA_SUPRIMIR · NUM_0…NUM_9 · NUM_ENTER.
Mouse
- BOTON_MOUSE(<acción>)
- Acciones: "click izquierdo/centro/derecho", "mantiene izquierdo/centro/derecho", "suelta izquierdo/centro/derecho".
- RUEDA_MOUSE(arriba | abajo)
- VERDADERO si la rueda se movió en esa dirección en este frame.
- MOUSE_ENCIMA(<sprite>)
- VERDADERO si el cursor está sobre la hitbox del sprite.
- POSICION_MOUSE(x | y)
- Coordenada del cursor en el espacio virtual de la pantalla QBJr.
Colisiones entre sprites
COLISIONA es un operador de comparación. La forma infija compara dos sprites específicos. La forma funcional compara contra todos los sprites registrados. Usa detección AABB (bounding box alineado con ejes).
SI proyectil COLISIONA enemigo ENTONCES
OCULTAR enemigo
puntos = puntos + 100
FIN SI
' Forma funcional
SI COLISIONA(jugador) ENTONCES vida = vida - 1 FIN SI
Funciones matemáticas
- ABS(<n>)
- Valor absoluto.
- RAIZ(<n>)
- Raíz cuadrada.
- POTENCIA(<base>, <exp>)
- Potencia (equivale al operador ^).
- SEN(<grados>) · COS(<grados>) · TAN(<grados>)
- Funciones trigonométricas. El ángulo se expresa en grados, no radianes.
- LOG(<n>) · LOG10(<n>) · LOG2(<n>)
- Logaritmo natural, base 10, base 2.
- RND()
- Número aleatorio entre 0 (inclusive) y 1 (exclusive).
- TRUNCAR(<n>)
- Elimina la parte decimal sin redondear.
TRUNCAR(3.9) = 3 - REDONDEAR(<n>)
- Redondea al entero más cercano.
x = 128 + COS(angulo) * 80
y = 120 + SEN(angulo) * 50
' Número aleatorio entre 1 y 6 (dado)
dado = TRUNCAR(RND() * 6) + 1
Funciones de cadena
- TEXTO(<número>)
- Convierte número a texto para concatenación.
- NUMERO(<texto>)
- Convierte texto numérico a número.
- LARGO(<texto>)
- Cantidad de caracteres de la cadena.
- RECORTAR(<texto>)
- Elimina espacios al inicio y al final.
- MAYUSCULA / MINUSCULA
- Convierte todo el texto a mayúsculas o minúsculas.
Funciones de cadena avanzadas, indexadas base-1 (el primer carácter es posición 1), coherentes con QBasic.
- BUSCAR(<texto>, <aguja> [, <desde>])
- Posición de la primera ocurrencia. 0 si no encuentra. → INSTR.
- EXTRAER(<texto>, <desde> [, <largo>])
- Subcadena desde la posición. → MID$.
- CORTAR_IZQ(<texto>, <n>)
- Primeros n caracteres. → LEFT$.
- CORTAR_DER(<texto>, <n>)
- Últimos n caracteres. → RIGHT$.
- REEMPLAZAR(<texto>, <viejo>, <nuevo>)
- Reemplaza todas las ocurrencias.
- REPETIR(<texto>, <n>)
- Repite el texto n veces.
- CARACTER(<n>)
- Carácter por código Unicode. → CHR$.
- CODIGO(<texto>)
- Código Unicode del primer carácter. → ASC.
sub = EXTRAER("hola mundo", 6, 5) ' = "mundo"
izq = CORTAR_IZQ("hola mundo", 4) ' = "hola"
rep = REPETIR("ab", 3) ' = "ababab"
Markdown extendido
- # texto #
- Blanco brillante (título inline, heredado de HORROR_ENGINE.BAS).
- *texto*
- Rojo (alertas / peligro).
- _texto_
- Verde (objetos / ítems).
- **texto**
- Negrita.
- //texto//
- Cursiva.
- __texto__
- Subrayado.
- ~~texto~~
- Tachado.
- ^texto^
- Superíndice (texto pequeño elevado).
- ~texto~
- Subíndice (texto pequeño bajo línea base).
- [c=color]texto[/c]
- Color por nombre de paleta o hex. Ejemplo:
[c=rojo]peligro[/c],[c=#FF4081]texto[/c]. - # Título
- Encabezado h1 (centrado, blanco grande).
- ## Subtítulo / ### h3
- Encabezados h2 y h3.
- ---
- Línea horizontal divisoria.
- ---===---
- Línea horizontal decorada.
TEXTO_MD 8 30 240 "**Día 3:** Encontré _la llave_. *Cuidado* con la puerta norte."
Para usar caracteres de marcado como literales, usar barra invertida: \\*, \\_, \\#.