強調表示されたメニューは、メニューを描画し、ループまたは を使用してキーが押されるのを待ちますSLEEP
。一般的な代替手段は、最初の数文字のうちの 1 つのテキストの色を変更するだけで、対応するキーを押して対応するメニュー オプションを選択するようにユーザーに通知することでした。たとえば、「Quit」の Q と「New Game」の N の文字は、行の残りのテキストとは異なる色になります。
ただし、矢印キーを使用するように求めているので、明らかにそのようにしたくありません。現在のメニュー項目を強調表示する方法は、使用中の画面モードによって異なります。画面モード 11、12、および 13 では背景色を指定できません。また、モード 7、8、および 9 で DOSBox に背景をレンダリングさせることもできません。この問題の回避策として、代わりに単純に現在の選択の横にボックスを描画し、ボックスを消去します (黒または画面の背景色を描画します)。または、アスタリスクを使用して、グラフィックス/テキスト サイズの問題を回避し、コードを簡素化することもできます。以下は、US-QWERTY キーボードが使用されていると仮定して、矢印キー、WASD キー、および Vim スタイルのキー (H=左、J=下、K=上、L=右) がすべてサポートされているボックス スタイルの例です。矢印キーだけが必要な場合は、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
ループ内のものだけで、表示方法を変更できます。