Repository navigation
DEZ80: Nivel 3
- Introducción
-
Nivel 3: Práctica
- Video 3.P01: Introducción al nivel 3
- Video 3.P02: Reto: Ensambla con WinApe
- Video 3.P03: EJEMPLO: Reto 1.1
- Video 3.P04: PRACTICA: Animación de movimiento
- Video 3.P05: RETO: Usa el teclado
- Video 3.P06: PRÁCTICA: Saltos condicionales (II)
- Video 3.P07: PRACTICA: Pulsaciones de teclado
- Video 3.P08: PRACTICA: Usando variables
- Video 3.P09: RETO: Primer minijuego
- Video 3.P10: Toma el control
- Video 3.P11: DESAFIO: tu primer juego
Introducción a todo lo que se va a ver en este segundo nivel
- Reto 1.1: 4 primeros pixeles, en ensamblador
- Reto 1.2: Vagoneta de 8x8 píxeles, en la línea 12 de caracteres. Se debe poder dibujar en cualquier parte de la fila
- Reto 1.3: Crear rail. Tile de 4x4 píxeles. Bonus: Patrones
- Pintar 4 píxeles rojos, en ensamblador. En la fila 1, posición 1
; Reto 1.1: Pintar 4 pixeles rojos
org #4000
run #4000
;; Al almacenar #FF en la memoria de video se
;; pintan 4 pixeles rojos
;; La memoria de video comienza en #C000
ld a, #FF
ld (#C000), a
;; Terminar (Bucle infinito)
jr $- Resultado:

Se rellena la memoria de vídeo con el valor 0xFF, que hace que se pongan todos los píxeles rojos
;; Rellenar toda la memoria de video
org #4000
run #4000
ld hl, #C000 ;; Primera direccion de la memoria de video
ld b,#45
repetir2:
ld a,#F0 ;; Contador: posiciones a rellenar
repetir:
;--- Pintar 4 pixeles ojos
ld (hl), #FF
inc hl ;-- Apuntar a la siguiente posicion
dec a ;-- Decrementar contador
jr nz, repetir
dec b
jr nz, repetir2
;; Terminar (Bucle infinito)
jr $- Resultado:

- Este es el sprite a hacer:
![]()
;; Reto 1.2: Sprite de la vagoneta
org #4000
run #4000
;;-- Fila 12. Posicion 1: #C410
;-- Dibujar 8x4 pixeles izquierdos
ld hl,#C420
ld (hl), #88
ld h,#CC
ld (hl), #F8
ld h,#D4
ld (hl), #FE
ld h, #DC
ld (hl), #FF
ld h, #E4
ld (hl), #BB
ld h, #EC
ld (hl), #15
ld h, #F4
ld (hl), #4A
ld h, #FC
ld (hl), #04
;;-- Dibujar 8x4 pixeles derechos
inc hl
ld h,#C4
ld (hl), #11
ld h,#CC
ld (hl), #F1
ld h,#D4
ld (hl), #F7
ld h, #DC
ld (hl), #FF
ld h, #E4
ld (hl), #DD
ld h, #EC
ld (hl), #8A
ld h, #F4
ld (hl), #25
ld h, #FC
ld (hl), #02
;--- Terminar
jr $- Resultado:

- Esta es la baldosa (tile) para el rail
![]()
;; Reto 1.3: Suelo de tiles
org #4000
run #4000
;-- Dibujar Vagoneta
ld hl,#C410
ld (hl), #88
ld h,#CC
ld (hl), #F8
ld h,#D4
ld (hl), #FE
ld h, #DC
ld (hl), #FF
ld h, #E4
ld (hl), #BB
ld h, #EC
ld (hl), #15
ld h, #F4
ld (hl), #4A
ld h, #FC
ld (hl), #04
inc hl
ld h,#C4
ld (hl), #11
ld h,#CC
ld (hl), #F1
ld h,#D4
ld (hl), #F7
ld h, #DC
ld (hl), #FF
ld h, #E4
ld (hl), #DD
ld h, #EC
ld (hl), #8A
ld h, #F4
ld (hl), #25
ld h, #FC
ld (hl), #02
;;-- Dibujar el rail
ld a, #50 ;; Contador para repeticion
ld l, #60 ;; Posicion inicial
repetir:
ld h, #c4
ld (hl), #5F
ld h,#CC
ld (hl), #40
ld h, #D4
ld (hl), #60
ld h, #DC
ld (hl), #50
inc hl
dec a
jr nz, repetir
;--- Terminar
jr $- Resultado:

- Dibujar el suelo con un patrón de tiles...
;; Reto 1.3: Suelo de tiles (BONUS: Patrones)
org #4000
run #4000
;-- Dibujar Vagoneta
ld hl,#C410
ld (hl), #88
ld h,#CC
ld (hl), #F8
ld h,#D4
ld (hl), #FE
ld h, #DC
ld (hl), #FF
ld h, #E4
ld (hl), #BB
ld h, #EC
ld (hl), #15
ld h, #F4
ld (hl), #4A
ld h, #FC
ld (hl), #04
inc hl
ld h,#C4
ld (hl), #11
ld h,#CC
ld (hl), #F1
ld h,#D4
ld (hl), #F7
ld h, #DC
ld (hl), #FF
ld h, #E4
ld (hl), #DD
ld h, #EC
ld (hl), #8A
ld h, #F4
ld (hl), #25
ld h, #FC
ld (hl), #02
;;-- Dibujar el rail
ld l, #60 ;; Posicion inicial
ld b,#8 ;;-- Contador para repetir patron
patron:
ld a, #9 ;; Contador para repeticion
repetir:
;;-- Dibujar rail normal
ld h, #c4
ld (hl), #5F
ld h,#CC
ld (hl), #40
ld h, #D4
ld (hl), #60
ld h, #DC
ld (hl), #50
inc hl
dec a
jr nz, repetir
;;-- Dibujar rail roto
ld h,#c4
ld (hl), #00
ld h,#00
ld (hl), #04
ld h, #D4
ld (hl), #06
ld h, #DC
ld (hl), #05
inc hl
dec b
jr nz, patron
;--- Terminar
jr $
- Sprite de la bola:
![]()
;; Video 3.P04
;; Animacion de una bola
org #4000
run #4000
;; Cargar en HL direccion de la memoria de video
ld hl, #C000
repetir:
;; Dibujar sprite de la bola
;; HL debe apuntar a la primera linea
ld (hl), %01100000 ; Sprite bola Linea 1
ld h, #C8 ; Siguiente linea
ld (hl), %11110110 ; Linea 2
ld h, #D0
ld (hl), %11110110 ; Linea 3
ld h, #D8
ld (hl), %01100000 ; Linea 4
ld h,#C0 ; HL apunta a la primera linea
;; *** Hacer una pausa **
ld b, 16
wait:
halt
dec b
jr nz, wait
;; **** Borrar la bola ***
ld (hl), #00 ; Sprite bola Linea 1
ld h, #C8 ; Siguiente linea
ld (hl), #00 ; Linea 2
ld h, #D0
ld (hl), #00 ; Linea 3
ld h, #D8
ld (hl), #00 ; Linea 4
ld h,#C0 ; HL apunta a la primera linea
;; Avanzar a la siguiente posicion
inc hl
jp repetir
;; Bucle infinito (Terminar)
jr $
- Resultado:

- Reto 2.1: Vagoneta se mueve si A=1. Se mueve hasta el centro y termina. Bonus: BuenaFrenada
- Reto 2.2: Vagoneta parada. Al apretar ESPACIO se mueve a la derecha y se para. Bonus: SuperVeloz
- Reto 2.3: R para resetear. Rutinas de dibujado. Bonus: TeclasVariables
Se han utilizado rutinas, para luego poder reutilizar el código en otros retos:
- Programa completo:
;; Reto 2.1: Vagoneta en movimiento
;; La vagoneta se mueve si A=1
;; Se mueve hasta el centro
;; Si A=0 permanece parada
org #4000
run inicio
inicio:
;; Dibujar el suelo
call dibujar_suelo
;; Dibujar vagoneta en posicion inicial
ld hl, #C410
call dibujar_vagoneta
;; Asignar un valor a A
ld a, 1 ;; 1=Se mueve. 0=Se queda parada
;;-- Comprobar el valor de A
dec a
jr nz, parar ; Si A-1 !=0, terminar (vagoneta parada)
;;-- A vale 1. Animar vagoneta!
call animar_vagoneta
parar:
;; Terminar (bucle infinito)
jr $
;;-------------------------------------------------------------
;; Animar la vagoneta
;;
;; ENTRADAS:
;; HL: Posicion inicial (donde esta la vagoneta)
;;
;; MODIFICA
;; B,
;;-------------------------------------------------------------
animar_vagoneta:
;;-- Contador de repeticiones
ld a, #28
;;-- Bucle de animacion
next_pos:
;;-- Borrar la vagoneta
call borrar_sprite_8x8
;;-- Incrementar la posicion
inc hl
;;-- Dibujar la vagoneta en la nueva posicion
call dibujar_vagoneta
;;-- Esperar
ld b, #6
call wait
;;-- Una posicion menos
dec a
jr nz, next_pos
;;-- Vagoneta ha finalizado el recorrido
ret
;;-------------------------------------------------------------
;; Dibujar Vagoneta en posicion dada en HL
;;
;; ENTRADAS:
;; HL: Posicion de la vagoneta
;;
;; MODIFICA:
;; -
;;--------------------------------------------------------------
dibujar_vagoneta:
;;-- Fila 1
ld (hl), #88 ;-- Izquierda
inc hl
ld (hl), #11 ;-- Derecha
;;-- Fila 2
ld h,#CC
ld (hl),#F1 ;-- Derecha
dec hl
ld (hl),#F8 ; -- Izquierda
;;-- Fila 3
ld h, #D4
ld (hl), #FE ;-- Izquierda
inc hl
ld (hl), #F7 ;-- Derecha
;;-- Fila 4
ld h, #DC
ld (hl), #FF ;-- Derecha
dec hl
ld (hl), #FF ;-- Izquierda
;;-- Fila 5
ld h, #E4
ld (hl), #BB ;-- Izquierda
inc hl
ld (hl), #DD ;-- Derecha
;;-- Fila 6
ld h, #EC
ld (hl), #8A ;-- Derecha
dec hl
ld (hl), #15 ;-- Izquierda
;;-- Fila 7
ld h, #F4 ;-- Izquierda
ld (hl), #4A
inc hl
ld (hl), #25 ;-- Derecha
;;-- Fila 8
ld h, #FC ;-- Derecha
ld (hl), #02
dec hl
ld (hl), #04 ;-- Izquierda
;;-- Establecer la posicion de partida en HL
ld h, #C4
ret
;;-------------------------------------------------------------
;; Rutina de pausa
;;
;; ENTRADAS:
;; B: Unidades a pausar (1 unidad = 3.3ms aprox)
;;
;; MODIFICA
;; -
;;-------------------------------------------------------------
wait:
halt
dec b
jr nz, wait
ret
;;-----------------------------------------------------------
;; Borrar el sprite 8x8 situado en la posicion dada
;; por HL
;;
;; ENTRADAS:
;; HL: Posicion donde borrar
;;
;; MODIFICA:
;; -
;;------------------------------------------------------------
borrar_sprite_8x8:
;;-- Fila 1
ld (hl), #00 ;-- Izquierda
inc hl
ld (hl), #00 ;-- Derecha
;;-- Fila 2
ld h,#CC
ld (hl),#00 ;-- Derecha
dec hl
ld (hl),#00 ; -- Izquierda
;;-- Fila 3
ld h, #D4
ld (hl), #00 ;-- Izquierda
inc hl
ld (hl), #00 ;-- Derecha
;;-- Fila 4
ld h, #DC
ld (hl), #00 ;-- Derecha
dec hl
ld (hl), #00 ;-- Izquierda
;;-- Fila 5
ld h, #E4
ld (hl), #00 ;-- Izquierda
inc hl
ld (hl), #00 ;-- Derecha
;;-- Fila 6
ld h, #EC
ld (hl), #00 ;-- Derecha
dec hl
ld (hl), #00 ;-- Izquierda
;;-- Fila 7
ld h, #F4 ;-- Izquierda
ld (hl), #00
inc hl
ld (hl), #00 ;-- Derecha
;;-- Fila 8
ld h, #FC ;-- Derecha
ld (hl), #00
dec hl
ld (hl), #00 ;-- Izquierda
;;-- Establecer la posicion de partida en HL
ld h, #C4
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Dibujar el suelo. Esta compuesto por 160
;; tiles de suelo
;;
;; ENTRADAS:
;; Ninguna
;;
;; MODIFICA:
;; -HL, B
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dibujar_suelo:
ld hl, #C460 ;; Posicion inicial del suelo
ld b, #50 ;; Numero de tiles a colocar
next_tile:
call dibujar_tile_suelo ;; Dibujar una baldosa
inc hl ;; Poner la proxima en la derecha
dec b ;; Queda una menos
jr nz, next_tile ;; Repetir si todavia quedan tiles por poner
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Dibujar el Tile del suelo en la fila 12
;; ENTRADAS:
;; HL: Contiene la posicion donde dibujar el tile
;; MODIFICA:
;; -
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dibujar_tile_suelo:
ld (hl), #5F ;; Fila 1
ld h,#CC ;; Fila 2
ld (hl), #40
ld h, #D4 ;; Fila 3
ld (hl), #60
ld h, #DC ;; Fila 4
ld (hl), #50
ld h, #c4 ;; Posicionar de vuelta en la fila 1
retCuando A vale 1, este es el resultado: (La vagoneta se mueve)

Cuando A vale 0 la vagoneta permanece en reposo:

-
Cuando la vagoneta alcance una determinada posición, deberá ir frenando hasta alcanzar la posición final
-
Algoritmo:
- Rutina de animación normal hasta la posicion 0x28-x (en vez de hasta 0x28)
- Otra rutina de animación con frenada,en la que en cada pasada del bucle se incrementa el retardo (Se realiza x veces)
-
Programa completo: reto-2-1-BuenaFrenada.asm
-
Rutina: wait:
;;-------------------------------------------------------------
;; Rutina de pausa
;;
;; ENTRADAS:
;; B: Unidades a pausar (1 unidad = 3.3ms aprox)
;;
;; MODIFICA
;; -
;;-------------------------------------------------------------
wait:
halt
dec b
jr nz, wait
ret- Rutina: animacion_vagoneta2: Anima la vagoneta desde el extremo izquierdo hasta la posición 29 (0x1D)
;;-------------------------------------------------------------
;; Animar la vagoneta
;;
;; ENTRADAS:
;; HL: Posicion inicial (donde esta la vagoneta)
;;
;; MODIFICA
;; B, A
;;-------------------------------------------------------------
animar_vagoneta2:
;;-- Contador de repeticiones
ld a, #1D
;;-- Bucle de animacion
next_pos:
;;-- Borrar la vagoneta
call borrar_sprite_8x8
;;-- Incrementar la posicion
inc hl
;;-- Dibujar la vagoneta en la nueva posicion
call dibujar_vagoneta
;;-- Esperar
ld b, #8
call wait
;;-- Una posicion menos
dec a
jr nz, next_pos
;;-- Vagoneta ha finalizado el recorrido
ret- Rutina: animar_vagoneta_freno:
;;------------------------------------------------------------------
;; Animar la vagoneta con frenada
;;
;; ENTRADAS:
;; HL: Posicion actual
;;
;; MODIFICA
;; A,B
;;--------------------------------------------------------------------
animar_vagoneta_freno:
ld a, #B ;;-- Posiciones a avanzar con frenada
ld c,#8 ;;-- Retardo inicial
;;-- Bucle de animacion
next_pos_freno:
;;-- Borrar la vagoneta
call borrar_sprite_8x8
;;-- Incrementar la posicion
inc hl
;;-- Dibujar la vagoneta en la nueva posicion
call dibujar_vagoneta
;;-- Ahora el retardo es variable
;;-- Se va incrementando
ld b,c
call wait
inc c
inc c
inc c
inc c
inc c
;;-- Una posicion menos
dec a
jr nz, next_pos_freno
ret- Programa principal: main:
inicio:
;; Dibujar el suelo
call dibujar_suelo
;; Dibujar vagoneta en posicion inicial
ld hl, #C410
call dibujar_vagoneta
;; Asignar un valor a A
ld a, 1 ;; 1=Se mueve. 0=Se queda parada
;;-- Comprobar el valor de A
dec a
jr nz, parar ; Si A-1 !=0, terminar (vagoneta parada)
;;-- A vale 1. Animar vagoneta!
call animar_vagoneta2
call animar_vagoneta_freno
parar:
;; Terminar (bucle infinito)
jr $- Resultado:

-
La animación comienza cuando se aprieta la tecla de Espacio
-
Programa final: reto-2.2.asm
Para eliminar las caminonetas que quedan de la última ejecución, y no tener que estar dando al reset, he creado la rutina borrar_vagonetas
- Rutina: borrar_vagonetas:
;;=====================================
;; Borrar vagonetas. Pintar una linea de 8x8 pixeles de fondo
;; sobre el rail para eliminar vagonetas anteriores
;;
;; MODIFICA:
;; hl,A
;;=====================================
borrar_vagonetas:
ld hl, #C410
;;-- En la linea hay 40 caracteres
ld a, 40
borrar_next:
;;-- Borrar la posicion actual
call borrar_sprite_8x8:
;;-- Incrementar hl en 2 para apuntar al siguiente sprinte
inc hl
inc hl
dec a
jr nz, borrar_next
ret- Programa principal: main:
main:
;; Borrar vagonetas: Eliminar vagonetas de la ejecucion anterior
call borrar_vagonetas
;; Dibujar el suelo
call dibujar_suelo
;; Dibujar vagoneta en posicion inicial
ld hl, #C410
call dibujar_vagoneta
;;-- Guardar posicion actual de la vagoneta
push hl
comprobar_teclado:
;; Comprobar si se pulsa espacio
ld a, 47
call #BB1E
jr nz, espacio_pulsado ; Si Z no activo (tecla pulsada), saltar a pulsada
;;-- Tecla no pulsada. Repetir
jr comprobar_teclado
;;-- Espacio pulsado! Animar vagoneta
espacio_pulsado:
;;-- Recuperar posicion inicial de la vagoneta
pop hl
;;-- Animar vagoneta!
call animar_vagoneta
parar:
;; Terminar (bucle infinito)
jr $- Resultado: Ahora la vagoneta sólo se mueve al apretar la tecla espacio

- En vez de empezar con el espacio, se comienza con las teclas 1-5. La 1 es la velocidad lenta y la 5 la rápida
He modificado la rutina animar_vagoneta para que adminta como parámetro el registro C, que contiene la pausa a realizar en el bucle de animación, controlando así la velocidad
-
El programa completo está aquí: reto-2-2-superveloz.asm
-
Programa principal:
main:
;; Borrar vagonetas: Eliminar vagonetas de la ejecucion anterior
call borrar_vagonetas
;; Dibujar el suelo
call dibujar_suelo
;; Dibujar vagoneta en posicion inicial
ld hl, #C410
call dibujar_vagoneta
;;-- Guardar posicion actual de la vagoneta
push hl
comprobar_teclado:
;; Comprobar si se pulsa tecla 1
ld a, 64
call #BB1E
jr nz, tecla_1_pulsada ;; Tecla 1 : Velocidad lenta
;;-- Tecla 2?
ld a, 65
call #BB1E
jr nz, tecla_2_pulsada
;;-- Tecla 3??
ld a,57
call #BB1E
jr nz, tecla_3_pulsada
;;-- Tecla 4??
ld a,56
call #BB1E
jr nz, tecla_4_pulsada
;;-- Tecla 4??
ld a,49
call #BB1E
jr nz, tecla_4_pulsada
;;-- Tecla 5??
ld a,48
call #BB1E
jr nz, tecla_5_pulsada
;;-- Tecla no pulsada. Repetir
jr comprobar_teclado
;;-- Tecla 1: Velocidad lenta
tecla_1_pulsada:
ld c,#40 ;;-- Establecer pausa
jr animar
tecla_2_pulsada:
ld c, #30
jr animar
tecla_3_pulsada:
ld c, #20
jr animar
tecla_4_pulsada:
ld c, #10
jr animar
tecla_5_pulsada:
ld c, #6
animar:
;;-- Recuperar posicion inicial de la vagoneta
pop hl
;;-- Animar vagoneta!
call animar_vagoneta
parar:
;; Terminar (bucle infinito)
jr $- Resultado final, cuando se aprieta la tecla 1 (lento):

- Resultado final, cuando se aprieta la tecla 5 (rápido):

Igual que reto 2.2, pero ahora cuando la vagoneta llega al final y se para, se vuelve a comenzar si se pulsa la tecla R (de reset)
- Programa principal:
main:
;; Borrar vagonetas: Eliminar vagonetas de la ejecucion anterior
call borrar_vagonetas
;; Dibujar el suelo
call dibujar_suelo
;; Dibujar vagoneta en posicion inicial
ld hl, #C410
call dibujar_vagoneta
;;-- Guardar posicion actual de la vagoneta
push hl
comprobar_teclado:
;; Comprobar si se pulsa espacio
ld a, 47
call #BB1E
jr nz, espacio_pulsado ; Si Z no activo (tecla pulsada), saltar a pulsada
;;-- Tecla no pulsada. Repetir
jr comprobar_teclado
;;-- Espacio pulsado! Animar vagoneta
espacio_pulsado:
;;-- Recuperar posicion inicial de la vagoneta
pop hl
;;-- Animar vagoneta!
call animar_vagoneta
parar:
;; Comprobar el teclado
ld a, 50
call #BB1E
jr nz, tecla_r_pulsada
;;-- Esperar a que se pulse tecla R
jr parar
tecla_r_pulsada:
jr main- Resultado:

-
Las teclas para mover la vagoneta y reiniciarla se deben poder redefinir en unas variables, de forma que cambiando su valor se eligen otras teclas
-
Programa principal:
org #4000
run main
;;==============================
;; VARIABLES
;;==============================
tecla_start:
db 18 ;;-- 47:Spacio
tecla_reset:
db 79 ;;-- 50: Tecla R
main:
;; Borrar vagonetas: Eliminar vagonetas de la ejecucion anterior
call borrar_vagonetas
;; Dibujar el suelo
call dibujar_suelo
;; Dibujar vagoneta en posicion inicial
ld hl, #C410
call dibujar_vagoneta
;;-- Guardar posicion actual de la vagoneta
push hl
comprobar_teclado:
;; Comprobar si se pulsa espacio
ld a, (tecla_start)
call #BB1E
jr nz, espacio_pulsado ; Si Z no activo (tecla pulsada), saltar a pulsada
;;-- Tecla no pulsada. Repetir
jr comprobar_teclado
;;-- Espacio pulsado! Animar vagoneta
espacio_pulsado:
;;-- Recuperar posicion inicial de la vagoneta
pop hl
;;-- Animar vagoneta!
call animar_vagoneta
parar:
;; Comprobar el teclado
ld a, (tecla_reset)
call #BB1E
jr nz, tecla_r_pulsada
;;-- Esperar a que se pulse tecla R
jr parar
tecla_r_pulsada:
jr mainDibujar un dado por la cara que se indique en el registro A
org #4000
run inicio
inicio:
ld a,2 ;;-- Numero de cara a dibujar
call dibuja_cara_A ;;-- Dibujar la cara indicaa en A
jr $
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Dibujar la Cara indicada en el registro A
;;
;; ENTRADA:
;; A: Numero de cara a dibujar (1-6)
;; MODIFICA:
;; HL, A
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dibuja_cara_A:
ld hl, #C000 ;; Posicion donde dibujar la cara
dec a ;; Restar 1 a A
jr z, era_un_1 ;-- Si A-1 = 0,entonces saltar
;;-- Comprobar si es 2
dec a ;;-- Restar 1 a A
jr z, era_un_2 ; Si A-2 = 0, saltar
;;-- Es > 2
;; Comprobar si es 3
dec a ;; Restar 1 a A
jr z, era_un_3 ; Si A-3 = 0, saltar
;; Es > 3
;; Comprobar si es 4
dec a
jr z, era_un_4
;; Es > 4
;; Comprobar si es 5
dec a
jr z, era_un_5
call dibuja_cara_6
jr fin
era_un_5:
call dibuja_cara_5
jr fin
era_un_4:
call dibuja_cara_4
jr fin
era_un_3:
call dibuja_cara_3
jr fin
era_un_2:
call dibuja_cara_2
jr fin
era_un_1:
call dibuja_cara_1
fin:
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Dibuja un dado mostrando la cara 1, en la posicion
;; en que se encuentra HL, asumiendo que esta en
;; la primera fila de caracteres de pantalla (C000-C04A)
;; ENTRADA:
;; HL: Posicion donde dibujar el dado
;; MODIFICA
;; -
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dibuja_cara_1:
ld (hl), #F0 ;; 4 Pixeles a la izquierda
inc hl ;; +1 Avanzar a la derecha
ld (hl), #E0 ;; 4 Pixeles derecha
ld h, #C8 ;; Bajar a fila 2
;; Fila 2
ld (hl), #E0
dec hl ;; -1 Retroceder a la izquierda
ld (hl), #F0
ld h, #D0 ; Bajar a fila 3
;; Fila 3
ld (hl), #F3
inc hl
ld (hl), #E8
ld h, #D8 ; Bajar a fila 4
;; Fila 4
ld (hl), #E8
dec hl
ld (hl), #F3
ld h, #E0 ; Bajar a fila 5
;; Fila 5
ld (hl), #F3
inc hl
ld (hl), #E8
ld h, #E8 ; Bajar a fila 6
;; Fila 6
ld (hl), #E0
dec hl
ld (hl), #F0
ld h, #F0 ; Bajar a fila 7
;; Fila 7
ld (hl), #F0
inc hl
ld (hl), #E0
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Dibuja un dado mostrando la cara 2
;; ENTRADA:
;; HL: Posicion donde dibujar el dado
;; MODIFICA
;; -
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dibuja_cara_2:
ld (hl), #F0 ;; 4 Pixeles a la izquierda
inc hl ;; +1 Avanzar a la derecha
ld (hl), #E0 ;; 4 Pixeles derecha
ld h, #C8 ;; Bajar a fila 2
ld (hl), #E0
dec hl ;; Retroceder a la izquierda
ld (hl), #F0
ld h, #D0 ; Bajar a fila 3
ld (hl), #F6
inc hl
ld (hl), #EC
ld h, #D8 ; Bajar a fila 4
ld (hl), #EC
dec hl
ld (hl), #F6
ld h, #E0 ; Bajar a fila 5
ld (hl), #F6
inc hl
ld (hl), #EC
ld h, #E8 ; Bajar a fila 6
ld (hl), #E0
dec hl
ld (hl), #F0
ld h, #F0 ; Bajar a fila 7
ld (hl), #F0
inc hl
ld (hl), #E0
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Dibuja un dado mostrando la cara 3
;; ENTRADA:
;; HL: Posicion donde dibujar el dado
;; MODIFICA
;; -
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dibuja_cara_3:
ld (hl), #F0 ;; 4 Pixeles a la izquierda
inc hl ;; +1 Avanzar a la derecha
ld (hl), #E0 ;; 4 Pixeles derecha
ld h, #C8 ;; Bajar a fila 2
ld (hl), #EC
dec hl ;; Retroceder a la izquierda
ld (hl), #F6
ld h, #D0 ; Bajar a fila 3
ld (hl), #F6
inc hl
ld (hl), #EC
ld h, #D8 ; Bajar a fila 4
ld (hl), #E0
dec hl
ld (hl), #F0
ld h, #E0 ; Bajar a fila 5
ld (hl), #F1
inc hl
ld (hl), #E8
ld h, #E8 ; Bajar a fila 6
ld (hl), #E8
dec hl
ld (hl), #F1
ld h, #F0 ; Bajar a fila 7
ld (hl), #F0
inc hl
ld (hl), #E0
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Dibuja un dado mostrando la cara 4
;; ENTRADA:
;; HL: Posicion donde dibujar el dado
;; MODIFICA
;; -
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dibuja_cara_4:
ld (hl), #F0 ;; 4 Pixeles a la izquierda
inc hl ;; +1 Avanzar a la derecha
ld (hl), #E0 ;; 4 Pixeles derecha
ld h, #C8 ;; Bajar a fila 2
ld (hl), #EC
dec hl ;; Retroceder a la izquierda
ld (hl), #F6
ld h, #D0 ; Bajar a fila 3
ld (hl), #F6
inc hl
ld (hl), #EC
ld h, #D8 ; Bajar a fila 4
ld (hl), #E0
dec hl
ld (hl), #F0
ld h, #E0 ; Bajar a fila 5
ld (hl), #F6
inc hl
ld (hl), #EC
ld h, #E8 ; Bajar a fila 6
ld (hl), #EC
dec hl
ld (hl), #F6
ld h, #F0 ; Bajar a fila 7
ld (hl), #F0
inc hl
ld (hl), #E0
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Dibuja un dado mostrando la cara 5
;; ENTRADA:
;; HL: Posicion donde dibujar el dado
;; MODIFICA
;; -
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dibuja_cara_5:
ld (hl), #F0 ;; 4 Pixeles a la izquierda
inc hl ;; +1 Avanzar a la derecha
ld (hl), #E0 ;; 4 Pixeles derecha
ld h, #C8 ;; Bajar a fila 2
ld (hl), #EC
dec hl ;; Retroceder a la izquierda
ld (hl), #F6
ld h, #D0 ; Bajar a fila 3
ld (hl), #F0
inc hl
ld (hl), #E0
ld h, #D8 ; Bajar a fila 4
ld (hl), #E8
dec hl
ld (hl), #F1
ld h, #E0 ; Bajar a fila 5
ld (hl), #F0
inc hl
ld (hl), #E0
ld h, #E8 ; Bajar a fila 6
ld (hl), #EC
dec hl
ld (hl), #F6
ld h, #F0 ; Bajar a fila 7
ld (hl), #F0
inc hl
ld (hl), #E0
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Dibuja un dado mostrando la cara 6
;; ENTRADA:
;; HL: Posicion donde dibujar el dado
;; MODIFICA
;; -
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dibuja_cara_6:
ld (hl), #F0 ;; 4 Pixeles a la izquierda
inc hl ;; +1 Avanzar a la derecha
ld (hl), #E0 ;; 4 Pixeles derecha
ld h, #C8 ;; Bajar a fila 2
ld (hl), #EC
dec hl ;; Retroceder a la izquierda
ld (hl), #F6
ld h, #D0 ; Bajar a fila 3
ld (hl), #F0
inc hl
ld (hl), #E0
ld h, #D8 ; Bajar a fila 4
ld (hl), #EC
dec hl
ld (hl), #F6
ld h, #E0 ; Bajar a fila 5
ld (hl), #F0
inc hl
ld (hl), #E0
ld h, #E8 ; Bajar a fila 6
ld (hl), #EC
dec hl
ld (hl), #F6
ld h, #F0 ; Bajar a fila 7
ld (hl), #F0
inc hl
ld (hl), #E0
ret
- Resultado:

- Códigos de las teclas

Al apretar la tecla de espacio se dibujan 4 píxeles rojos. Al soltarla se borran
org #4000
run inicio
inicio:
;; Comprobar si se pulsa espacio
ld a, 47
call #BB1E
jr nz, pulsada ; Si Z no activo (tecla pulsada), saltar a pulsada
;; No pulsada
;; Borrar la vagoneta
ld hl, #C000
call borrar_8x8 ;; Dibuja un cuadrado 8x8 color fondo
jr continuar ;;-- Continuar la ejecucion
pulsada:
;; Dibujar vagoneta
ld hl, #C000
call dibujar_vagoneta
continuar:
jr inicio
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Borrar los pixeles
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
borrar_8x8:
ld (hl), 00
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Dibujar los pixeles
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dibujar_vagoneta:
ld (hl), #FF
ret- Resultado:

- Reto 3.1: Barril 4x8 al final. Bonus: Posición variable
- Reto 3.2: Barriles hasta el final
- Reto 3.3: Espacio para Frenar
- Reto 3.4: Explosion al chocar
- Sprite del Barril:
![]()
- Rutina: dibujar_barril
;;========================================
;; Dibujar barril
;;
;; ENTRADA:
;; HL: Posicion del barril en memoria de video
;;
;; MODIFICA:
;;
;;========================================
dibujar_barril:
;;-- Fila 1
ld (hl), #99
;;-- Fila 2
ld h,#CC
ld (hl),#6F
;;-- Fila 3
ld h, #D4
ld (hl), #9F
;;-- Fila 4
ld h, #DC
ld (hl), #FF
;;-- Fila 5
ld h, #E4
ld (hl), #6F
;;-- Fila 6
ld h, #EC
ld (hl), #9F
;;-- Fila 7
ld h, #F4
ld (hl), #F6
;;-- Fila 8
ld h, #FC
ld (hl), #60
;;-- Establecer la posicion de partida en HL
ld h, #C4
ret- Programa principal:
;;==============================
;; VARIABLES
;;==============================
tecla_start:
db 47 ;;-- 47:Spacio
tecla_reset:
db 50 ;;-- 50: Tecla R
vagoneta_home:
dw #C410
barril_home:
dw #C43A
main:
;; Borrar vagonetas: Eliminar vagonetas de la ejecucion anterior
call borrar_vagonetas
;; Dibujar el suelo
call dibujar_suelo
;; Dibujar vagoneta en posicion inicial
ld hl, (vagoneta_home)
call dibujar_vagoneta
;; Dibujar el barril
ld hl, (barril_home)
call dibujar_barril
comprobar_teclado:
;; Comprobar si se pulsa espacio
ld a, (tecla_start)
call #BB1E
jr nz, espacio_pulsado ; Si Z no activo (tecla pulsada), saltar a pulsada
;;-- Tecla no pulsada. Repetir
jr comprobar_teclado
;;-- Espacio pulsado! Animar vagoneta
espacio_pulsado:
;;-- Recuperar posicion inicial de la vagoneta
ld hl, (vagoneta_home)
;;-- Animar vagoneta!
call animar_vagoneta
parar:
;; Comprobar el teclado
ld a, (tecla_reset)
call #BB1E
jr nz, tecla_r_pulsada
;;-- Esperar a que se pulse tecla R
jr parar
tecla_r_pulsada:
jr main- Resultado:

- Programa principal:
;;==============================
;; VARIABLES
;;==============================
tecla_start:
db 47 ;;-- 47:Spacio
tecla_reset:
db 50 ;;-- 50: Tecla R
vagoneta_home:
dw #C410
;;-- Direccion de memoria donde colocar barril
barril_home:
dw #0000
;;-- Posicion del barril en la fila
x_inicio:
db #30
main:
;; Calcular la posicion del barril
;; barril_home = #C410 + x_inicio
ld hl,#C410
ld a, (x_inicio)
add l ;; A = x_inicio + L
ld l,a ;; L = x_inicio + L
ld (barril_home), hl
;; Borrar vagonetas: Eliminar vagonetas de la ejecucion anterior
call borrar_vagonetas
;; Dibujar el suelo
call dibujar_suelo
;; Dibujar vagoneta en posicion inicial
ld hl, (vagoneta_home)
call dibujar_vagoneta
;; Dibujar el barril
ld hl, (barril_home)
call dibujar_barril
comprobar_teclado:
;; Comprobar si se pulsa espacio
ld a, (tecla_start)
call #BB1E
jr nz, espacio_pulsado ; Si Z no activo (tecla pulsada), saltar a pulsada
;;-- Tecla no pulsada. Repetir
jr comprobar_teclado
;;-- Espacio pulsado! Animar vagoneta
espacio_pulsado:
;;-- Recuperar posicion inicial de la vagoneta
ld hl, (vagoneta_home)
;;-- Animar vagoneta!
call animar_vagoneta
parar:
;; Comprobar el teclado
ld a, (tecla_reset)
call #BB1E
jr nz, tecla_r_pulsada
;;-- Esperar a que se pulse tecla R
jr parar
tecla_r_pulsada:
jr main- Resultado: Barril colocado en posición 0x30

- Rutina: dibujar_barriles
;;========================================
;; Dibujar barriles
;;
;; MODIFICA:
;; HL, A
;;========================================
dibujar_barriles:
;;-- Obtener posicion inicial en memoria de video
ld hl, (barril_home)
;;-- Contador de barriles
ld a, #13
dibujar_sig_barril:
;; Dibujar un barril
call dibujar_barril
;; Apuntar a la siguiente posicion
inc hl
inc hl
;;-- Un barril menos por dibujar
dec a
jr nz, dibujar_sig_barril
retEn el programa principal simplemente se llama a dibujar barriles:
main:
;; Borrar vagonetas: Eliminar vagonetas de la ejecucion anterior
call borrar_vagonetas
;; Dibujar el suelo
call dibujar_suelo
;; Dibujar vagoneta en posicion inicial
ld hl, (vagoneta_home)
call dibujar_vagoneta
;;-- Dibujar los barriles
call dibujar_barriles
...
...- Resultado:

- Este es el programa principal:
;;==============================
;; VARIABLES
;;==============================
tecla_start:
db 47 ;;-- 47:Spacio
tecla_reset:
db 50 ;;-- 50: Tecla R
vagoneta_home:
dw #C410
barril_home:
dw #C43A
;;-- Posicion final de la vagoneta
pos_vagoneta:
db #28
;;-- Posicion de la vagoneta en la memoria de video
pos_vagoneta_video:
dw 00
;;========
;; MAIN
;;========
main:
;; Borrar vagonetas: Eliminar vagonetas de la ejecucion anterior
call borrar_vagonetas
;; Dibujar el suelo
call dibujar_suelo
;; Dibujar vagoneta en posicion inicial
ld hl, (vagoneta_home)
call dibujar_vagoneta
;;-- Dibujar los barriles
call dibujar_barriles
;;-- Inicializar variables
ld a,#28
ld (pos_vagoneta), a ;;-- Posicion inicial vagoneta
ld hl, (vagoneta_home)
ld (pos_vagoneta_video), hl ;;-- Posicion vagoneta en memoria video
;;-- Espera incial
ld b, #80
call wait
;;-- Animar vagoneta!
;;-- Bucle de animacion
next_pos:
;;-- Recuperar posicion inicial de la vagoneta
ld hl, (pos_vagoneta_video)
;;-- Borrar la vagoneta
call borrar_sprite_8x8
;;-- Incrementar la posicion
inc hl
;;-- Dibujar la vagoneta en la nueva posicion
call dibujar_vagoneta
;;-- Guardar la posicion de la vagoneta
ld (pos_vagoneta_video), hl
;;-- Esperar
ld b, #6
call wait
;;-- Comprobar el teclado
ld a, (tecla_start)
call #BB1E
jr nz, espacio_pulsado ; Si Z no activo (tecla pulsada), saltar a pulsada
;;-- Una posicion menos
ld a, (pos_vagoneta)
dec a
ld (pos_vagoneta),a
jr nz, next_pos
;;-- Vagoneta ha finalizado el recorrido (HAS PERDIDO!!!!)
;;-- Espacio pulsado! Animar vagoneta
espacio_pulsado:
parar:
;; Comprobar el teclado
ld a, (tecla_reset)
call #BB1E
jr nz, tecla_r_pulsada
;;-- Esperar a que se pulse tecla R
jr parar
tecla_r_pulsada:
jr main- Resultado:

- Sprites de la explosión:

Desde el programa principal se llama a la rutina animacion_explosion:
- Programa principal
;;========
;; MAIN
;;========
main:
;; Borrar vagonetas: Eliminar vagonetas de la ejecucion anterior
call borrar_vagonetas
;; Dibujar el suelo
call dibujar_suelo
;; Dibujar vagoneta en posicion inicial
ld hl, (vagoneta_home)
call dibujar_vagoneta
;;-- Dibujar los barriles
call dibujar_barriles
;;-- Inicializar variables
ld a,#28
ld (pos_vagoneta), a ;;-- Posicion inicial vagoneta
ld hl, (vagoneta_home)
ld (pos_vagoneta_video), hl ;;-- Posicion vagoneta en memoria video
;;-- Espera incial
ld b, #80
call wait
;;-- Animar vagoneta!
;;-- Bucle de animacion
next_pos:
;;-- Recuperar posicion de la vagoneta
ld hl, (pos_vagoneta_video)
;;-- Borrar la vagoneta
call borrar_sprite_8x8
;;-- Incrementar la posicion
inc hl
;;-- Dibujar la vagoneta en la nueva posicion
call dibujar_vagoneta
;;-- Guardar la posicion de la vagoneta
ld (pos_vagoneta_video), hl
;;-- Esperar
ld b, #6
call wait
;;-- Comprobar el teclado
ld a, (tecla_start)
call #BB1E
jr nz, espacio_pulsado ; Si Z no activo (tecla pulsada), saltar a pulsada
;;-- Una posicion menos
ld a, (pos_vagoneta)
dec a
ld (pos_vagoneta),a
jr nz, next_pos
;;-- Recuperar posicion de la vagoneta
ld hl, (pos_vagoneta_video)
;;-- Borrar la vagoneta
call borrar_sprite_8x8
inc hl
;;-- Vagoneta ha finalizado el recorrido (HAS PERDIDO!!!!)
call animacion_explosion
;;-- Espacio pulsado! Animar vagoneta
espacio_pulsado:
parar:
;; Comprobar el teclado
ld a, (tecla_reset)
call #BB1E
jr nz, tecla_r_pulsada
;;-- Esperar a que se pulse tecla R
jr parar
tecla_r_pulsada:
jr mainEn esta rutina se hace la animación de la explosión. Rutina: animacion_explosion:
;;========================================
;; Animacion explosion
;;
;; ENTRADAS:
;; HL: posicion memoria video donde dibujar
;;
;; MODIFICA:
;;
;;========================================
animacion_explosion:
;;-- Fotograma 1
call dibujar_explosion_1
ld b,#20
call wait
;;-- Fotograma 2
call dibujar_explosion_2
ld b,#20
call wait
;;-- Fotograma 3
call dibujar_explosion_3
ld b,#20
call wait
;;-- Fotograma 4 (Blanco)
call borrar_sprite_8x8
retEsta rutina a su vez llama a las rutinas dibujar_explosion_1, 2 y 3 para dibujar los fotogramas de la explosión
- Resultado:

- Reto 4.1: Mover a la derecha. Rutina mover
- Reto 4.2: Mover a la izquierda. Rutina Teclado
- Reto 4.3: Colisión lado izquierdo
- Reto 4.4: Colision con barriles
-
Mientras P esté pulsada, la vagoneta se mueve a la derecha. Al soltar la tecla se para. Rutina de mover que se invoca al pulsar la tecla. Mover con la tecla P. Bonus: LetraVariable
-
Rutina para mover a la derecha:
;;========================================
;; Mover la vagoneta 4 pixeles a la derecha
;;
;; MODIFICA:
;; HL, B, A
;;========================================
vagoneta_derecha:
;;-- Recuperar posicion de la vagoneta
ld hl, (pos_vagoneta_video)
;;-- Borrar la vagoneta
call borrar_sprite_8x8
;;-- Incrementar la posicion
inc hl
;;-- Dibujar la vagoneta en la nueva posicion
call dibujar_vagoneta
;;-- Guardar la posicion de la vagoneta
ld (pos_vagoneta_video), hl
;;-- Esperar
ld b, #6
call wait
;;-- Una posicion menos
ld a, (pos_vagoneta)
dec a
ld (pos_vagoneta),a
retEl Bonus LetraVariable está también implementado. ESte es el programa principal:
;==============================
;; VARIABLES
;;==============================
tecla_start:
db 47 ;;-- 47:Spacio
tecla_reset:
db 50 ;;-- 50: Tecla R
tecla_derecha:
db 27 ;; Tecla P
vagoneta_home:
dw #C410
barril_home:
dw #C43A
;;-- Posicion final de la vagoneta
pos_vagoneta:
db #28
;;-- Posicion de la vagoneta en la memoria de video
pos_vagoneta_video:
dw 00
;;========
;; MAIN
;;========
main:
;; Borrar vagonetas: Eliminar vagonetas de la ejecucion anterior
call borrar_vagonetas
;; Dibujar el suelo
call dibujar_suelo
;; Dibujar vagoneta en posicion inicial
ld hl, (vagoneta_home)
call dibujar_vagoneta
;;-- Dibujar los barriles
call dibujar_barriles
;;-- Inicializar variables
ld a,#28
ld (pos_vagoneta), a ;;-- Posicion inicial vagoneta
ld hl, (vagoneta_home)
ld (pos_vagoneta_video), hl ;;-- Posicion vagoneta en memoria video
;;-- Espera incial
ld b, #80
call wait
;;-- Bucle principal
bucle_main:
;;-- Comprobar tecla ir a la derecha
ld a, (tecla_derecha)
call #BB1E
jr nz, mover_derecha
;;-- Comprobar tecla de reinicio
ld a, (tecla_reset)
call #BB1E
jr nz, reiniciar
jr bucle_main
;;-- Reiniciar el juego
reiniciar:
;;-- Saltar al comienzo
jr main
;;-- Mover a la derecha
mover_derecha:
call vagoneta_derecha
;;-- Continuar con el bucle principal
jr bucle_main- Resultado:

- Mover a la izquierda con la tecla O. Crear una rutina específica de teclado
La rutina de mover a la izquierda es la misma que la de ir a la derecha, pero en vez de incrementar hl, se decrementa
La rutina del teclado es la siguiente:
;;========================================
;; Rutina de teclado. Comprobar que teclas se han pulsado
;; y llamar a las rutinas correspondientes
;;========================================
leer_teclas:
;;-- Comprobar tecla ir a la derecha
ld a, (tecla_derecha)
call #BB1E
jr nz, mover_derecha
;;-- Comprobar tecla ir a la izquierda
ld a, (tecla_izquierda)
call #BB1E
jr nz, mover_izquierda
;;-- Comprobar tecla de reinicio
ld a, (tecla_reset)
call #BB1E
jr nz, reiniciar
;;-- Terminar
jr leer_teclas_fin
;;-- Reiniciar el juego
reiniciar:
or a ;;-- Poner flag z a 0
jr leer_teclas_fin
;;-- Mover a la izquierda
mover_izquierda:
call vagoneta_izquierda
jr flag_z_set
;;-- Mover a la derecha
mover_derecha:
call vagoneta_derecha
flag_z_set:
xor a ;;-- Poner flag z a 1
;;-- Fin de la rutina
leer_teclas_fin:
ret- Este es el bucle principal:
;;-- Bucle principal
bucle_main:
;;-- Comprobar las teclas pulsadas
call leer_teclas
;;-- Saltar al comienzo si el flag z NO esta activado
;;-- (Esto ocurre cuando se aprieta la tecla de reset)
jr nz,main
;;-- Continuar con el bucle principal
jr bucle_main- Resultado:

Unificar las dos rutinas de movimiento de la vagoneta en una única rutina que reciba como parámetro de entrada el incremento de la posición: +1 (ir a la derecha) y -1 (ir a la izquierda)
- Rutina mover_vagoneta
;;========================================
;; Mover la vagoneta 4 pixeles a la izquierda o la derecha
;;
;; ENTRADA:
;; A: Incremento a aplicar: 1 (derecha). -1 (izquierda)
;;
;; MODIFICA:
;; HL, B, A
;;========================================
mover_vagoneta:
;;-- Recuperar posicion de la vagoneta
ld hl, (pos_vagoneta_video)
;;-- Borrar la vagoneta
call borrar_sprite_8x8
;;-- Actualizar la posicion
;; hl = hl + a
add l ;;-- a = a + l
ld l,a ;;-- l = l + a
;;-- Dibujar la vagoneta en la nueva posicion
call dibujar_vagoneta
;;-- Guardar la posicion de la vagoneta
ld (pos_vagoneta_video), hl
;;-- Esperar
ld b, #6
call wait
;;-- Una posicion menos
ld a, (pos_vagoneta)
dec a
ld (pos_vagoneta),a
ret-
Cuando llega al lado izquierdo no se permite que se siga moviendo, aunque se apriete la tecla
-
La rutina Leer_tecla se modifica para añdir una comparación en la posicion:
...
;;-- Mover a la izquierda
mover_izquierda:
;;-- Hay que comprobar en que posicion estamos
ld hl, (pos_vagoneta_video)
ld a,l
cp #10 ;;-- Vagoneta en la posicion inicial?
jr nz, mover_izquierda_ok
;;-- Estamos colisionando con la parez izquierda!!
;;-- No permitir movimiento
jr flag_z_set
mover_izquierda_ok:
ld a,#FF ;; (a=-1)
call mover_vagoneta
jr flag_z_set
...- Resultado:

-
Si la vagoneta está en la izquierda y la tecla O está pulsada, se debe reproducir alguna animación para indicar que no puede seguir
-
Resultado:

- Rutina principal:
;;===================
;; VARIABLES
;;===================
;; Posicion de la vagoneta (0 - 79)
vagoneta_pos:
db 0
barril1_pos:
db 0
barril2_pos:
db 0
tecla_start:
db 47 ;;-- 47:Spacio
tecla_reset:
db 50 ;;-- 50: Tecla R
tecla_derecha:
db 27 ;; Tecla P
tecla_izquierda:
db 34 ;; Tecla O
;;====================
;; MAIN
;;====================
main:
;;-- Inicializar variables
ld a, 40
ld (vagoneta_pos), a
ld a, 12
ld (barril1_pos),a
ld a,60
ld (barril2_pos),a
;;-- Borrar el escenario anterior
call borrar_escenario
;; Dibujar el suelo
call dibujar_suelo
;; Dibujar vagoneta
call dibujar_vagoneta
;;-- Dibujar barriles
call dibujar_barril1
call dibujar_barril2
;;-- Bucle principal
bucle_main:
;;-- Comprobar las teclas pulsadas
call leer_teclas
;;-- Comprobar colisiones
;; vagoneta_pos == barril1_pos?
ld a, (barril1_pos)
ld b, a
ld a, (vagoneta_pos)
cp b
jr z, colision
;; vagoneta_pos == barril2_pos?
ld a, (barril2_pos)
ld b, a
ld a, (vagoneta_pos)
cp b
jr z, colision
jr bucle_main
colision:
;;-- Inicializar HL con la posicion 0
ld hl, #C410
;;-- Calcular la direccion de video sumando la posicion
ld a, (vagoneta_pos)
add l
ld l,a ;;-- L = L + barril1_pos
call animacion_explosion
muerto:
;;-- Comprobar tecla de reinicio
ld a, (tecla_reset)
call #BB1E
jr nz, main
jr muertoSe ha implementado directamente el Bonus MasVariable
- Resultado:

- Sprites del videojuego:
![]()
- Programa completo: desafio-1.asm
- Resultado:
Aquí se muestra a velocidad lenta, para que sea fácil terminalo y comprobar que funciona:

Y en esta animación se muestra a velocidad normal, que es más difícil de acabar

- Programa completo: desafio-2.asm
- Resultado:
Pantalla de inicio:

Animación del juego:

Animación a pantalla completa:











