我目前正在为一个大学项目做一个6502程序集的平台游戏演示,我不明白如何在这个项目中实现平滑的水平/垂直移动和加速。基本上,每个移动都包含以下代码的一个稍微不同的版本:
READ_RIGHT:
LDA JOYPAD1
AND #%00000001
BNE DO_RIGHT
JMP READ_RIGHT_DONE
DO_RIGHT:
JSR HandleAcceleration
JSR UpdatePlayerPosition
READ_RIGHT_DONE:
RTI
HandleAcceleration:
LDA ACCEL + 1
CLC
ADC #$01
STA ACCEL + 1
BCC @ON_CARRY
LDA ACCEL + 0
CMP MAX_ACCEL
BCC @NOT_MAX_ACCEL
LDA MAX_ACCEL
STA ACCEL
@ON_CARRY:
INC ACCEL
INC MOV_FLAG
@NOT_MAX_ACCEL:
RTS
UpdatePlayerPosition:
LDA PLAYER_X
STA $0203
STA $020B
TAX
CLC
ADC #$08
STA $0207
STA $020F
ADC SPEED
STA PLAYER_X
RTS
字符串
我想我应该用定点算法来做这个,但是每次我试过,程序都不像预期的那样工作。如果有人知道我应该做什么或者我做错了什么,请帮助我。
我尝试将以下逻辑应用于代码:
READ_RIGHT:
LDA JOYPAD1
AND #%00000001
BNE DO_RIGHT
JMP READ_RIGHT_DONE
DO_RIGHT:
JSR HandleAcceleration
JSR UpdatePlayerPosition
READ_RIGHT_DONE:
RTI
HandleAcceleration:
LDA ACCEL + 1
CLC
ADC #$01
STA ACCEL + 1
BCC @ON_CARRY
LDA ACCEL + 0
CMP MAX_ACCEL
BCC @NOT_MAX_ACCEL
LDA MAX_ACCEL
STA ACCEL
@ON_CARRY:
INC ACCEL
INC MOV_FLAG
@NOT_MAX_ACCEL:
RTS
UpdatePlayerPosition:
LDA PLAYER_X
STA $0203
STA $020B
TAX
CLC
ADC #$08
STA $0207
STA $020F
ADC SPEED
STA PLAYER_X
RTS
型
并没有给精灵平稳的加速度,只是让它瞬间加速了很多,没有其他作用。
2条答案
按热度按时间1qczuiv01#
你的问题是由于没有注意垂直回扫引起的。当你没有捕捉到光束或没有正确设置IRQ时,CPU会连续运行你的代码。你需要的是以恒定的速度/FPS运行你的代码。我不是内斯硬件Maven,但从文档来看,$2002地址似乎是主循环结构的答案。尝试添加;
字符串
或者通过使用IRQ,尝试正确设置IRQ进入参数,同时考虑到垂直回扫。每个基于6502的8位机器都有一种方法来捕获屏幕顶部的光束。您只需要为内斯研究“垂直回扫”,“捕获光束”科目。
kmbjn2e32#
这是一个轻微的猜测,因为我从来没有做过任何内斯编程,但6502是一个little endian机器。传统上,16位值存储在低地址的最低有效字节和高地址的最高有效字节。
在你的代码中,你首先在高位字节加1,然后做了一些我不完全理解的奇怪的事情,很可能是错误的,如下所示:
如果
ACCEL
是一个16位的值,要向它添加1,我会期望这样的结果:字符串
另一个问题是
bcc @on_carry
之后的代码。紧接着的代码只有在设置了进位时才会执行。如果你加1,那么只有在加法结果为零时才会设置进位(从$ff
开始循环)。因此,大多数情况下,您最终会同时递增
accel
和accel+1
。如果加法后
accel+1
为零,则将accel
与max_accel
进行比较。如果累加器小于操作数,则cmp
* 清除 * 进位标志。因此,如果A < max_accel
如果
accel
小于max_accel
,你什么都不做(直接进入rts
),但是如果它大于max_accel
,你设置accel
为max_accel
,然后你通过增加accel
。