SOLOMON'S KEY para ORIC-Atmos

dancresp
Mensajes: 5321
Registrado: 13 Nov 2010 02:08
Agradecido : 139 veces
Agradecimiento recibido: 275 veces

SOLOMON'S KEY para ORIC-Atmos

Mensajepor dancresp » 10 May 2019 00:16

SolomonsKey_Atmos-Spectrum.png
SolomonsKey_Atmos-Spectrum.png (21.88 KiB) Visto 681 veces


EL JUEGO
Solomon’s Key es un juego publicado por Tecmo en el año 1986, que fue licenciado para distintos sistemas a partir del año 1987. De las versiones de 8 bits se encargó US Gold.

Es un juego mezcla de plataformas y estrategia en el que controlamos a un pequeño mago que tiene que recoger una llave y salir por la puerta para pasar de nivel. El mago tiene la capacidad de crear y destruir unos bloques azules que le permitirán llegar a la llave. Cada nivel está lleno de enemigos que le matarán al más mínimo contacto. Disponemos de 5 vidas.

Esta versión sigue la misma mecánica del juego original, con las 17 pantallas de la versión ZX-Spectrum, que se repiten indefinidamente. El movimiento de los enemigos se ha adaptado a las limitaciones del BASIC.

Controles:
Mueve al mago a izquierda o derecha con “Z” y “X”.
Pulsa “L” para crear o destruir un bloque azul. Según tu posición, se creará delante de ti a tu altura o a una altura inferior.
Pulsa “P” para saltar, pudiendo controlar la dirección pulsando a continuación “Z” o “X”. Si tienes un bloque encima, lo destruyes de un cabezazo.

Descargar "Solomon's Key" para ORIC-Atmos en formato TAP:
Solomons.rar
(3.71 KiB) Descargado 15 veces


BLOQUES
Se ha dividido el listado en 10 bloques:

- Declaración de las variables y matrices e inicio del juego.
- Bucle principal de desarrollo.
- Movimiento de los enemigos.
- Movimiento del protagonista.
- Rutinas de las acciones del protagonista.
- Pasar el Nivel o perder una Vida.
- Rutina para mostrar el nivel de juego.
- Presentación e inicio de la partida.
- Cargar UDG.
- DATA con los UDG del juego y valores de matrices.


COMO FUNCIONA
Todo el programa ocupa 170 líneas.

5 – Definimos las variables del juego.
10 – Definimos las matrices del juego.
20 – Salto a la subrutina que redefine los caracteres y define variables globales.
40 – Mostrar el nivel en pantalla.
100 – REPEAT que indica el Inicio del bucle principal.
105 – Controla si estamos saltando.
110 – Si no tenemos suelo bajo los pies, el personaje cae.
115 – Coger la tecla pulsada.
120 – Tecla de Salto.
125 – Tecla de poner/quitar bloque.
130 – Tecla movimiento a la derecha.
135 – Tecla movimiento a la izquierda.
140 – Controla si el personaje toca puerta, llave o moneda.
150 – Salto a subrutina de movimiento de los enemigos.
155 – Volver al REPEAT si la variable U=0.
160 – Al salir del bucle mira el valor de U. U=-1 pasar de nivel y U=2 pierde una vida.
200 – Mover al fantasma a la derecha.
225 – Mover al fantasma a la izquierda.
300 – Controla la caída del personaje.
320 – Detecta que objeto tiene debajo del personaje.
350 – Rutina de salto.
400 – Poner/quitar bloque.
440 – Rutina de reposición de fondo al poner o quitar un bloque o coger un objeto.
500 – Rutina de pasar un nivel.
550 – Rutina de pérdida de vida y final de partida.
600 – Mostrar los marcadores de puntos, nivel y vidas.
2000 – Rutina que muestra el nivel. Los datos están codificados en la matriz M$.
2050 – Definir tipo, velocidad y dirección de los enemigos, y los coloca en pantalla.
2500 – Pantalla de presentación.
3000 – Selección de colores, borrar de pantalla, ocultar cursor y ocultar el “CAPS” superior.
3005 – Lectura de los DATA de los UDG.
3010 – Define variables con tiras de caracteres.
9000 – DATA con los gráficos de los UDG, posiciones, bloques de gráficos y codificación de los niveles.
9200 – Bloques gráficos usados por la instrucción DOKE.
9300 – Posición inicial del personaje según la pantalla.
9500 – Datos de los niveles.
9600 – Datos con los tipos y posición de los enemigos.


EL LISTADO

Código: Seleccionar todo

   5 X=0:S=0:D=0:M=0:H=0:G=0:J=0:E=0:K=0:F=0:I=0:P=0:L=0:N=0:Y=0

  10 DIMT(6),I(5),S(5),P(5),M(5),D(14),M$(17),X(17),E$(17)

  20 GOSUB3000
  40 GOSUB2500

     ' Bucle principal
 100 REPEAT
 105 IFSTHEN370
 110 IFPEEK(X+80)<122ANDPEEK(X+81)<122THENGOSUB300:GOTO150
 115 F=PEEK(520)
 120 IFF=157THEN350
 125 IFF=143THEN400
 130 IFF=176THEN200
 135 IFF=170THEN225
 140 IFM>26212THENGOSUB320
 150 GOSUB170
 155 UNTIL U

 160 IFU=-1THEN500ELSE550

     ' Mover Enemigos
 170 E=E+1:IFT(E)=0THENE=1
 171 POKEP(E),M(E):P(E)=P(E)+S(E):F=P(E):I=PEEK(F)
 172 IFI<114THENM(E)=I:POKEF,37:RETURN
 175 IFI<122THENU=2:RETURN
 176 IFI>128THENGOSUB440:DOKEY,N:DOKEY+40,I
 180 IFT(E)>4THENS(E)=-S(E):P(E)=F+S(E)+S(E)ELSEP(E)=I(E)
 185 M(E)=PEEK(P(E)):POKEP(E),37:RETURN

     ' Mover Derecha
 200 IFD=-1THEND=1:J=29554:G=30068:DOKEX,J:DOKEX+40,G:GOTO140
 205 IFPEEK(X+42)=37THENU=2:GOTO215
 210 IFPEEK(X+2)>121ORPEEK(X+42)>121THEN150
 215 DOKEX,M:X=X+1:M=DEEK(X):DOKEX,J:DOKEX+39,H:H=DEEK(X+40):DOKEX+40,G:GOTO140
 
     ' Mover Izquierda
 225 IFD=1THEND=-1:J=30582:G=31096:DOKEX,J:DOKEX+40,G:GOTO150
 230 IFPEEK(X+39)=37THENU=2:GOTO240
 235 IFPEEK(X-1)>121ORPEEK(X+39)>121THEN150
 240 DOKEX,M:X=X-1:M=DEEK(X):DOKEX,J:DOKEX+41,H:H=DEEK(X+40):DOKEX+40,G:GOTO140

     ' Caer
 300 IFPEEK(X+80)=37ORPEEK(X+81)=37THENU=2
 305 DOKEX,M:M=H:H=DEEK(X+80):X=X+40:DOKEX,J:DOKEX+40,G

     ' Que toca?
 320 IFM=27498THENU=(K=0):RETURN
 325 IFM=28526THENK=K-1:PING:P=P+50:GOSUB600:I=X-48085:GOSUB450:M=N:H=I:RETURN
 330 IFM=26213THENP=P+20:GOSUB600:I=X-48085:GOSUB450:M=N:H=I
 335 RETURN

     ' Saltar
 350 IFX<48127THEN150
 355 N=X-40:IFPEEK(N)=37ORPEEK(X-39)=37THENU=2:GOTO370
 360 IFPEEK(N)=252THENI=X-48165:GOSUB450:DOKEX-80,N:DOKEX-40,I:S=1:GOTO150
 365 IFPEEK(N)>121ORPEEK(X-39)>121THEN150ELSES=2:GOTO150
 370 S=S-1:DOKEX+40,H:H=M:X=X-40:M=DEEK(X):DOKEX,J:DOKEX+40,G
 375 F=PEEK(520):GOTO130

     ' Poner/quitar Bloque
 400 F=X+D+D:IFX/2=INT(X/2)THENF=F+80-D
 405 IFPEEK(F)>128THENI=F-48085:GOSUB450:DOKEF,N:DOKEF+40,I:GOTO150
 410 IFPEEK(F+40)=37ORPEEK(F+41)=37THEN150
 415 IFPEEK(F)<97ORPEEK(F)>100THEN150
 420 DOKEF,64506:DOKEF+40,65020:GOTO150

     ' Reponer el fondo al coger un objeto o quitar un bloque
 440 IFI<252THENY=F-I+250:I=Y+2ELSEY=F-40-I+252:I=Y+2
 450 I=(INT(I/80)+INT(I/2))/2:IFI=INT(I)THENN=25185:I=26979:RETURN
 455 N=25186:I=25632:RETURN

     ' Pasar Nivel
 500 ZAP:DOKEX,27498:DOKEX+40,28012:P=P+100:GOSUB600:WAIT250
 505 L=L+1:IFL=18THENL=1
 510 GOSUB610:GOSUB2000:GOTO100

     ' Perder Vida
 550 FORF=1TO5:IFT(F)THENPOKEP(F),37
 555 NEXT:SHOOT:V=V-1:GOSUB620:FORF=1TO5:PAPER1:WAIT10:PAPER0:WAIT10:NEXT
 560 IFVTHENGOSUB2000:GOTO100
 565 WAIT250:GETA$:GOTO40

     ' Marcadores
 600 PLOT9,0,CHR$(7)+RIGHT$("  "+STR$(P),4)+CHR$(1):RETURN
 610 PLOT23,0,CHR$(7)+RIGHT$(" "+STR$(L),2)+CHR$(1):RETURN
 620 PLOT35,0,CHR$(7)+MID$(STR$(V),2)+CHR$(1):RETURN

     ' Montar Pantalla
2000 I=1:FORF=1TO24STEP2:PLOT2,F,D$+"z{"+MID$(B$,I,30)+"z{"+D$
2005 PLOT2,F+1,D$+"|}"+MID$(C$,I,30)+"|}"+D$:IFI=1THENI=3ELSEI=1
2010 NEXT:PLOT2,25,D$+"z{z{z{z{z{z{z{z{z{z{z{z{z{z{z{z{z{"+D$
2012 PLOT2,26,D$+"|}|}|}|}|}|}|}|}|}|}|}|}|}|}|}|}|}"+D$
2015 I=48085:N=I:C=1:A$=M$(L):FORF=1TOLEN(A$):X=ASC(MID$(A$,F,1))
2020 IFX>96THENN=N+(X-96)*2:GOTO2045
2025 IFX>64THENFORJ=1TOX-64:DOKEN,D(C):DOKEN+40,D(C+7):N=N+2:NEXT:GOTO2040
2030 IFX=46THENI=I+80:N=I:GOTO2045
2035 IFX>47THENDOKEN,D(X-48):DOKEN+40,D(X-41):N=N+2:GOTO2045
2040 IFC=1THENC=5ELSEC=1
2045 NEXT:X=X(L):M=DEEK(X):H=DEEK(X+40):J=29554:G=30068:DOKEX,J:DOKEX+40,G
2050 FORF=1TO5:T(F)=0:NEXT:IFL=4ORL=12ORL=17THENK=3ELSEK=1
2055 E=1:FORF=1TOLEN(E$(L))STEP3:T(E)=VAL(MID$(E$(L),F,1))
2060 I(E)=48040+ASC(MID$(E$(L),F+1,1))-60+40*(ASC(MID$(E$(L),F+2,1))-64)
2065 S(E)=(T(E)/2<>INT(T(E)/2))+2:P(E)=I(E):M(E)=PEEK(I(E)):POKEI(E),37
2070 IFT(E)=3ORT(E)=4ORT(E)>6THENS(E)=S(E)*40
2075 E=E+1:NEXT:D=1:U=0:E=0:S=0:RETURN

     ' Pantalla de Presentación
2500 CLS:P=0:L=1:V=3
2502 FORF=1TO25:PLOT1,F,CHR$(VAL(MID$("6666602222200077711033005",F,1))):NEXT
2504 PLOT2,1,"zz{ zz{ z   zz{ {   { zz{ z  { { zz{"
2506 PLOT2,2,"{   { { {   { { z{ z{ { { z{ {   {"
2508 PLOT2,3,"zz{ { { {   { { { } { { { { z{   zz{"
2510 PLOT2,4,"  { { { {   { { {   { { { {  {     {"
2512 PLOT2,5,"zz{ zz} zz} zz} {   { ||} {  {   ||}"
2514 PLOT7,7,"z{    z{  z{z{z{z{  z{  z{"
2516 PLOT7,8,"|}  |}    |}        |}  |}"
2518 PLOT7,9,"z{z{      z{z{z{     z{z{"
2520 PLOT7,10,"z{  z{    z{          z{"
2522 PLOT7,11,"|}    |}  |}|}|}|}    |}"
2524 PLOT4,15,"                     vw"
2526 PLOT4,16,"  jk  no      vw     xy     rs"
2528 PLOT4,17,"  lm  pq      xy            tu"
2530 PLOT2,18,"z{z{z{z{z{z{z{z{z{z{z{z{z{z{z{z{z{z{"
2532 PLOT2,19,"|}|}|}|}|}|}|}|}|}|}|}|}|}|}|}|}|}|}"
2534 PLOT7,21,"KEYS: Z = LEFT - X = RIGHT"
2536 PLOT7,22,"      P = JUMP - L = BLOCK"
2538 PLOT6,25,"COPYRIGHT SCAINET SOFT, 2019"
2540 GETA$:CLS:PLOT2,0,CHR$(1)+"SCORE:        LEVEL:      LIVES:"
2545 GOSUB600:GOSUB610:GOSUB620:GOSUB2000:RETURN

     ' Inicializar Juego
3000 CLS:INK3:PAPER0:PLOT16,12,"WAIT ...":POKE#BBA3,0:POKE#26A,10
3005 FORF=46816TO47087:READD:POKEF,D:NEXT:FORF=46376TO46415:READD:POKEF,D:NEXT
3006 FOR F=1TO14:READD(F):NEXT:FORF=1TO17:READX(F):NEXT
3010 B$="abbbabbbabbbabbbabbbabbbabbbabbbabbb"
3015 C$="ci dci dci dci dci dci dci dci dci d":D$=CHR$(224)

     ' Gráficos UDG
9000 DATA30,31,31,16,26,28,30,31,0,46,48,48,24,30,62,54
9001 DATA27,29,30,31,31,31,31,30,58,48,0,0,56,56,48,0
9002 DATA41,45,37,45,41,45,37,45
9004 DATA0,31,31,30,28,24,24,16,0,63,0,0,0,0,0,0
9005 DATA16,16,16,16,16,16,16,0,2,0,2,0,10,0,42,0
9010 DATA0,15,31,60,59,52,52,48,0,51,56,52,24,4,8,4
9015 DATA52,52,52,56,60,31,13,0,8,4,8,20,36,8,16,0
9020 DATA0,0,0,0,0,0,0,0
9025 DATA3,4,9,17,20,39,47,35,48,8,36,34,10,57,61,45
9030 DATA59,35,47,47,35,59,35,47,5,5,5,45,45,45,61,61
9035 DATA0,2,22,25,31,13,6,3,0,6,0,32,32,0,0,2
9040 DATA3,1,0,0,0,0,2,0,32,62,34,42,42,34,62,0
9045 DATA3,1,1,15,0,1,4,11,48,60,63,0,54,60,0,62
9050 DATA6,22,16,22,26,24,49,1,62,0,58,52,52,0,58,60
9055 DATA3,15,63,0,27,15,0,31,48,32,32,60,0,32,8,52
9060 DATA31,0,23,11,11,0,23,15,24,26,2,26,22,6,35,32
9065 DATA15,31,42,61,62,31,63,63,62,60,42,52,50,52,34,20
9070 DATA31,63,63,63,47,29,54,0,50,52,50,52,50,52,48,0
9074 DATA 20,41,14,63,63,30,55,10
9075 DATA12,16,63,48,35,39,46,44,12,2,63,3,33,5,13,29
9080 DATA40,33,43,25,8,26,26,15,57,49,37,6,4,22,22,60

     ' Bloques gráficos
9200 DATA31610,27498,28526,26213,64506,23900,10022
9205 DATA32124,28012,29040,26727,65020,24414,10536

     ' Posición inicial personaje
9300 DATA48813,48727,48331,48729,48593,48487,48977,48979,48969,48973
9305 DATA48975,48729,48819,48975,48979,48991,48729

     ' DATA Niveles
9500 M$(1)=".g2..eACA.eA444*A.b4bACAb4.fC..cAAAc*AAA.cAa*E3*A.cAAAc*AAA.*"
9505 M$(2)=".a7a7.g4e3.aBiB.cBeB.eBaB..e*CB.cGBa2.aBiB..*"
9510 M$(3)="Ae*Ce*A.*Ad7Cc4aA.*A6d*AAAbAbA.*Ae*Ce*A.*MAA.*Ee*Ca*A.*ADd2ABa*A."
9511 M$(3)=M$(3)+"ABBe*CAA.*Ad*E3c*A.*AAc*EdA.*Ad*AAa*AAd*A.*Jd*A*"
9515 M$(4)="e*Aa*Aa*Ad.*Ci*C.a3*Ab*Ac*Ab*A3.*Ci*C...a*Ak*A..g3d2.bADADA.*b7i7."
9520 M$(5)="..c7g7.Be*Ae*B.g4.e*A434*A.a2e4.*Dc*Ac*D..dAe*A.f4a4."
9525 M$(6)=".c7c4d7...aA.g3e2.a*A..f4a4.e*E..*"
9530 M$(7)=".b7g*Aa7a*A.kAB.h*Ab*Ab3.bBe*B.fAb*A.gBb44.dAb*A.eB.C.2*AaB.B"
9535 M$(8)="d7f7.g4.aAEAEA.aAa4a4a*Aa4a4a*A.a*A4AAA4A4AAA4A."
9536 M$(8)=M$(8)+"a*Aa*A3*Aa*Aa*A2*Aa*A.a*A4AAA4A4AAA4A.a*Ae*Ae*A.aAEAEA...*"
9540 M$(9)=".f7a7...fA4*A..f*A3*A..f*A4*A...g*A*e2"
9545 M$(10)="e7.a4.aAa*Aa*ABA..a2cAABAAA3*AA..aAa*ABA..b*ADAa*AAAAA.."
9546 M$(10)=M$(10)+"a*AAA.*i4a4a4"
9550 M$(11)="..e4..bE.bCaA.b*Cb*B.e*A3b*A.*Db*Bb*A.g*BaA.a4a*AdCb2.6i*A*"
9555 M$(12)=M$(4)
9560 M$(13)="e*Ac*A.b7b*Aa2a*Ab7.e*Ac*A.b4bACAb4b..g4.b*ABAa3a*ABA.fAAA.."
9561 M$(13)=M$(13)+"bABAc*ABA.fAAA."
9565 M$(14)="7.b3.D4.f*A.b*BAC.fA44.AABb*A44.f*A44.c*AAD.f*A.*Db*A.2e*A*"
9570 M$(15)=".f747.a4k4.a4cAc*Ac4.e*Ac*A.d*Ae*A.d*Ae*A.*ABAg*ABA."
9571 M$(15)=M$(15)+"A4*AAg*AAa*A.*A4*AAg*AAa*A.*CAg*AC.*A2*AA4e4*AA3*A"
9575 M$(16)=".m2..6.6.6.6.6b4c4.c44a44.7b4a4a4.c4c4.l3"
9580 M$(17)=M$(4)

     ' DATA Posiciones enemigos
9600 E$(1)="6AF5MR"
9605 E$(2)="6AF4PB6ON6YX"
9610 E$(3)="1EF6SH6YR5CR6KP"
9615 E$(4)="6AJ6WL6NP"
9620 E$(5)="3HG6AN6OJ5QP5IP"
9625 E$(6)="4HF6EJ6EN6OR4ZF"
9630 E$(7)="4KB8KT5YJ6SN6OR"
9635 E$(8)="6NT6IH6UP6AV"
9640 E$(9)="6AL6PL6IP6XP5QX"
9645 E$(10)="6OH6AL6WP4FB"
9650 E$(11)="5OP5AT4DB6WR1CX"
9655 E$(12)=E$(4)
9660 E$(13)="5MN6EJ6UL6AH4ZF"
9665 E$(14)="6MD5AH6KL5AP5KT"
9670 E$(15)="5MH6AN6WN6OT5\T"
9675 E$(16)="2CH2CJ2CL2CN2CP"
9680 E$(17)=E$(4)
9690 RETURN


APUNTES FINALES
Casi cuatro años sin programar nada para el ORIC y cuando me pongo con “Averno”, quedo tan satisfecho del resultado que a continuación me lío con otro todavía más complejo.

AVERNO ha sido el primer juego que he hecho en BASIC donde el protagonista se mueve sobre el fondo sin borrarlo. Para ello monto toda la zona de juego en una matriz de texto y voy moviendo el fantasma, reponiendo el fondo a partir de los datos de esta matriz. El resultado es bueno, pero con el coste de tener que montar la matriz, proceso que tarda unos 10 segundos. A nivel gráfico, el uso de 3x2 caracteres me permitió hacer unos gráficos casi idénticos al original, pero monocromos.

Posteriormente, el usuario Dom50 del foro oric.org mejoró el aspecto utilizando una propiedad de los atributos de color de la pantalla que permiten que se puedan mostrar los colores complementarios de los colores principales. También mejoró la composición del nivel guardando las pantallas. Y para redondearlo, lo metió en un disquete. He de reconocer que ha mejorado mi versión y el aspecto es mejor. Chapó por él !!!


Los sprites
Con “Solomon’s Key” he querido experimentar un uso de “sprites” mejorado, sin tener que montar todo el lío de la matriz, pokeando directamente valores de 16 bits en la memoria de vídeo mediante la instrucción DOKE. Esta instrucción afecta a la dirección de memoria indicada y la siguiente.

Todo el proceso es bastante sencillo, y la verdad es que no se me había ocurrido antes. En resumidas cuentas, cada sprite tiene un tamaño de 2x2 caracteres. Antes de poner un sprite en pantalla guardo en dos variables numéricas el valor de los 2x2 caracteres donde irá. Esto se hace con un DEEK, que es un PEEK de 16 bits. La posición del sprite es una dirección de memoria y no dos coordenadas. Con dos DOKE pongo el sprite en pantalla de una forma rápida. Antes de moverlo, repongo el fondo en la posición correspondiente a partir del valor guardado en la variable numérica, cambio la posición del sprite, guardo en la variable el fondo y a continuación lo pongo en la nueva posición mediante los dos DOKE. El resultado salta a la vista.


La pantalla
El juego original en ZX-Spectrum tiene un ancho de pantalla de 32 caracteres. Dos para los márgenes y 15 bloques de 2x2 caracteres. Para que esta versión tuviera el mismo aspecto debería haber usado bloques de 3x2, pero con el ORIC solo puedo acceder a 38 columnas y habría necesitado 47. Esto me ha obligado a usar realmente 2x2, pero como sus caracteres son de 6 pixeles, en lugar de los 8 habituales, el aspecto final es el que es, con unos gráficos achatados. Y como todos los gráficos los he querido mostrar mediante dos DOKE, así se ha quedado.

Por otro lado, como el ancho de pantalla tienen más caracteres, he puesto una columna de bloques a ambos lados de la pantalla y otra inferior. Esto también me ha servido para controlar los límites de los elementos móviles del juego.

En las líneas 440 a 455 hay tres líneas de código que se encargan de calcular que bloque del fondo se ha de poner en una zona de la pantalla cuando se quita un bloque azul o al coger la llave o una moneda, o cuando un enemigo impacta con un bloque azul.


Los gráficos
El juego de caracteres del ORIC solo dispone de 128 caracteres. Si he de mantener las letras, números y algunos caracteres especiales, me las he visto y deseado para redefinir el mínimo número de gráficos posibles. El uso de dos caracteres en lugar de tres ha ayudado. El principal coste ha sido que el protagonista no mueve sus patitas, pero también ha servido para simplificar algo el código y mejorar el rendimiento. Sigo pudiendo mostrarlo todo con dos simples DOKE.

Y como siempre que se programa en el ORIC, los gráficos se han tenido que rediseñar ya que en lugar de la habitual matriz de 8x8 pixeles pasamos a una de 8x6, y solo disponemos de 12 pixeles horizontales en lugar de los 16 habituales de la mayoría de sistemas.

Otro problema ha sido el tema del color, ya que por la forma como gestiona los atributos lo he tenido que hacer monocromo, dando un poco de color en la presentación y en los marcadores. Para destacar los ladrillos que podemos destruir he aplicado la técnica de usar los colores complementarios de los dos colores principales añadiendo 128 al código ASCII del carácter. De esta forma, la zona de juego pasa de 2 a 4 colores.


Codificando los niveles
Y en este punto llegamos a la creación de la pantalla. Cada pantalla se compone de una matriz de 12 filas y 15 columnas. En cada una de las columnas hay un gráfico de 2x2 caracteres, como bloques de piedra, puertas, llaves o monedas. He optado por codificar los niveles mediante un formato similar al de “Averno” pero más simplificado. La presentación del nivel tarda aproximadamente unos 6 segundos, y la codificación se realizada de la siguiente forma:

- Una letra entre la “A” y la “Z” tiene un valor entre 1 y 26, y corresponde a los bloques de piedra que se han de mostrar. Alternativamente se muestran amarillos o azules.
- Un carácter “*” significa que cambia el tipo de bloque de piedra que debería mostrar, ya sea azul o amarillo.
- Una letra entre la “a” y la “z” tiene un valor entre 1 y 26, y corresponde a bloques vacíos de 2x2.
- Un carácter “.” significa un final de fila, saltando a la siguiente.
- Un carácter numérico corresponde a un objeto: 2-Puerta, 3-Llave, 4-Moneda, 6-Cabeza y 7-Desague. Los bloques 1 y 5 corresponden a los bloques de piedra amarillos y azules.

Screen_Code.png
Screen_Code.png (18.67 KiB) Visto 681 veces

Como se puede ver en este ejemplo, con 60 caracteres se han colocado 180 bloques.


Controlando al protagonista
Una de las primeras dificultades antes de empezar a desarrollar el juego fue como gestionar los distintos movimientos y acciones que puede hacer el protagonista. Al estar hecho el juego en BASIC no puedo leer varias teclas a la vez, con lo que ha tocado adaptarse a estas limitaciones.

- Pulsando “Z” y “X” movemos al mago a izquierda o derecha.
- Pulsando “P” saltamos. Si hay un bloque encima, lo rompemos. Si no, podemos subir la altura de un bloque. Si mientras estamos saltando pulsamos una tecla de dirección, nos moveremos en esa dirección.
- Pulsando “L” ponemos o quitamos un bloque azul. Si estamos justo encima de un bloque lo pondremos delante, y si no lo ponemos a la altura del suelo.


Enemigos
A diferencia del juego “Averno”, en este sí hay enemigos, y se mueven. He montado una rutina muy básica pero que a su vez me permite mover hasta cinco enemigos y definir dos velocidades (uno o dos caracteres), desplazamiento horizontal o vertical, y efecto rebote o no al tocar una pared, pudiendo destruir los bloques azules que toca. Todo en siete líneas de código. Y al igual que el protagonista, se mueven sin borrar el fondo y detectando si tocan al protagonista.

El tipo de movimiento del enemigo y su posición inicial se definen en los DATA a partir de la línea 9600. Cada enemigo requiere de tres caracteres: el primero indica el tipo, y los otros dos su posición inicial horizontal y vertical. Para las posiciones uso letras para poder indicar valores mayores a un dígito con un solo carácter.

La rutina de movimiento controla el número de enemigos que hay en ese nivel. Cuantos menos enemigos hay, con más frecuencia se mueven y más rápido son.

Los sprites de los enemigos también se desplazan sobre el fondo sin borrarlo. Al igual que el sprite del protagonista se ha usado la técnica de guardar en una matriz el carácter que había en pantalla antes de poner al enemigo en pantalla. Al moverlo, repone el fondo, se recalcula su nueva posición y a continuación se pone el gráfico del enemigo.


Resultado final
Relativo a la velocidad, el BASIC del ORIC se podría situar en la gama media de los ordenadores de 8 bits. Es uno de los más rápidos en imprimir en pantalla, pero para el resto de cosas quedaría al nivel del MSX o del ZX-Spectrum. Ordenadores como el Amstrad CPC son muy lentos imprimiendo en pantalla pero más rápidos con el resto, en línea con ordenadores como el BBC Micro/Electron o el Camputers Lynx. La gama baja se queda para el ZX-81 y sobretodo, el Texas Instruments TI/99-4A que come aparte.

Después de todo este ladrillo, he de reconocer que a pesar de las limitaciones del BASIC del ORIC, por aspecto y rendimiento, he quedado muy satisfecho. Parece un juego comercial, pero es BASIC puro y duro. Creo que no es habitual ver programas en BASIC como éste. Creo que me he puesto el listón muy alto, pero con la experimentación de estas técnicas, seguro que en breve hago algo más. Realmente, en el fondo ya tengo idea de adaptar todo un clásico inexistente en ORIC.


Pues nada más, solo me queda esperar que os guste...

Os invito a probarlo.

SolomonsKey_Screen1.png
SolomonsKey_Screen1.png (5.74 KiB) Visto 681 veces

SolomonsKey_Screen2.png
SolomonsKey_Screen2.png (9.57 KiB) Visto 681 veces

SolomonsKey_Screen3.png
SolomonsKey_Screen3.png (10.69 KiB) Visto 681 veces

SolomonsKey_Screen4.png
SolomonsKey_Screen4.png (10.58 KiB) Visto 681 veces

SolomonsKey_Screen5.png
SolomonsKey_Screen5.png (10.31 KiB) Visto 681 veces

SolomonsKey_Screen6.png
SolomonsKey_Screen6.png (9.48 KiB) Visto 681 veces

Avatar de Usuario
Taburoto
Mensajes: 1255
Registrado: 15 Mar 2011 00:40
Agradecido : 14 veces
Agradecimiento recibido: 81 veces

Re: SOLOMON'S KEY para ORIC-Atmos

Mensajepor Taburoto » 10 May 2019 00:25

Gracias por el programa,es fantástico

Avatar de Usuario
duca750
Mensajes: 1283
Registrado: 19 May 2015 10:52
Ubicación: Olivenza (Badajoz)
Agradecido : 241 veces
Agradecimiento recibido: 66 veces

Re: SOLOMON'S KEY para ORIC-Atmos

Mensajepor duca750 » 10 May 2019 06:53

Madre mía, con menudas cosas estás contribuyendo últimamente, gracias por compartirlo y por el trabajo que te has pegado.
-4mstr4d CPC464(7),472 Y 6128 (2) -sp3zy 16K&48K GOMAS,+2,+2A/2B +3 -cocbm1 64 Y -coam1** -0r1c 1 (2ud) y ATMOS** -m3s3x CANON V20, SPECTRAVIDEO 728,TOSHIBA HX10, PHILIPS VG8020,2 NMS 8250+GOTEK -j4tar1 STFM 800XL -3nt3r 64-ACORN ELECTRON -codrg1 32

Avatar de Usuario
minter
Mensajes: 2342
Registrado: 22 Jul 2014 18:51
Agradecido : 2101 veces
Agradecimiento recibido: 926 veces

Re: SOLOMON'S KEY para ORIC-Atmos

Mensajepor minter » 10 May 2019 08:26

Pedazo Port!!!
Y en Basic!!!

Y en Oric!!!! -shock

Te has ganado el premio de la revista de este mes de RetroWiki Magazine!!!

MilDuros.jpg
MilDuros.jpg (9.54 KiB) Visto 641 veces

Avatar de Usuario
ron
Mensajes: 18276
Registrado: 28 Oct 2010 14:20
Ubicación: retrocrypta
Agradecido : 1491 veces
Agradecimiento recibido: 1248 veces

Re: SOLOMON'S KEY para ORIC-Atmos

Mensajepor ron » 10 May 2019 08:35

Gracias por volver a hacerlo DaniWallyDancresp !!!

Avatar de Usuario
Chema
Mensajes: 2184
Registrado: 21 Jun 2012 20:13
Ubicación: Gijón
Agradecido : 1660 veces
Agradecimiento recibido: 551 veces
Contactar:

Re: SOLOMON'S KEY para ORIC-Atmos

Mensajepor Chema » 10 May 2019 08:48

Eres la caña tío. Enhorabuena!

Avatar de Usuario
Silicebit
Mensajes: 1483
Registrado: 16 May 2011 21:13
Ubicación: La buhardilla del silicio.
Agradecido : 98 veces
Agradecimiento recibido: 193 veces
Contactar:

Re: SOLOMON'S KEY para ORIC-Atmos

Mensajepor Silicebit » 10 May 2019 20:35

¡¡Olé y olé!! pa'la saca ahora mismo a probarlo, ¡gracias dancresp! -drinks
El 6809 es el Rolls-Royce de los 8bits, el 6502 es el Mercedes, y el Z80 el SEAT 850. Sorry, but... I think different. :-P -0r1c -m3s3x -t4nd1 -cbmja YouTube

Avatar de Usuario
web8bits
Mensajes: 1028
Registrado: 31 Oct 2010 10:34
Ubicación: Vigo
Agradecido : 108 veces
Agradecimiento recibido: 84 veces
Contactar:

Re: SOLOMON'S KEY para ORIC-Atmos

Mensajepor web8bits » 11 May 2019 11:44

Eres un verdadero crack, en serio, gracias por compartir tus conocimientos con el resto de los mortales.

jltursan
Mensajes: 2469
Registrado: 20 Sep 2011 13:59
Agradecido : 160 veces
Agradecimiento recibido: 437 veces

Re: SOLOMON'S KEY para ORIC-Atmos

Mensajepor jltursan » 12 May 2019 09:40

Nivelazo -shock

Y siendo BASIC encima podría ser portable a otros sistemas desfavorecidos.

Avatar de Usuario
Telemach
Mensajes: 63
Registrado: 20 Oct 2016 22:45
Agradecido : 61 veces
Agradecimiento recibido: 13 veces

Re: SOLOMON'S KEY para ORIC-Atmos

Mensajepor Telemach » 12 May 2019 22:53

Impresionante el trabajo y la explicación del código. Gracias!
-m3s3x (1/2/2+/turbo R) -cocbm1 -sp3zy -j4tar1 -4mstr4d -coam1 -b3b3c3 -0r1c -m4c -cosam -3nt3r -x68kxs

Water can flow...Water can crush...Be water my friend.

dancresp
Mensajes: 5321
Registrado: 13 Nov 2010 02:08
Agradecido : 139 veces
Agradecimiento recibido: 275 veces

Re: SOLOMON'S KEY para ORIC-Atmos

Mensajepor dancresp » 12 May 2019 23:24

Gracias a todos los vuestros comentarios y agradecimientos. -drinks

Si alguien encuentra algún fallo o lo que sea, que me lo haga saber.


Volver a “Lenguajes de Programación y herramientas Dev”

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado