[英]Enemy bullets targeting player on a C64
我在沒有找到答案的情況下掃描互聯網和舊的C64書籍,所以最后我不得不在這里發布。 我喜歡C64編碼的美好時光,雖然我目前還沒有在這個平台上編寫游戲,但我想知道當時是如何克服某些硬件限制的。
在所有現代游戲編程書籍和教程中,找到向玩家發射敵人子彈的正確方向的方法是使用向量數學與浮點數,或多或少像這個偽代碼:
bullet_velocity = (player.position - bullet.position).normalize();
現在,考慮到C64的限制,我在源代碼中大量使用正弦表來提高速度,也許我分心了,但是當我從C64程序員那里閱讀舊的C64書籍或評論程序時,我從未見過關於矢量數學的一個詞,我想知道如何在同一時間獲得同樣的目標。
請回答,我有這樣的一千個疑問,但回答這個問題也許我可以發現自己對其余的回應! :-)
編輯:只是一個注釋:用針對玩家的子彈的C64游戲的例子是Silkworm和Cybernoid。
假設您對足夠少的輸出方向感到滿意,最容易通過查找表來完成。 例如,對於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 ...
......有一個更智能的解決方案可能涉及更多類似的東西:
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 / 256th。 以子像素精度移動子彈的所有成本都是每個矢量額外幾個字節的存儲空間和額外的幾個ADC。
根據上面的建議,你可以通過從另一個字節中減去一個字節來獲得從源到目的地的向量。 結果將是兩個單個字節,這兩個字節都是輸出的小數部分。 因此,例如,您可能決定使用(87 / 256,239 / 256)矢量(即20度角)發射子彈。
你也可以(ab)使用Bresenham的線條繪制算法來瞄准你的子彈,“線”的起始坐標是敵人的坐標,而末端則是你的船的坐標。 不是在行中添加像素,而是在每次迭代時在當前位置重新繪制項目符號。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.