07、控制器
NES上有2個控制器端口。您可以使用端口4016和4017隨時讀取它們。在幕後,它會關閉和打開4016端口,然後一次讀取按鈕,1個按鈕,8次讀取,然後將它們轉換爲變量。
Neslib,使用此功能的方法。
pad1 = pad_poll(0) 讀取控制器1。
pad2 = pad_poll(1) 讀取控制器2。
如果你希望不重複讀取手柄的情況下獲取值可以使用下面的方法再次取到值。
pad_state(0)
pad_state(1)
pad_trigger() 獲取最近按下的按鈕。我不用它。
如果你用了,順序將是pad_trigger() 然後是pad_state(),因爲觸發器運行了pad_poll()函數。
我寫了一個函數get_pad_new(),它類似於pad_trigger(),除了先運行pad_poll() 然後運行get_pad_new()。
pad1 = pad_poll(0);
pad1_new = get_pad_new(0);
pad1_new 會獲取最近被按下的按鈕。如果按下了暫停鍵,我們不希望他連續的暫停、恢復、暫停、恢復的循環。應該是鬆開暫停鍵,再按下的時候纔會修改當前狀態(暫停再按一次應該恢復到運行狀態)
pad1 是一個8位的char類型,正好是8個按鈕的字段位置。我們需要用位標識來判斷按下了那個按鍵。
if(pad1_new & PAD_START){
Pause();
}
精靈與碰撞
我給每個精靈都設置了單獨的控制,當他們碰撞的時候就改變背景顏色。
if(collision){
pal_col(0,0x30);
}
我寫了個功能,可以測試任何精靈對象是否發生了觸碰。函數需要2個4字節的對象(或數組),字節順序是(x,y,寬,高)
我讓這個函數接受2個void指針,我希望以後可以使用不同類型的對象結構。至少,這是個方案。
碰撞檢測代碼例子
collision = check_collision(&BoxGuy1, &BoxGuy2);
我們還能把他直接放到if條件裏使用
if(check_collision(&BoxGuy1, &BoxGuy2))
可以考慮使用ASM彙編方式優化這個代碼
if((obj1_right >= obj2_left) &&
(obj2_right >= obj1_left) &&
(obj1_bottom >= obj2_top) &&
(obj2_bottom >= obj1_top)) return 1;
else return 0;
在發生碰撞的時候屏幕背景變成了白色,能確認他生效了。
一個精靈離開另一個精靈一半的時候會有點問題,不過這已經滿足需求了。
https://github.com/nesdoug/08_Pads/blob/master/Pads.c
https://github.com/nesdoug/08_Pads