You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:如何在8086 TASM中实现6×6像素图形对象的移动?

Fixing Your 8086 TASM Bullet Movement Issue

Hey there! Let's tackle this bullet problem head-on—since this is your high school final project with a weekend deadline, let's get this sorted out step by step. I've gone through your code and spotted several key issues that are stopping your bullet from moving and causing those weird leftover pixels.

1. Your Bullet Detection Logic Is Targeting the Wrong Pixels

The biggest problem is in your progbullets procedure. Right now, you're checking pixels at X=87, Y=dx (since int 10h function 0Dh uses cx for X and dx for Y), but your left-facing bullet is drawn at Y=87, X=133 (from bulletleft: mov di,320*87+133). You're looking in the wrong place entirely—so your code never finds the red bullet pixel to trigger movement.

Fix for progbullets:

We need to loop through the actual area where your bullet is located (6x6 pixels: Y from 87 to 92, X starting at 133 and moving left). Here's a revised version:

proc progbullets
    mov bx, [bullet_x_left]  ; Load current bullet X position
check_left_pixel:
    mov cx, bx               ; X coordinate to check
    mov dx, 87               ; Starting Y coordinate of the bullet
check_y_range:
    mov ah, 0Dh              ; Read pixel function
    int 10h
    cmp al, 4                ; Check if it's the red bullet color
    je move_left_bullet      ; Found the bullet—move it
    inc dx
    cmp dx, 93               ; Check all 6 Y lines (87 to 92)
    jne check_y_range
    dec bx
    cmp bx, 0                ; Stop if bullet hits left edge
    jge check_left_pixel
    jmp exit1

move_left_bullet:
    ; First, erase the old bullet (draw black over it)
    mov di, 320*87 + bx
    lea si, [black_bullet]   ; 6x6 array filled with black (0) pixels
    mov [LineLength], 6
    mov [NumOfLines], 6
    call DrawPix
    ; Now draw the bullet one pixel left
    dec bx
    mov [bullet_x_left], bx  ; Save new X position
    mov di, 320*87 + bx
    lea si, [bullet]
    mov [LineLength], 6
    mov [NumOfLines], 6
    call DrawPix
exit1:
    ret
endp

Note: You'll need to create a black_bullet data array identical to your bullet array but filled with black (0) pixels—this erases the old bullet position so you don't get leftover pixels.

2. Your leftbull Procedure Has Incorrect Position Calculation

Your current leftbull uses mov di,320*84 + dx, which targets Y=84 instead of the bullet's actual Y=87. Plus, you're not erasing the old bullet, which causes those "异常像素" (leftover pixels). The revised code above handles both erasing and correct positioning, so you can replace your existing leftbull with this logic.

3. Control Movement Speed to 4 Pixels Per Second

Right now, your loop runs as fast as possible, which would make the bullet zoom across the screen if it worked. To get a steady 4 pixels per second:

  • Use the system timer (int 1Ah) to trigger a move every 1/4 second (since 18.2 timer ticks = 1 second, ~4.5 ticks per move).
  • Add a variable to track when the last move happened.

Adjust your main loop like this:

start:
    mov [bullet_x_left], 133  ; Initialize bullet's starting X
    mov [last_move_tick], 0
Main_Loop:
    call keycontrol
func_Loop:
    ; Check if enough time has passed to move the bullet
    mov ah, 00H
    int 1Ah
    sub dx, [last_move_tick]
    cmp dx, 5  ; ~1/4 second (adjust if needed for speed)
    jl skip_move
    ; Update the last move time
    mov [last_move_tick], dx
    call progbullets
skip_move:
    ; Keep the loop running
    jmp func_Loop
    ; Exit code
    mov ah,1
    int 21h
    mov ax, 4C00H
    int 21h

4. Quick Fix for Your bulletleft Procedure

Make sure when you first fire the bullet, you initialize its starting X position:

bulletleft:
    mov di,320*87+133
    mov [bullet_x_left], 133  ; Save starting X coordinate
    lea si, [bullet]
    mov [LineLength],6
    mov [NumOfLines],6
    call DrawPix
    ret
endp

Key Takeaways

  • Always erase the old sprite before drawing the new one to avoid leftover pixels.
  • Double-check int 10h coordinate order: cx = X, dx = Y—it's easy to mix these up!
  • Use the system timer to control movement speed instead of looping as fast as possible.

I hope this gets your bullet moving smoothly in time for your deadline!

内容的提问来源于stack exchange,提问作者doraviv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:08:37