2016-06-21 102 views
2

任何人都有一個示例代碼或說明使這項工作?我從來沒有能夠完成突出顯示的菜單,使用箭頭鍵並輸入選擇。提前致謝!Qbasic突出顯示的菜單,認真

更新! 我預計這個工作方式是通過爲每個選項繪製框,並在選擇選項時着色文本的同時重新繪製框,但我不確定如何設計一個循環來完成此操作。我對INKEY $和SELECT CASE函數很滿意,但我不知道如何將它們分解。

回答

2

突出顯示的菜單將繪製菜單並等待循環中的按鍵或使用SLEEP。一種常見的選擇是簡單地改變前幾個字母之一的文字顏色,通知用戶按下相應的鍵以選擇相應的菜單選項。例如,「退出」中的字母Q和「新遊戲」中的字母N將與該行中其餘文本的顏色不同。

但是,您要求使用箭頭鍵,很明顯,您不希望這樣做。如何突出顯示當前菜單項取決於正在使用的屏幕模式。屏幕模式11,12和13不允許您指定背景顏色,並且無法使DOSBox使用模式7,8和9呈現背景。作爲解決此問題的解決方法,您可以改爲在當前選擇旁邊畫一個盒子並清除盒子(繪製一個黑色或任何屏幕的背景色)。或者您可以使用星號來避免圖形/文字大小問題並簡化代碼。假設使用US-QWERTY鍵盤,下面是一個帶有箭頭鍵,WASD鍵和Vim風格鍵(H = Left,J = Down,K = Up,L = Right)的盒子樣式的例子。如果你只想要方向鍵,那麼你只需要將第一個(外部)SELECT CASE...END SELECT塊更改爲IF LEFT$(k$, 1) = CHR$(0) THEN...END IF,同時保留與擴展密鑰一起工作的內部SELECT CASE...END SELECT塊。

'size% is used in the selIncDec subroutine. 
DIM text$(0 TO 3) 
DIM SHARED size% 
size% = UBOUND(text$) - LBOUND(text$) + 1 

selected% = 0 

text$(0) = "Example 1" 
text$(1) = "Example 2" 
text$(2) = "Example 3" 
text$(3) = "Example 4" 

SCREEN 12 

' Width and height of a text cell in pixels. 
' I use 8x8 text cells for max screen compatibility, despite 8x16 looking better. 
xpxText% = 8 
ypxText% = 8 

' See the documentation for SCREEN to determine which screen sizes are 
' available with the screen mode you want to use. 
' 80x60 for mode 12 results in 8x8 text cells. 80x30 results in 8x16 text cells. 
WIDTH 80, 60 

DO 
    LOCATE 1, 1 
    FOR i% = LBOUND(text$) TO UBOUND(text$) 
     PRINT TAB(3); text$(i%) 
     ' selected% = i% 
     ' is an equality comparison, resulting in -1 for true and 0 for false. 
     ' If false, -(0) * 2 = 0; if true, -(-1) * 2 = 2. 
     LINE (0, i% * ypxText%)-STEP(xpxText% - 1, xpxText% - 1), -(selected% = i%) * 2, BF 
    NEXT i% 

    SLEEP 
    k$ = INKEY$ 
    SELECT CASE UCASE$(LEFT$(k$, 1)) 
     ' Left -- does nothing 
     CASE "H", "A" 

     ' Right -- does nothing 
     CASE "L", "D" 

     ' Up 
     CASE "K", "W" 
     CALL selIncDec(selected%, -1) 

     ' Down 
     CASE "J", "S" 
     CALL selIncDec(selected%, 1) 

     ' Enter key 
     CASE CHR$(13) 
     EXIT DO 

     ' Extended key, such as arrows. 
     CASE CHR$(0) 
     SELECT CASE RIGHT$(k$, 1) 
      ' Left 
      CASE "K" 

      ' Right 
      CASE "M" 

      ' Up 
      CASE "H" 
      CALL selIncDec(selected%, -1) 

      ' Down 
      CASE "P" 
      CALL selIncDec(selected%, 1) 
     END SELECT 
    END SELECT 
LOOP 

PRINT USING "You selected option #"; selected% + 1 

END 

SUB selIncDec (selected%, amtInc%) 
    selected% = selected% + amtInc% 
    IF selected% >= size% THEN 
     selected% = selected% - size% 
    ELSEIF selected% < 0 THEN 
     selected% = selected% + size% 
    END IF 
END SUB 

如果你使用的是支持背景色屏幕模式或突出顯示某些形式,如屏幕0,你也許可以用簡單的「突出」整行的文本模式背景脫身。您不需要指定屏幕的寬度以使「反向視頻」效果起到突出顯示的作用,但當您將整行高亮顯示而非僅顯示文本時,效果會更好。在打印菜單項後,只需將顏色更改回默認值,然後照常繼續打印。下面顯示了上面的代碼進行一些更改(屏幕模式下,屏幕寬度設置,菜單顯示的代碼),但它否則仍然是相同的:

SCREEN 0 
'8x8 text cells in SCREEN 0 for VGA adapters. 
WIDTH 80, 43 

... 

    FOR i% = LBOUND(text$) TO UBOUND(text$) 
     ' "Reverse video" highlighting. 
     IF selected% = i% THEN COLOR 0, 7 ELSE COLOR 7, 0 
     PRINT TAB(3); text$(i%); SPACE$(78 - LEN(text$(i%))) 
    NEXT i% 

    ' The screen will turn "white" when the last menu item is selected. 
    ' This fixes the issue. 
    COLOR 7, 0 

    SLEEP 
... 

請注意,我假設一個VGA適配器與彩色顯示屏,所有上述代碼早已被各種其他顯示適配器標準所取代,這些顯示適配器標準即使在像智能手錶一樣小的設備上也正在使用。

您應該能夠調整代碼以適應您的需求。我設計了它,您可以根據需要簡單地添加菜單項。此外,顯示代碼本身完全包含在FOR...NEXT循環中,其功能緊隨其後,所以您需要更改的是FOR...NEXT循環內的內容,以改變顯示內容的方式。