我正在浏览互联网和旧的C64书籍寻找这个问题,但没有找到答案,所以最后我不得不把它张贴在这里。我喜欢C64编码的美好时光,虽然我目前还没有在这个平台上编写游戏,但我想知道在那个时候,一些硬件限制是如何克服的。
在所有现代游戏编程书籍和教程中,找到向玩家发射敌人子弹的正确方向的方法是使用向量数学和浮点数,大致类似于这个伪代码:
bullet_velocity = (player.position - bullet.position).normalize();现在,考虑到C64的局限性,我在源代码中看到的用于速度的正弦表的大量使用,也许我有点心烦意乱,但当我阅读旧的C64书籍或C64程序员的评论程序时,我从未见过一个关于向量数学的词,我想知道这个目标是如何在当时实现的。
请回答,我有上千个这样的疑问,但是回答这个问题也许我能为其他人找到一个答案!
编辑:只是一个注: C64游戏的例子,子弹瞄准玩家是蚕和赛博。
发布于 2015-10-28 01:56:22
如果您对足够少的输出方向感到满意,那么通过查找表是最简单的。例如,对于64个输出方向,从源到目的地获取向量(x, y),如果两者都是正的,则向左移动,直到其中一个填充符号位,然后从每一位的前两位形成一个4位的表索引,并查看输出向量。
假设你在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 .....。使用更聪明的解决方案,可能涉及以下内容:
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 ...或者,您可以创建一个256个字节的查找表来查找基于x|y的例程地址(因为它们都是正的,所以最多只能有127个地址),然后直接跳转到移位而不计位。
关于物体位置和定点的底漆:
假设您处于160x200模式,那么您可以将对象位置的每个组件存储为一个字节。因此,一个字节表示x,一个字节表示y。许多游戏所做的是将每个位置存储为两个字节。所以x和y总共有四个字节。
其中一个字节与单个字节格式相同-它是整数位置。另一个是小数部分。因此,如果你有一个位置和一个速度(和欧拉积分),那么你做一个16位的速度加法到位置。然后,您只需使用顶部字节的位置。
这通常被称为不动点算法。与浮点不同,小数点所在的整数中的位置是固定的。在这里描述的方案中,总是有8位。
因此,例如添加一个只有字节数量的偏移量:
clc
lda xPosition
adc xVelocity
sta xPosition
sta SomeHardwareRegisterForSpritePosition若要添加带有定点方案的偏移量:
clc
lda xFractionalPosition
adc xFractionalVelocity
sta xFractionalPosition
lda xPosition
adc xVelocity
sta xPosition
sta SomeHardwareRegisterForSpritePosition优点是,你的速度矢量现在可以小到1/256像素在任何方向。例如,你可以存储一个速度,表示你的子弹将向左移动一个像素,向下移动一个像素的32/256。以亚像素精度移动子弹所需的代价是,每个向量需要额外的几个字节的存储空间,以及一个额外的两个ADC。
有了上述建议,您将从一个字节减去一个字节到另一个字节,从而得到从源到目的地的向量。结果将是两个单个字节,这两个字节都是输出的小数部分。例如,你可以决定发射一个矢量为(87/256,239/256)的子弹,即20度的角度。
发布于 2016-01-15 17:10:51
你也可以使用Bresenham的直线绘制算法瞄准你的子弹,“线”的起始坐标是敌人的坐标,末端的坐标是你的飞船的坐标。然而,与其将像素添加到一行中,不如在每次迭代的当前位置重新绘制符号。
https://stackoverflow.com/questions/33367982
复制相似问题