Adjusting player movement speed with the mouse wheel

I have a basic movement script with forward, backward, left, right, and jump keys. What I want now is to add the ability to either increase or decrease the player’s movement speed with the mouse wheel, like the old Splinter Cell games. And like those games, I want the maximum and minimum speeds to be capped, so even if I scroll the mouse wheel upward a thousand times, the speed will remain constant after only three or four scrolls . . . if that makes any sense lol.

Here’s my script so far:


import bge


def main():

    # Assigning the variables.
    cont = bge.logic.getCurrentController()
    player = cont.owner
    keyboard = bge.logic.keyboard
    mouse = bge.logic.mouse
    spdNormal = 0.1
    spdUp = 0.02
    spdDown = -0.02

    # Defining movement keys (input method and keyboard/mouse event).
    keyForward = bge.logic.KX_INPUT_ACTIVE == keyboard.events[bge.events.WKEY]
    keyBackward = bge.logic.KX_INPUT_ACTIVE == keyboard.events[bge.events.SKEY]
    keyLeft = bge.logic.KX_INPUT_ACTIVE == keyboard.events[bge.events.AKEY]
    keyRight = bge.logic.KX_INPUT_ACTIVE == keyboard.events[bge.events.DKEY]
    keyJump = bge.logic.KX_INPUT_JUST_ACTIVATED == keyboard.events[bge.events.SPACEKEY]
    keySpdUp = bge.logic.KX_INPUT_JUST_ACTIVATED == mouse.events[bge.events.WHEELUPMOUSE]
    keySpdDown = bge.logic.KX_INPUT_JUST_ACTIVATED == mouse.events[bge.events.WHEELDOWNMOUSE]

    # Arguments for player.applyMovement are as follows: ([x, y, z], Local?)
    if keyForward:
        player.applyMovement([0, spdNormal, 0], True)
    if keyBackward:
        player.applyMovement([0, -spdNormal, 0], True)
    if keyLeft:
        player.applyMovement([-spdNormal, 0, 0], True)
    if keyRight:
        player.applyMovement([spdNormal, 0, 0], True)
    if keyJump:
        player.applyMovement([0, 0, 0.8], False)

main()

Any help would be greatly appreciated.

A) place the speed into a property

mouse wheel up sensor   -> AND -> property Add "speed"  0.02
mouse wheel down sensor -> AND -> property Add "speed" -0.02

B) use the current value of the property to perform motion


def move(controller):
    sensors = controller.sensors
    owner = controller.owner

    speed  = owner.get("speed", 0.1)
    
    xSpeed  = sensors["forward"].positive * 1 + sensors["backward"].positive * -1
    ySpeed  = sensors["right"].positive * 1 + sensors["left"].positive * -1

    owner.applyMovement([ xSpeed, ySpeed, 0.0], True)

I tried it, but it’s not working lol.

The “forward,” “backward,” etc. . . . should I replace that with “keyForward,” “keyBackward,” etc.? Sorry, I’m really new to scripting.

To set caps, just use a couple of if statements:


MIN = 0.02
MAX = 0.2
spd = owner['speed']
if spd <= MIN:
    spd = MIN
if spd >= MAX:
   spd = MAX
owner['speed'] = spd

have these tests run before checking for movement keys and applying movement.

So would this be correct?


import bge


def main():

    # Assigning the variables.
    cont = bge.logic.getCurrentController()
    player = cont.owner
    keyboard = bge.logic.keyboard
    mouse = bge.logic.mouse
    spdNormal = 0.1
    spdUp = 0.02
    spdDown = -0.02

    # Assigning min/max movement speed.
    spdMin = 0.02
    spdMax = 0.2
    spdPlayer = player['speed']

    if spdPlayer <= spdMin:
        spdPlayer = spdMin
    if spdPlayer >= spdMax:
        spdPlayer = spdMax
    player['speed'] = spdPlayer

    # Defining movement keys (input method and keyboard/mouse event).
    keyForward = bge.logic.KX_INPUT_ACTIVE == keyboard.events[bge.events.WKEY]
    keyBackward = bge.logic.KX_INPUT_ACTIVE == keyboard.events[bge.events.SKEY]
    keyLeft = bge.logic.KX_INPUT_ACTIVE == keyboard.events[bge.events.AKEY]
    keyRight = bge.logic.KX_INPUT_ACTIVE == keyboard.events[bge.events.DKEY]
    keyJump = bge.logic.KX_INPUT_JUST_ACTIVATED == keyboard.events[bge.events.SPACEKEY]
    keySpdUp = bge.logic.KX_INPUT_JUST_ACTIVATED == mouse.events[bge.events.WHEELUPMOUSE]
    keySpdDown = bge.logic.KX_INPUT_JUST_ACTIVATED == mouse.events[bge.events.WHEELDOWNMOUSE]

    # Arguments for player.applyMovement are as follows: ([x, y, z], Local?)
    if keyForward:
        player.applyMovement([0, spdNormal, 0], True)
    if keyBackward:
        player.applyMovement([0, -spdNormal, 0], True)
    if keyLeft:
        player.applyMovement([-spdNormal, 0, 0], True)
    if keyRight:
        player.applyMovement([spdNormal, 0, 0], True)
    if keyJump:
        player.applyMovement([0, 0, 0.8], False)

main()

The player[‘speed’] = spdPlayer . . . is “speed” referring to the property from Monster’s post? Because I haven’t implemented that yet lol. Frankly I’m confused by his code. (I’m new to scripting, so try to be patient with me :p.) Can you explain what his code means and how to implement it into my script?

I hope this work for you


if keySpdUp.positive and spdNormal < 1: #cap at 1
    spdNormal += spdUp
elif keySpdDown.positive and spdNormal > 0: #cap at 0
    spdNormal -= spdDown   

Sorry I forgot to add the speed to the formula:


def move(controller):
    sensors = controller.sensors
    owner = controller.owner

    speed  = owner.get("speed", 0.1)
    
    xSpeed  = (sensors["forward"].positive * 1 + sensors["backward"].positive * -1)*speed
    ySpeed  = (sensors["right"].positive * 1 + sensors["left"].positive * -1)*speed
    
    
    owner.applyMovement([ xSpeed, ySpeed, 0.0], True)

Btw. you do not need to define a function in a script. It forces the reader to jump up and down in your file to follow the process flow.

Attachments

variableSpeedDemo.blend (83.5 KB)

All right, thanks to everyone’s help, I can use the mouse wheel to change the player’s movement speed between 0.025 and 0.175 units per second. However, the mouse wheel controls and actuators are done through logic bricks, but I’d like to know how to implement them in the script.

Oh, and on an unrelated note, the player keeps falling through the floor whenever I hit Spacebar more than once per jump lol. Does anyone know why this happens and how I can prevent this?

Here’s the blend file if you feel like helping me out with either problem. I hope all the scripts are embedded in the blend.

move_test.blend (580 KB)