移动方块时无法将方块保持完整的方块 [英] Unable to keep a square a full square while moving it

查看:117
本文介绍了移动方块时无法将方块保持完整的方块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直试图在装配中画一个盒子并将其水平移动 在屏幕上.打印正方形本身的代码对我有用,但是当我尝试使其移动时,效果并不很好.如果您明白我的观点,我可以看到它在移动,但不是完整的正方形.

I have been trying to draw a box in assembly and move it horizontally across the screen. The code of printing the square itself works for me but when I try to make it move it is not working very well. I can see it moving but not as a full square, if you get my point.

我的代码:在Assembly Tasm中

My code: in Assembly Tasm

STA SEGMENT STACK
DB 0FFFeH DUP(?)
STA ENDS
DATA SEGMENT
;-----------
;VARIABLES HERE
xpos dw 50h
ypos dw 50h
color db 9h
constat equ 0ffffh
siNum dw ?
diNum dw ?
numOFtime dw 0h

;-------------
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STA

START :
MOV AX,DATA
MOV DS,AX
;start coding here:

mov ah, 0   ;Set display mode
mov al, 13h ;13h = 320x200, 256 colors
int  10H   ;Video BIOS Services
mov cx,50h
mov dx,50h
mov si,25H
mov di,25H

PrintSquare:
;------------------------------------------------------------------------
;cx = xpos , dx = ypos, si = x-length, di = y-length, al = color

didi:
mov color,9h
mov bp,0h
do:
add cx,si
here:
mov bh,0h
mov al,color
mov ah, 0Ch   ;write pixel at coordinate
int 10h      ;draw pixel!
dec cx
cmp cx,xpos
ja here
inc dx
inc bp
cmp bp,25h
jbe do
call drawBlackBox
inc numOFtime
inc xpos;incrising to make the sqaure moving horizontically
mov cx,xpos;cx gets the xposition
mov dx,ypos
cmp numOFtime,constat
jb didi






mov ah,004Ch  ;terminate program
int 21h
;
drawBlackBox proc
mov color,0h ;black color 
mov bp,0h
mov cx,xpos
mov dx,ypos
do1:
add cx,si
here1:
mov bh,0h
mov al,color
mov ah, 0Ch   ;write pixel at coordinate
int 10h      ;draw pixel!
dec cx
cmp cx,xpos
ja here1
inc dx
inc bp
cmp bp,25h
jbe do1
mov cx,xpos
ret

drawBlackBox endp


CODE ENDS
END START

推荐答案

如果通过不好地移动来表示边缘似乎在不同的时间移动,那么通常通过双重缓冲来解决(撕裂)这个问题.该问题是由于您正在渲染到活动(可见)表面上而导致屏幕上可能会显示一半修改的帧而引起的.

If, by not moving well, you mean the edges seem to move at different times, that's an issue (tearing) usually solved by double buffering. The problem is caused by the fact that you're rendering to an active (visible) surface so the screen may show half-modified frames.

插图可能会有所帮助.假设您正尝试从左侧图片更改为右侧图片:

An illustration may help. Let's say you're trying to change from the left image to the right:

~   ~             ^   ^
O   O             O   O
  ^      ---->      ^
|---|             \___/

如果图像是从左到右更新的,并且数据在更新过程中途发送到屏幕,您将看到类似以下内容的东西:

If the image is updated left to right and the data is sent to the screen halfway through your update process, you will see something like:

^   ~
O   O
  ^
\_--|

这就是所谓的撕裂.

要解决此问题,您可以在单独内存块中构造下一帧(可以使用rep stosb在最短的时间内构造下一帧),然后使用rep movsb或类似的方法快速,将其传输到视频内存.这样会稍微降低您的帧速率,但可以减轻您可能看到的任何撕裂感.

To solve it, you can construct the next frame in a separate memory block (you can use rep stosb to construct the next frame in minimal time) then use rep movsb, or something similarly speedy, to transfer that to video memory. That will slow down your frame rate a little but should alleviate any tearing you may be seeing.

下面是一个示例,显示了此操作.它的功能与您类似,但是使用双重缓冲来解决棘手的问题,并且在执行 specific 的功能方面,它的结构也更好(无论如何):

Here's an example showing this in action. It's similar functionality to yours but uses double buffering to get around the tearing issue, and it's also a little better structured (in my opinion anyway) in terms of functions doing specific things:

stacksg segment stack
    db 0fffeh dup(?)
stacksg ends

datasg segment
    buffer dw 32000 dup(0)
datasg ends

codesg segment
assume cs:codesg, es: datasg, ds:datasg, ss:stacksg

doline: ; ax = line, bx = column, cx = width
    push        di            ; preserve
    push        ax
    push        dx            ; imul hits this

    push        bx            ; get byte offset to di
    mov         bx, 320
    imul        bx
    pop         bx
    add         ax, bx
    mov         di, ax

    push        cx            ; blat line
    mov         al, 9    
    cld
    rep stosb
    pop         cx

    pop         dx            ; restore and return
    pop         ax
    pop         di
    ret

dosquare: ; ax = line, bx = column, cx = width, dx = height
    push        ax            ; preserve
    push        bx
    push        cx
    push        dx

    push        di            ; clear buffer to black
    push        ax
    push        cx
    xor         di, di
    xor         ax, ax
    mov         cx, 32000
    cld
    rep stosw
    pop         cx
    pop         ax
    pop         di

makeline:
    call        doline
    inc         ax
    dec         dx
    jnz         makeline

    push        es            ; blat double buffer to screen
    push        si
    push        di
    xor         si, si
    mov         ax, 0a000h
    mov         es, ax
    xor         di, di
    mov         cx, 32000
    cld
    rep movsw    
    pop         di
    pop         si
    pop         es

    pop         dx            ; restore and return
    pop         cx
    pop         bx
    pop         ax
    ret

start:
    mov         ax, datasg
    mov         ds, ax
    mov         es, ax

    mov         ah, 0         ; set display mode 13h, 320x200, 8bbp
    mov         al, 13h
    int         10h

    mov         ax, 10        ; line
    mov         bx, 10        ; start column
    mov         cx, 40        ; width
    mov         dx, 40        ; height

printSquare:
    call        dosquare      ; do the square
    inc         bx            ; move right but reset at end
    cmp         bx, 310 - 40
    jne         printSquare
    mov         bx, 10
    jmp         printSquare

codesg ends
end start

将其插入GNU Turbo汇编器中并检出.我同时运行了您的原始(撕裂)代码和此变体,而后者是更流畅的动画.

Plug that into GNU Turbo Assembler and check it out. I ran both your original (tearing) code and this variant and the latter was much smoother animation.

这篇关于移动方块时无法将方块保持完整的方块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆