敌人的子弹针对C64上的玩家

1Ga*_*010 3 assembly artificial-intelligence c64 6502 6510

我在没有找到答案的情况下扫描互联网和旧的C64书籍,所以最后我不得不在这里发布.我喜欢C64编码的美好时光,虽然我目前还没有在这个平台上编写游戏,但我想知道当时是如何克服某些硬件限制的.

在所有现代游戏编程书籍和教程中,找到向玩家发射敌人子弹的正确方向的方法是使用向量数学与浮点数,或多或少像这个伪代码:

bullet_velocity = (player.position - bullet.position).normalize();
Run Code Online (Sandbox Code Playgroud)

现在,考虑到C64的限制,我在源代码中大量使用正弦表来提高速度,也许我分心了,但是当我从C64程序员那里阅读旧的C64书籍或评论程序时,我从未见过关于矢量数学的一个词,我想知道如何在同一时间获得同样的目标.

请回答,我有这样的一千个疑问,但回答这个问题也许我可以发现自己对其余的回应!:-)

编辑:只是一个注释:用针对玩家的子弹的C64游戏的例子是Silkworm和Cyber​​noid.

Tom*_*mmy 5

假设您对足够少的输出方向感到满意,最容易通过查找表来完成.例如,对于64个输出方向,(x, y)从源到目标获取向量,如果两者都为正,则向左移动直到其中一个填充符号位,然后从每个的前两位形成一个四位表索引并查看输出向量.

假设你是160x200,那么我猜你在进入之前需要稍微精确一点.

适当地镜像以处理其他象限.假设对象位置的固定点为8.8,子弹速度为1,那么这是一个32字节的查找表.

所以,天真地,像:

xPosYPos:

    ; assuming ($00) has the positive x difference
    ; and ($01) has the positive y difference

    lda $00
    ora $01

shiftLoop:
    asl $00
    asl $01
    asl a
    bpl shiftLoop

    ; load A with table index
    lda #$00
    rol $00
    rol a
    rol $00
    rol a
    rol $01
    rol a
    rol $01
    rol a

    ; look up vector
    tax
    lda xVec, x
    ; ... put somewhere ...
    lda yVec, x
    ; ... put somewhere ...
Run Code Online (Sandbox Code Playgroud)

......有一个更智能的解决方案可能涉及更多类似的东西:

    lda $00
    ora $01

    asl a
    bmi shift1
    asl a
    bmi shift2
    ... etc ...

shift1:

... etc, but you can shift directly to form
the table index rather than going to all the work
of shifting the vector then piecing together from
the top bits ...
Run Code Online (Sandbox Code Playgroud)

或者你可以创建一个256字节的查找表来查找基于的例程地址x|y(由于它们都是正数,它总是最多127个)并直接跳转到移位而不计算位.


对象位置和固定点的入门:

假设您处于160x200模式,那么您可以将对象位置的每个组件存储为单个字节.所以x为一个字节,y为一个字节.许多游戏所做的是将每个位置存储为两个字节.因此x和y共有四个字节.

其中一个字节与单字节格式相同 - 它是整数位置.另一个是小数部分.因此,如果您有一个位置和一个速度(以及Euler积分),那么您可以将16位速度添加到位置.然后你只需使用顶部字节作为位置.

这通常称为定点算术.与浮点不同,小数点所在的整数内的位置是固定的.在这里描述的方案中,它始终是8位.

因此,例如,添加仅包含字节数量的偏移量:

clc
lda xPosition
adc xVelocity
sta xPosition

sta SomeHardwareRegisterForSpritePosition
Run Code Online (Sandbox Code Playgroud)

要使用固定点方案添加偏移量:

clc

lda xFractionalPosition
adc xFractionalVelocity
sta xFractionalPosition

lda xPosition
adc xVelocity
sta xPosition

sta SomeHardwareRegisterForSpritePosition
Run Code Online (Sandbox Code Playgroud)

优势在于您的速度矢量现在可以在任何方向上小到像素的1/256.因此,例如,您可以存储一个速度,该速度表示您的子弹将向左移动一个像素并向下移动一个像素的32/256th.以子像素精度移动子弹的所有成本都是每个矢量额外几个字节的存储空间和额外的几个ADC.

根据上面的建议,你可以通过从另一个字节中减去一个字节来获得从源到目标的向量.结果将是两个单个字节,这两个字节都是输出的小数部分.因此,例如,您可能决定使用(87/256,239/256)矢量(即20度角)发射子弹.