Multiple key press player movement routine.
#1
If you ever wanted to move a player in any direction by holding down the cursor arrow keys while still being able to process other events and even type other keys while still moving, this might be of interest to you.

Controls: (Hold down keys for perpetual movement.)
Right arrow = move right.
Left arrow = move left.
Up arrow = move up
Down arrow = move down... Duh, this sounds so stupid up to now, but wait...
Up arrow + left arrow = diagonal up and to the left.
Up arrow + right arrow = diagonal up and to the right.
Down arrow + left arrow = diagonal down and to the left.
Down arrow + right arrow = diagonal down and to the right.
Left ctrl + or without any arrow keys held and while or while not moving increases speed.
Left alt + or without any arrow keys held and while or while not moving decreases speed.
Type any key to print key character to the upper right screen while or while not moving.
space bar honks horn.
esc to quit.

An old problem with QBasic was not being able to detect more than two key presses. Special keys like ctrl, alt, and shift all had to be recognized with DEF SEG PEEK/POKE routines. (BTW - we can still use those PEKK/POKE (1046) routines in QB64.)

Anyway, here's the demo...

Code: (Select All)
' Note: timer is not adjusted for stroke of midnight event, so don't stay up late playing this.
WIDTH 140, 42
_SCREENMOVE 0, 0
DIM move_speed AS DOUBLE
top = 2: bottom = _HEIGHT: left = 1: right = _WIDTH
PRINT "Press single or combo of arrow keys to move. Rt. Ctrl = faster / Rt. Alt = slower. "
LOCATE 2, 1: PRINT STRING$(_WIDTH, "_");
move_speed = 25
player_y = _HEIGHT \ 2 + 1: player_x = _WIDTH \ 2
LOCATE player_y, player_x: PRINT "*";
_KEYCLEAR
DO
    _LIMIT 60
    LOCATE 1, 50: PRINT "Movement y, x: "; mpy; mpx; "  Speed Delay ="; move_speed;

    ' If you only want speed changes when a player moves then remove the timer and move this routine to: IF move_player = -1 AND ABS(z1 - TIMER) > .07 THEN
    IF ABS(z3 - TIMER) > .1 THEN ' Check every .1 seconds for a speed change.
        IF _KEYDOWN(100307) AND move_speed < 50 THEN move_speed = move_speed + 1
        IF _KEYDOWN(100305) AND move_speed > 0 THEN move_speed = move_speed - 1
        z3 = TIMER
    END IF

    IF ABS(z2 - TIMER) > move_speed / 100 THEN ' Moving lag. Note: Division needed because computer math can't add decimal numbers correctly.
        IF move_player = 0 THEN
            IF _KEYDOWN(18432) OR _KEYDOWN(19200) OR _KEYDOWN(19712) OR _KEYDOWN(20480) THEN ' Arrow keys.
                move_player = -1
                z1 = TIMER ' Delay timer for key lag.
            END IF
        END IF
    END IF

    IF move_player = -1 THEN
        IF ABS(z1 - TIMER) > .05 THEN ' Key lag. A slight delay to allow player to press two keys together within a reasonable amout of time.
            DO ' Falx loop to throw out illegal key combos like up + down.
                mpx = 0: mpy = 0

                ' Eliminate illegal combos.
                IF _KEYDOWN(18432) AND _KEYDOWN(20480) THEN move_player = 0: z2 = TIMER: EXIT DO
                IF _KEYDOWN(19712) AND _KEYDOWN(19200) THEN move_player = 0: z2 = TIMER: EXIT DO

                ' IF female THEN STOP AND GET #1, directions.
                IF _KEYDOWN(18432) THEN ' Up-arrow.
                    mpy = -1
                END IF
                IF _KEYDOWN(19712) THEN ' Right-arrow.
                    mpx = 1
                END IF
                IF _KEYDOWN(20480) THEN ' Down-arrow.
                    mpy = 1
                END IF
                IF _KEYDOWN(19200) THEN ' Left-arrow.
                    mpx = -1
                END IF

                IF mpx AND mpy THEN ' Routine to cancel keys as a double hold is being lifted. This allows for the difference of both keys cannot be released at exactly the same time.
                    combo = -1
                ELSE
                    IF combo THEN combo = 0: move_player = 0: EXIT DO
                END IF

                ' Move player
                IF player_y + mpy > top AND player_y + mpy <= bottom AND player_x + 2 * mpx > left AND player_x + 2 * mpx < right THEN
                    LOCATE player_y, player_x
                    PRINT " ";
                    player_y = player_y + mpy: player_x = player_x + 2 * mpx
                    LOCATE player_y, player_x
                    PRINT "*";
                ELSE
                    BEEP ' Hit the wall!
                END IF
                move_player = 0
                z2 = TIMER ' Timer for moving lag regulated by the move_speed variable.
                EXIT DO
            LOOP
        END IF
    ELSE ' If you want additional key routines, put them here...
        ky$ = INKEY$
        IF LEN(ky$) = 1 THEN ' For demo, exclude keys that start with chr$(0). Note without this arrow keys would still register here.
            LOCATE 1, _WIDTH - 22: PRINT SPACE$(22);
            LOCATE 1, _WIDTH - 22
            PRINT "You pressed key: "; ky$;
            SELECT CASE ky$
                CASE CHR$(32) ' Space bar
                    BEEP
                CASE CHR$(27) ' Esc
                    END
            END SELECT
        END IF
    END IF
LOOP

Pete
Reply


Messages In This Thread
Multiple key press player movement routine. - by Pete - 10-02-2022, 05:46 PM



Users browsing this thread: 2 Guest(s)