En el post anterior de esta serie mostramos cómo desplegar una imagen bmp. En este post expandiremos el código para mover la imagen alrededor de la pantalla. El siguiente video muestra el objetivo final del programa.
Lo primero que realizamos fue separar las rutinas relacionadas con desplegar la imagen, éstas fueron colocadas en el archivo libgraf.asm con su respectivo archivo libgraf.inc para poder exportar las funciones más importantes a otros módulos (el siguiente post muestra cómo exportar funciones entre módulos). La función principal para desplegar una imagen bmp (mostrar_bmp) ahora recibe los siguientes parámetros: la ruta del archivo y la posición inicial de la esquina superior izquierda de la imagen en la pantalla. De esta forma ya podemos colocar una imagen en cualquier parte de la pantalla y no sólo en la esquina superior izquierda.
La lógica para mover la imagen en la pantalla es muy sencilla (bmp01.asm):
1 Inicializar el modo de video 2 Ciclo hasta que presionemos una tecla: 2.1 Limpiar pantalla 2.2 Actualizar la coordenada x en la dirección actual 2.3 Si hubo una colisión contra el límite izquierdo o derecho 2.3.1 Ajustar coordenada x 2.3.2 Invertir dirección en x 2.4 Realizar pasos 2.2 y 2.3 para y 2.5 Desplegar imagen
El código que implementa esta lógica se muestra a continuación (bmp01.asm). En el siguiente proyecto de mercurial podrás descargar los 3 archivos necesarios para construir el ejecutable. El proyecto también incluye la imagen bmp usada. Para ensamblar y ligar estos archivos basta con invocar:
ml bmp01.asm libgraf.asm
Como pueden observar en el video, la imagen parpadea notablemente, esto se debe a que estamos escribiendo al área de memoria de gráficos al mismo tiempo que esta área está siendo desplegada en la pantalla. Esto causa que frecuentemente se desplieguen en la pantalla versiones incompletas de la imagen final. En el siguiente post exploraremos una opción para mejorar esto.
.model small .stack 128 INCLUDE libgraf.inc .data ; El nombre del archivo debe terminar en 0 pelotaf db "pelota.bmp",0 pelotax dw 100 pelotay dw 100 pelotad dw 40 maxx dw 320 maxy dw 200 deltax dw 2 deltay dw 2 .code .startup mov ax,@data mov ds,ax main proc ; Configurar modo grafico VGA con resolucion de 320x200 call InitVid ciclo1: call limpiar_pantalla ; ------------------------------------------------------- ; Controlar posicion x de la pelota ; ------------------------------------------------------- testX: mov ax, pelotax ; avanzar la pelota en la direccion actual add ax, deltax ; validar colision contra limite derecho testmaxX: mov cx, maxx sub cx, pelotad cmp cx, ax jg testminX ; si la pelota esta en el limite derecho ; alinearla al limite e invertir la direccion mov ax, cx mov deltax, -2 ; validar colision contra limite izquierdo testminX: cmp ax,0 jg testY ; si la pelota esta en el limite izquierdo ; alinearla al limite e invertir la direccion mov ax,0 mov deltax, 2 ; ------------------------------------------------------- ; Controlar posicion y de la pelota ; ------------------------------------------------------- testY: mov bx, pelotay ; avanzar la pelota en la direccion actual add bx, deltay ; validar colision contra limite inferior testmaxY: mov cx, maxy sub cx, pelotad cmp cx, bx jg testminY ; si la pelota esta en el limite inferior ; alinearla al limite e invertir la direccion mov bx, cx mov deltay, -2 ; validar colision contra limite superior testminY: cmp bx,0 jg dibpelota ; si la pelota esta en el limite superior ; alinearla al limite e invertir la direccion mov bx,0 mov deltay, 2 ; ------------------------------------------------------- ; Actualizar posicion (x,y) y pintar pelota ; ------------------------------------------------------- dibpelota: mov pelotax, ax mov pelotay, bx mov dx, offset pelotaf call mostrar_bmp ; Si una tecla es presionada, salimos del ciclo. ; Noten que esta interrupcion no espera por una tecla, ; solo verifica si fue presionada y si no, continua. mov ah,01h int 16h jnz fin jmp ciclo1 fin: ; Regresar a modo texto mov ax,0003h int 10h ; Finalizar el programa mov ax,4c00h int 21h ret main endp end
Hola, no entiendo la parte de ensamblar y ligar ambos archivos, podrías explicarme con que lo hago? O si lo hago con MASM y LINK tambien? Gracias...
ResponderEliminarHola Hack1892, sólo tienes que invocar ml.exe con los archivos .asm. ml.exe ensambla y liga ambos archivos para generar el ejecutable. Saludos.
ResponderEliminar