Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

excel - Trying to capture key press while sub running ( for snake game ) VBA

i'm a but stuck with a snake game I am trying to make, it seems that at the moment the "HEAD" of the snake (this is a colored cell that is green with a green "x") will move perfectly and continuously till the end of the game playing board and stops at the boarder as i want. But it will not pickup any other key presses whilst it is moving.

Is there a way another key press can interrupt any other subs running.

I would really appreciate any help from you guys or maybe another way of doing it.

    Option Explicit
Public speed As Integer
Dim r As Integer
Dim c As Integer
Dim moves As Boolean
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)

...

Public Sub start()
    Application.ScreenUpdating = False
    Application.OnKey "{LEFT}", "k_left"
    Application.OnKey "{UP}", "k_up"
    Application.OnKey "{DOWN}", "k_down"
    Application.OnKey "{RIGHT}", "k_right"
    Application.ScreenUpdating = True
End Sub

....

Function go_Speed(x As Integer)
speed = 300 / x
End Function

....

Sub movecheck()
    Do While moves = True
        Call k_move(r, c)
    Loop

End Sub

....

Function k_move(rows As Integer, columns As Integer)

DoEvents
Sleep (speed)
Dim a As Range
    For Each a In Range("E4:ak37")
        If a.Value = "x" Then
                If a.Offset(rows, columns).Interior.Color <> RGB(255, 255, 255) Then
                        '''crash check call goes here
                        moves = False
                        Exit Function
                Else
                        a.Interior.Color = RGB(255, 255, 255)
                        a.Offset(rows, columns).Interior.Color = RGB(78, 238, 148)
                        a.Offset(rows, columns).Font.Color = RGB(78, 238, 148)
                        a.Offset(rows, columns) = a.Value
                        a.Cells.Clear
                        a.Cells.BorderAround 1
                        movecheck
                End If
        End If
    Next a
End Function

....

Sub k_left()
    moves = False
    r = 0
    c = -1
    moves = True
    Call movecheck
End Sub

....

Sub k_up()
    moves = False
    r = -1
    c = 0
    moves = True
    Call movecheck
End Sub

....

Sub k_down()
    moves = False
    r = 1
    c = 0
    moves = True
    Call movecheck
    End Sub

.....

Sub k_right()
    moves = False
    r = 0
    c = 1
    moves = True
    Call movecheck
End Sub

.....

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can poll the keyboard in your sub before each step. Then do a

Public Declare Function GetKeyboardState Lib "user32" Alias "GetKeyboardState" (pbKeyState As Byte) As Long

dim keybrdbuff(255) as byte

For x = 0 to 255
    If 0<>keybrdbuff(x) then Exit Sub
Next

GetKeyboardState Function


The GetKeyboardState function copies the status of the 256 virtual keys to the specified buffer.

Syntax

BOOL GetKeyboardState(PBYTE lpKeyState);

Parameters

lpKeyState [in] Pointer to the 256-byte array that receives the status data for each virtual key. Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

An application can call this function to retrieve the current status of all the virtual keys. The status changes as a thread removes keyboard messages from its message queue. The status does not change as keyboard messages are posted to the thread's message queue, nor does it change as keyboard messages are posted to or retrieved from message queues of other threads. (Exception: Threads that are connected through AttachThreadInput share the same keyboard state.)

When the function returns, each member of the array pointed to by the lpKeyState parameter contains status data for a virtual key. If the high-order bit is 1, the key is down; otherwise, it is up. If the key is a toggle key, for example CAPS LOCK, then the low-order bit is 1 when the key is toggled and is 0 if the key is untoggled. The low-order bit is meaningless for non-toggle keys. A toggle key is said to be toggled when it is turned on. A toggle key's indicator light (if any) on the keyboard will be on when the key is toggled, and off when the key is untoggled.

To retrieve status information for an individual key, use the GetKeyState function. To retrieve the current state for an individual key regardless of whether the corresponding keyboard message has been retrieved from the message queue, use the GetAsyncKeyState function.

An application can use the virtual-key code constants VK_SHIFT, VK_CONTROL and VK_MENU as indices into the array pointed to by lpKeyState. This gives the status of the SHIFT, CTRL, or ALT keys without distinguishing between left and right. An application can also use the following virtual-key code constants as indices to distinguish between the left and right instances of those keys:

VK_LSHIFT 
VK_RSHIFT 
VK_LCONTROL 
VK_RCONTROL 
VK_LMENU 
VK_RMENU

These left- and right-distinguishing constants are available to an application only through the GetKeyboardState, SetKeyboardState, GetAsyncKeyState, GetKeyState, and MapVirtualKey functions.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...